]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - offlineasm/ast.rb
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / offlineasm / ast.rb
index e555b5d98a8cfe0c9b4e885ed54a7e91a04d9c62..1241b7fe5a2b1c721b342929d7de600255ddd676 100644 (file)
@@ -21,6 +21,8 @@
 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 # THE POSSIBILITY OF SUCH DAMAGE.
 
+require "config"
+
 #
 # Base utility types for the AST.
 #
@@ -227,6 +229,10 @@ class Immediate < NoChildren
         true
     end
     
+    def immediateOperand?
+        true
+    end
+        
     def register?
         false
     end
@@ -253,6 +259,10 @@ class AddImmediates < Node
         "(#{left.dump} + #{right.dump})"
     end
     
+    def value
+        "#{left.value} + #{right.value}"
+    end
+    
     def address?
         false
     end
@@ -265,6 +275,10 @@ class AddImmediates < Node
         true
     end
     
+    def immediateOperand?
+        true
+    end
+    
     def register?
         false
     end
@@ -291,6 +305,10 @@ class SubImmediates < Node
         "(#{left.dump} - #{right.dump})"
     end
     
+    def value
+        "#{left.value} - #{right.value}"
+    end
+    
     def address?
         false
     end
@@ -303,6 +321,10 @@ class SubImmediates < Node
         true
     end
     
+    def immediateOperand?
+        true
+    end
+    
     def register?
         false
     end
@@ -341,6 +363,10 @@ class MulImmediates < Node
         true
     end
     
+    def immediateOperand?
+        false
+    end
+    
     def register?
         false
     end
@@ -378,6 +404,10 @@ class NegImmediate < Node
         true
     end
     
+    def immediateOperand?
+        false
+    end
+    
     def register?
         false
     end
@@ -416,6 +446,10 @@ class OrImmediates < Node
         true
     end
     
+    def immediateOperand?
+        false
+    end
+    
     def register?
         false
     end
@@ -454,6 +488,10 @@ class AndImmediates < Node
         true
     end
     
+    def immediateOperand?
+        false
+    end
+    
     def register?
         false
     end
@@ -492,6 +530,10 @@ class XorImmediates < Node
         true
     end
     
+    def immediateOperand?
+        false
+    end
+    
     def register?
         false
     end
@@ -529,6 +571,48 @@ class BitnotImmediate < Node
         true
     end
     
+    def immediateOperand?
+        false
+    end
+    
+    def register?
+        false
+    end
+end
+
+class StringLiteral < NoChildren
+    attr_reader :value
+    
+    def initialize(codeOrigin, value)
+        super(codeOrigin)
+        @value = value[1..-2]
+        raise "Bad string literal #{value.inspect} at #{codeOriginString}" unless value.is_a? String
+    end
+    
+    def dump
+        "#{value}"
+    end
+    
+    def ==(other)
+        other.is_a? StringLiteral and other.value == @value
+    end
+    
+    def address?
+        false
+    end
+    
+    def label?
+        false
+    end
+    
+    def immediate?
+        false
+    end
+    
+    def immediateOperand?
+        false
+    end
+        
     def register?
         false
     end
@@ -605,6 +689,10 @@ class FPRegisterID < NoChildren
         false
     end
     
+    def immediateOperand?
+        false
+    end
+    
     def register?
         true
     end
@@ -627,6 +715,10 @@ class SpecialRegister < NoChildren
         false
     end
     
+    def immediateOperand?
+        false
+    end
+    
     def register?
         true
     end
@@ -669,6 +761,10 @@ class Address < Node
         raise "Bad offset for address #{offset.inspect} at #{codeOriginString}" unless offset.is_a? Variable or offset.immediate?
     end
     
+    def withOffset(extraOffset)
+        Address.new(codeOrigin, @base, Immediate.new(codeOrigin, @offset.value + extraOffset))
+    end
+    
     def children
         [@base, @offset]
     end
@@ -693,6 +789,10 @@ class Address < Node
         false
     end
     
+    def immediateOperand?
+        true
+    end
+    
     def register?
         false
     end
@@ -725,6 +825,10 @@ class BaseIndex < Node
         end
     end
     
+    def withOffset(extraOffset)
+        BaseIndex.new(codeOrigin, @base, @index, @scale, Immediate.new(codeOrigin, @offset.value + extraOffset))
+    end
+    
     def children
         [@base, @index, @offset]
     end
@@ -749,6 +853,10 @@ class BaseIndex < Node
         false
     end
     
+    def immediateOperand?
+        false
+    end
+    
     def register?
         false
     end
@@ -762,6 +870,10 @@ class AbsoluteAddress < NoChildren
         @address = address
     end
     
+    def withOffset(extraOffset)
+        AbsoluteAddress.new(codeOrigin, Immediate.new(codeOrigin, @address.value + extraOffset))
+    end
+    
     def dump
         "#{address.dump}[]"
     end
@@ -778,18 +890,23 @@ class AbsoluteAddress < NoChildren
         false
     end
     
+    def immediateOperand?
+        true
+    end
+    
     def register?
         false
     end
 end
 
 class Instruction < Node
-    attr_reader :opcode, :operands
+    attr_reader :opcode, :operands, :annotation
     
-    def initialize(codeOrigin, opcode, operands)
+    def initialize(codeOrigin, opcode, operands, annotation=nil)
         super(codeOrigin)
         @opcode = opcode
         @operands = operands
+        @annotation = annotation
     end
     
     def children
@@ -797,12 +914,25 @@ class Instruction < Node
     end
     
     def mapChildren(&proc)
-        Instruction.new(codeOrigin, @opcode, @operands.map(&proc))
+        Instruction.new(codeOrigin, @opcode, @operands.map(&proc), @annotation)
     end
     
     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
+        when "emit"
+          $asm.puts "#{operands[0].dump}"
+        else
+            raise "Unhandled opcode #{opcode} at #{codeOriginString}"
+        end
+    end
 end
 
 class Error < NoChildren
@@ -838,6 +968,7 @@ class ConstDecl < Node
 end
 
 $labelMapping = {}
+$referencedExternLabels = Array.new
 
 class Label < NoChildren
     attr_reader :name
@@ -845,17 +976,61 @@ class Label < NoChildren
     def initialize(codeOrigin, name)
         super(codeOrigin)
         @name = name
+        @extern = true
+        @global = false
     end
     
-    def self.forName(codeOrigin, name)
+    def self.forName(codeOrigin, name, definedInFile = false)
         if $labelMapping[name]
             raise "Label name collision: #{name}" unless $labelMapping[name].is_a? Label
         else
             $labelMapping[name] = Label.new(codeOrigin, name)
         end
+        if definedInFile
+            $labelMapping[name].clearExtern()
+        end
         $labelMapping[name]
     end
-    
+
+    def self.setAsGlobal(codeOrigin, name)
+        if $labelMapping[name]
+            label = $labelMapping[name]
+            raise "Label: #{name} declared global multiple times" unless not label.global?
+            label.setGlobal()
+        else
+            newLabel = Label.new(codeOrigin, name)
+            newLabel.setGlobal()
+            $labelMapping[name] = newLabel
+        end
+    end
+
+    def self.resetReferenced
+        $referencedExternLabels = Array.new
+    end
+
+    def self.forReferencedExtern()
+        $referencedExternLabels.each {
+            | label |
+            yield "#{label.name}"
+        }
+    end
+
+    def clearExtern
+        @extern = false
+    end
+
+    def extern?
+        @extern
+    end
+
+    def setGlobal
+        @global = true
+    end
+
+    def global?
+        @global
+    end
+
     def dump
         "#{name}:"
     end
@@ -923,10 +1098,24 @@ class LabelReference < Node
         label.name
     end
     
+    def extern?
+        $labelMapping[name].is_a? Label and $labelMapping[name].extern?
+    end
+
+    def used
+        if !$referencedExternLabels.include?(@label) and extern?
+            $referencedExternLabels.push(@label)
+        end
+    end
+
     def dump
         label.name
     end
     
+    def value
+        asmLabel()
+    end
+
     def address?
         false
     end
@@ -938,6 +1127,10 @@ class LabelReference < Node
     def immediate?
         false
     end
+    
+    def immediateOperand?
+        true
+    end
 end
 
 class LocalLabelReference < NoChildren
@@ -963,6 +1156,10 @@ class LocalLabelReference < NoChildren
     def dump
         label.name
     end
+
+    def value
+        asmLabel()
+    end
     
     def address?
         false
@@ -975,6 +1172,10 @@ class LocalLabelReference < NoChildren
     def immediate?
         false
     end
+    
+    def immediateOperand?
+        true
+    end
 end
 
 class Sequence < Node
@@ -1125,7 +1326,7 @@ class Not < Node
     end
     
     def children
-        [@left, @right]
+        [@child]
     end
     
     def mapChildren
@@ -1177,7 +1378,7 @@ end
 
 class Macro < Node
     attr_reader :name, :variables, :body
-    
+
     def initialize(codeOrigin, name, variables, body)
         super(codeOrigin)
         @name = name
@@ -1199,14 +1400,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
@@ -1214,7 +1416,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