[pypy-svn] r28372 - in pypy/dist/pypy/translator/js2: . jssrc modules test

fijal at codespeak.net fijal at codespeak.net
Tue Jun 6 14:52:27 CEST 2006


Author: fijal
Date: Tue Jun  6 14:52:25 2006
New Revision: 28372

Added:
   pypy/dist/pypy/translator/js2/metavm.py
Removed:
   pypy/dist/pypy/translator/js2/_builtin.py
Modified:
   pypy/dist/pypy/translator/js2/   (props changed)
   pypy/dist/pypy/translator/js2/function.py
   pypy/dist/pypy/translator/js2/jssrc/misc.js
   pypy/dist/pypy/translator/js2/modules/dom.py
   pypy/dist/pypy/translator/js2/opcodes.py
   pypy/dist/pypy/translator/js2/test/   (props changed)
   pypy/dist/pypy/translator/js2/test/test_dom.py
   pypy/dist/pypy/translator/js2/test/test_genllvm.py
Log:
Added svn:ignore for *.pyc
Refactored builtin code support, so DOM support should be much easier now.


Modified: pypy/dist/pypy/translator/js2/function.py
==============================================================================
--- pypy/dist/pypy/translator/js2/function.py	(original)
+++ pypy/dist/pypy/translator/js2/function.py	Tue Jun  6 14:52:25 2006
@@ -451,8 +451,3 @@
         self.load(base_obj)
         self.load(item)
         self.ilasm.list_getitem()
-
-    def list_resize(self, lst, new_size):
-        self.load(lst)
-        self.load(new_size)
-        self.set_field(None, 'length')

Modified: pypy/dist/pypy/translator/js2/jssrc/misc.js
==============================================================================
--- pypy/dist/pypy/translator/js2/jssrc/misc.js	(original)
+++ pypy/dist/pypy/translator/js2/jssrc/misc.js	Tue Jun  6 14:52:25 2006
@@ -21,40 +21,6 @@
     return (false);
 }
 
-Function.method('old_inherits', function (parent) {
-    var d = 0, p = (this.prototype = new parent());
-    //var p = new parent();
-    //var d = 0;
-    this.method('uber', function uber(name) {
-        var f, r, t = d, v = parent.prototype;
-        if (t) {
-            while (t) {
-                v = v.constructor.prototype;
-                t -= 1;
-            }
-            f = v[name];
-        } else {
-            f = p[name];
-            if (f == this[name]) {
-                f = v[name];
-            }
-        }
-        d += 1;
-        r = f.apply(this, Array.prototype.slice.apply(arguments, [1]));
-        d -= 1;
-        return r;
-    });
-    return this;
-});
-
-Function.method('swiss', function (parent) {
-    for (var i = 1; i < arguments.length; i += 1) {
-        var name = arguments[i];
-        this.prototype[name] = parent.prototype[name];
-    }
-    return this;
-});
-
 function alloc_and_set(L0, len, elem) {
     l = [];
     for(i = 0; i < len; ++i){

Added: pypy/dist/pypy/translator/js2/metavm.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/js2/metavm.py	Tue Jun  6 14:52:25 2006
@@ -0,0 +1,238 @@
+
+""" Opcode meaning objects, descendants of MicroInstruction
+"""
+
+#from pypy.translator.js2.jsbuiltin import Builtins
+from pypy.translator.cli.metavm import PushArg, PushAllArgs, StoreResult,\
+    InstructionList, New, SetField, GetField, RuntimeNew, MicroInstruction
+
+from pypy.translator.js2.log import log
+from pypy.rpython.ootypesystem import ootype
+
+class _ListSetitem(MicroInstruction):
+    def render(self, generator, op):
+        generator.load(op.args[1])
+        generator.load(op.args[3])
+        generator.load(op.args[2])
+        generator.ilasm.list_setitem()
+ListSetitem = _ListSetitem()
+
+class _ListGetitem(MicroInstruction):
+    def render(self, generator, op):
+        generator.load(op.args[1])
+        generator.load(op.args[2])
+        generator.ilasm.list_getitem()
+ListGetitem = _ListGetitem()
+
+class _Call(MicroInstruction):
+    def render(self, generator, op):
+        graph = op.args[0].value.graph
+        self._render_function(generator, graph, op.args)
+
+    def _render_builtin(self, generator, builtin, args):
+        for func_arg in args[1:]: # push parameters
+            generator.load(func_arg)
+        generator.call_external(builtin, args[1:])
+    
+    def _render_builtin_method(self, generator, builtin, args, is_property):
+        if not is_property:
+            for func_arg in args:
+                generator.load(func_arg)
+            generator.call_external_method(builtin, len(args)-1)
+        else:
+            generator.load(args[0])
+            generator.get_field(None, builtin)
+
+    def _render_function(self, generator, graph, args):
+        for func_arg in args[1:]: # push parameters
+            generator.load(func_arg)
+        generator.call_graph(graph)
+    
+    # Various low level function-to-operator mappings
+    
+    def _render_method(self, generator, method_name, args):
+        this = args[0]
+        for arg in args: # push parametes
+            generator.load(arg)
+        generator.call_method(this.concretetype, method_name)
+
+Call = _Call()
+
+class CallBuiltin(_Call):
+    def __init__(self, builtin):
+        self.builtin = builtin
+    
+    def render(self, generator, op):
+        self._render_builtin(generator, self.builtin, op.args)
+
+class _Builtins(object):
+    def __init__(self):
+        list_resize = lambda g,op: SetBuiltinField.run_it(g, op.args[1], 'length', op.args[2])
+        
+        self.builtin_map = {
+            'll_js_jseval' : CallBuiltin('eval'),
+            'll_newlist' : lambda g,op: g.ilasm.load_const("[]"),
+            'll_alloc_and_set' : CallBuiltin('alloc_and_set'),
+        }
+        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' : ListGetitem,
+                'll_streq' : InstructionList([PushAllArgs, '==']),
+                'll_strcmp' : CallBuiltin('strcmp'),
+                'll_startswith' : CallBuiltin('startswith'),
+                'll_endswith' : CallBuiltin('endswith'),
+            },
+            ootype.List: {
+                'll_setitem_fast' : ListSetitem,
+                'll_getitem_fast' : ListGetitem,
+                '_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'),
+            }
+        }
+        
+Builtins = _Builtins()
+
+class _SameAs(MicroInstruction):
+    def render(self, generator, op):
+        generator.change_name(op.result, op.args[0])
+
+class _CastFun(MicroInstruction):
+    def __init__(self, name, num):
+        self.name = name
+        self.num = num
+
+    def render(self, generator, op):
+        log("Args: %r"%op.args)
+        generator.cast_function(self.name, self.num)
+
+class _Prefix(MicroInstruction):
+    def __init__(self, st):
+        self.st = st
+    
+    def render(self, generator, op):
+        generator.prefix_op(self.st)
+
+class _NotImplemented(MicroInstruction):
+    def __init__(self, reason):
+        self.reason = reason
+    
+    def render(self, generator, op):
+        raise NotImplementedError(self.reason)
+        
+class _New(MicroInstruction):
+    def render(self, generator, op):
+        generator.new(op.args[0].value)
+
+class _CastString(MicroInstruction):
+    def render(self, generator, op):
+        this = op.args[0]
+        generator.load(this)
+        generator.call_external_method("toString", 0)
+    
+class _GetBuiltinField(MicroInstruction):
+    def render(self, generator, op):
+        this = op.args[0]
+        field = op.args[1]
+        field_name = this.value.methods[field].name[1:]
+        self.run_it(generator, this, field_name)
+    
+    def run_it(self, generator, this, field_name):
+        generator.load(this)
+        generator.get_field(None, field_name)
+
+GetBuiltinField = _GetBuiltinField()
+
+class _SetBuiltinField(MicroInstruction):
+    def render(self, generator, op):
+        this = op.args[0]
+        field = op.args[1]
+        value = op.args[2]
+        field_name = this.value.methods[field].name[1:]
+        self.run_it(generator, this, field_name, value)
+    
+    def run_it(self, generator, this, field_name, value):
+        generator.load(this)
+        generator.load(value)
+        generator.set_field(None, field_name)
+
+SetBuiltinField = _SetBuiltinField()
+
+class _CallMethod(_Call):
+    def render(self, generator, op):
+        method = op.args[0]
+        self._render_method(generator, method.value, op.args[1:])
+
+class _IsInstance(MicroInstruction):
+    def render(self, generator, op):
+        # FIXME: just temporary hack
+        generator.load(op.args[0])
+        generator.ilasm.load_const(op.args[1].value._name.replace('.', '_'))#[-1])
+        generator.cast_function("isinstanceof", 2)
+
+# There are three distinct possibilities where we need to map call differently:
+# 1. Object is marked with rpython_hints as a builtin, so every attribut access
+#    and function call goes as builtin
+# 2. Function called is a builtin, so it might be mapped to attribute access, builtin function call
+#    or even method call
+# 3. Object on which method is called is primitive object and method is mapped to some
+#    method/function/attribute access
+class _GeneralDispatcher(MicroInstruction):
+    def render(self, generator, op):
+        raise NotImplementedError("pure virtual class")
+    
+    def check_builtin(self, this):
+        if not isinstance(this, ootype.Instance):
+            return False
+        return this._hints.get('_suggested_external')
+
+class _MethodDispatcher(_GeneralDispatcher):
+    def render(self, generator, op):
+        method = op.args[0].value
+        this = op.args[1].concretetype
+        if self.check_builtin(this):
+            return CallBuiltinObject.render(generator, op)
+        try:
+            Builtins.builtin_obj_map[this.__class__][method](generator, op)
+            log("%r.%r declared builtin" % (this, method))
+        except KeyError:
+            log("%r.%r declared normal" % (this, method))
+            CallMethod.render(generator, op)
+
+class _CallDispatcher(_GeneralDispatcher):
+    def render(self, generator, op):
+        func = op.args[0]
+        if getattr(func.value._callable, 'suggested_primitive', False):
+            func_name = func.value._name.split("__")[0]
+            log("Function name: %s suggested primitive" % func_name)
+            if Builtins.builtin_map.has_key(func_name):
+                return Builtins.builtin_map[func_name](generator, op)
+        else:
+            return Call.render(generator, op)
+    
+class _GetFieldDispatcher(_GeneralDispatcher):
+    def render(self, generator, op):
+        if self.check_builtin(op.args[0].concretetype):
+            return GetBuiltinField.render(generator, op)
+        else:
+            return GetField.render(generator, op)
+    
+class _SetFieldDispatcher(_GeneralDispatcher):
+    def render(self, generator, op):
+        if self.check_builtin(op.args[0].concretetype):
+            return SetBuiltinField.render(generator, op)
+        else:
+            return SetField.render(generator, op)
+
+MethodDispatcher = _MethodDispatcher()
+CallDispatcher = _CallDispatcher()
+GetFieldDispatcher = _GetFieldDispatcher()
+SetFieldDispatcher = _SetFieldDispatcher()
+IsInstance = _IsInstance()
+CallMethod = _CallMethod()
+CopyName = [PushAllArgs, _SameAs ()]
+CastString = _CastString()
+SameAs = CopyName

Modified: pypy/dist/pypy/translator/js2/modules/dom.py
==============================================================================
--- pypy/dist/pypy/translator/js2/modules/dom.py	(original)
+++ pypy/dist/pypy/translator/js2/modules/dom.py	Tue Jun  6 14:52:25 2006
@@ -6,15 +6,47 @@
 
 # FIXME: this should map somehow to xml.dom interface, or something else
 
+import time
+
+class Style(object):
+    def __init__(self, s_str):
+        self.left = "0"
+        self.top = "0"
+    
+    def setLeft(self, left):
+        self.left = left
+    
+    def getLeft(self):
+        return self.left
+    
+    def setTop(self, top):
+        self.top = top
+    
+    def getTop(self):
+        return self.top
+
 class Node(object):
+    _rpython_hints = {'_suggested_external' : True}
+    
     def __init__(self):
         self.innerHTML = ""
+        self.style = None
     
     def getElementById(self, id):
         return Node()
     
     def setInnerHTML(self, data):
         self.innerHTML = data
+    
+    def setAttribute(self, name, style_str):
+        if name == 'style':
+            self.style = Style( style_str)
+        
+    def getStyle(self):
+        return self.style
+
+document = Node()
 
-def get_document():
-    return Node()
+def setTimeout(func, delay):
+    # scheduler call, but we don't want to mess with threads right now
+    return func

Modified: pypy/dist/pypy/translator/js2/opcodes.py
==============================================================================
--- pypy/dist/pypy/translator/js2/opcodes.py	(original)
+++ pypy/dist/pypy/translator/js2/opcodes.py	Tue Jun  6 14:52:25 2006
@@ -3,151 +3,16 @@
 """
 
 from pypy.translator.cli.metavm import PushArg, PushAllArgs, StoreResult,\
-     InstructionList, New, SetField, GetField, RuntimeNew, MicroInstruction
+    InstructionList, New, SetField, GetField, RuntimeNew, MicroInstruction
+     
+from pypy.translator.js2.metavm import SameAs, IsInstance, Call, CallMethod, CopyName, CastString,\
+    _Prefix, _CastFun, _NotImplemented, GetFieldDispatcher, SetFieldDispatcher, CallDispatcher, MethodDispatcher
 
 DoNothing = [PushAllArgs]
 
 from pypy.translator.js2._builtin import Builtins
 from pypy.translator.js2.log import log
 
-##class _GetField(MicroInstruction):
-##    def render(self, generator, op):
-##        this, field = op.args
-##        generator.load(this)
-##        generator.get_field(this.concretetype, field.value)
-
-class _SameAs(MicroInstruction):
-    def render(self, generator, op):
-        generator.change_name(op.result, op.args[0])
-
-class _CastFun(MicroInstruction):
-    def __init__(self, name, num):
-        self.name = name
-        self.num = num
-
-    def render(self, generator, op):
-        log("Args: %r"%op.args)
-        generator.cast_function(self.name, self.num)
-
-class _Prefix(MicroInstruction):
-    def __init__(self, st):
-        self.st = st
-    
-    def render(self, generator, op):
-        generator.prefix_op(self.st)
-
-class _NotImplemented(MicroInstruction):
-    def __init__(self, reason):
-        self.reason = reason
-    
-    def render(self, generator, op):
-        raise NotImplementedError(self.reason)
-        
-class _New(MicroInstruction):
-    def render(self, generator, op):
-        generator.new(op.args[0].value)
-
-class _CastString(MicroInstruction):
-    def render(self, generator, op):
-        this = op.args[0]
-        generator.load(this)
-        generator.call_external_method("toString", 0)
-
-class _Call(MicroInstruction):
-    def render(self, generator, op):
-        graph = op.args[0].value.graph
-        #method_name = oopspec.get_method_name(graph, op)
-        #if method_name is None:
-        if op.args[0] in generator.db.name_manager.predefined:
-            bt = op.args[0], False
-        else:
-            bt = Builtins.map_builtin_function(op.args[0], self, op.args, generator)
-        if bt:
-            builtin, is_property = bt
-            self._render_builtin(generator, builtin, op.args, is_property)
-            log("Suggested builtin %r %r"%(bt, is_property))
-        if bt is None:
-            self._render_function(generator, graph, op.args)
-        #else:
-        #    self._render_method(generator, method_name, op.args[1:])
-
-    def _render_builtin(self, generator, builtin, args, is_property):
-        if not is_property:
-            for func_arg in args[1:]: # push parameters
-                generator.load(func_arg)
-            generator.call_external(builtin, args[1:])
-        else:
-            generator.load_str(builtin)
-    
-    def _render_builtin_method(self, generator, builtin, args, is_property):
-        if not is_property:
-            for func_arg in args:
-                generator.load(func_arg)
-            generator.call_external_method(builtin, len(args)-1)
-        else:
-            generator.load(args[0])
-            generator.get_field(None, builtin)
-
-    def _render_function(self, generator, graph, args):
-        #func_sig = generator.function_signature(graph)
-        for func_arg in args[1:]: # push parameters
-            generator.load(func_arg)
-        generator.call_graph(graph)
-    
-    # Various low level function-to-operator mappings
-    
-    def list_ll_setitem(self, base_obj, args, generator):
-        generator.list_setitem(base_obj, args[1], args[2])
-    
-    def list_ll_getitem(self, base_obj, args, generator):
-        generator.list_getitem(base_obj, args[1])
-    
-    def list_ll_resize(self, base_obj, args, generator):
-        generator.list_resize(base_obj, args[1])
-    
-    def do_nothing(self, base_obj, args, generator):
-        generator.load_void()
-    
-    def setitem(self, base_obj, args, generator, real_name):
-        generator.load(base_obj)
-        generator.load(args[1])
-        generator.set_field(None, real_name)
-    
-    def equal(self, base_obj, args, generator):
-        generator.load(args[1])
-        generator.load(args[2])
-        generator.emit("==")
-
-    def _render_method(self, generator, method_name, args):
-        this = args[0]
-        bt = Builtins.map_builtin_method(this, method_name, args, self, generator)
-        if bt:
-            function,is_property = bt
-            self._render_builtin_method(generator, function, args, is_property)
-        if bt is None:
-            for arg in args: # push parametes
-                generator.load(arg)
-            generator.call_method(this.concretetype, method_name)
-
-class _CallMethod(_Call):
-    def render(self, generator, op):
-        method = op.args[0]
-        self._render_method(generator, method.value, op.args[1:])
-
-class _IsInstance(MicroInstruction):
-    def render(self, generator, op):
-        # FIXME: just temporary hack
-        generator.load(op.args[0])
-        generator.ilasm.load_const(op.args[1].value._name.replace('.', '_'))#[-1])
-        generator.cast_function("isinstanceof", 2)
-
-IsInstance = _IsInstance()
-Call = _Call()
-CallMethod = _CallMethod()
-CopyName = [PushAllArgs, _SameAs ()]
-CastString = _CastString()
-SameAs = CopyName
-
 opcodes = {'int_mul': '*',
     'int_add': '+',
     'int_sub': '-',
@@ -224,7 +89,7 @@
     'uint_is_true': [PushAllArgs,_Prefix('!!')],
     'float_is_true': [PushAllArgs,_Prefix('!!')],
     
-    'direct_call' : [Call],
+    'direct_call' : [CallDispatcher],
     'indirect_call' : [_NotImplemented("Indirect call not implemented")],
     'same_as' : SameAs,
     'new' : [New],
@@ -232,9 +97,9 @@
     
     # objects
     
-    'oosetfield' : [SetField],
-    'oogetfield' : [GetField],
-    'oosend'     : [CallMethod],
+    'oosetfield' : [SetFieldDispatcher],
+    'oogetfield' : [GetFieldDispatcher],
+    'oosend'     : [MethodDispatcher],
     #'ooupcast'   : [_NotImplemented("Inheritance not implemented (ooupcast)")],
     #'oodowncast' : [_NotImplemented("Inheritance not implemented (oodowncast)")],
     'ooupcast'   : DoNothing,

Modified: pypy/dist/pypy/translator/js2/test/test_dom.py
==============================================================================
--- pypy/dist/pypy/translator/js2/test/test_dom.py	(original)
+++ pypy/dist/pypy/translator/js2/test/test_dom.py	Tue Jun  6 14:52:25 2006
@@ -5,7 +5,7 @@
 import py
 
 from pypy.translator.js2.test.runtest import compile_function
-from pypy.translator.js2.modules.dom import get_document
+from pypy.translator.js2.modules.dom import document, setTimeout, Node
 from pypy.translator.js2 import conftest
 
 import time
@@ -16,8 +16,30 @@
 class TestDOM(object):
     def test_document_base(self):
         def f():
-            get_document().getElementById("dupa").setInnerHTML("<h1>Fire!</h1>")
-            return get_document().getElementById("dupa")
+            return document.getElementById("dupa")
+            #document.getElementById("dupa").setInnerHTML("<h1>Fire!</h1>")
+            #return document.getElementById("dupa")
         
         fn = compile_function(f, [], html = 'html/test.html')
         assert fn() == '[object HTMLHeadingElement]'
+
+    def test_anim(self):
+        def move_it_by(obj, dx, dy, dir):
+            if dir < 0:
+                dx = -dx
+                dy = -dy
+            obj.getStyle().setLeft(str(int(obj.getStyle().getLeft()) + dx) + "px")
+            obj.getStyle().setTop(str(int(obj.getStyle().getTop()) + dy) + "px")
+        
+        def move_it():
+            move_it_by(get_document().getElementById("anim_img"), 3, 3, 1)
+            setTimeout('move_it()', 100)
+        
+        def anim_fun():
+            obj = get_document().getElementById("anim_img")
+            obj.setAttribute('style', 'position: absolute; top: 0; left: 0;')
+            setTimeout('move_it()', 100)
+            move_it()
+        
+        fn = compile_function(anim_fun, [], html = 'html/anim.html', is_interactive = True)
+        assert fn() == 'ok'

Modified: pypy/dist/pypy/translator/js2/test/test_genllvm.py
==============================================================================
--- pypy/dist/pypy/translator/js2/test/test_genllvm.py	(original)
+++ pypy/dist/pypy/translator/js2/test/test_genllvm.py	Tue Jun  6 14:52:25 2006
@@ -411,3 +411,11 @@
     f = compile_function(testf, [int])
     assert f(1) == testf(1)
     assert f(2) == testf(2)
+
+def test_cast_str():
+    def cast_str(x):
+        return str(x)+str(x)+'px'
+    
+    f = compile_function(cast_str, [int])
+    assert f(1) == cast_str(1)
+    assert f(10) == cast_str(10)



More information about the Pypy-commit mailing list