summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/offlineasm
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/offlineasm')
-rw-r--r--Source/JavaScriptCore/offlineasm/armv7.rb6
-rw-r--r--Source/JavaScriptCore/offlineasm/asm.rb66
-rw-r--r--Source/JavaScriptCore/offlineasm/ast.rb20
-rw-r--r--Source/JavaScriptCore/offlineasm/config.rb31
-rw-r--r--Source/JavaScriptCore/offlineasm/parser.rb69
-rw-r--r--Source/JavaScriptCore/offlineasm/transform.rb3
-rw-r--r--Source/JavaScriptCore/offlineasm/x86.rb6
7 files changed, 135 insertions, 66 deletions
diff --git a/Source/JavaScriptCore/offlineasm/armv7.rb b/Source/JavaScriptCore/offlineasm/armv7.rb
index 18538120b..6595fdc71 100644
--- a/Source/JavaScriptCore/offlineasm/armv7.rb
+++ b/Source/JavaScriptCore/offlineasm/armv7.rb
@@ -743,8 +743,8 @@ end
class Instruction
def lowerARMv7
- $asm.codeOrigin codeOriginString
- $asm.annotation annotation
+ $asm.codeOrigin codeOriginString if $enableCodeOriginComments
+ $asm.annotation annotation if $enableInstrAnnotations
case opcode
when "addi", "addp", "addis"
@@ -1012,7 +1012,7 @@ class Instruction
raise "Wrong number of arguments to smull in #{self.inspect} at #{codeOriginString}" unless operands.length == 4
$asm.puts "smull #{operands[2].armV7Operand}, #{operands[3].armV7Operand}, #{operands[0].armV7Operand}, #{operands[1].armV7Operand}"
else
- raise "Unhandled opcode #{opcode} at #{codeOriginString}"
+ lowerDefault
end
end
end
diff --git a/Source/JavaScriptCore/offlineasm/asm.rb b/Source/JavaScriptCore/offlineasm/asm.rb
index 0cf6320af..1603f4af4 100644
--- a/Source/JavaScriptCore/offlineasm/asm.rb
+++ b/Source/JavaScriptCore/offlineasm/asm.rb
@@ -45,6 +45,8 @@ class Assembler
@codeOrigin = nil
@numLocalLabels = 0
@numGlobalLabels = 0
+
+ @newlineSpacerState = :none
end
def enterAsm
@@ -66,33 +68,60 @@ class Assembler
# Concatenates all the various components of the comment to dump.
def lastComment
+ separator = " "
result = ""
- result = " #{@comment} ." if @comment
- result += " #{@annotation} ." if @annotation and $enableTrailingInstrAnnotations
- result += " #{@internalComment} ." if @internalComment
- result += " #{@codeOrigin} ." if @codeOrigin and $enableCodeOriginComments
+ result = "#{@comment}" if @comment
+ if @annotation and $enableInstrAnnotations
+ result += separator if result != ""
+ result += "#{@annotation}"
+ end
+ if @internalComment
+ result += separator if result != ""
+ result += "#{@internalComment}"
+ end
+ if @codeOrigin and $enableCodeOriginComments
+ result += separator if result != ""
+ result += "#{@codeOrigin}"
+ end
if result != ""
- result = " //" + result
+ result = "// " + result
end
# Reset all the components that we've just sent to be dumped.
@commentState = :none
@comment = nil
- @internalComment = nil
@annotation = nil
@codeOrigin = nil
+ @internalComment = nil
result
end
- # Dumps the current instruction annotation in interlaced mode if appropriate.
- def putInterlacedAnnotation()
+ def formatDump(dumpStr, comment, commentColumns=$preferredCommentStartColumn)
+ if comment.length > 0
+ "%-#{commentColumns}s %s" % [dumpStr, comment]
+ else
+ dumpStr
+ end
+ end
+
+ # private method for internal use only.
+ def putAnnotation(text)
raise unless @state == :asm
- if $enableInterlacedInstrAnnotations
- @outp.puts(" // #{@annotation}") if @annotation
+ if $enableInstrAnnotations
+ @outp.puts text
@annotation = nil
end
end
+ def putLocalAnnotation()
+ putAnnotation " // #{@annotation}" if @annotation
+ end
+
+ def putGlobalAnnotation()
+ putsNewlineSpacerIfAppropriate(:annotation)
+ putAnnotation "// #{@annotation}" if @annotation
+ end
+
def putsLastComment
comment = lastComment
unless comment.empty?
@@ -102,8 +131,7 @@ class Assembler
def puts(*line)
raise unless @state == :asm
- putInterlacedAnnotation
- @outp.puts(" \"\\t" + line.join('') + "\\n\"#{lastComment}")
+ @outp.puts(formatDump(" \"\\t" + line.join('') + "\\n\"", lastComment))
end
def print(line)
@@ -111,12 +139,20 @@ class Assembler
@outp.print("\"" + line + "\"")
end
+ def putsNewlineSpacerIfAppropriate(state)
+ if @newlineSpacerState != state
+ @outp.puts("\n")
+ @newlineSpacerState = state
+ end
+ end
+
def putsLabel(labelName)
raise unless @state == :asm
@numGlobalLabels += 1
- @outp.puts("\n")
+ putsNewlineSpacerIfAppropriate(:global)
@internalComment = $enableLabelCountComments ? "Global Label #{@numGlobalLabels}" : nil
- @outp.puts("OFFLINE_ASM_GLOBAL_LABEL(#{labelName})#{lastComment}")
+ @outp.puts(formatDump("OFFLINE_ASM_GLOBAL_LABEL(#{labelName})", lastComment))
+ @newlineSpacerState = :none # After a global label, we can use another spacer.
end
def putsLocalLabel(labelName)
@@ -124,7 +160,7 @@ class Assembler
@numLocalLabels += 1
@outp.puts("\n")
@internalComment = $enableLabelCountComments ? "Local Label #{@numLocalLabels}" : nil
- @outp.puts("OFFLINE_ASM_LOCAL_LABEL(#{labelName})#{lastComment}")
+ @outp.puts(formatDump(" OFFLINE_ASM_LOCAL_LABEL(#{labelName})", lastComment))
end
def self.labelReference(labelName)
diff --git a/Source/JavaScriptCore/offlineasm/ast.rb b/Source/JavaScriptCore/offlineasm/ast.rb
index 86ad6bcb2..9333247dc 100644
--- a/Source/JavaScriptCore/offlineasm/ast.rb
+++ b/Source/JavaScriptCore/offlineasm/ast.rb
@@ -806,6 +806,17 @@ class Instruction < Node
def dump
"\t" + opcode.to_s + " " + operands.collect{|v| v.dump}.join(", ")
end
+
+ def lowerDefault
+ case opcode
+ when "localAnnotation"
+ $asm.putLocalAnnotation
+ when "globalAnnotation"
+ $asm.putGlobalAnnotation
+ else
+ raise "Unhandled opcode #{opcode} at #{codeOriginString}"
+ end
+ end
end
class Error < NoChildren
@@ -1180,7 +1191,7 @@ end
class Macro < Node
attr_reader :name, :variables, :body
-
+
def initialize(codeOrigin, name, variables, body)
super(codeOrigin)
@name = name
@@ -1202,14 +1213,15 @@ class Macro < Node
end
class MacroCall < Node
- attr_reader :name, :operands
+ attr_reader :name, :operands, :annotation
- def initialize(codeOrigin, name, operands)
+ def initialize(codeOrigin, name, operands, annotation)
super(codeOrigin)
@name = name
@operands = operands
raise unless @operands
@operands.each{|v| raise unless v}
+ @annotation = annotation
end
def children
@@ -1217,7 +1229,7 @@ class MacroCall < Node
end
def mapChildren(&proc)
- MacroCall.new(codeOrigin, @name, @operands.map(&proc))
+ MacroCall.new(codeOrigin, @name, @operands.map(&proc), @annotation)
end
def dump
diff --git a/Source/JavaScriptCore/offlineasm/config.rb b/Source/JavaScriptCore/offlineasm/config.rb
index ce1898170..e6287f367 100644
--- a/Source/JavaScriptCore/offlineasm/config.rb
+++ b/Source/JavaScriptCore/offlineasm/config.rb
@@ -21,6 +21,8 @@
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGE.
+$preferredCommentStartColumn = 70
+
# Turns on dumping of the count of labels.
# For example, the output will look like this:
@@ -45,32 +47,11 @@ $enableCodeOriginComments = true
# Turns on recording and dumping of annotations in the generated output file.
# An annotations can be specified for each instruction in the source asm files.
-#
-# $enableInterlacedInstrAnnotations will interlace the annotation between
-# instructions. For example, the output will look like this:
+# For example, the output will look like this:
#
# ...
-# // @ t2<CodeBlock> = cfr.CodeBlock
-# "\tmovq -8(%r13), %rcx\n"
-# // @ t2<size_t> = t2<CodeBlock>.m_numVars
-# "\tmovl 52(%rcx), %ecx\n"
+# "\tmovq -8(%r13), %rcx\n" // t2<CodeBlock> = cfr.CodeBlock
+# "\tmovl 52(%rcx), %ecx\n" // t2<size_t> = t2<CodeBlock>.m_numVars
# ...
#
-# $enableTrailingInstrAnnotations will insert the annotation in the trailing
-# comment after your instructions. For example, the output will look like this:
-#
-# ...
-# "\tmovq -8(%r13), %rcx\n" // @ t2<CodeBlock> = cfr.CodeBlock
-# "\tmovl 52(%rcx), %ecx\n" // @ t2<size_t> = t2<CodeBlock>.m_numVars
-# ...
-#
-# If both $enableInterlacedInstrAnnotations and $enableTrailingInstrAnnotations
-# are enabled, interlaced annotations will take precedence, and any available
-# annotations will only be dumped in the interlaced format.
-#
-$enableInterlacedInstrAnnotations = false
-$enableTrailingInstrAnnotations = false
-
-
-# Sanity check for annotation configs.
-$enableInstrAnnotations = ($enableInterlacedInstrAnnotations or $enableTrailingInstrAnnotations)
+$enableInstrAnnotations = false
diff --git a/Source/JavaScriptCore/offlineasm/parser.rb b/Source/JavaScriptCore/offlineasm/parser.rb
index 8696a61a9..70b03cf70 100644
--- a/Source/JavaScriptCore/offlineasm/parser.rb
+++ b/Source/JavaScriptCore/offlineasm/parser.rb
@@ -74,6 +74,15 @@ class Token
end
end
+class Annotation
+ attr_reader :codeOrigin, :type, :string
+ def initialize(codeOrigin, type, string)
+ @codeOrigin = codeOrigin
+ @type = type
+ @string = string
+ end
+end
+
#
# The lexer. Takes a string and returns an array of tokens.
#
@@ -83,17 +92,20 @@ def lex(str, fileName)
result = []
lineNumber = 1
annotation = nil
+ whitespaceFound = false
while not str.empty?
case str
when /\A\#([^\n]*)/
# comment, ignore
- when /\A\/\/([^\n]*)/
+ when /\A\/\/\ ?([^\n]*)/
# annotation
annotation = $1
+ annotationType = whitespaceFound ? :local : :global
when /\A\n/
# We've found a '\n'. Emit the last comment recorded if appropriate:
if $enableInstrAnnotations and annotation
- result << Token.new(CodeOrigin.new(fileName, lineNumber), "@" + annotation)
+ result << Annotation.new(CodeOrigin.new(fileName, lineNumber),
+ annotationType, annotation)
annotation = nil
end
result << Token.new(CodeOrigin.new(fileName, lineNumber), $&)
@@ -106,6 +118,9 @@ def lex(str, fileName)
result << Token.new(CodeOrigin.new(fileName, lineNumber), $&)
when /\A([ \t]+)/
# whitespace, ignore
+ whitespaceFound = true
+ str = $~.post_match
+ next
when /\A0x([0-9a-fA-F]+)/
result << Token.new(CodeOrigin.new(fileName, lineNumber), $&.hex.to_s)
when /\A0([0-7]+)/
@@ -119,6 +134,7 @@ def lex(str, fileName)
else
raise "Lexer error at #{CodeOrigin.new(fileName, lineNumber).to_s}, unexpected sequence #{str[0..20].inspect}"
end
+ whitespaceFound = false
str = $~.post_match
end
result
@@ -146,10 +162,6 @@ def isIdentifier(token)
token =~ /\A[a-zA-Z]([a-zA-Z0-9_]*)\Z/ and not isKeyword(token)
end
-def isAnnotation(token)
- token =~ /\A\@([^\n]*)/
-end
-
def isLabel(token)
token =~ /\A_([a-zA-Z0-9_]*)\Z/
end
@@ -175,6 +187,7 @@ class Parser
def initialize(data, fileName)
@tokens = lex(data, fileName)
@idx = 0
+ @annotation = nil
end
def parseError(*comment)
@@ -487,6 +500,20 @@ class Parser
loop {
if (@idx == @tokens.length and not final) or (final and @tokens[@idx] =~ final)
break
+ elsif @tokens[@idx].is_a? Annotation
+ # This is the only place where we can encounter a global
+ # annotation, and hence need to be able to distinguish between
+ # them.
+ # globalAnnotations are the ones that start from column 0. All
+ # others are considered localAnnotations. The only reason to
+ # distinguish between them is so that we can format the output
+ # nicely as one would expect.
+
+ codeOrigin = @tokens[@idx].codeOrigin
+ annotationOpcode = (@tokens[@idx].type == :global) ? "globalAnnotation" : "localAnnotation"
+ list << Instruction.new(codeOrigin, annotationOpcode, [], @tokens[@idx].string)
+ @annotation = nil
+ @idx += 2 # Consume the newline as well.
elsif @tokens[@idx] == "\n"
# ignore
@idx += 1
@@ -547,21 +574,22 @@ class Parser
@idx += 1
if (not final and @idx == @tokens.size) or (final and @tokens[@idx] =~ final)
# Zero operand instruction, and it's the last one.
- list << Instruction.new(codeOrigin, name, [])
+ list << Instruction.new(codeOrigin, name, [], @annotation)
+ @annotation = nil
break
- elsif isAnnotation @tokens[@idx]
- annotation = @tokens[@idx].string
- list << Instruction.new(codeOrigin, name, [], annotation)
+ elsif @tokens[@idx].is_a? Annotation
+ list << Instruction.new(codeOrigin, name, [], @tokens[@idx].string)
+ @annotation = nil
@idx += 2 # Consume the newline as well.
elsif @tokens[@idx] == "\n"
# Zero operand instruction.
- list << Instruction.new(codeOrigin, name, [])
+ list << Instruction.new(codeOrigin, name, [], @annotation)
+ @annotation = nil
@idx += 1
else
# It's definitely an instruction, and it has at least one operand.
operands = []
endOfSequence = false
- annotation = nil
loop {
operands << parseOperand("while inside of instruction #{name}")
if (not final and @idx == @tokens.size) or (final and @tokens[@idx] =~ final)
@@ -571,8 +599,8 @@ class Parser
elsif @tokens[@idx] == ","
# Has another operand.
@idx += 1
- elsif isAnnotation @tokens[@idx]
- annotation = @tokens[@idx].string
+ elsif @tokens[@idx].is_a? Annotation
+ @annotation = @tokens[@idx].string
@idx += 2 # Consume the newline as well.
break
elsif @tokens[@idx] == "\n"
@@ -583,11 +611,14 @@ class Parser
parseError("Expected a comma, newline, or #{final} after #{operands.last.dump}")
end
}
- list << Instruction.new(codeOrigin, name, operands, annotation)
+ list << Instruction.new(codeOrigin, name, operands, @annotation)
+ @annotation = nil
if endOfSequence
break
end
end
+
+ # Check for potential macro invocation:
elsif isIdentifier @tokens[@idx]
codeOrigin = @tokens[@idx].codeOrigin
name = @tokens[@idx].string
@@ -624,7 +655,13 @@ class Parser
end
}
end
- list << MacroCall.new(codeOrigin, name, operands)
+ # Check if there's a trailing annotation after the macro invoke:
+ if @tokens[@idx].is_a? Annotation
+ @annotation = @tokens[@idx].string
+ @idx += 2 # Consume the newline as well.
+ end
+ list << MacroCall.new(codeOrigin, name, operands, @annotation)
+ @annotation = nil
else
parseError "Expected \"(\" after #{name}"
end
diff --git a/Source/JavaScriptCore/offlineasm/transform.rb b/Source/JavaScriptCore/offlineasm/transform.rb
index a47ea0ad6..c838629f0 100644
--- a/Source/JavaScriptCore/offlineasm/transform.rb
+++ b/Source/JavaScriptCore/offlineasm/transform.rb
@@ -229,6 +229,9 @@ class Sequence
mapping[myMacros[item.name].variables[idx]] = item.operands[idx]
end
}
+ if item.annotation
+ newList << Instruction.new(item.codeOrigin, "localAnnotation", [], item.annotation)
+ end
newList += myMacros[item.name].body.substitute(mapping).demacroify(myMyMacros).renameLabels(item.name).list
else
newList << item.demacroify(myMacros)
diff --git a/Source/JavaScriptCore/offlineasm/x86.rb b/Source/JavaScriptCore/offlineasm/x86.rb
index 470318a09..cebc83326 100644
--- a/Source/JavaScriptCore/offlineasm/x86.rb
+++ b/Source/JavaScriptCore/offlineasm/x86.rb
@@ -624,8 +624,8 @@ class Instruction
end
def lowerX86Common
- $asm.codeOrigin codeOriginString
- $asm.annotation annotation
+ $asm.codeOrigin codeOriginString if $enableCodeOriginComments
+ $asm.annotation annotation if $enableInstrAnnotations
case opcode
when "addi"
@@ -1028,7 +1028,7 @@ class Instruction
when "leap"
$asm.puts "lea#{x86Suffix(:ptr)} #{operands[0].x86AddressOperand(:ptr)}, #{operands[1].x86Operand(:ptr)}"
else
- raise "Bad opcode: #{opcode}"
+ lowerDefault
end
end
end