[Qt]REGRESSION(r92254): It made 2 tests timeout
[WebKit-https.git] / Source / JavaScriptCore / offlineasm / offsets.rb
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 "ast"
25 require "offset_extractor_constants"
26
27 OFFSET_MAGIC_NUMBERS = [ 0xec577ac7, 0x0ff5e755 ]
28
29 #
30 # offsetsList(ast)
31 # sizesList(ast)
32 #
33 # Returns a list of offsets and sizes used by the AST.
34 #
35
36 def offsetsList(ast)
37     ast.filter(StructOffset).uniq.sort
38 end
39
40 def sizesList(ast)
41     ast.filter(Sizeof).uniq.sort
42 end
43
44 #
45 # offsetsAndConfigurationIndex(ast, file) ->
46 #     [offsets, index]
47 #
48 # Parses the offsets from a file and returns a list of offsets and the
49 # index of the configuration that is valid in this build target.
50 #
51
52 def offsetsAndConfigurationIndex(file)
53     index = nil
54     offsets = []
55     endiannessMarkerBytes = nil
56     
57     def readInt(endianness, inp)
58         bytes = []
59         4.times {
60             bytes << inp.getbyte
61         }
62         
63         if endianness == :little
64             # Little endian
65             (bytes[0] << 0 |
66              bytes[1] << 8 |
67              bytes[2] << 16 |
68              bytes[3] << 24)
69         else
70             # Big endian
71             (bytes[0] << 24 |
72              bytes[1] << 16 |
73              bytes[2] << 8 |
74              bytes[3] << 0)
75         end
76     end
77     
78     [:little, :big].each {
79         | endianness |
80         magicBytes = []
81         MAGIC_NUMBERS.each {
82             | number |
83             currentBytes = []
84             4.times {
85                 currentBytes << (number & 0xff)
86                 number >>= 8
87             }
88             if endianness == :big
89                 currentBytes.reverse!
90             end
91             magicBytes += currentBytes
92         }
93         
94         File.open(file, "r") {
95             | inp |
96             whereInMarker = 0
97             loop {
98                 byte = inp.getbyte
99                 break unless byte
100                 if byte == magicBytes[whereInMarker]
101                     whereInMarker += 1
102                     if whereInMarker == magicBytes.size
103                         # We have a match! If we have not yet read the endianness marker and index,
104                         # then read those now; otherwise read an offset.
105                         
106                         if not index
107                             index = readInt(endianness, inp)
108                         else
109                             offsets << readInt(endianness, inp)
110                         end
111                         
112                         whereInMarker = 0
113                     end
114                 else
115                     whereInMarker = 0
116                 end
117             }
118         }
119         
120         break if index
121     }
122     
123     raise unless index
124     
125     [offsets, index]
126 end
127
128 #
129 # buildOffsetsMap(ast, offsetsList) -> [offsets, sizes]
130 #
131 # Builds a mapping between StructOffset nodes and their values.
132 #
133
134 def buildOffsetsMap(ast, offsetsList)
135     offsetsMap = {}
136     sizesMap = {}
137     astOffsetsList = offsetsList(ast)
138     astSizesList = sizesList(ast)
139     raise unless astOffsetsList.size + astSizesList.size == offsetsList.size
140     offsetsList(ast).each_with_index {
141         | structOffset, index |
142         offsetsMap[structOffset] = offsetsList.shift
143     }
144     sizesList(ast).each_with_index {
145         | sizeof, index |
146         sizesMap[sizeof] = offsetsList.shift
147     }
148     [offsetsMap, sizesMap]
149 end
150