]>
git.saurik.com Git - apple/javascriptcore.git/blob - offlineasm/transform.rb
1 # Copyright (C) 2011 Apple Inc. All rights reserved.
3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions
6 # 1. Redistributions of source code must retain the above copyright
7 # notice, this list of conditions and the following disclaimer.
8 # 2. Redistributions in binary form must reproduce the above copyright
9 # notice, this list of conditions and the following disclaimer in the
10 # documentation and/or other materials provided with the distribution.
12 # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
13 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
14 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
15 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
16 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
17 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
18 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
19 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
20 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
21 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
22 # THE POSSIBILITY OF SUCH DAMAGE.
28 # node.resolveSettings(settings)
30 # Construct a new AST that does not have any IfThenElse nodes by
31 # substituting concrete boolean values for each Setting.
35 def resolveSettings(settings
)
38 child
.resolveSettings(settings
)
44 def resolveSettings(settings
)
50 def resolveSettings(settings
)
56 def resolveSettings(settings
)
57 settings
[@name].asNode
62 def resolveSettings(settings
)
63 (@left.resolveSettings(settings
).value
and @right.resolveSettings(settings
).value
).asNode
68 def resolveSettings(settings
)
69 (@left.resolveSettings(settings
).value
or @right.resolveSettings(settings
).value
).asNode
74 def resolveSettings(settings
)
75 (not @child.resolveSettings(settings
).value
).asNode
80 def resolveSettings(settings
)
81 if @predicate.resolveSettings(settings
).value
82 @thenCase.resolveSettings(settings
)
84 @elseCase.resolveSettings(settings
)
90 def resolveSettings(settings
)
94 item
= item
.resolveSettings(settings
)
95 if item
.is_a
? Sequence
101 Sequence
.new(codeOrigin
, newList
)
106 # node.demacroify(macros)
107 # node.substitute(mapping)
109 # demacroify() constructs a new AST that does not have any Macro
110 # nodes, while substitute() replaces Variable nodes with the given
111 # nodes in the mapping.
115 def demacroify(macros
)
118 child
.demacroify(macros
)
122 def substitute(mapping
)
125 child
.substitute(mapping
)
129 def substituteLabels(mapping
)
132 child
.substituteLabels(mapping
)
138 def substitute(mapping
)
142 unless @variables.include? key
143 myMapping
[key
] = value
148 child
.substitute(myMapping
)
154 def substitute(mapping
)
164 def substituteLabels(mapping
)
174 def substitute(constants
)
176 myConstants
= constants
.dup
179 if item
.is_a
? ConstDecl
180 myConstants
[item
.variable
] = item
.value
.substitute(myConstants
)
182 newList
<< item
.substitute(myConstants
)
185 Sequence
.new(codeOrigin
, newList
)
188 def renameLabels(comment
)
193 if item
.is_a
? LocalLabel
194 mapping
[item
] = LocalLabel
.unique(if comment
then comment +
"_" else "" end + item
.cleanName
)
198 substituteLabels(mapping
)
201 def demacroify(macros
)
202 myMacros
= macros
.dup
206 myMacros
[item
.name
] = item
214 elsif item
.is_a
? MacroCall
216 myMyMacros
= myMacros
.dup
217 raise "Could not find macro #{item.name} at #{item.codeOriginString}" unless myMacros
[item
.name
]
218 raise "Argument count mismatch for call to #{item.name} at #{item.codeOriginString}" unless item
.operands
.size
== myMacros
[item
.name
].variables
.size
219 item
.operands
.size
.times
{
221 if item
.operands
[idx
].is_a
? Variable
and myMacros
[item
.operands
[idx
].name
]
222 myMyMacros
[myMacros
[item
.name
].variables
[idx
].name
] = myMacros
[item
.operands
[idx
].name
]
223 mapping
[myMacros
[item
.name
].variables
[idx
].name
] = nil
224 elsif item
.operands
[idx
].is_a
? Macro
225 myMyMacros
[myMacros
[item
.name
].variables
[idx
].name
] = item
.operands
[idx
]
226 mapping
[myMacros
[item
.name
].variables
[idx
].name
] = nil
228 myMyMacros
[myMacros
[item
.name
].variables
[idx
]] = nil
229 mapping
[myMacros
[item
.name
].variables
[idx
]] = item
.operands
[idx
]
233 newList
<< Instruction
.new(item
.codeOrigin
, "localAnnotation", [], item
.annotation
)
235 newList +
= myMacros
[item
.name
].body
.substitute(mapping
).demacroify(myMyMacros
).renameLabels(item
.name
).list
237 newList
<< item
.demacroify(myMacros
)
240 Sequence
.new(codeOrigin
, newList
).substitute({})
245 # node.resolveOffsets(offsets, sizes)
247 # Construct a new AST that has offset values instead of symbolic
252 def resolveOffsets(offsets
, sizes
)
255 child
.resolveOffsets(offsets
, sizes
)
261 def resolveOffsets(offsets
, sizes
)
263 Immediate
.new(codeOrigin
, offsets
[self])
271 def resolveOffsets(offsets
, sizes
)
273 Immediate
.new(codeOrigin
, sizes
[self])
275 puts
"Could not find #{self.inspect} in #{sizes.keys.inspect}"
276 puts
"sizes = #{sizes.inspect}"
285 # Resolve constant references and compute arithmetic expressions.
301 return self unless @left.is_a
? Immediate
302 return self unless @right.is_a
? Immediate
303 Immediate
.new(codeOrigin
, @left.value +
@right.value
)
311 return self unless @left.is_a
? Immediate
312 return self unless @right.is_a
? Immediate
313 Immediate
.new(codeOrigin
, @left.value
- @right.value
)
321 return self unless @left.is_a
? Immediate
322 return self unless @right.is_a
? Immediate
323 Immediate
.new(codeOrigin
, @left.value
* @right.value
)
330 return self unless @child.is_a
? Immediate
331 Immediate
.new(codeOrigin
, -@child.value
)
339 return self unless @left.is_a
? Immediate
340 return self unless @right.is_a
? Immediate
341 Immediate
.new(codeOrigin
, @left.value
| @right.value
)
349 return self unless @left.is_a
? Immediate
350 return self unless @right.is_a
? Immediate
351 Immediate
.new(codeOrigin
, @left.value
& @right.value
)
359 return self unless @left.is_a
? Immediate
360 return self unless @right.is_a
? Immediate
361 Immediate
.new(codeOrigin
, @left.value ^
@right.value
)
365 class BitnotImmediate
368 return self unless @child.is_a
? Immediate
369 Immediate
.new(codeOrigin
, ~
@child.value
)
374 # node.resolveAfterSettings(offsets, sizes)
376 # Compile assembly against a set of offsets.
380 def resolve(offsets
, sizes
)
381 demacroify({}).resolveOffsets(offsets
, sizes
).fold
388 # Checks that the node is ready for backend compilation.
393 raise "Unresolved #{dump} at #{codeOriginString}"
408 # Further verify that this list contains only instructions, labels, and skips.
411 unless node
.is_a
? Instruction
or
413 node
.is_a
? LocalLabel
or
415 raise "Unexpected #{node.inspect} at #{node.codeOrigin}"
448 class AbsoluteAddress
480 class LocalLabelReference