diff options
Diffstat (limited to 'Source/JavaScriptCore/offlineasm')
-rw-r--r-- | Source/JavaScriptCore/offlineasm/armv7.rb | 6 | ||||
-rw-r--r-- | Source/JavaScriptCore/offlineasm/asm.rb | 66 | ||||
-rw-r--r-- | Source/JavaScriptCore/offlineasm/ast.rb | 20 | ||||
-rw-r--r-- | Source/JavaScriptCore/offlineasm/config.rb | 31 | ||||
-rw-r--r-- | Source/JavaScriptCore/offlineasm/parser.rb | 69 | ||||
-rw-r--r-- | Source/JavaScriptCore/offlineasm/transform.rb | 3 | ||||
-rw-r--r-- | Source/JavaScriptCore/offlineasm/x86.rb | 6 |
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 |