]> git.saurik.com Git - apple/javascriptcore.git/blame - offlineasm/asm.rb
JavaScriptCore-1097.3.tar.gz
[apple/javascriptcore.git] / offlineasm / asm.rb
CommitLineData
6fe7ccc8
A
1#!/usr/bin/env ruby
2
3# Copyright (C) 2011 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$: << File.dirname(__FILE__)
27
28require "backends"
29require "digest/sha1"
30require "offsets"
31require "parser"
32require "self_hash"
33require "settings"
34require "transform"
35
36class Assembler
37 def initialize(outp)
38 @outp = outp
39 @state = :cpp
40 @commentState = :none
41 @comment = nil
42 end
43
44 def enterAsm
45 @outp.puts "asm ("
46 @state = :asm
47 end
48
49 def leaveAsm
50 putsLastComment
51 @outp.puts ");"
52 @state = :cpp
53 end
54
55 def inAsm
56 enterAsm
57 yield
58 leaveAsm
59 end
60
61 def lastComment
62 if @comment
63 result = "// #{@comment}"
64 else
65 result = ""
66 end
67 @commentState = :none
68 @comment = nil
69 result
70 end
71
72 def putsLastComment
73 comment = lastComment
74 unless comment.empty?
75 @outp.puts comment
76 end
77 end
78
79 def puts(*line)
80 raise unless @state == :asm
81 @outp.puts("\"\\t" + line.join('') + "\\n\" #{lastComment}")
82 end
83
84 def print(line)
85 raise unless @state == :asm
86 @outp.print("\"" + line + "\"")
87 end
88
89 def putsLabel(labelName)
90 raise unless @state == :asm
91 @outp.puts("OFFLINE_ASM_GLOBAL_LABEL(#{labelName}) #{lastComment}")
92 end
93
94 def putsLocalLabel(labelName)
95 raise unless @state == :asm
96 @outp.puts("LOCAL_LABEL_STRING(#{labelName}) \":\\n\" #{lastComment}")
97 end
98
99 def self.labelReference(labelName)
100 "\" SYMBOL_STRING(#{labelName}) \""
101 end
102
103 def self.localLabelReference(labelName)
104 "\" LOCAL_LABEL_STRING(#{labelName}) \""
105 end
106
107 def comment(text)
108 case @commentState
109 when :none
110 @comment = text
111 @commentState = :one
112 when :one
113 @outp.puts "// #{@comment}"
114 @outp.puts "// #{text}"
115 @comment = nil
116 @commentState = :many
117 when :many
118 @outp.puts "// #{text}"
119 else
120 raise
121 end
122 end
123end
124
125asmFile = ARGV.shift
126offsetsFile = ARGV.shift
127outputFlnm = ARGV.shift
128
129$stderr.puts "offlineasm: Parsing #{asmFile} and #{offsetsFile} and creating assembly file #{outputFlnm}."
130
131begin
132 configurationList = offsetsAndConfigurationIndex(offsetsFile)
133rescue MissingMagicValuesException
134 $stderr.puts "offlineasm: No magic values found. Skipping assembly file generation assuming the classic interpreter is enabled."
135 exit 0
136end
137
138inputHash =
139 "// offlineasm input hash: " + parseHash(asmFile) +
140 " " + Digest::SHA1.hexdigest(configurationList.map{|v| (v[0] + [v[1]]).join(' ')}.join(' ')) +
141 " " + selfHash
142
143if FileTest.exist? outputFlnm
144 File.open(outputFlnm, "r") {
145 | inp |
146 firstLine = inp.gets
147 if firstLine and firstLine.chomp == inputHash
148 $stderr.puts "offlineasm: Nothing changed."
149 exit 0
150 end
151 }
152end
153
154File.open(outputFlnm, "w") {
155 | outp |
156 $output = outp
157 $output.puts inputHash
158
159 $asm = Assembler.new($output)
160
161 ast = parse(asmFile)
162
163 configurationList.each {
164 | configuration |
165 offsetsList = configuration[0]
166 configIndex = configuration[1]
167 forSettings(computeSettingsCombinations(ast)[configIndex], ast) {
168 | concreteSettings, lowLevelAST, backend |
169 lowLevelAST = lowLevelAST.resolve(*buildOffsetsMap(lowLevelAST, offsetsList))
170 lowLevelAST.validate
171 emitCodeInConfiguration(concreteSettings, lowLevelAST, backend) {
172 $asm.inAsm {
173 lowLevelAST.lower(backend)
174 }
175 }
176 }
177 }
178}
179
180$stderr.puts "offlineasm: Assembly file #{outputFlnm} successfully generated."
181