]>
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.
27 # node.resolveSettings(settings)
29 # Construct a new AST that does not have any IfThenElse nodes by
30 # substituting concrete boolean values for each Setting.
34 def resolveSettings(settings
)
37 child
.resolveSettings(settings
)
43 def resolveSettings(settings
)
49 def resolveSettings(settings
)
55 def resolveSettings(settings
)
56 settings
[@name].asNode
61 def resolveSettings(settings
)
62 (@left.resolveSettings(settings
).value
and @right.resolveSettings(settings
).value
).asNode
67 def resolveSettings(settings
)
68 (@left.resolveSettings(settings
).value
or @right.resolveSettings(settings
).value
).asNode
73 def resolveSettings(settings
)
74 (not @child.resolveSettings(settings
).value
).asNode
79 def resolveSettings(settings
)
80 if @predicate.resolveSettings(settings
).value
81 @thenCase.resolveSettings(settings
)
83 @elseCase.resolveSettings(settings
)
89 def resolveSettings(settings
)
93 item
= item
.resolveSettings(settings
)
94 if item
.is_a
? Sequence
100 Sequence
.new(codeOrigin
, newList
)
105 # node.demacroify(macros)
106 # node.substitute(mapping)
108 # demacroify() constructs a new AST that does not have any Macro
109 # nodes, while substitute() replaces Variable nodes with the given
110 # nodes in the mapping.
114 def demacroify(macros
)
117 child
.demacroify(macros
)
121 def substitute(mapping
)
124 child
.substitute(mapping
)
128 def substituteLabels(mapping
)
131 child
.substituteLabels(mapping
)
137 def substitute(mapping
)
141 unless @variables.include? key
142 myMapping
[key
] = value
147 child
.substitute(myMapping
)
153 def substitute(mapping
)
163 def substituteLabels(mapping
)
173 def substitute(constants
)
175 myConstants
= constants
.dup
178 if item
.is_a
? ConstDecl
179 myConstants
[item
.variable
] = item
.value
.substitute(myConstants
)
181 newList
<< item
.substitute(myConstants
)
184 Sequence
.new(codeOrigin
, newList
)
187 def renameLabels(comment
)
192 if item
.is_a
? LocalLabel
193 mapping
[item
] = LocalLabel
.unique(if comment
then comment +
"_" else "" end + item
.cleanName
)
197 substituteLabels(mapping
)
200 def demacroify(macros
)
201 myMacros
= macros
.dup
205 myMacros
[item
.name
] = item
213 elsif item
.is_a
? MacroCall
215 myMyMacros
= myMacros
.dup
216 raise "Could not find macro #{item.name} at #{item.codeOriginString}" unless myMacros
[item
.name
]
217 raise "Argument count mismatch for call to #{item.name} at #{item.codeOriginString}" unless item
.operands
.size
== myMacros
[item
.name
].variables
.size
218 item
.operands
.size
.times
{
220 if item
.operands
[idx
].is_a
? Variable
and myMacros
[item
.operands
[idx
].name
]
221 myMyMacros
[myMacros
[item
.name
].variables
[idx
].name
] = myMacros
[item
.operands
[idx
].name
]
222 mapping
[myMacros
[item
.name
].variables
[idx
].name
] = nil
223 elsif item
.operands
[idx
].is_a
? Macro
224 myMyMacros
[myMacros
[item
.name
].variables
[idx
].name
] = item
.operands
[idx
]
225 mapping
[myMacros
[item
.name
].variables
[idx
].name
] = nil
227 myMyMacros
[myMacros
[item
.name
].variables
[idx
]] = nil
228 mapping
[myMacros
[item
.name
].variables
[idx
]] = item
.operands
[idx
]
231 newList +
= myMacros
[item
.name
].body
.substitute(mapping
).demacroify(myMyMacros
).renameLabels(item
.name
).list
233 newList
<< item
.demacroify(myMacros
)
236 Sequence
.new(codeOrigin
, newList
).substitute({})
241 # node.resolveOffsets(offsets, sizes)
243 # Construct a new AST that has offset values instead of symbolic
248 def resolveOffsets(offsets
, sizes
)
251 child
.resolveOffsets(offsets
, sizes
)
257 def resolveOffsets(offsets
, sizes
)
259 Immediate
.new(codeOrigin
, offsets
[self])
267 def resolveOffsets(offsets
, sizes
)
269 Immediate
.new(codeOrigin
, sizes
[self])
271 puts
"Could not find #{self.inspect} in #{sizes.keys.inspect}"
272 puts
"sizes = #{sizes.inspect}"
281 # Resolve constant references and compute arithmetic expressions.
297 return self unless @left.is_a
? Immediate
298 return self unless @right.is_a
? Immediate
299 Immediate
.new(codeOrigin
, @left.value +
@right.value
)
307 return self unless @left.is_a
? Immediate
308 return self unless @right.is_a
? Immediate
309 Immediate
.new(codeOrigin
, @left.value
- @right.value
)
317 return self unless @left.is_a
? Immediate
318 return self unless @right.is_a
? Immediate
319 Immediate
.new(codeOrigin
, @left.value
* @right.value
)
326 return self unless @child.is_a
? Immediate
327 Immediate
.new(codeOrigin
, -@child.value
)
335 return self unless @left.is_a
? Immediate
336 return self unless @right.is_a
? Immediate
337 Immediate
.new(codeOrigin
, @left.value
| @right.value
)
345 return self unless @left.is_a
? Immediate
346 return self unless @right.is_a
? Immediate
347 Immediate
.new(codeOrigin
, @left.value
& @right.value
)
355 return self unless @left.is_a
? Immediate
356 return self unless @right.is_a
? Immediate
357 Immediate
.new(codeOrigin
, @left.value ^
@right.value
)
361 class BitnotImmediate
364 return self unless @child.is_a
? Immediate
365 Immediate
.new(codeOrigin
, ~
@child.value
)
370 # node.resolveAfterSettings(offsets, sizes)
372 # Compile assembly against a set of offsets.
376 def resolve(offsets
, sizes
)
377 demacroify({}).resolveOffsets(offsets
, sizes
).fold
384 # Checks that the node is ready for backend compilation.
389 raise "Unresolved #{dump} at #{codeOriginString}"
433 class AbsoluteAddress
465 class LocalLabelReference