[pypy-svn] r52544 - in pypy/branch/jit-refactoring/pypy/lang/js: . test

fijal at codespeak.net fijal at codespeak.net
Sat Mar 15 02:28:52 CET 2008


Author: fijal
Date: Sat Mar 15 02:28:50 2008
New Revision: 52544

Modified:
   pypy/branch/jit-refactoring/pypy/lang/js/baseop.py
   pypy/branch/jit-refactoring/pypy/lang/js/interpreter.py
   pypy/branch/jit-refactoring/pypy/lang/js/jscode.py
   pypy/branch/jit-refactoring/pypy/lang/js/jsobj.py
   pypy/branch/jit-refactoring/pypy/lang/js/operations.py
   pypy/branch/jit-refactoring/pypy/lang/js/test/test_interp.py
   pypy/branch/jit-refactoring/pypy/lang/js/test/test_parser.py
Log:
More tests passing.


Modified: pypy/branch/jit-refactoring/pypy/lang/js/baseop.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/lang/js/baseop.py	(original)
+++ pypy/branch/jit-refactoring/pypy/lang/js/baseop.py	Sat Mar 15 02:28:50 2008
@@ -3,6 +3,8 @@
 """
 
 from pypy.lang.js.jsobj import W_String, W_IntNumber, W_FloatNumber
+from pypy.rlib.rarithmetic import r_uint, intmask, INFINITY, NAN, ovfcheck,\
+     isnan, isinf
 
 def plus(ctx, nleft, nright):
     if isinstance(nleft, W_String) or isinstance(nright, W_String):
@@ -21,3 +23,15 @@
         fleft = nleft.ToNumber()
         fright = nright.ToNumber()
         return W_FloatNumber(fleft + fright)
+
+def sub(ctx, nleft, nright):
+    if isinstance(nleft, W_IntNumber) and isinstance(nright, W_IntNumber):
+        ileft = nleft.ToInt32()
+        iright = nright.ToInt32()
+        try:
+            return W_IntNumber(ovfcheck(ileft - iright))
+        except OverflowError:
+            return W_FloatNumber(float(ileft) - float(iright))
+    fleft = nleft.ToNumber()
+    fright = nright.ToNumber()
+    return W_FloatNumber(fleft - fright)

Modified: pypy/branch/jit-refactoring/pypy/lang/js/interpreter.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/lang/js/interpreter.py	(original)
+++ pypy/branch/jit-refactoring/pypy/lang/js/interpreter.py	Sat Mar 15 02:28:50 2008
@@ -9,6 +9,7 @@
 from pypy.lang.js.execution import ThrowException, JsTypeError
 from pypy.rlib.objectmodel import we_are_translated
 from pypy.rlib.streamio import open_file_as_stream
+from pypy.lang.js.jscode import JsCode
 
 ASTBUILDER = ASTBuilder()
 
@@ -551,7 +552,10 @@
 
     def run(self, script):
         """run the interpreter"""
-        return script.execute(self.global_context)
+        bytecode = JsCode()
+        script.emit(bytecode)
+        bytecode.run(self.global_context)
+        # XXX not sure what this should return
 
 def wrap_arguments(pyargs):
     "receives a list of arguments and wrap then in their js equivalents"

Modified: pypy/branch/jit-refactoring/pypy/lang/js/jscode.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/lang/js/jscode.py	(original)
+++ pypy/branch/jit-refactoring/pypy/lang/js/jscode.py	Sat Mar 15 02:28:50 2008
@@ -1,7 +1,9 @@
 
-from pypy.lang.js.jsobj import W_IntNumber, W_FloatNumber, W_String
+from pypy.lang.js.jsobj import W_IntNumber, W_FloatNumber, W_String,\
+     W_Array, W_PrimitiveObject, W_Reference, ActivationObject
+from pypy.lang.js.execution import JsTypeError
 from pypy.rlib.unroll import unrolling_iterable
-from pypy.lang.js.baseop import plus
+from pypy.lang.js.baseop import plus, sub
 
 class AlreadyRun(Exception):
     pass
@@ -128,8 +130,8 @@
     def __init__(self, value):
         self.w_intvalue = W_IntNumber(int(value))
 
-    def eval(self, ctx):
-        return self.w_intvalue
+    def eval(self, ctx, stack):
+        stack.append(self.w_intvalue)
 
     def __repr__(self):
         return 'LOAD_INTCONSTANT %s' % (self.w_intvalue.intval,)
@@ -148,8 +150,8 @@
     def __init__(self, value):
         self.w_stringvalue = W_String(value)
 
-    def eval(self, ctx):
-        return self.w_stringvalue
+    def eval(self, ctx, stack):
+        stack.append(self.w_stringvalue)
 
     def get_literal(self):
         return W_String(self.strval).ToString()
@@ -161,8 +163,8 @@
     def __init__(self, identifier):
         self.identifier = identifier
 
-    def eval(self, ctx):
-        return ctx.resolve_identifier(self.identifier)
+    def eval(self, ctx, stack):
+        stack.append(ctx.resolve_identifier(self.identifier).GetValue())
 
     def __repr__(self):
         return 'LOAD_VARIABLE "%s"' % (self.identifier,)
@@ -171,12 +173,12 @@
     def __init__(self, counter):
         self.counter = counter
 
-    def eval(self, ctx):
+    def eval(self, ctx, stack):
         proto = ctx.get_global().Get('Array').Get('prototype')
         array = W_Array(ctx, Prototype=proto, Class = proto.Class)
-        for i in range(len(self.nodes)):
-            array.Put(str(i), self.nodes[i].eval(ctx).GetValue())
-        return array
+        for i in range(self.counter):
+            array.Put(str(self.counter - i - 1), stack.pop().GetValue())
+        stack.append(array)
 
     def __repr__(self):
         return 'LOAD_ARRAY %d' % (self.counter,)
@@ -196,8 +198,10 @@
     def __init__(self, name):
         self.name = name
     
-    def eval(self, ctx):
-        XXX
+    def eval(self, ctx, stack):
+        value = stack.pop().GetValue()
+        ctx.assign(self.name, value)
+        stack.append(value)
 
     def __repr__(self):
         return 'STORE "%s"' % self.name
@@ -206,11 +210,15 @@
     def __init__(self, listofnames):
         self.listofnames = listofnames
 
+    def eval(self, ctx, stack):
+        XXX
+
     def __repr__(self):
         return 'LOAD_OBJECT %r' % (self.listofnames,)
 
 class SUB(BaseBinaryOperation):
-    pass
+    def operation(self, ctx, left, right):
+        return sub(ctx, left, right)
 
 class ADD(BaseBinaryOperation):
     def operation(self, ctx, left, right):
@@ -302,7 +310,30 @@
     pass
 
 class POP(Opcode):
-    pass
+    def eval(self, ctx, stack):
+        stack.pop()
+
+class CALL(Opcode):
+    def eval(self, ctx, stack):
+        r1 = stack.pop()
+        args = stack.pop()
+        r3 = r1.GetValue()
+        if not isinstance(r3, W_PrimitiveObject):
+            raise ThrowException(W_String("it is not a callable"))
+            
+        if isinstance(r1, W_Reference):
+            r6 = r1.GetBase()
+        else:
+            r6 = None
+        if isinstance(args, ActivationObject):
+            r7 = None
+        else:
+            r7 = r6
+        try:
+            res = r3.Call(ctx=ctx, args=args.tolist(), this=r7)
+        except JsTypeError:
+            raise ThrowException(W_String('it is not a function'))
+        stack.append(res)
 
 OpcodeMap = {}
 

Modified: pypy/branch/jit-refactoring/pypy/lang/js/jsobj.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/lang/js/jsobj.py	(original)
+++ pypy/branch/jit-refactoring/pypy/lang/js/jsobj.py	Sat Mar 15 02:28:50 2008
@@ -496,7 +496,6 @@
             self.this = scope[-1]
         else:
             self.this = this
-        # create a fast lookup
         if variable is None:
             self.variable = self.scope[0]
         else:
@@ -512,7 +511,13 @@
         return "<ExCtx %s, var: %s>"%(self.scope, self.variable)
         
     def assign(self, name, value):
-        pass
+        for obj in self.scope:
+            assert isinstance(obj, W_PrimitiveObject)
+            if obj.HasProperty(name):
+                obj.Put(name, value)
+                return
+        # if not, we need to put this thing in current scope
+        self.scope[0].Put(name, value)
     
     def get_global(self):
         return self.scope[-1]
@@ -573,11 +578,13 @@
         self.base = base
         self.property_name = property_name
 
-    def GetValue(self):
+    def check_empty(self):
         if self.base is None:
             exception = "ReferenceError: %s is not defined"%(self.property_name,)
-            raise ThrowException(W_String(exception))
-        
+            raise ThrowException(W_String(exception))        
+
+    def GetValue(self):
+        self.check_empty()
         return self.base.Get(self.property_name)
 
     def PutValue(self, w, ctx):

Modified: pypy/branch/jit-refactoring/pypy/lang/js/operations.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/lang/js/operations.py	(original)
+++ pypy/branch/jit-refactoring/pypy/lang/js/operations.py	Sat Mar 15 02:28:50 2008
@@ -9,8 +9,6 @@
      W_PrimitiveObject, W_Reference, ActivationObject, W_Array, W_Boolean,\
      w_Null, W_BaseNumber, isnull_or_undefined
 from pypy.rlib.parsing.ebnfparse import Symbol, Nonterminal
-from pypy.rlib.rarithmetic import r_uint, intmask, INFINITY, NAN, ovfcheck,\
-     isnan, isinf
 from pypy.lang.js.execution import ExecutionReturned, JsTypeError,\
      ThrowException
 from pypy.lang.js.jscode import JsCode, JsFunction
@@ -262,27 +260,16 @@
     
 
 
-class Call(BinaryOp):
-    def eval(self, ctx):
-        r1 = self.left.eval(ctx)
-        r2 = self.right.eval(ctx)
-        r3 = r1.GetValue()
-        if not isinstance(r3, W_PrimitiveObject):
-            raise ThrowException(W_String("it is not a callable"))
-            
-        if isinstance(r1, W_Reference):
-            r6 = r1.GetBase()
-        else:
-            r6 = None
-        if isinstance(r2, ActivationObject):
-            r7 = None
-        else:
-            r7 = r6
-        try:
-            res = r3.Call(ctx=ctx, args=r2.get_args(), this=r7)
-        except JsTypeError:
-            raise ThrowException(W_String('it is not a function'))
-        return res
+class Call(Expression):
+    def __init__(self, pos, left, args):
+        self.pos = pos
+        self.left = left
+        self.args = args
+    
+    def emit(self, bytecode):
+        self.args.emit(bytecode)
+        self.left.emit(bytecode)
+        bytecode.emit('CALL')
 
 class Comma(BinaryOp):
     def eval(self, ctx):
@@ -707,6 +694,10 @@
     def eval(self, ctx):
         return W_List([node.eval(ctx).GetValue() for node in self.nodes])
 
+    def emit(self, bytecode):
+        for node in self.nodes:
+            node.emit(bytecode)
+        bytecode.emit('LOAD_ARRAY', len(self.nodes))
 
 ##############################################################################
 #
@@ -755,18 +746,6 @@
         val = fleft / fright
     return W_FloatNumber(val)
 
-def sub(ctx, nleft, nright):
-    if isinstance(nleft, W_IntNumber) and isinstance(nright, W_IntNumber):
-        ileft = nleft.ToInt32()
-        iright = nright.ToInt32()
-        try:
-            return W_IntNumber(ovfcheck(ileft - iright))
-        except OverflowError:
-            return W_FloatNumber(float(ileft) - float(iright))
-    fleft = nleft.ToNumber()
-    fright = nright.ToNumber()
-    return W_FloatNumber(fleft - fright)
-
 class Plus(BinaryNumberOp):
     operation_name = 'ADD'
 
@@ -914,6 +893,10 @@
 
         for node in self.nodes:
             node.emit(bytecode)
+            # we don't need to pop after certain instructions, let's
+            # list them
+            if not isinstance(node, Return):
+                bytecode.emit('POP')
 
     def execute(self, ctx):
         for varname in self.var_decl:
@@ -941,9 +924,8 @@
         self.pos = pos
         self.body = body
 
-    def execute(self, ctx):
-        return self.body.execute(ctx)
-    
+    def emit(self, bytecode):
+        self.body.emit(bytecode)
 
 class Return(Statement):
     def __init__(self, pos, expr):

Modified: pypy/branch/jit-refactoring/pypy/lang/js/test/test_interp.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/lang/js/test/test_interp.py	(original)
+++ pypy/branch/jit-refactoring/pypy/lang/js/test/test_interp.py	Sat Mar 15 02:28:50 2008
@@ -4,7 +4,7 @@
 from pypy.lang.js.operations import AEC, IntNumber, FloatNumber, Position, Plus
 from pypy.lang.js.jsobj import W_Object, ExecutionContext, W_Root, w_Null
 from pypy.lang.js.execution import ThrowException
-from pypy.lang.js.jscode import JsCode
+from pypy.lang.js.jscode import JsCode, POP
 
 def test_simple():
     bytecode = JsCode()
@@ -33,7 +33,13 @@
     jsint = interpreter.Interpreter()
     ctx = jsint.w_Global
     try:
-        code_val = jsint.run(interpreter.load_source(code, '')).GetValue()
+        bytecode = JsCode()
+        interpreter.load_source(code, '').emit(bytecode)
+        # XXX terrible hack
+        assert isinstance(bytecode.opcodes[-1], POP)
+        bytecode.opcodes.pop()
+        bytecode.run(ExecutionContext([ctx]), check_stack=False)
+        code_val = bytecode.stack[0].GetValue()
     except ThrowException, excpt:
         code_val = excpt.exception
     print code_val, value
@@ -52,7 +58,6 @@
     jsint = interpreter.Interpreter()
     py.test.raises(value, 'jsint.run(interpreter.load_source(code, ""))')
     
-    
 def test_interp_parse():
     yield assertv, "1+1;", 2
     yield assertp, "print(1+2+3); print(1);", ["6", "1"]

Modified: pypy/branch/jit-refactoring/pypy/lang/js/test/test_parser.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/lang/js/test/test_parser.py	(original)
+++ pypy/branch/jit-refactoring/pypy/lang/js/test/test_parser.py	Sat Mar 15 02:28:50 2008
@@ -442,14 +442,23 @@
 
     def test_function_decl(self):
         self.check('function f(x, y, z) {x;}',
-                   ['DECLARE_FUNCTION f [\'x\', \'y\', \'z\'] [\n  LOAD_VARIABLE "x"\n]'])
+                   ['DECLARE_FUNCTION f [\'x\', \'y\', \'z\'] [\n  LOAD_VARIABLE "x"\n  POP\n]'])
 
     def test_function_expression(self):
         self.check('var x = function() {return x}',[
             'DECLARE_VAR "x"',
             'DECLARE_FUNCTION [] [\n  LOAD_VARIABLE "x"\n  RETURN\n]',
             'LOAD_FUNCTION',
-            'STORE "x"'])
+            'STORE "x"',
+            'POP'])
+
+    def test_call(self):
+        self.check('print("stuff")',[
+            'LOAD_STRINGCONSTANT "stuff"',
+            'LOAD_ARRAY 1',
+            'LOAD_VARIABLE "print"',
+            'CALL',
+            'POP'])
 
 from pypy.lang.js.jsparser import parse
     



More information about the Pypy-commit mailing list