Update LLVM binary drops and scripts to the latest version from SVN
[WebKit-https.git] / Tools / ReducedFTL / combineModules.rb
1 #!/usr/bin/env ruby
2
3 # Copyright (C) 2013 Apple Inc. All rights reserved.
4 #
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions
7 # are met:
8 # 1. Redistributions of source code must retain the above copyright
9 #    notice, this list of conditions and the following disclaimer.
10 # 2. Redistributions in binary form must reproduce the above copyright
11 #    notice, this list of conditions and the following disclaimer in the
12 #    documentation and/or other materials provided with the distribution.
13 #
14 # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
15 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
18 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24 # THE POSSIBILITY OF SUCH DAMAGE.
25
26 class Reference
27     attr_reader :kind, :number
28     
29     def initialize(kind, number)
30         @kind = kind
31         @number = number
32     end
33     
34     def resolve(hashTable, bangTable)
35         case @kind
36         when "#"
37             result = hashTable[@number]
38         when "!"
39             result = bangTable[@number]
40         else
41             raise
42         end
43         raise unless result
44         result
45     end
46 end
47
48 def parse(string)
49     result = []
50     until string.empty?
51         before, match, string = string.partition(/[!#]([0-9]+)/)
52         result << before
53         if match.empty?
54             result << string
55             break
56         end
57         result << Reference.new(match[0..0], match[1..-1].to_i)
58     end
59     result
60 end
61
62 class MetaData
63     attr_reader :index, :name, :parent
64     
65     def initialize(index, name, parent)
66         @index = index
67         @name = name
68         @parent = parent
69     end
70 end
71
72 $definitions = []
73 $declarations = {}
74 $attributes = []
75 $metaData = {}
76 $attributesBackMap = {}
77 $count = 0
78
79 loop {
80     line = $stdin.readline
81     if line =~ /^; NOTE: THIS IS A COMBINED MODULE/
82         puts line
83         puts $stdin.read
84         exit 0
85     end
86     break if line =~ /^define/
87 }
88
89 puts "; NOTE: THIS IS A COMBINED MODULE"
90
91 # Loop over all definitions.
92 shouldContinue = true
93 while shouldContinue
94     # We're starting a new definition.
95     body = ""
96     loop {
97         line = $stdin.readline
98         break if line.chomp == "}"
99         body += line
100     }
101     
102     body = parse(body)
103     
104     declarations=[]
105     metaDataMap=[]
106     attributeMap = []
107     unresolvedMetaData = []
108     
109     loop {
110         line = $stdin.gets
111         
112         if not line
113             shouldContinue = false
114             break
115         elsif line =~ /^define/
116             break
117         elsif line =~ /^declare/
118             declarations << parse(line)
119         elsif line =~ /!([0-9]+) = metadata !{metadata !\"([a-zA-Z0-9_]+)\"}/
120             index = $1.to_i
121             name = $2
122             unless $metaData[name]
123                 $metaData[name] = MetaData.new($metaData.size, name, nil)
124             end
125             metaDataMap[index] = $metaData[$2].index
126         elsif line =~ /!([0-9]+) = metadata !{metadata !\"([a-zA-Z0-9_]+)\", metadata !([0-9]+)/
127             metaData = MetaData.new($1.to_i, $2, $3.to_i)
128             unresolvedMetaData << metaData
129         elsif line =~ /attributes #([0-9]+) = /
130             attributeNumber = $1.to_i
131             attributeBody = $~.post_match
132             if $attributesBackMap[attributeBody]
133                 attributeMap[attributeNumber] = $attributesBackMap[attributeBody]
134             else
135                 attributeMap[attributeNumber] = $attributes.size
136                 $attributesBackMap[attributeBody] = $attributes.size
137                 $attributes << attributeBody
138             end
139         end
140     }
141     
142     # Iteratively resolve meta-data references
143     until unresolvedMetaData.empty?
144         index = 0
145         while index < unresolvedMetaData.size
146             metaData = unresolvedMetaData[index]
147             if $metaData[metaData.name]
148                 metaDataMap[metaData.index] = $metaData[metaData.name].index
149                 unresolvedMetaData[index] = unresolvedMetaData[-1]
150                 unresolvedMetaData.pop
151             elsif metaDataMap[metaData.parent]
152                 metaDataMap[metaData.index] = $metaData.size
153                 $metaData[metaData.name] = MetaData.new($metaData.size, metaData.name, metaDataMap[metaData.parent])
154                 unresolvedMetaData[index] = unresolvedMetaData[-1]
155                 unresolvedMetaData.pop
156             else
157                 index += 1
158             end
159         end
160     end
161     
162     # Output the body with all of the things remapped.
163     puts "define i64 @jsBody_#{$count += 1}(i64) {"
164     body.each {
165         | thing |
166         if thing.is_a? Reference
167             print(thing.kind + thing.resolve(attributeMap, metaDataMap).to_s)
168         else
169             print(thing)
170         end
171     }
172     puts "}"
173     
174     # Figure out what to do with declarations.
175     declarations.each {
176         | declaration |
177         declaration = declaration.map {
178             | thing |
179             if thing.is_a? Reference
180                 thing.kind + thing.resolve(attributeMap, metaDataMap).to_s
181             else
182                 thing
183             end
184         }
185         declaration = declaration.join('')
186         
187         next if $declarations[declaration]
188         
189         $declarations[declaration] = true
190     }
191 end
192
193 $declarations.each_key {
194     | declaration |
195     puts declaration
196 }
197
198 $attributes.each_with_index {
199     | attribute, index |
200     puts "attributes ##{index} = #{attribute}"
201 }
202
203 $metaData.each_value {
204     | metaData |
205     print "!#{metaData.index} = metadata !{metadata !\"#{metaData.name}\""
206     if metaData.parent
207         print ", metadata !#{metaData.parent}"
208     end
209     puts "}"
210 }
211