[pypy-svn] r42790 - pypy/dist/pypy/translator/js

fijal at codespeak.net fijal at codespeak.net
Mon May 7 13:17:59 CEST 2007


Author: fijal
Date: Mon May  7 13:17:59 2007
New Revision: 42790

Modified:
   pypy/dist/pypy/translator/js/asmgen.py
   pypy/dist/pypy/translator/js/function.py
   pypy/dist/pypy/translator/js/js.py
   pypy/dist/pypy/translator/js/jsbuiltin.py
   pypy/dist/pypy/translator/js/metavm.py
   pypy/dist/pypy/translator/js/opcodes.py
Log:
* builtin refactorings, got rid of some ugly hacks
* subst_table is working again => better resulting code
* be insanly delicate about stack. No unnecessary values
  should reside on stack any more
* this refactoring should fix misterious test failure apeearing from
  time to time in the nightly test run


Modified: pypy/dist/pypy/translator/js/asmgen.py
==============================================================================
--- pypy/dist/pypy/translator/js/asmgen.py	(original)
+++ pypy/dist/pypy/translator/js/asmgen.py	Mon May  7 13:17:59 2007
@@ -53,6 +53,15 @@
     def __len__(self):
         return len(self.l)
 
+    def __nonzero__(self):
+        return len(self.l) > 0
+
+    def empty(self):
+        self.l = []
+
+    def __repr__(self):
+        return "<Queue %s>" % (repr(self.l),)
+
 class AsmGen(object):
     """ JS 'assembler' generator routines
     """
@@ -166,9 +175,8 @@
         self.codegenerator.openblock()
 
     def change_name(self, from_name, to_name):
-    #    if isinstance(from_name,Variable) and isinstance(to_name,Variable):
-    #        self.subst_table[from_name.name] = to_name.name
-        pass
+        if isinstance(from_name,Variable) and isinstance(to_name,Variable):
+            self.subst_table[from_name.name] = to_name.name
     
     def cast_function(self, name, num):
         # FIXME: redundancy with call
@@ -193,7 +201,7 @@
     def set_field(self, useless_parameter, name):
         v = self.right_hand.pop()
         self.codegenerator.writeline("%s.%s = %s;"%(self.right_hand.pop(), name, v))
-        self.right_hand.append(None)
+        #self.right_hand.append(None)
     
     def call_method(self, obj, name, signature):
         l = [self.right_hand.pop() for i in signature]
@@ -215,7 +223,7 @@
         self.right_hand.append("this")
     
     def store_void(self):
-        if len(self.right_hand) == 0:
+        if not len(self.right_hand):
             return
         v = self.right_hand.pop()
         if v is not None and v.find('('):
@@ -286,3 +294,6 @@
     
     def throw_real(self, s):
         self.codegenerator.writeline("throw(%s);"%s)
+
+    def clean_stack(self):
+        self.right_hand.empty()

Modified: pypy/dist/pypy/translator/js/function.py
==============================================================================
--- pypy/dist/pypy/translator/js/function.py	(original)
+++ pypy/dist/pypy/translator/js/function.py	Mon May  7 13:17:59 2007
@@ -34,13 +34,11 @@
             assert False
 
     def store(self, v):
-        if isinstance(v, flowmodel.Variable):
-            if v.concretetype is not Void:
-                self.ilasm.store_local(v)
-            else:
-                self.ilasm.store_void()
+        assert isinstance(v, flowmodel.Variable)
+        if v.concretetype is not Void:
+            self.ilasm.store_local(v)
         else:
-            assert False
+            self.ilasm.store_void()
     
     def change_name(self, name, to_name):
         self.ilasm.change_name(name, to_name)
@@ -230,3 +228,6 @@
 
     def begin_try(self):
         self.ilasm.begin_try()
+
+    def clean_stack(self):
+        self.ilasm.clean_stack()

Modified: pypy/dist/pypy/translator/js/js.py
==============================================================================
--- pypy/dist/pypy/translator/js/js.py	(original)
+++ pypy/dist/pypy/translator/js/js.py	Mon May  7 13:17:59 2007
@@ -101,6 +101,7 @@
             self.gen_pendings()
             self.db.gen_constants(self.ilasm, self.db._pending_nodes)
         self.ilasm.close()
+        assert len(self.ilasm.right_hand) == 0
         return self.tmpfile.strpath
         
     def write_source(self):

Modified: pypy/dist/pypy/translator/js/jsbuiltin.py
==============================================================================
--- pypy/dist/pypy/translator/js/jsbuiltin.py	(original)
+++ pypy/dist/pypy/translator/js/jsbuiltin.py	Mon May  7 13:17:59 2007
@@ -1,55 +1,52 @@
 """ JavaScript builtin mappings
 """
 
-from pypy.translator.oosupport.metavm import InstructionList, PushAllArgs
+from pypy.translator.oosupport.metavm import InstructionList, PushAllArgs,\
+     _PushAllArgs
 from pypy.translator.js.metavm import SetBuiltinField, ListGetitem, ListSetitem, \
     GetBuiltinField, CallBuiltin, Call, SetTimeout, ListContains,\
-    NewBuiltin, SetOnEvent
+    NewBuiltin, SetOnEvent, ListRemove, CallBuiltinMethod, _GetPredefinedField,\
+    _SetPredefinedField
 
 from pypy.rpython.ootypesystem import ootype
 
 class _Builtins(object):
     def __init__(self):
-        list_resize = lambda g,op: SetBuiltinField.run_it(g, op.args[1], 'length', op.args[2])
+        list_resize = _SetPredefinedField('length')
         
         self.builtin_map = {
             'll_js_jseval' : CallBuiltin('eval'),
             'set_on_keydown' : SetOnEvent('onkeydown'),
             'set_on_keyup' : SetOnEvent('onkeyup'),
             'setTimeout' : SetTimeout,
-            'll_int_str' : lambda g,op: Call._render_builtin_method(g, 'toString' , [op.args[2]]),
-            'll_strconcat' : InstructionList([PushAllArgs, '+']),
+            'll_int_str' : CallBuiltinMethod('toString', [2]),
+            'll_strconcat' : InstructionList([_PushAllArgs(slice(1, None)), '+']),
             'll_int' : CallBuiltin('parseInt'),
             #'alert' : CallBuiltin('alert'),
             'seval' : CallBuiltin('seval'),
             'date': NewBuiltin('Date'),
-            'll_math.ll_math_fmod' : InstructionList([PushAllArgs, '%']),
+            'll_math.ll_math_fmod' : InstructionList([_PushAllArgs(slice(1, None)), '%']),
             'll_time_time' : CallBuiltin('time'),
             'll_time_clock' : CallBuiltin('clock'),
             'll_os_write' : CallBuiltin('print'),
         }
         self.builtin_obj_map = {
             ootype.String.__class__: {
-                'll_strconcat' : InstructionList([PushAllArgs, '+']),
-                'll_strlen' : lambda g,op: GetBuiltinField.run_it(g, op.args[1], 'length'),
-                'll_stritem_nonneg' : lambda g, op: Call._render_builtin_method(g, 'charAt', [op.args[1], op.args[2]]),
-                'll_streq' : InstructionList([PushAllArgs, '==']),
+                'll_strconcat' : InstructionList([_PushAllArgs(slice(1, None)), '+']),
+                'll_strlen' : _GetPredefinedField('length'),
+                'll_stritem_nonneg' : CallBuiltinMethod('charAt', slice(1,None)),
+                'll_streq' : InstructionList([_PushAllArgs(slice(1, None)), '==']),
                 'll_strcmp' : CallBuiltin('strcmp'),
                 'll_startswith' : CallBuiltin('startswith'),
                 'll_endswith' : CallBuiltin('endswith'),
                 'll_split_chr' : CallBuiltin('splitchr'),
-                #'ll_substring' : lambda g,op: Call._render_builtin_method(g, 'substring', [op.args[1], op.args[2], op.args[3]]),
                 'll_substring' : CallBuiltin('substring'),
-                'll_lower' : lambda g, op: Call._render_builtin_method(g, 'toLowerCase', [op.args[1]]),
-                'll_upper' : lambda g, op: Call._render_builtin_method(g, 'toUpperCase', [op.args[1]]),
+                'll_lower' : CallBuiltinMethod('toLowerCase', slice(1, None)),
+                'll_upper' : CallBuiltinMethod('toUpperCase', slice(1, None)),
                 'll_find' : CallBuiltin('findIndexOf'),
                 'll_find_char' : CallBuiltin('findIndexOf'),
-                #'ll_find' : lambda g, op: Call._render_builtin_method(g, 'indexOf', [op.args[1], op.args[2], op.args[3]]),
-                #'ll_find_char' : lambda g, op: Call._render_builtin_method(g, 'indexOf', [op.args[1], op.args[2], op.args[3]]),
                 'll_contains' : CallBuiltin('findIndexOfTrue'),
-                'll_replace_chr_chr' : lambda g, op:
-                     Call._render_builtin_method(g, 'replace',
-                     [op.args[1], op.args[2], op.args[3], 'g']),
+                'll_replace_chr_chr' : CallBuiltinMethod('replace', slice(1, None), ['g']),
                 'll_count_char' : CallBuiltin('countCharOf'),
                 'll_count' : CallBuiltin('countOf'),
             },
@@ -59,7 +56,7 @@
                 '_ll_resize' : list_resize,
                 '_ll_resize_ge' : list_resize,
                 '_ll_resize_le' : list_resize,
-                'll_length' : lambda g,op: GetBuiltinField.run_it(g, op.args[1], 'length'),
+                'll_length' : _GetPredefinedField('length'),
             },
             ootype.Dict: {
                 'll_get' : ListGetitem,
@@ -67,7 +64,7 @@
                 'll_contains' : ListContains,
                 'll_get_items_iterator' : CallBuiltin('dict_items_iterator'),
                 'll_length' : CallBuiltin('get_dict_len'),
-                'll_remove' : lambda g, op: CallBuiltin('delete')._render_builtin_prepared_args(g, 'delete', ['%s[%s]' % (op.args[1], op.args[2])]),
+                'll_remove' : ListRemove,
                 'll_clear': CallBuiltin('clear_dict'),
             },
             ootype.Record: {
@@ -76,5 +73,12 @@
                 'll_contains' : ListContains,
             }
         }
+        self.fix_opcodes()
+
+    def fix_opcodes(self):
+        from pypy.translator.js.metavm import fix_opcodes
+        #fix_opcodes(self.builtin_map)
+        #for value in self.builtin_obj_map.values():
+        #    fix_opcodes(value)
 
 Builtins = _Builtins()

Modified: pypy/dist/pypy/translator/js/metavm.py
==============================================================================
--- pypy/dist/pypy/translator/js/metavm.py	(original)
+++ pypy/dist/pypy/translator/js/metavm.py	Mon May  7 13:17:59 2007
@@ -3,7 +3,7 @@
 
 #from pypy.translator.js.jsbuiltin import Builtins
 from pypy.translator.oosupport.metavm import PushArg, PushAllArgs, StoreResult,\
-    InstructionList, New, SetField, GetField, MicroInstruction
+    InstructionList, New, GetField, MicroInstruction
 
 from pypy.translator.js.log import log
 from pypy.rpython.ootypesystem import ootype
@@ -82,6 +82,20 @@
     def render(self, generator, op):
         self._render_builtin(generator, self.builtin, op.args)
 
+class CallBuiltinMethod(_Call):
+    def __init__(self, builtin, slice=None, additional_args=[]):
+        self.builtin = builtin
+        self.slice = slice
+        self.additional_args = additional_args
+
+    def render(self, generator, op):
+        if self.slice is not None:
+            args = op.args[self.slice]
+        else:
+            args = op.args
+        args += self.additional_args
+        self._render_builtin_method(generator, self.builtin, args)
+
 class _SameAs(MicroInstruction):
     def render(self, generator, op):
         generator.change_name(op.result, op.args[0])
@@ -128,11 +142,17 @@
     def render(self, generator, op):
         this = op.args[0]
         field = op.args[1].value[1:]
-        self.run_it(generator, this, field)
-    
-    def run_it(self, generator, this, field_name):
         generator.load(this)
-        generator.get_field(None, field_name)
+        generator.get_field(None, field)
+
+class _GetPredefinedField(MicroInstruction):
+    def __init__(self, field):
+        self.field = field
+
+    def render(self, generator, op):
+        this = op.args[1]
+        generator.load(this)
+        generator.get_field(None, self.field)
 
 GetBuiltinField = _GetBuiltinField()
 
@@ -151,6 +171,15 @@
         generator.load(this)
         generator.load_special(value)
         generator.set_field(None, field_name)
+
+class _SetPredefinedField(_SetBuiltinField):
+    def __init__(self, field):
+        self.field = field
+
+    def render(self, generator, op):
+        value = op.args[2]
+        this = op.args[1]
+        self.run_it(generator, this, self.field, value)
     
 class _SetExternalField(_SetBuiltinField):
     def render(self, generator, op):
@@ -177,7 +206,7 @@
         this = op.args[1].concretetype
         method = op.args[0]
         method_name = method.value
-        generator.load(op.args[1])
+        #generator.load(op.args[1])
         self._render_builtin_method(generator, method_name, op.args[1:])
 
 CallBuiltinObject = _CallBuiltinObject()
@@ -213,6 +242,10 @@
         generator.load(op.args[2])
         generator.call_external('setTimeout',[0]*2)
 
+class _DiscardStack(MicroInstruction):
+    def render(self, generator, op):
+        generator.clean_stack()
+
 class SetOnEvent(MicroInstruction):
     def __init__(self, field):
         self.field = field
@@ -222,29 +255,23 @@
         val = op.args[1].value
         val = val.concretize().value
         assert(isinstance(val, ootype._static_meth))
-        #if isinstance(val, ootype.StaticMethod):
         real_name = val._name
         generator.db.pending_function(val.graph)
-            #generator.db.pending_function(val.graph)
-        #else:
-        #    concrete = val.concretize()
-        #    real_name = concrete.value._name
-        #    generator.db.pending_function(concrete.value.graph)
-        #generator.load_str("'%s()'" % real_name)
-        #generator.load(op.args[2])
         generator.load_str("document")
         generator.load_str(real_name)
         generator.set_field(None, self.field)
-        #generator.call_external('setTimeout',[0]*2)
 
-##class _XmlSetCallback(MicroInstruction):
-##    # FIXME: Another dirty hack. To remove soon
-##    def render(self, generator, op):
-##        generator.load(op.args[2])
-##        generator.load(op.args[1])
-##        generator.set_field(None, 'onreadystatechange')
-##
-##XmlSetCallback = _XmlSetCallback()
+class _CheckLength(MicroInstruction):
+    def render(self, generator, op):
+        assert not generator.ilasm.right_hand
+
+class _ListRemove(MicroInstruction):
+    def render(self, generator, op):
+        generator.list_getitem(op.args[1], op.args[2])
+        generator.call_external('delete', [0])
+
+ListRemove = _ListRemove()
+CheckLength = _CheckLength()
 SetTimeout = _SetTimeout()
 IndirectCall = _IndirectCall()
 IsInstance = _IsInstance()
@@ -252,3 +279,19 @@
 CopyName = [PushAllArgs, _SameAs ()]
 CastString = _CastFun("convertToString", 1)
 SameAs = CopyName
+DiscardStack = _DiscardStack()
+
+def fix_opcodes(opcodes):
+    for key, value in opcodes.iteritems():
+        if type(value) is str:
+            value = InstructionList([PushAllArgs, value, StoreResult, CheckLength])
+        elif value == []:
+            value = InstructionList([CheckLength])
+        elif value is not None:
+            if StoreResult not in value:
+                value.append(StoreResult)
+            if CheckLength not in value:
+                value.append(CheckLength)
+            value = InstructionList(value)
+
+        opcodes[key] = value

Modified: pypy/dist/pypy/translator/js/opcodes.py
==============================================================================
--- pypy/dist/pypy/translator/js/opcodes.py	(original)
+++ pypy/dist/pypy/translator/js/opcodes.py	Mon May  7 13:17:59 2007
@@ -2,19 +2,21 @@
 """
 
 from pypy.translator.oosupport.metavm import PushArg, PushAllArgs, StoreResult,\
-    InstructionList, New, SetField, GetField, MicroInstruction, RuntimeNew, PushPrimitive
+    InstructionList, New, GetField, MicroInstruction, RuntimeNew, PushPrimitive
      
 from pypy.translator.oosupport.metavm import _GetFieldDispatcher, _SetFieldDispatcher, \
-    _CallDispatcher, _MethodDispatcher
+    _CallDispatcher, _MethodDispatcher, SetField
 
-from pypy.translator.js.metavm import SameAs, IsInstance, Call, CallMethod, CopyName, CastString,\
-    _Prefix, _CastFun, _NotImplemented, CallBuiltin, CallBuiltinObject, GetBuiltinField, SetBuiltinField,\
-    IndirectCall, CallExternalObject, SetExternalField, _CastMethod, _LoadConst
+from pypy.translator.js.metavm import IsInstance, Call, CallMethod,\
+     CopyName, CastString, _Prefix, _CastFun, _NotImplemented, CallBuiltin,\
+     CallBuiltinObject, GetBuiltinField, SetBuiltinField, IndirectCall,\
+     CallExternalObject, SetExternalField, _CastMethod, _LoadConst,\
+     DiscardStack, CheckLength, fix_opcodes
 
 from pypy.translator.js.jsbuiltin import Builtins
 from pypy.rpython.ootypesystem import ootype
 
-DoNothing = [PushAllArgs]
+DoNothing = []
 
 from pypy.translator.js.log import log
 
@@ -113,7 +115,7 @@
     
     'direct_call' : [_CallDispatcher(Builtins, class_map)],
     'indirect_call' : [IndirectCall],
-    'same_as' : SameAs,
+    'same_as' : CopyName,
     'new' : [New],
     'runtimenew' : [RuntimeNew],
     'instanceof' : [IsInstance],
@@ -124,8 +126,8 @@
     'oosetfield' : [_SetFieldDispatcher(Builtins, class_map)],
     'oogetfield' : [_GetFieldDispatcher(Builtins, class_map)],
     'oosend'     : [_MethodDispatcher(Builtins, class_map)],
-    'ooupcast'   : DoNothing,
-    'oodowncast' : DoNothing,        
+    'ooupcast'   : CopyName,
+    'oodowncast' : CopyName,        
     'oononnull'  : [PushAllArgs,_Prefix('!!')],
     'oostring'   : [PushArg(0),CastString],
     'ooparse_int' : [PushAllArgs,_CastFun("parseInt",2)],
@@ -153,12 +155,4 @@
     'is_early_constant': [PushPrimitive(ootype.Bool, False)],
 }
 
-for key, value in opcodes.iteritems():
-    if type(value) is str:
-        value = InstructionList([PushAllArgs, value, StoreResult])
-    elif value is not None:
-        if StoreResult not in value:
-            value.append(StoreResult)
-        value = InstructionList(value)
-
-    opcodes[key] = value
+fix_opcodes(opcodes)


More information about the pypy-svn mailing list