[pypy-svn] r55476 - in pypy/branch/js-refactoring/pypy/lang/js: . test test/ecma

santagada at codespeak.net santagada at codespeak.net
Mon Jun 2 00:37:31 CEST 2008


Author: santagada
Date: Mon Jun  2 00:37:28 2008
New Revision: 55476

Modified:
   pypy/branch/js-refactoring/pypy/lang/js/astbuilder.py
   pypy/branch/js-refactoring/pypy/lang/js/interpreter.py
   pypy/branch/js-refactoring/pypy/lang/js/js_interactive.py
   pypy/branch/js-refactoring/pypy/lang/js/jscode.py
   pypy/branch/js-refactoring/pypy/lang/js/jsobj.py
   pypy/branch/js-refactoring/pypy/lang/js/operations.py
   pypy/branch/js-refactoring/pypy/lang/js/test/ecma/conftest.py
   pypy/branch/js-refactoring/pypy/lang/js/test/ecma/shell.js
   pypy/branch/js-refactoring/pypy/lang/js/test/test_interp.py
Log:
lots of bugfixes. A new for, forin, forinvar, with, some more methods on standard objects, and a rewrite to make scopes grow like a normal stack. also a bugfix on some code for bytecode dipatch that was much slower than it should

Modified: pypy/branch/js-refactoring/pypy/lang/js/astbuilder.py
==============================================================================
--- pypy/branch/js-refactoring/pypy/lang/js/astbuilder.py	(original)
+++ pypy/branch/js-refactoring/pypy/lang/js/astbuilder.py	Mon Jun  2 00:37:28 2008
@@ -426,7 +426,15 @@
         else:
             target = None
         return operations.Break(pos, target)
-    
+
+    def visit_continuestatement(self, node):
+        pos = self.get_pos(node)
+        if len(node.children) > 0:
+            target = self.dispatch(node.children[0])
+        else:
+            target = None
+        return operations.Continue(pos, target)
+
     def visit_returnstatement(self, node):
         pos = self.get_pos(node)
         if len(node.children) > 0:
@@ -463,7 +471,7 @@
     
     def visit_withstatement(self, node):
         pos = self.get_pos(node)
-        identifier = self.dispatch(node.children[0])
+        withpart = self.dispatch(node.children[0])
         body = self.dispatch(node.children[1])
-        return operations.With(pos, identifier, body)
-        
+        return operations.With(pos, withpart, body)
+    

Modified: pypy/branch/js-refactoring/pypy/lang/js/interpreter.py
==============================================================================
--- pypy/branch/js-refactoring/pypy/lang/js/interpreter.py	(original)
+++ pypy/branch/js-refactoring/pypy/lang/js/interpreter.py	Mon Jun  2 00:37:28 2008
@@ -11,7 +11,7 @@
 from pypy.rlib.objectmodel import we_are_translated
 from pypy.rlib.streamio import open_file_as_stream
 from pypy.lang.js.jscode import JsCode
-from pypy.rlib.rarithmetic import NAN, INFINITY, isnan, isinf
+from pypy.rlib.rarithmetic import NAN, INFINITY, isnan, isinf, r_uint
 
 ASTBUILDER = ASTBuilder()
 
@@ -307,15 +307,25 @@
             raise JsTypeError('Wrong type')
         return W_String(this.Value.ToString(ctx))
 
-
 class W_NumberValueToString(W_ValueToString):
     mytype = 'number'
 
 class W_BooleanValueToString(W_ValueToString):
     mytype = 'boolean'
 
-class W_StringValueToString(W_ValueToString):
-    mytype = 'string'
+class W_StringValueToString(W_NewBuiltin):
+    "this is the toString function for objects with Value"
+    def Call(self, ctx, args=[], this=None):
+        if this.type() != 'string':
+            raise JsTypeError('Wrong type')
+        return this
+
+class W_StringValueOf(W_NewBuiltin):
+    "this is the toString function for objects with Value"
+    def Call(self, ctx, args=[], this=None):
+        if this.type() != 'string':
+            raise JsTypeError('Wrong type')
+        return this
 
 
 def get_value_of(type, ctx):
@@ -398,6 +408,7 @@
         return W_String(common_join(ctx, this, sep=','))
 
 class W_ArrayJoin(W_NewBuiltin):
+    length = 1
     def Call(self, ctx, args=[], this=None):
         if len(args) >= 1 and not args[0] is w_Undefined:
             sep = args[0].ToString(ctx)
@@ -406,6 +417,28 @@
         
         return W_String(common_join(ctx, this, sep))
 
+class W_ArrayReverse(W_NewBuiltin):
+    length = 0
+    def Call(self, ctx, args=[], this=None):
+        r2 = this.Get(ctx, 'length').ToUInt32(ctx)
+        k = r_uint(0)
+        r3 = r_uint(math.floor( float(r2)/2.0 ))
+        if r3 == k:
+            return this
+        
+        while k < r3:
+            r6 = r2 - k - 1
+            r7 = str(k)
+            r8 = str(r6)
+            
+            r9 = this.Get(ctx, r7)
+            r10 = this.Get(ctx, r8)
+            
+            this.Put(ctx, r7, r10)
+            this.Put(ctx, r8, r9)
+            k += 1
+        
+        return this
 
 class W_DateFake(W_NewBuiltin): # XXX This is temporary
     def Call(self, ctx, args=[], this=None):
@@ -433,13 +466,15 @@
         
         w_Function = W_Function(ctx, Class='Function', 
                               Prototype=w_ObjPrototype)
-        
         w_Global.Put(ctx, 'Function', w_Function)
+        w_Function.Put(ctx, 'length', W_IntNumber(1), flags = allon)
         
         w_Object = W_ObjectObject('Object', w_Function)
         w_Object.Put(ctx, 'prototype', w_ObjPrototype, flags = allon)
         
         w_Global.Put(ctx, 'Object', w_Object)
+        w_Global.Prototype = w_ObjPrototype
+        
         w_FncPrototype = w_Function.Call(ctx, this=w_Function)
         w_Function.Put(ctx, 'prototype', w_FncPrototype, flags = allon)
         w_Function.Put(ctx, 'constructor', w_Function)
@@ -450,7 +485,7 @@
         
         put_values(w_ObjPrototype, {
             'constructor': w_Object,
-            '__proto__': w_Null,
+            '__proto__': w_FncPrototype,
             'toString': toString,
             'toLocaleString': toString,
             'valueOf': W_ValueOf(ctx),
@@ -461,11 +496,12 @@
         
         #properties of the function prototype
         put_values(w_FncPrototype, {
-            'constructor': w_FncPrototype,
-            '__proto__': w_ObjPrototype,
+            'constructor': w_Function,
+            '__proto__': w_FncPrototype,
             'toString': W_FToString(ctx),
             'apply': W_Apply(ctx),
-            'call': W_Call(ctx),        
+            'call': W_Call(ctx),
+            'arguments': w_Null,
         })
         
         w_Boolean = W_BooleanObject('Boolean', w_FncPrototype)
@@ -528,7 +564,7 @@
             'constructor': w_FncPrototype,
             '__proto__': w_StrPrototype,
             'toString': W_StringValueToString(ctx),
-            'valueOf': get_value_of('String', ctx),
+            'valueOf': W_StringValueOf(ctx),
             'charAt': W_CharAt(ctx),
             'concat': W_Concat(ctx),
             'indexOf': W_IndexOf(ctx),
@@ -536,6 +572,7 @@
         })
         
         w_String.Put(ctx, 'prototype', w_StrPrototype)
+        w_String.Put(ctx, 'fromCharCode', w_String) #dummy
         w_Global.Put(ctx, 'String', w_String)
 
         w_Array = W_ArrayObject('Array', w_FncPrototype)
@@ -546,7 +583,9 @@
             'constructor': w_FncPrototype,
             '__proto__': w_ArrPrototype,
             'toString': W_ArrayToString(ctx),
-            'join': W_ArrayJoin(ctx)
+            'join': W_ArrayJoin(ctx),
+            'reverse': W_ArrayReverse(ctx),
+            'sort': w_FncPrototype, #dummy
         })
         
         w_Array.Put(ctx, 'prototype', w_ArrPrototype, flags = allon)
@@ -574,9 +613,9 @@
         w_Date = W_DateFake(ctx, Class='Date')
         w_Global.Put(ctx, 'Date', w_Date)
         
-        w_Global.Put(ctx, 'NaN', W_FloatNumber(NAN))
-        w_Global.Put(ctx, 'Infinity', W_FloatNumber(INFINITY))
-        w_Global.Put(ctx, 'undefined', w_Undefined)
+        w_Global.Put(ctx, 'NaN', W_FloatNumber(NAN), flags = DE|DD)
+        w_Global.Put(ctx, 'Infinity', W_FloatNumber(INFINITY), flags = DE|DD)
+        w_Global.Put(ctx, 'undefined', w_Undefined, flags = DE|DD)
         w_Global.Put(ctx, 'eval', W_Builtin(evaljs))
         w_Global.Put(ctx, 'parseInt', W_Builtin(parseIntjs))
         w_Global.Put(ctx, 'parseFloat', W_Builtin(parseFloatjs))
@@ -585,7 +624,6 @@
         w_Global.Put(ctx, 'print', W_Builtin(printjs))
         w_Global.Put(ctx, 'unescape', W_Builtin(unescapejs))
 
-        w_Global.Put(ctx, 'this', w_Global)
 
         # DEBUGGING
         if 0:

Modified: pypy/branch/js-refactoring/pypy/lang/js/js_interactive.py
==============================================================================
--- pypy/branch/js-refactoring/pypy/lang/js/js_interactive.py	(original)
+++ pypy/branch/js-refactoring/pypy/lang/js/js_interactive.py	Mon Jun  2 00:37:28 2008
@@ -33,7 +33,7 @@
 
 
 def loadjs(ctx, args, this):
-    filename = args[0].ToString()
+    filename = args[0].ToString(ctx)
     t = load_file(filename)
     return t.execute(ctx)
 
@@ -106,7 +106,7 @@
 
     def showtraceback(self, exc):
         # XXX format exceptions nicier
-        print exc.exception.ToString()
+        print exc.exception.ToString(None) #XXX should not be none
 
     def showsyntaxerror(self, filename, exc):
         # XXX format syntax errors nicier

Modified: pypy/branch/js-refactoring/pypy/lang/js/jscode.py
==============================================================================
--- pypy/branch/js-refactoring/pypy/lang/js/jscode.py	(original)
+++ pypy/branch/js-refactoring/pypy/lang/js/jscode.py	Mon Jun  2 00:37:28 2008
@@ -10,6 +10,7 @@
      compare_e, increment, commonnew, mult, division, uminus, mod
 from pypy.rlib.jit import hint
 from pypy.rlib.rarithmetic import intmask
+from pypy.rlib.objectmodel import we_are_translated
 
 class AlreadyRun(Exception):
     pass
@@ -25,13 +26,21 @@
     to_pop = 0
     try:
         while i < len(opcodes):
-            for name, op in opcode_unrolling:
+            if we_are_translated():
+                #this is an optimization strategy for translated code
+                #on top of cpython it destroys the performance
+                #besides, this code might be completely wrong
                 opcode = opcodes[i]
-                opcode = hint(opcode, deepfreeze=True)
-                if isinstance(opcode, op):
-                    result = opcode.eval(ctx, stack)
-                    assert result is None
-                    break
+                for name, op in opcode_unrolling:
+                    opcode = hint(opcode, deepfreeze=True)
+                    if isinstance(opcode, op):
+                        result = opcode.eval(ctx, stack)
+                        assert result is None
+                        break
+            else:
+                opcode = opcodes[i]
+                result = opcode.eval(ctx, stack)
+                assert result is None                
             if isinstance(opcode, BaseJump):
                 i = opcode.do_jump(stack, i)
             else:
@@ -110,7 +119,7 @@
 
     def emit_continue(self):
         if not self.startlooplabel:
-            raise ThrowError(W_String("Continue outside loop"))
+            raise ThrowException(W_String("Continue outside loop"))
         self.emit('JUMP', self.startlooplabel[-1])
 
     def emit(self, operation, *args):
@@ -174,6 +183,9 @@
             self.code.run(ctx)
         except ReturnException, e:
             return e.value
+        except:
+            print "unhandled exception in function:", self.name
+            raise
         return w_Undefined
 
 class Opcode(object):
@@ -275,7 +287,11 @@
         self.identifier = identifier
 
     def eval(self, ctx, stack):
-        stack.append(ctx.resolve_identifier(self.identifier))
+        try:
+            stack.append(ctx.resolve_identifier(ctx, self.identifier))
+        except:
+            print self.identifier
+            raise
 
     def __repr__(self):
         return 'LOAD_VARIABLE "%s"' % (self.identifier,)
@@ -371,7 +387,11 @@
 
     def eval(self, ctx, stack):
         w_obj = stack.pop().ToObject(ctx)
-        stack.append(w_obj.Get(ctx, self.name))
+        try:
+            stack.append(w_obj.Get(ctx, self.name))
+        except:
+            print w_obj, self.name
+            raise
         #stack.append(W_Reference(self.name, w_obj))
 
     def __repr__(self):
@@ -415,7 +435,7 @@
 
     def eval(self, ctx, stack):
         try:
-            var = ctx.resolve_identifier(self.name)
+            var = ctx.resolve_identifier(ctx, self.name)
             stack.append(W_String(var.type()))
         except ThrowException:
             stack.append(W_String('undefined'))
@@ -541,7 +561,7 @@
         left = stack.pop()
         elem = stack.pop()
         value = stack.pop()
-        name = elem.ToString()
+        name = elem.ToString(ctx)
         value = self.operation(ctx, left, name, value)
         left.ToObject(ctx).Put(ctx, name, value)
         stack.append(value)
@@ -588,7 +608,7 @@
 class BaseAssignOper(BaseStore):
     def process(self, ctx, name, stack):
         right = stack.pop()
-        left = ctx.resolve_identifier(name)
+        left = ctx.resolve_identifier(ctx, name)
         result = self.operation(ctx, left, right)
         stack.append(result)
         return result
@@ -596,7 +616,7 @@
 class BaseAssignBitOper(BaseStore):
     def process(self, ctx, name, stack):
         right = stack.pop().ToInt32(ctx)
-        left = ctx.resolve_identifier(name).ToInt32(ctx)
+        left = ctx.resolve_identifier(ctx, name).ToInt32(ctx)
         result = self.operation(ctx, left, right)
         stack.append(result)
         return result
@@ -627,14 +647,14 @@
 
 class STORE_POSTINCR(BaseStore):
     def process(self, ctx, name, stack):
-        value = ctx.resolve_identifier(name)
+        value = ctx.resolve_identifier(ctx, name)
         newval = increment(ctx, value)
         stack.append(value)
         return newval
 
 class STORE_POSTDECR(BaseStore):
     def process(self, ctx, name, stack):
-        value = ctx.resolve_identifier(name)
+        value = ctx.resolve_identifier(ctx, name)
         newval = increment(ctx, value, -1)
         stack.append(value)
         return newval
@@ -742,31 +762,31 @@
     def eval(self, ctx, stack):
         stack.pop()
 
+def common_call(ctx, r1, args, this, name):
+    if not isinstance(r1, W_PrimitiveObject):
+        raise ThrowException(W_String("%s is not a callable (%s)"%(r1.ToString(ctx), name)))
+    try:
+        res = r1.Call(ctx=ctx, args=args.tolist(), this=this)
+    except JsTypeError:
+        raise ThrowException(W_String("%s is not a function (%s)"%(r1.ToString(ctx), name)))
+    return res
+
 class CALL(Opcode):
     def eval(self, ctx, stack):
         r1 = stack.pop()
         args = stack.pop()
-        if not isinstance(r1, W_PrimitiveObject):
-            raise ThrowException(W_String("it is not a callable"))
-        try:
-            res = r1.Call(ctx=ctx, args=args.tolist(), this=None)
-        except JsTypeError:
-            raise ThrowException(W_String('it is not a function'))
-        stack.append(res)
+        name = r1.ToString(ctx)
+        #XXX hack, this should be comming from context
+        stack.append(common_call(ctx, r1, args, ctx.scope[-1], name))
 
 class CALL_METHOD(Opcode):
     def eval(self, ctx, stack):
         method = stack.pop()
         what = stack.pop().ToObject(ctx)
         args = stack.pop()
-        r1 = what.Get(ctx, method.ToString())
-        if not isinstance(r1, W_PrimitiveObject):
-            raise ThrowException(W_String("it is not a callable"))
-        try:
-            res = r1.Call(ctx=ctx, args=args.tolist(), this=what)
-        except JsTypeError:
-            raise ThrowException(W_String('it is not a function'))
-        stack.append(res)
+        name = method.ToString(ctx) #XXX missing ctx?
+        r1 = what.Get(ctx, name)
+        stack.append(common_call(ctx, r1, args, what, name))
         
 
 class DUP(Opcode):
@@ -856,11 +876,8 @@
 # ---------------- with support ---------------------
 
 class WITH_START(Opcode):
-    def __init__(self, name):
-        self.name = name
-
     def eval(self, ctx, stack):
-        ctx.push_object(ctx.resolve_identifier(self.name).ToObject(ctx))
+        ctx.push_object(stack.pop().ToObject(ctx))
 
 class WITH_END(Opcode):
     def eval(self, ctx, stack):
@@ -877,7 +894,7 @@
 
 class DELETE_MEMBER(Opcode):
     def eval(self, ctx, stack):
-        what = stack.pop().ToString()
+        what = stack.pop().ToString(ctx)
         obj = stack.pop().ToObject(ctx)
         stack.append(newbool(obj.Delete(what)))
 

Modified: pypy/branch/js-refactoring/pypy/lang/js/jsobj.py
==============================================================================
--- pypy/branch/js-refactoring/pypy/lang/js/jsobj.py	(original)
+++ pypy/branch/js-refactoring/pypy/lang/js/jsobj.py	Mon Jun  2 00:37:28 2008
@@ -256,8 +256,10 @@
         if Prototype is None:
             proto = ctx.get_global().Get(ctx, 'Function').Get(ctx, 'prototype')
             Prototype = proto
-
+        
         W_PrimitiveObject.__init__(self, ctx, Prototype, Class, Value, callfunc)
+        if hasattr(self, 'length'):
+            self.Put(ctx, 'length', W_IntNumber(self.length), flags = DD|RO)
 
     def Call(self, ctx, args=[], this = None):
         raise NotImplementedError
@@ -364,7 +366,7 @@
     def ToObject(self, ctx):
         return create_object(ctx, 'Boolean', Value=self)
 
-    def ToString(self, ctx=None):
+    def ToString(self, ctx):
         if self.boolval == True:
             return "true"
         return "false"
@@ -386,6 +388,7 @@
 class W_String(W_Primitive):
     def __init__(self, strval):
         super(W_String, self).__init__()
+        self.Class = 'string' #hack
         self.strval = strval
 
     def __repr__(self):
@@ -398,10 +401,13 @@
             proto = ctx.get_global().Get(ctx, 'String').Get(ctx, 'prototype')
             return proto.Get(ctx, P)
 
+    def Put(self, ctx, P, V, flags=0):
+        pass
+
     def ToObject(self, ctx):
         return self #create_object(ctx, 'String', Value=self)
 
-    def ToString(self, ctx=None):
+    def ToString(self, ctx):
         return self.strval
     
     def ToBoolean(self):
@@ -414,7 +420,7 @@
         return 'string'
 
     def GetPropertyName(self):
-        return self.ToString()
+        return self.strval
 
     def ToNumber(self, ctx):
         if not self.strval:
@@ -444,7 +450,7 @@
         super(W_IntNumber, self).__init__()
         self.intval = intmask(intval)
 
-    def ToString(self, ctx=None):
+    def ToString(self, ctx):
         # XXX incomplete, this doesn't follow the 9.8.1 recommendation
         return str(self.intval)
 
@@ -462,7 +468,7 @@
         return r_uint(self.intval)
 
     def GetPropertyName(self):
-        return self.ToString()
+        return str(self.intval)
 
     def __repr__(self):
         return 'W_IntNumber(%s)' % (self.intval,)
@@ -474,7 +480,7 @@
         super(W_FloatNumber, self).__init__()
         self.floatval = float(floatval)
     
-    def ToString(self, ctx = None):
+    def ToString(self, ctx):
         # XXX incomplete, this doesn't follow the 9.8.1 recommendation
         if isnan(self.floatval):
             return 'NaN'
@@ -517,7 +523,7 @@
     def __init__(self, list_w):
         self.list_w = list_w
 
-    def ToString(self, ctx = None):
+    def ToString(self, ctx):
         raise SeePage(42)
 
     def ToBoolean(self):
@@ -538,7 +544,7 @@
         assert scope is not None
         self.scope = scope
         if this is None:
-            self.this = scope[-1]
+            self.this = scope[0]
         else:
             self.this = this
         if variable is None:
@@ -557,7 +563,7 @@
         
     def assign(self, name, value):
         assert name is not None
-        for obj in self.scope:
+        for obj in reversed(self.scope):
             assert isinstance(obj, W_PrimitiveObject)
             try:
                 P = obj.propdict[name]
@@ -571,7 +577,7 @@
         self.variable.Put(self.get_global(), name, value)
 
     def delete_identifier(self, name):
-        for obj in self.scope:
+        for obj in reversed(self.scope):
             assert isinstance(obj, W_PrimitiveObject)
             try:
                 P = obj.propdict[name]
@@ -588,26 +594,25 @@
         self.variable.Put(ctx, name, value, flags = flags)
     
     def get_global(self):
-        return self.scope[-1]
+        return self.scope[0]
             
     def push_object(self, obj):
         """push object into scope stack"""
         assert isinstance(obj, W_PrimitiveObject)
-        # XXX O(n^2)
-        self.scope.insert(0, obj)
+        self.scope.append(obj)
         self.variable = obj
     
     def pop_object(self):
         """remove the last pushed object"""
-        return self.scope.pop(0)
+        return self.scope.pop()
         
-    def resolve_identifier(self, identifier):
-        for obj in self.scope:
+    def resolve_identifier(self, ctx, identifier):
+        if identifier == 'this':
+            return self.this
+        for obj in reversed(self.scope):
             assert isinstance(obj, W_PrimitiveObject)
-            try:
-                return obj.propdict[identifier].value
-            except KeyError:
-                pass
+            if obj.HasProperty(identifier):
+                return obj.Get(ctx, identifier)
         raise ThrowException(W_String("ReferenceError: %s is not defined" % identifier))
 
 def global_context(w_global):

Modified: pypy/branch/js-refactoring/pypy/lang/js/operations.py
==============================================================================
--- pypy/branch/js-refactoring/pypy/lang/js/operations.py	(original)
+++ pypy/branch/js-refactoring/pypy/lang/js/operations.py	Mon Jun  2 00:37:28 2008
@@ -712,14 +712,14 @@
         bytecode.emit('LOAD_UNDEFINED')
 
 class With(Statement):
-    def __init__(self, pos, identifier, body):
+    def __init__(self, pos, withpart, body):
         self.pos = pos
-        assert isinstance(identifier, VariableIdentifier)
-        self.identifier = identifier.identifier
+        self.withpart = withpart
         self.body = body
 
     def emit(self, bytecode):
-        bytecode.emit('WITH_START', self.identifier)
+        self.withpart.emit(bytecode)
+        bytecode.emit('WITH_START')
         self.body.emit(bytecode)
         bytecode.emit('WITH_END')
 
@@ -750,17 +750,15 @@
         bytecode.emit('JUMP', startlabel)
         bytecode.emit_endloop_label(endlabel)    
 
-class ForVarIn(Statement):
-    def __init__(self, pos, vardecl, lobject, body):
+class ForIn(Statement):
+    def __init__(self, pos, name, lobject, body):
         self.pos = pos
-        assert isinstance(vardecl, VariableDeclaration)
-        self.iteratorname = vardecl.identifier
+        #assert isinstance(iterator, Node)
+        self.iteratorname = name
         self.object = lobject
         self.body = body
 
-    
     def emit(self, bytecode):
-        bytecode.emit('DECLARE_VAR', self.iteratorname)
         self.object.emit(bytecode)
         bytecode.emit('LOAD_ITERATOR')
         precond = bytecode.emit_startloop_label()
@@ -770,27 +768,19 @@
         self.body.emit(bytecode)
         bytecode.emit('JUMP', precond)
         bytecode.emit_endloop_label(finish)
-        bytecode.emit('POP')    
+        bytecode.emit('POP')
 
-class ForIn(Statement):
-    def __init__(self, pos, name, lobject, body):
+class ForVarIn(ForIn):
+    def __init__(self, pos, vardecl, lobject, body):
         self.pos = pos
-        #assert isinstance(iterator, Node)
-        self.iteratorname = name
+        assert isinstance(vardecl, VariableDeclaration)
+        self.iteratorname = vardecl.identifier
         self.object = lobject
         self.body = body
 
     def emit(self, bytecode):
-        self.object.emit(bytecode)
-        bytecode.emit('LOAD_ITERATOR')
-        precond = bytecode.emit_startloop_label()
-        finish = bytecode.prealocate_endloop_label()
-        bytecode.emit('JUMP_IF_ITERATOR_EMPTY', finish)
-        bytecode.emit('NEXT_ITERATOR', self.iteratorname)
-        self.body.emit(bytecode)
-        bytecode.emit('JUMP', precond)
-        bytecode.emit_endloop_label(finish)
-        bytecode.emit('POP')
+        bytecode.emit('DECLARE_VAR', self.iteratorname)
+        ForIn.emit(self, bytecode)
 
 class For(Statement):
     def __init__(self, pos, setup, condition, update, body):
@@ -804,13 +794,17 @@
         self.setup.emit(bytecode)
         if isinstance(self.setup, Expression):
             bytecode.emit('POP')
+        
+        firstep = bytecode.prealocate_label()
+        bytecode.emit('JUMP', firstep)
         precond = bytecode.emit_startloop_label()
         finish = bytecode.prealocate_endloop_label()
+        self.update.emit(bytecode)
+        bytecode.emit('POP')
+        bytecode.emit_label(firstep)
         self.condition.emit(bytecode)
         bytecode.emit('JUMP_IF_FALSE', finish)
         self.body.emit(bytecode)
-        self.update.emit(bytecode)
-        bytecode.emit('POP')
         bytecode.emit('JUMP', precond)
         bytecode.emit_endloop_label(finish)
     

Modified: pypy/branch/js-refactoring/pypy/lang/js/test/ecma/conftest.py
==============================================================================
--- pypy/branch/js-refactoring/pypy/lang/js/test/ecma/conftest.py	(original)
+++ pypy/branch/js-refactoring/pypy/lang/js/test/ecma/conftest.py	Mon Jun  2 00:37:28 2008
@@ -44,8 +44,8 @@
         if not hasattr(cls, 'shellfile'):
             cls.shellfile = load_file(str(shellpath))
         cls.interp.run(cls.shellfile)
-        cls.testcases = cls.interp.global_context.resolve_identifier('testcases')
-        cls.tc = cls.interp.global_context.resolve_identifier('tc')
+        cls.testcases = cls.interp.global_context.resolve_identifier(cls.interp.global_context, 'testcases')
+        cls.tc = cls.interp.global_context.resolve_identifier(cls.interp.global_context, 'tc')
         # override eval
         cls.interp.w_Global.Put(cls.interp.global_context, 'eval', W_Builtin(overriden_evaljs))
         
@@ -71,10 +71,11 @@
         except JsBaseExcept:
             raise Failed(msg="Javascript Error", excinfo=py.code.ExceptionInfo())
         except:
+            #print self.interp._code
             raise Failed(excinfo=py.code.ExceptionInfo())
         ctx = self.interp.global_context
-        testcases = ctx.resolve_identifier('testcases')
-        self.tc = ctx.resolve_identifier('tc')
+        testcases = ctx.resolve_identifier(ctx, 'testcases')
+        self.tc = ctx.resolve_identifier(ctx, 'tc')
         testcount = testcases.Get(ctx, 'length').ToInt32(ctx)
         self.testcases = testcases
         return range(testcount)
@@ -89,9 +90,9 @@
         
     def run(self):
         ctx = JSTestFile.interp.global_context
-        r3 = ctx.resolve_identifier('run_test')
+        r3 = ctx.resolve_identifier(ctx, 'run_test')
         w_test_number = W_IntNumber(self.number)
-        result = r3.Call(ctx=ctx, args=[w_test_number]).ToString()
+        result = r3.Call(ctx=ctx, args=[w_test_number]).ToString(ctx)
         __tracebackhide__ = True
         if result != "passed":
             raise Failed(msg=result)

Modified: pypy/branch/js-refactoring/pypy/lang/js/test/ecma/shell.js
==============================================================================
--- pypy/branch/js-refactoring/pypy/lang/js/test/ecma/shell.js	(original)
+++ pypy/branch/js-refactoring/pypy/lang/js/test/ecma/shell.js	Mon Jun  2 00:37:28 2008
@@ -120,9 +120,9 @@
 
   // print out bugnumber
 
-  if ( BUGNUMBER ) {
-    print ("BUGNUMBER: " + BUGNUMBER );
-  }
+  // if ( BUGNUMBER ) {
+  //   print ("BUGNUMBER: " + BUGNUMBER );
+  // }
 }
 
 function test() {

Modified: pypy/branch/js-refactoring/pypy/lang/js/test/test_interp.py
==============================================================================
--- pypy/branch/js-refactoring/pypy/lang/js/test/test_interp.py	(original)
+++ pypy/branch/js-refactoring/pypy/lang/js/test/test_interp.py	Mon Jun  2 00:37:28 2008
@@ -341,6 +341,15 @@
     }
     print('out');""", "out")
 
+def test_continue():
+    assertp("""
+    for(x = 0; x < 3; x++) {
+        print(x);
+        continue;
+        print('error');
+    }
+    print('out');""", ["0","1","2","out"])
+
 def test_typeof():
     assertv("""
     var x = 3;
@@ -501,7 +510,7 @@
     yield assertv, "2 !== 2;", False
 
 def test_with():
-    assertp("""
+    yield assertp, """
     var mock = {x:2};
     var x=4;
     print(x);
@@ -516,7 +525,13 @@
         print(y);
     }
     print(x);
-    """, ['4', '2', '3', '4'])
+    """, ['4', '2', '3', '4']
+    
+    yield assertp, """
+    with(new Array(1,2,3)) {
+        print(join('.'))
+    }
+    """, "1.2.3"
 
 def test_bitops():
     yield assertv, "2 ^ 2;", 0



More information about the Pypy-commit mailing list