summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/offlineasm/asm.rb
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/offlineasm/asm.rb')
-rw-r--r--Source/JavaScriptCore/offlineasm/asm.rb176
1 files changed, 176 insertions, 0 deletions
diff --git a/Source/JavaScriptCore/offlineasm/asm.rb b/Source/JavaScriptCore/offlineasm/asm.rb
new file mode 100644
index 000000000..a93a8c5dd
--- /dev/null
+++ b/Source/JavaScriptCore/offlineasm/asm.rb
@@ -0,0 +1,176 @@
+#!/usr/bin/env ruby
+
+# Copyright (C) 2011 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+$: << File.dirname(__FILE__)
+
+require "backends"
+require "digest/sha1"
+require "offsets"
+require "parser"
+require "self_hash"
+require "settings"
+require "transform"
+
+class Assembler
+ def initialize(outp)
+ @outp = outp
+ @state = :cpp
+ @commentState = :none
+ @comment = nil
+ end
+
+ def enterAsm
+ @outp.puts "asm ("
+ @state = :asm
+ end
+
+ def leaveAsm
+ putsLastComment
+ @outp.puts ");"
+ @state = :cpp
+ end
+
+ def inAsm
+ enterAsm
+ yield
+ leaveAsm
+ end
+
+ def lastComment
+ if @comment
+ result = "// #{@comment}"
+ else
+ result = ""
+ end
+ @commentState = :none
+ @comment = nil
+ result
+ end
+
+ def putsLastComment
+ comment = lastComment
+ unless comment.empty?
+ @outp.puts comment
+ end
+ end
+
+ def puts(*line)
+ raise unless @state == :asm
+ @outp.puts("\"\\t" + line.join('') + "\\n\" #{lastComment}")
+ end
+
+ def print(line)
+ raise unless @state == :asm
+ @outp.print("\"" + line + "\"")
+ end
+
+ def putsLabel(labelName)
+ raise unless @state == :asm
+ @outp.puts("OFFLINE_ASM_GLOBAL_LABEL(#{labelName}) #{lastComment}")
+ end
+
+ def putsLocalLabel(labelName)
+ raise unless @state == :asm
+ @outp.puts("LOCAL_LABEL_STRING(#{labelName}) \":\\n\" #{lastComment}")
+ end
+
+ def self.labelReference(labelName)
+ "\" SYMBOL_STRING(#{labelName}) \""
+ end
+
+ def self.localLabelReference(labelName)
+ "\" LOCAL_LABEL_STRING(#{labelName}) \""
+ end
+
+ def comment(text)
+ case @commentState
+ when :none
+ @comment = text
+ @commentState = :one
+ when :one
+ @outp.puts "// #{@comment}"
+ @outp.puts "// #{text}"
+ @comment = nil
+ @commentState = :many
+ when :many
+ @outp.puts "// #{text}"
+ else
+ raise
+ end
+ end
+end
+
+asmFile = ARGV.shift
+offsetsFile = ARGV.shift
+outputFlnm = ARGV.shift
+
+$stderr.puts "offlineasm: Parsing #{asmFile} and #{offsetsFile} and creating assembly file #{outputFlnm}."
+
+configurationList = offsetsAndConfigurationIndex(offsetsFile)
+inputData = IO::read(asmFile)
+
+inputHash =
+ "// offlineasm input hash: " + Digest::SHA1.hexdigest(inputData) +
+ " " + Digest::SHA1.hexdigest(configurationList.map{|v| (v[0] + [v[1]]).join(' ')}.join(' ')) +
+ " " + selfHash
+
+if FileTest.exist? outputFlnm
+ File.open(outputFlnm, "r") {
+ | inp |
+ firstLine = inp.gets
+ if firstLine and firstLine.chomp == inputHash
+ $stderr.puts "offlineasm: Nothing changed."
+ exit 0
+ end
+ }
+end
+
+File.open(outputFlnm, "w") {
+ | outp |
+ $output = outp
+ $output.puts inputHash
+
+ $asm = Assembler.new($output)
+
+ ast = parse(lex(inputData))
+
+ configurationList.each {
+ | configuration |
+ offsetsList = configuration[0]
+ configIndex = configuration[1]
+ forSettings(computeSettingsCombinations(ast)[configIndex], ast) {
+ | concreteSettings, lowLevelAST, backend |
+ lowLevelAST = lowLevelAST.resolve(*buildOffsetsMap(lowLevelAST, offsetsList))
+ emitCodeInConfiguration(concreteSettings, lowLevelAST, backend) {
+ $asm.inAsm {
+ lowLevelAST.lower(backend)
+ }
+ }
+ }
+ }
+}
+
+$stderr.puts "offlineasm: Assembly file #{outputFlnm} successfully generated."
+