~ubuntu-branches/ubuntu/raring/qtwebkit-source/raring-proposed

« back to all changes in this revision

Viewing changes to Source/JavaScriptCore/offlineasm/transform.rb

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-02-18 14:24:18 UTC
  • Revision ID: package-import@ubuntu.com-20130218142418-eon0jmjg3nj438uy
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2011 Apple Inc. All rights reserved.
 
2
#
 
3
# Redistribution and use in source and binary forms, with or without
 
4
# modification, are permitted provided that the following conditions
 
5
# are met:
 
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.
 
11
#
 
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.
 
23
 
 
24
require "config"
 
25
require "ast"
 
26
 
 
27
#
 
28
# node.resolveSettings(settings)
 
29
#
 
30
# Construct a new AST that does not have any IfThenElse nodes by
 
31
# substituting concrete boolean values for each Setting.
 
32
#
 
33
 
 
34
class Node
 
35
    def resolveSettings(settings)
 
36
        mapChildren {
 
37
            | child |
 
38
            child.resolveSettings(settings)
 
39
        }
 
40
    end
 
41
end
 
42
 
 
43
class True
 
44
    def resolveSettings(settings)
 
45
        self
 
46
    end
 
47
end
 
48
 
 
49
class False
 
50
    def resolveSettings(settings)
 
51
        self
 
52
    end
 
53
end
 
54
 
 
55
class Setting
 
56
    def resolveSettings(settings)
 
57
        settings[@name].asNode
 
58
    end
 
59
end
 
60
 
 
61
class And
 
62
    def resolveSettings(settings)
 
63
        (@left.resolveSettings(settings).value and @right.resolveSettings(settings).value).asNode
 
64
    end
 
65
end
 
66
 
 
67
class Or
 
68
    def resolveSettings(settings)
 
69
        (@left.resolveSettings(settings).value or @right.resolveSettings(settings).value).asNode
 
70
    end
 
71
end
 
72
 
 
73
class Not
 
74
    def resolveSettings(settings)
 
75
        (not @child.resolveSettings(settings).value).asNode
 
76
    end
 
77
end
 
78
 
 
79
class IfThenElse
 
80
    def resolveSettings(settings)
 
81
        if @predicate.resolveSettings(settings).value
 
82
            @thenCase.resolveSettings(settings)
 
83
        else
 
84
            @elseCase.resolveSettings(settings)
 
85
        end
 
86
    end
 
87
end
 
88
 
 
89
class Sequence
 
90
    def resolveSettings(settings)
 
91
        newList = []
 
92
        @list.each {
 
93
            | item |
 
94
            item = item.resolveSettings(settings)
 
95
            if item.is_a? Sequence
 
96
                newList += item.list
 
97
            else
 
98
                newList << item
 
99
            end
 
100
        }
 
101
        Sequence.new(codeOrigin, newList)
 
102
    end
 
103
end
 
104
 
 
105
#
 
106
# node.demacroify(macros)
 
107
# node.substitute(mapping)
 
108
#
 
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.
 
112
#
 
113
 
 
114
class Node
 
115
    def demacroify(macros)
 
116
        mapChildren {
 
117
            | child |
 
118
            child.demacroify(macros)
 
119
        }
 
120
    end
 
121
    
 
122
    def substitute(mapping)
 
123
        mapChildren {
 
124
            | child |
 
125
            child.substitute(mapping)
 
126
        }
 
127
    end
 
128
    
 
129
    def substituteLabels(mapping)
 
130
        mapChildren {
 
131
            | child |
 
132
            child.substituteLabels(mapping)
 
133
        }
 
134
    end
 
135
end
 
136
 
 
137
class Macro
 
138
    def substitute(mapping)
 
139
        myMapping = {}
 
140
        mapping.each_pair {
 
141
            | key, value |
 
142
            unless @variables.include? key
 
143
                myMapping[key] = value
 
144
            end
 
145
        }
 
146
        mapChildren {
 
147
            | child |
 
148
            child.substitute(myMapping)
 
149
        }
 
150
    end
 
151
end
 
152
 
 
153
class Variable
 
154
    def substitute(mapping)
 
155
        if mapping[self]
 
156
            mapping[self]
 
157
        else
 
158
            self
 
159
        end
 
160
    end
 
161
end
 
162
 
 
163
class LocalLabel
 
164
    def substituteLabels(mapping)
 
165
        if mapping[self]
 
166
            mapping[self]
 
167
        else
 
168
            self
 
169
        end
 
170
    end
 
171
end
 
172
 
 
173
class Sequence
 
174
    def substitute(constants)
 
175
        newList = []
 
176
        myConstants = constants.dup
 
177
        @list.each {
 
178
            | item |
 
179
            if item.is_a? ConstDecl
 
180
                myConstants[item.variable] = item.value.substitute(myConstants)
 
181
            else
 
182
                newList << item.substitute(myConstants)
 
183
            end
 
184
        }
 
185
        Sequence.new(codeOrigin, newList)
 
186
    end
 
187
    
 
188
    def renameLabels(comment)
 
189
        mapping = {}
 
190
        
 
191
        @list.each {
 
192
            | item |
 
193
            if item.is_a? LocalLabel
 
194
                mapping[item] = LocalLabel.unique(if comment then comment + "_" else "" end + item.cleanName)
 
195
            end
 
196
        }
 
197
        
 
198
        substituteLabels(mapping)
 
199
    end
 
200
    
 
201
    def demacroify(macros)
 
202
        myMacros = macros.dup
 
203
        @list.each {
 
204
            | item |
 
205
            if item.is_a? Macro
 
206
                myMacros[item.name] = item
 
207
            end
 
208
        }
 
209
        newList = []
 
210
        @list.each {
 
211
            | item |
 
212
            if item.is_a? Macro
 
213
                # Ignore.
 
214
            elsif item.is_a? MacroCall
 
215
                mapping = {}
 
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 {
 
220
                    | idx |
 
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
 
227
                    else
 
228
                        myMyMacros[myMacros[item.name].variables[idx]] = nil
 
229
                        mapping[myMacros[item.name].variables[idx]] = item.operands[idx]
 
230
                    end
 
231
                }
 
232
                if item.annotation
 
233
                    newList << Instruction.new(item.codeOrigin, "localAnnotation", [], item.annotation)
 
234
                end
 
235
                newList += myMacros[item.name].body.substitute(mapping).demacroify(myMyMacros).renameLabels(item.name).list
 
236
            else
 
237
                newList << item.demacroify(myMacros)
 
238
            end
 
239
        }
 
240
        Sequence.new(codeOrigin, newList).substitute({})
 
241
    end
 
242
end
 
243
 
 
244
#
 
245
# node.resolveOffsets(offsets, sizes)
 
246
#
 
247
# Construct a new AST that has offset values instead of symbolic
 
248
# offsets.
 
249
#
 
250
 
 
251
class Node
 
252
    def resolveOffsets(offsets, sizes)
 
253
        mapChildren {
 
254
            | child |
 
255
            child.resolveOffsets(offsets, sizes)
 
256
        }
 
257
    end
 
258
end
 
259
 
 
260
class StructOffset
 
261
    def resolveOffsets(offsets, sizes)
 
262
        if offsets[self]
 
263
            Immediate.new(codeOrigin, offsets[self])
 
264
        else
 
265
            self
 
266
        end
 
267
    end
 
268
end
 
269
 
 
270
class Sizeof
 
271
    def resolveOffsets(offsets, sizes)
 
272
        if sizes[self]
 
273
            Immediate.new(codeOrigin, sizes[self])
 
274
        else
 
275
            puts "Could not find #{self.inspect} in #{sizes.keys.inspect}"
 
276
            puts "sizes = #{sizes.inspect}"
 
277
            self
 
278
        end
 
279
    end
 
280
end
 
281
 
 
282
#
 
283
# node.fold
 
284
#
 
285
# Resolve constant references and compute arithmetic expressions.
 
286
#
 
287
 
 
288
class Node
 
289
    def fold
 
290
        mapChildren {
 
291
            | child |
 
292
            child.fold
 
293
        }
 
294
    end
 
295
end
 
296
 
 
297
class AddImmediates
 
298
    def fold
 
299
        @left = @left.fold
 
300
        @right = @right.fold
 
301
        return self unless @left.is_a? Immediate
 
302
        return self unless @right.is_a? Immediate
 
303
        Immediate.new(codeOrigin, @left.value + @right.value)
 
304
    end
 
305
end
 
306
 
 
307
class SubImmediates
 
308
    def fold
 
309
        @left = @left.fold
 
310
        @right = @right.fold
 
311
        return self unless @left.is_a? Immediate
 
312
        return self unless @right.is_a? Immediate
 
313
        Immediate.new(codeOrigin, @left.value - @right.value)
 
314
    end
 
315
end
 
316
 
 
317
class MulImmediates
 
318
    def fold
 
319
        @left = @left.fold
 
320
        @right = @right.fold
 
321
        return self unless @left.is_a? Immediate
 
322
        return self unless @right.is_a? Immediate
 
323
        Immediate.new(codeOrigin, @left.value * @right.value)
 
324
    end
 
325
end
 
326
 
 
327
class NegImmediate
 
328
    def fold
 
329
        @child = @child.fold
 
330
        return self unless @child.is_a? Immediate
 
331
        Immediate.new(codeOrigin, -@child.value)
 
332
    end
 
333
end
 
334
 
 
335
class OrImmediates
 
336
    def fold
 
337
        @left = @left.fold
 
338
        @right = @right.fold
 
339
        return self unless @left.is_a? Immediate
 
340
        return self unless @right.is_a? Immediate
 
341
        Immediate.new(codeOrigin, @left.value | @right.value)
 
342
    end
 
343
end
 
344
 
 
345
class AndImmediates
 
346
    def fold
 
347
        @left = @left.fold
 
348
        @right = @right.fold
 
349
        return self unless @left.is_a? Immediate
 
350
        return self unless @right.is_a? Immediate
 
351
        Immediate.new(codeOrigin, @left.value & @right.value)
 
352
    end
 
353
end
 
354
 
 
355
class XorImmediates
 
356
    def fold
 
357
        @left = @left.fold
 
358
        @right = @right.fold
 
359
        return self unless @left.is_a? Immediate
 
360
        return self unless @right.is_a? Immediate
 
361
        Immediate.new(codeOrigin, @left.value ^ @right.value)
 
362
    end
 
363
end
 
364
 
 
365
class BitnotImmediate
 
366
    def fold
 
367
        @child = @child.fold
 
368
        return self unless @child.is_a? Immediate
 
369
        Immediate.new(codeOrigin, ~@child.value)
 
370
    end
 
371
end
 
372
 
 
373
#
 
374
# node.resolveAfterSettings(offsets, sizes)
 
375
#
 
376
# Compile assembly against a set of offsets.
 
377
#
 
378
 
 
379
class Node
 
380
    def resolve(offsets, sizes)
 
381
        demacroify({}).resolveOffsets(offsets, sizes).fold
 
382
    end
 
383
end
 
384
 
 
385
#
 
386
# node.validate
 
387
#
 
388
# Checks that the node is ready for backend compilation.
 
389
#
 
390
 
 
391
class Node
 
392
    def validate
 
393
        raise "Unresolved #{dump} at #{codeOriginString}"
 
394
    end
 
395
    
 
396
    def validateChildren
 
397
        children.each {
 
398
            | node |
 
399
            node.validate
 
400
        }
 
401
    end
 
402
end
 
403
 
 
404
class Sequence
 
405
    def validate
 
406
        validateChildren
 
407
    end
 
408
end
 
409
 
 
410
class Immediate
 
411
    def validate
 
412
    end
 
413
end
 
414
 
 
415
class RegisterID
 
416
    def validate
 
417
    end
 
418
end
 
419
 
 
420
class FPRegisterID
 
421
    def validate
 
422
    end
 
423
end
 
424
 
 
425
class Address
 
426
    def validate
 
427
        validateChildren
 
428
    end
 
429
end
 
430
 
 
431
class BaseIndex
 
432
    def validate
 
433
        validateChildren
 
434
    end
 
435
end
 
436
 
 
437
class AbsoluteAddress
 
438
    def validate
 
439
        validateChildren
 
440
    end
 
441
end
 
442
 
 
443
class Instruction
 
444
    def validate
 
445
        validateChildren
 
446
    end
 
447
end
 
448
 
 
449
class Error
 
450
    def validate
 
451
    end
 
452
end
 
453
 
 
454
class Label
 
455
    def validate
 
456
    end
 
457
end
 
458
 
 
459
class LocalLabel
 
460
    def validate
 
461
    end
 
462
end
 
463
 
 
464
class LabelReference
 
465
    def validate
 
466
    end
 
467
end
 
468
 
 
469
class LocalLabelReference
 
470
    def validate
 
471
    end
 
472
end
 
473
 
 
474
class Skip
 
475
    def validate
 
476
    end
 
477
end
 
478