[pypy-commit] lang-js default: wip

stepahn noreply at buildbot.pypy.org
Fri Dec 28 11:33:22 CET 2012


Author: Stephan <stephan at stzal.com>
Branch: 
Changeset: r182:5781d99a3ec4
Date: 2012-05-09 17:37 +0200
http://bitbucket.org/pypy/lang-js/changeset/5781d99a3ec4/

Log:	wip

diff too long, truncating to 2000 out of 2273 lines

diff --git a/js/astbuilder.py b/js/astbuilder.py
--- a/js/astbuilder.py
+++ b/js/astbuilder.py
@@ -356,7 +356,7 @@
         if self.is_local_identifier(left):
             return operations.LocalAssignmentOperation(pos, left, None, atype, is_post)
         elif self.is_identifier(left):
-            return operations.AssignmentOperation(pos, left, None, atype, is_post)
+            return operations.AssignmentOperation(pos, left, left.name, left.index, None, atype, is_post)
         elif self.is_member(left):
             return operations.MemberAssignmentOperation(pos, left, None, atype, is_post)
         else:
diff --git a/js/builtins.py b/js/builtins.py
--- a/js/builtins.py
+++ b/js/builtins.py
@@ -267,14 +267,29 @@
     from js.jsobj import W__Function
 
     scope = None
-    jsfunc = JsNativeFunction(function, name)
-    return W__Function(jsfunc, scope)
+    jsfunc = JsNativeFunction(native_function(function), name)
+    return W__Function(jsfunc)
+
+def native_function(func):
+    from js.jsobj import _w
+    def f(*args):
+        return _w(func(*args))
+    return f
 
 def setup_builtins(global_object):
     def put_native_function(obj, name, func, writable = False, configurable = False, enumerable = False):
         jsfunc = new_native_function(func, name)
         put_property(obj, name, jsfunc, writable = writable, configurable = configurable, enumerable = enumerable)
 
+    def put_intimate_function(obj, name, func, writable = False, configurable = False, enumerable = False):
+        from js.functions import JsIntimateFunction
+        from js.jsobj import W__Function
+
+        scope = None
+        jsfunc = JsIntimateFunction(native_function(func), name)
+        w_func = W__Function(jsfunc)
+        put_property(obj, name, w_func, writable = writable, configurable = configurable, enumerable = enumerable)
+
     # 15
     def put_property(obj, name, value, writable = True, configurable = False, enumerable = True):
         from js.jsobj import put_property as _put_property
@@ -560,18 +575,19 @@
     put_property(global_object, 'Date', w_Date)
 
     # 15.1.1.1
-    put_property(global_object, 'NaN', w_NAN, enumerable = False, configurable = False)
+    put_property(global_object, 'NaN', w_NAN, writable = False, enumerable = False, configurable = False)
 
     # 15.1.1.2
-    put_property(global_object, 'Infinity', w_POSITIVE_INFINITY, enumerable = False, configurable = False)
+    put_property(global_object, 'Infinity', w_POSITIVE_INFINITY, writable = False, enumerable = False, configurable = False)
 
     # 15.1.1.3
-    put_property(global_object, 'undefined', w_Undefined, enumerable = False, configurable = False)
+    put_property(global_object, 'undefined', w_Undefined, writable = False, enumerable = False, configurable = False)
+
+    import js.builtins_global as global_builtins
 
     # 15.1.2.1
-    put_property(global_object, 'eval', W__Eval())
-
-    import js.builtins_global as global_builtins
+    #put_property(global_object, 'eval', W__Eval())
+    put_intimate_function(global_object, 'eval', global_builtins.js_eval)
 
     # 15.1.2.2
     put_native_function(global_object, 'parseInt', global_builtins.parse_int)
diff --git a/js/builtins_array.py b/js/builtins_array.py
--- a/js/builtins_array.py
+++ b/js/builtins_array.py
@@ -18,8 +18,8 @@
 # 15.4.4.2
 def to_string(this, args):
     array = this.ToObject()
-    func = array.Get('join')
-    if func.IsCallable():
+    func = array.get('join')
+    if func.is_callable():
         return func.Call(this = this).to_string()
     else:
         return this.to_string()
@@ -27,7 +27,7 @@
 # 15.4.4.5
 def join(this, args):
     o = this.ToObject()
-    lenVal = o.Get('length')
+    lenVal = o.get('length')
     length = lenVal.ToUInt32()
 
     sep = ','
@@ -37,7 +37,7 @@
     if length == 0:
         return ''
 
-    element0 = o.Get('0')
+    element0 = o.get('0')
     if isnull_or_undefined(element0):
         return ''
 
@@ -47,7 +47,7 @@
 
     while(k < length):
         s = r + sep
-        element = o.Get(str(k))
+        element = o.get(str(k))
         if isnull_or_undefined(element):
             n = ''
         else:
diff --git a/js/builtins_global.py b/js/builtins_global.py
--- a/js/builtins_global.py
+++ b/js/builtins_global.py
@@ -94,3 +94,22 @@
 
 def version(this, args):
     return '1.0'
+
+def js_eval(ctx):
+    from js.astbuilder import parse_to_ast
+    from js.jscode import ast_to_bytecode
+    from js.jsobj import _w
+    from js.functions import JsEvalCode
+    from js.execution_context import EvalExecutionContext
+
+    args = ctx.argv()
+    src = args[0].to_string()
+    ast = parse_to_ast(src)
+    symbol_map = ast.symbol_map
+    code = ast_to_bytecode(ast, symbol_map)
+
+    f = JsEvalCode(code)
+    calling_context = ctx._calling_context_
+    ctx = EvalExecutionContext(f, calling_context = calling_context)
+    res = f.run(ctx)
+    return _w(res)
diff --git a/js/environment_record.py b/js/environment_record.py
--- a/js/environment_record.py
+++ b/js/environment_record.py
@@ -63,7 +63,13 @@
 
     # 10.2.1.1.5
     def delete_binding(self, identifier):
-        raise NotImplementedError(self.__class__)
+        if not self.has_binding(identifier):
+            return True
+        if self.mutable_bindings[identifier] is False:
+            return False
+        del(self.mutable_bindings[identifier])
+        del(self.bindings[identifier])
+        return False
 
     # 10.2.1.1.6
     def implicit_this_value(self):
diff --git a/js/execution.py b/js/execution.py
--- a/js/execution.py
+++ b/js/execution.py
@@ -1,4 +1,3 @@
-
 class JsBaseExcept(Exception):
     pass
 
@@ -24,6 +23,9 @@
         self.exception = exception
         self.args = [exception]
 
+class JsThrowException(ThrowException):
+    pass
+
 class JsTypeError(JsBaseExcept):
     pass
 
@@ -32,3 +34,6 @@
 
 class JsRangeError(JsBaseExcept):
     pass
+
+class JsSyntaxError(JsBaseExcept):
+    pass
diff --git a/js/execution_context.py b/js/execution_context.py
--- a/js/execution_context.py
+++ b/js/execution_context.py
@@ -1,10 +1,15 @@
 from js.jsobj import w_Undefined
 
-_global_object_ = None
 
 def get_global_object():
     return GlobalExecutionContext.global_object
 
+def get_global_context():
+    return GlobalExecutionContext.global_context
+
+def get_global_environment():
+    return get_global_context().variable_environment()
+
 class ExecutionContext(object):
     def __init__(self):
         self._stack_ = []
@@ -12,59 +17,6 @@
         self._variable_environment_ = None
         self._this_binding_ = None
 
-    def declaration_binding_initialization(self, env, code, arguments = []):
-        strict = False
-        configurable_bindings = code.configurable_bindings
-
-        n = 0
-        arg_count = len(arguments)
-
-        names = code.params()
-        for arg_name in names:
-            n += 1
-            if n > arg_count:
-                v = w_Undefined
-            else:
-                v = arguments[n-1]
-            arg_already_declared = env.has_binding(arg_name)
-            if arg_already_declared is False:
-                env.create_mutuable_binding(arg_name, configurable_bindings)
-            env.set_mutable_binding(arg_name, v)
-
-        # 5.
-        func_declarations = code.functions()
-        for fn in func_declarations:
-            fo = None
-            func_already_declared = env.has_binding(fn)
-            if func_already_declared is False:
-                env.create_mutuable_binding(fn, configurable_bindings)
-            else:
-                pass #see 10.5 5.e
-            env.set_mutable_binding(fn, fo)
-
-        arguments_already_declared = env.has_binding('arguments')
-        # 7.
-        from js.functions import JsFunction
-        if isinstance(code, JsFunction) and arguments_already_declared is False:
-            from js.jsobj import W_Arguments
-            # TODO get calling W_Function
-            func = None
-            args_obj = W_Arguments(func, names, arguments, env, strict)
-            if strict is True:
-                env.create_immutable_bining('arguments')
-                env.initialize_immutable_binding('arguments', args_obj)
-            else:
-                env.create_mutuable_binding('arguments', False) # TODO not sure if mutable binding is deletable
-                env.set_mutable_binding('arguments', args_obj, False)
-
-        # 8.
-        var_declarations = code.variables()
-        for dn in var_declarations:
-            var_already_declared = env.has_binding(dn)
-            if var_already_declared == False:
-                env.create_mutuable_binding(dn, configurable_bindings)
-                env.set_mutable_binding(dn, w_Undefined)
-
     def stack_append(self, value):
         self._stack_.append(value)
 
@@ -84,15 +36,6 @@
         self._stack_  = s
         return r
 
-    def run(self):
-        raise NotImplementedError(self.__class__)
-
-    def get_value(self, index):
-        raise NotImplementedError(self.__class__)
-
-    def set_value(self, index, value):
-        raise NotImplementedError(self.__class__)
-
     def this_binding(self):
         return self._this_binding_
 
@@ -102,99 +45,143 @@
     def lexical_environment(self):
         return self._lexical_environment_
 
+    def declaration_binding_initialization(self):
+        env = self._variable_environment_.environment_record
+        strict = self._strict_
+        code = self._code_
+
+        if code.is_eval_code():
+            configurable_bindings = True
+        else:
+            configurable_bindings = False
+
+        # 4.
+        if code.is_function_code():
+            names = self._formal_parameters_
+            n = 0
+            args = self._argument_values_
+
+            arg_count = len(args)
+            for arg_name in names:
+                n += 1
+                if n > arg_count:
+                    v = w_Undefined
+                else:
+                    v = args[n-1]
+                arg_already_declared = env.has_binding(arg_name)
+                if arg_already_declared is False:
+                    env.create_mutuable_binding(arg_name, configurable_bindings)
+                env.set_mutable_binding(arg_name, v)
+
+        # 5.
+        func_declarations = code.functions()
+        for fn in func_declarations:
+            fo = None
+            func_already_declared = env.has_binding(fn)
+            if func_already_declared is False:
+                env.create_mutuable_binding(fn, configurable_bindings)
+            else:
+                pass #see 10.5 5.e
+            env.set_mutable_binding(fn, fo)
+
+        arguments_already_declared = env.has_binding('arguments')
+        # 7.
+        if code.is_function_code() and arguments_already_declared is False:
+            from js.jsobj import W_Arguments
+            # TODO get calling W_Function
+            func = None
+            arguments = self._argument_values_
+            names = self._formal_parameters_
+            args_obj = W_Arguments(func, names, arguments, env, strict)
+            if strict is True:
+                env.create_immutable_bining('arguments')
+                env.initialize_immutable_binding('arguments', args_obj)
+            else:
+                env.create_mutuable_binding('arguments', False) # TODO not sure if mutable binding is deletable
+                env.set_mutable_binding('arguments', args_obj, False)
+
+        # 8.
+        var_declarations = code.variables()
+        for dn in var_declarations:
+            var_already_declared = env.has_binding(dn)
+            if var_already_declared == False:
+                env.create_mutuable_binding(dn, configurable_bindings)
+                env.set_mutable_binding(dn, w_Undefined)
+
+    def get_ref(self, symbol):
+        ## TODO pre-bind symbols, work with idndex, does not work, see test_foo18
+        lex_env = self.lexical_environment()
+        ref = lex_env.get_identifier_reference(symbol)
+        return ref
+
 class GlobalExecutionContext(ExecutionContext):
     global_object = None
-    def __init__(self, code, global_object):
+    global_context = None
+    def __init__(self, code, global_object, strict = False):
         ExecutionContext.__init__(self)
-        self.code = code
+        self._code_ = code
+        self._strict_ = strict
 
         from js.lexical_environment import ObjectEnvironment
         localEnv = ObjectEnvironment(global_object)
         self._lexical_environment_ = localEnv
         self._variable_environment_ = localEnv
         GlobalExecutionContext.global_object = global_object
+        GlobalExecutionContext.global_context = self
         self._this_binding_ = global_object
 
-        self.declaration_binding_initialization(self._variable_environment_.environment_record, self.code)
-
-    def run(self):
-        return self.code.run(self)
-
-    def _symbol_for_index(self, index):
-        sym = self.code.symbol_for_index(index)
-        assert sym is not None
-        return sym
-
-    def get_ref(self, index):
-        symbol = self._symbol_for_index(index)
-        lex_env = self.lexical_environment()
-        ref = lex_env.get_identifier_reference(symbol)
-        return ref
-
-    #def get_value(self, index):
-        #env = self.variable_environment()
-        #env_record = env.environment_record
-        #identifier = self._symbol_for_index(index)
-        #value = env_record.get_binding_value(identifier)
-        #return value
-
-    #def set_value(self, index, value):
-        #env = self.variable_environment()
-        #env_record = env.environment_record
-        #identifier = self._symbol_for_index(index)
-        #env_record.set_mutable_binding(identifier, value)
+        self.declaration_binding_initialization()
 
 class EvalExecutionContext(ExecutionContext):
-    pass
+    def __init__(self, code, calling_context = None):
+        ExecutionContext.__init__(self)
+        self._code_ = code
+        self._strict_ = code.strict
 
+        if not calling_context:
+            raise NotImplementedError()
+        else:
+            self._this_binding_ = calling_context.this_binding()
+            self._variable_environment_ = calling_context.variable_environment()
+            self._lexical_environment_ = calling_context.lexical_environment()
+        if self._strict_:
+            strict_var_env = DeclarativeEnvironment(self._lexical_environment_)
+            self._variable_environment_ = strict_var_env
+            self._lexical_environment_ = strict_var_env
+
+
+        self.declaration_binding_initialization()
+
+from js.jsobj import w_Undefined
 class FunctionExecutionContext(ExecutionContext):
-    def __init__(self, formal_parameters = [], args = [], this = None):
+    def __init__(self, code, formal_parameters = [], argv = [], this = w_Undefined, strict = False, scope = None, w_func = None):
         ExecutionContext.__init__(self)
+        self._code_ = code
         self._formal_parameters_ = formal_parameters
-        self._args_ = args
+        self._argument_values_ = argv
         self._this_ = this
+        self._strict_ = strict
+        self._scope_ = scope
+        self._w_func_ = w_func
+        self._calling_context_ = None
 
-        #self.function = function
-        #self.arguments = argument_values
+        from js.lexical_environment import DeclarativeEnvironment
+        localEnv = DeclarativeEnvironment(scope)
+        self._lexical_environment_ = localEnv
+        self._variable_environment_ = localEnv
 
-        #from js.lexical_environment import DeclarativeEnvironment
-        #localEnv = DeclarativeEnvironment(scope)
-        #self._lexical_environment_ = localEnv
-        #self._variable_environment_ = localEnv
+        from js.jsobj import isnull_or_undefined
 
-        #from js.jsobj import isnull_or_undefined
-        #strict = False
+        if strict:
+            self._this_binding_ = this
+        elif isnull_or_undefined(this):
+            self._this_binding_ = get_global_object()
+        elif this.klass() is not 'Object':
+            self._this_binding_ = this.ToObject()
+        else:
+            self._this_binding_ = this
 
-        #if strict:
-            #self._this_binding_ = this
-        #elif isnull_or_undefined(this):
-            #self._this_binding_ = get_global_object()
-        #elif this.klass() is not 'Object':
-            #self._this_binding_ = this.ToObject()
-        #else:
-            #self._this_binding_ = this
+        self.declaration_binding_initialization()
 
-        #self.symbol_slots = {}
-        #self.declaration_binding_initialization(self._variable_environment_.environment_record, self.function, self.arguments)
-
-    def run(self):
-        pass
-        #self._bind_symbols()
-        #return self.function.run(self)
-
-    #def _bind_symbols(self):
-        #lex_env = self.variable_environment()
-        #for symbol in self.function.symbols():
-            #idx = self._index_for_symbol(symbol)
-            #ref = lex_env.get_identifier_reference(symbol)
-            #self.symbol_slots[idx] = ref
-
-    #def _index_for_symbol(self, symbol):
-        #return self.function.index_for_symbol(symbol)
-
-    #def get_ref(self, index):
-        ## TODO pre-bind symbols does not work, see test_foo18
-        #symbol = self.function.symbol_for_index(index)
-        #lex_env = self.lexical_environment()
-        #ref = lex_env.get_identifier_reference(symbol)
-        #return ref
+    def argv(self):
+        return self._argument_values_
diff --git a/js/interpreter.py b/js/interpreter.py
--- a/js/interpreter.py
+++ b/js/interpreter.py
@@ -41,7 +41,7 @@
         from js.execution_context import GlobalExecutionContext
         ctx = GlobalExecutionContext(c, self.global_object)
 
-        return ctx.run()
+        return c.run(ctx)
 
         #"""run the interpreter"""
         #bytecode = JsCode()
diff --git a/js/jscode.py b/js/jscode.py
--- a/js/jscode.py
+++ b/js/jscode.py
@@ -18,7 +18,8 @@
 
 def ast_to_bytecode(ast, symbol_map):
     bytecode = JsCode(symbol_map)
-    ast.emit(bytecode)
+    if ast is not None:
+        ast.emit(bytecode)
     return bytecode
 
 class AlreadyRun(Exception):
@@ -155,17 +156,19 @@
     def unpop_or_undefined(self):
         if not self.unpop():
             self.emit('LOAD_UNDEFINED')
-        elif not self.returns():
-            self.emit('LOAD_UNDEFINED')
+        #elif not self.returns():
+            #self.emit('LOAD_UNDEFINED')
 
     def to_function_opcodes(self):
+        self.unlabel()
         self.unpop_or_undefined()
-        self.unlabel()
         return self.opcodes
 
     def to_global_opcodes(self):
-        self.unpop()
+        #import pdb; pdb.set_trace()
         self.unlabel()
+        self.unpop_or_undefined()
+        #self.unpop()
         return self.opcodes
 
     def remove_labels(self):
diff --git a/js/jsobj.py b/js/jsobj.py
--- a/js/jsobj.py
+++ b/js/jsobj.py
@@ -27,28 +27,27 @@
     def to_string(self):
         return ''
 
-    #def type(self):
-        #return self._type_
+    def type(self):
+        return self._type_
 
-    #def ToBoolean(self):
-        #return False
+    def ToBoolean(self):
+        return False
 
-    #def ToPrimitive(self, hint = None):
-        #return self
+    def ToPrimitive(self, hint = None):
+        return self
 
-    #def ToObject(self):
-        #raise JsTypeError
+    def ToObject(self):
+        raise JsTypeError()
 
-    #def ToNumber(self):
-        #return 0.0
+    def ToNumber(self):
+        return 0.0
 
-    #def ToInteger(self):
-        #return int(self.ToNumber())
+    def ToInteger(self):
+        return int(self.ToNumber())
 
     def is_callable(self):
         return False
 
-
 class W_Primitive(W_Root):
     pass
 
@@ -340,7 +339,7 @@
         if proto is w_Null or proto is w_Undefined:
             return self.extensible()
 
-        inherited = proto.GetProperty(p)
+        inherited = proto.get_property(p)
         if inherited is w_Undefined:
             return self.extensible()
 
@@ -566,7 +565,7 @@
     def is_callable(self):
         return True
 
-    def Call(self, args=[], this=None):
+    def Call(self, args = [], this = None, calling_context = None):
         return self.Construct(args)
 
     def Construct(self, args=[]):
@@ -584,13 +583,13 @@
     def __init__(self):
         W_BasicObject.__init__(self)
 
-    def Call(self, args=[], this=None):
+    def Call(self, args = [], this = None, calling_context = None):
         raise NotImplementedError(self.__class__)
 
     # 13.2.2
     def Construct(self, args=[]):
         obj = W__Object()
-        proto = self.Get('prototype')
+        proto = self.get('prototype')
         if isinstance(proto, W_BasicObject):
             obj._prototype_ = proto
         else:
@@ -614,30 +613,41 @@
     def to_string(self):
         return "function Function() { [native code] }"
 
-    def Call(self, args=[], this=None):
-        from js.jsparser import parse
-        from js.jscode import JsCode
-        from js.astbuilder import make_ast_builder
+    def Call(self, args = [], this = None, calling_context = None):
+        arg_count = len(args)
+        p = ''
+        if arg_count == 0:
+            body = ''
+        elif arg_count == 1:
+            body = args[0]
+        else:
+            first_arg = args[0]
+            p = first_arg.to_string()
+            k = 2
+            while k < arg_count:
+                next_arg = args[k-1]
+                p = "%s, %s" % (p, next_arg.to_string())
+                k = k + 1
+            body = args[k-1]
 
-        # 15.3.2.1
-        functioncode = "function () { }"
-        tam = len(args)
-        if tam >= 1:
-            fbody  = args[tam-1].to_string()
-            argslist = []
-            for i in range(tam-1):
-                argslist.append(args[i].to_string())
-            fargs = ','.join(argslist)
-            functioncode = "return function (%s) {%s}"%(fargs, fbody)
-        #remove program and sourcelements node
-        funcnode = parse(functioncode).children[0].children[0]
-        builder = make_ast_builder()
-        ast = builder.dispatch(funcnode)
-        bytecode = JsCode()
-        ast.emit(bytecode)
-        func = bytecode.make_js_function()
-        func2 = func.run(self._context_)
-        return func2
+        body = body.to_string()
+        src = "function (%s) { %s }" % (p, body)
+
+        from js.astbuilder import parse_to_ast
+        from js.jscode import ast_to_bytecode
+
+        ast = parse_to_ast(src)
+        symbol_map = ast.symbol_map
+        code = ast_to_bytecode(ast, symbol_map)
+        # TODO hackish
+        func = code.opcodes[0].funcobj
+
+        from js.execution_context import get_global_environment
+        scope = get_global_environment()
+        strict = func.strict
+        params = func.params()
+        w_func = W__Function(func, formal_parameter_list = params, scope = scope, strict = strict)
+        return w_func
 
     # TODO
     def Construct(self, args=[]):
@@ -646,7 +656,7 @@
 # 15.7.2
 class W_NumberConstructor(W_BasicFunction):
     # 15.7.1.1
-    def Call(self, args=[], this=None):
+    def Call(self, args = [], this = None, calling_context = None):
         if len(args) >= 1 and not isnull_or_undefined(args[0]):
             return _w(args[0].ToNumber())
         elif len(args) >= 1 and args[0] is w_Undefined:
@@ -660,7 +670,7 @@
 
 # 15.5.2
 class W_StringConstructor(W_BasicFunction):
-    def Call(self, args=[], this=None):
+    def Call(self, args = [], this = None, calling_context = None):
         if len(args) >= 1:
             return W_String(args[0].to_string())
         else:
@@ -671,7 +681,7 @@
 
 # 15.6.2
 class W_BooleanConstructor(W_BasicFunction):
-    def Call(self, args=[], this=None):
+    def Call(self, args = [], this = None, calling_context = None):
         if len(args) >= 1 and not isnull_or_undefined(args[0]):
             return _w(args[0].ToBoolean())
         else:
@@ -694,7 +704,7 @@
 class W__Function(W_BasicFunction):
     #_immutable_fields_ = ['_function_']
 
-    def __init__(self, function_body, formal_parameter_list = [], scope = None, strict = False):
+    def __init__(self, function_body, formal_parameter_list=[], scope=None, strict=False):
         W_BasicFunction.__init__(self)
         self._function_ = function_body
         self._scope_ = scope
@@ -704,15 +714,27 @@
     def code(self):
         return self._function_
 
-    def Call(self, args=[], this=None):
-        pass
-        #f = self._function_
-        #scope = self._scope_
+    def formal_parameters(self):
+        return self._params_
 
-        #from js.execution_context import FunctionExecutionContext
-        #ctx = FunctionExecutionContext(f, this, args, scope)
-        #result = ctx.run()
-        #return result
+    def Call(self, args = [], this = None, calling_context = None):
+        from js.execution_context import FunctionExecutionContext
+        code = self.code()
+        argn = self.formal_parameters()
+        strict = self._strict_
+        scope = self.scope()
+
+        ctx = FunctionExecutionContext(code,\
+            formal_parameters = argn,\
+            argv = args,\
+            this = this,\
+            strict = strict,\
+            scope = scope,\
+            w_func = self)
+        ctx._calling_context_ = calling_context
+
+        res = code.run(ctx)
+        return res
 
     # 15.3.5.4
     def get(self, p):
@@ -725,11 +747,15 @@
         return self._function_.to_string()
 
     def scope(self):
-        return self._context_
+        return self._scope_
 
     def is_strict(self):
         return self._strict_
 
+class W_Eval(W_BasicFunction):
+    def Call(self, args = [], this = None, calling_context = None):
+        raise NotImplementedError()
+
 # 10.6
 class W_Arguments(W_BasicObject):
     _class_ = 'Arguments'
@@ -803,7 +829,7 @@
     def is_callable(self):
         return True
 
-    def Call(self, args=[], this=None):
+    def Call(self, args = [], this = None, calling_context = None):
         if len(args) == 1 and isinstance(args[0], W_Number):
             array = W__Array()
         else:
@@ -849,21 +875,28 @@
 
             new_len_desc.value = _w(new_len)
 
+            # f
             if new_len >= old_len:
                 return W_BasicObject.define_own_property(self, 'length', new_len_desc, throw)
+            # g
             if old_len_desc.writable is False:
                 return reject()
 
+            # h
             if new_len_desc.writable is None or new_len_desc.writable is true:
                 new_writable = True
+            # i
             else:
                 new_len_desc.writable = True
                 new_writable = False
 
+            # j
             succeeded = W_BasicObject.define_own_property(self, 'length', new_len_desc, throw)
+            # k
             if succeeded is False:
                 return False
 
+            # l
             while new_len < old_len:
                 old_len = old_len - 1
                 delete_succeeded = self.delete(str(old_len), False)
@@ -874,6 +907,7 @@
                     W_BasicObject.define_own_property(self, 'length', new_len_desc, False)
                     return reject()
 
+            # m
             if new_writable is False:
                 desc = PropertyDescriptor(writable = False)
                 res = W_BasicObject.define_own_property(self, 'length', desc, False)
@@ -883,21 +917,27 @@
 
         # 4
         elif is_array_index(p):
+            # a
             index = p.ToUInt32()
+            # b
             if index >= old_len and old_len_desc.writable is False:
                 return reject()
 
-            succeeded = W_BasicObject.define_own_property(self, 'length', desc, False)
+            # c
+            succeeded = W_BasicObject.define_own_property(self, p, desc, False)
+            # d
             if succeeded is False:
                 return reject()
 
+            # e
             if index >= old_len:
                 old_len_desc.value = _w(index + 1)
                 res = W_BasicObject.define_own_property(self, 'length', old_len_desc, False)
                 assert res is True
+            # f
             return True
         # 5
-        return W_BasicObject.define_own_property(self, 'length', desc, throw)
+        return W_BasicObject.define_own_property(self, p, desc, throw)
 
 def is_array_index(p):
     return (isinstance(p, W_Number) or isinstance(p, W_NumericObject)) and str(p.ToUInt32()) == p
@@ -983,7 +1023,7 @@
 
     def __eq__(self, other):
         other_string = other.to_string()
-        return self._strval_ == other_string
+        return self.to_string() == other_string
 
     def __repr__(self):
         return 'W_String(%s)' % (repr(self._strval_),)
@@ -1036,6 +1076,12 @@
     def ToUInt32(self):
         return r_uint32(self.ToInteger())
 
+    def __eq__(self, other):
+        if isinstance(other, W_Number):
+            return self.ToNumber() == other.ToNumber()
+        else:
+            return False
+
 class W_IntNumber(W_Number):
     _immutable_fields_ = ['_intval_']
     """ Number known to be an integer
@@ -1058,9 +1104,6 @@
         # XXX incomplete, this doesn't follow the 9.8.1 recommendation
         return str(self.ToInteger())
 
-    def __eq__(self, other):
-        return self._intval_ == other._intval_
-
 def r_int32(n):
     return intmask(rffi.cast(rffi.INT, n))
 
@@ -1112,8 +1155,6 @@
 
         return intmask(int(self._floatval_))
 
-    def __eq__(self, other):
-        return self._floatval_ == other._floatval_
 
 def isnull_or_undefined(obj):
     if obj is w_Null or obj is w_Undefined:
@@ -1156,7 +1197,7 @@
     def __init__(self, values):
         self.values = values
 
-    def ToList(self):
+    def to_list(self):
         return self.values
 
 from pypy.rlib.objectmodel import specialize
diff --git a/js/opcodes.py b/js/opcodes.py
--- a/js/opcodes.py
+++ b/js/opcodes.py
@@ -1,6 +1,6 @@
 from js.jsobj import W_IntNumber, W_FloatNumber, W_String,\
      w_Undefined, newbool, W__Object, \
-     w_True, w_False, w_Null, W_Root, W__Function
+     w_True, w_False, w_Null, W_Root, W__Function, _w
 from js.execution import JsTypeError, ReturnException, ThrowException
 from js.baseop import plus, sub, compare, AbstractEC, StrictEC,\
      compare_e, increment, decrement, commonnew, mult, division, uminus, mod
@@ -111,11 +111,12 @@
     def __init__(self, index, identifier):
         assert index is not None
         self.index = index
+        self.identifier = identifier
 
     # 11.1.2
     def eval(self, ctx):
         # TODO put ref onto stack
-        ref = ctx.get_ref(self.index)
+        ref = ctx.get_ref(self.identifier)
         value = ref.get_value()
         ctx.stack_append(value)
 
@@ -166,8 +167,15 @@
         #proto = ctx.get_global().Get('Function').Get('prototype')
         #from js.builtins import get_builtin_prototype
         #proto = get_builtin_prototype('Function')
+
+        # 13.2 Creating Function Objects
+
+        func = self.funcobj
         scope = ctx.lexical_environment()
-        w_func = W__Function(self.funcobj, scope)
+        params = func.params()
+        strict = func.strict
+        w_func = W__Function(func, formal_parameter_list = params, scope = scope, strict = strict)
+
         #w_func = W_CallableObject(ctx, proto, self.funcobj)
         #w_func.Put('length', W_IntNumber(len(self.funcobj.params)))
         #w_obj = create_object('Object')
@@ -220,7 +228,8 @@
         if not isinstance(right, W_BasicObject):
             raise ThrowException(W_String("TypeError: "+ repr(right)))
         name = left.to_string()
-        return newbool(right.HasProperty(name))
+        has_name = right.has_property(name)
+        return newbool(has_name)
 
 class TYPEOF(BaseUnaryOperation):
     def eval(self, ctx):
@@ -228,13 +237,16 @@
         ctx.stack_append(W_String(one.type()))
 
 class TYPEOF_VARIABLE(Opcode):
-    def __init__(self, name):
+    def __init__(self, index, name):
+        self.index = index
         self.name = name
 
     def eval(self, ctx):
         try:
-            var = ctx.resolve_identifier(self.name)
-            ctx.stack_append(W_String(var.type()))
+            ref = ctx.get_ref(self.name)
+            var = ref.get_value()
+            var_type = var.type()
+            ctx.stack_append(W_String(var_type))
         except ThrowException:
             ctx.stack_append(W_String('undefined'))
 
@@ -365,19 +377,20 @@
         member = ctx.stack_pop()
         value = ctx.stack_pop()
         name = member.to_string()
-        left.ToObject().Put(name, value)
+        left.ToObject().put(name, value)
         ctx.stack_append(value)
 
 class STORE(Opcode):
     #_immutable_fields_ = ['name']
     _stack_change = 0
-    def __init__(self, index):
+    def __init__(self, index, identifier):
         assert index is not None
         self.index = index
+        self.identifier = identifier
 
     def eval(self, ctx):
         value = ctx.stack_top()
-        ref = ctx.get_ref(self.index)
+        ref = ctx.get_ref(self.identifier)
         ref.put_value(value)
 
 
@@ -518,7 +531,7 @@
         raise ThrowException(W_String("%s is not a callable (%s)"%(r1.to_string(), name.to_string())))
     #jit.promote(r1)
     #try:
-    res = r1.Call(args.ToList(), this)
+    res = r1.Call(args = args.to_list(), this = this, calling_context = ctx)
     #except JsTypeError:
         #raise ThrowException(W_String("%s is not a function (%s)"%(r1.to_string(), name.to_string())))
     return res
@@ -538,7 +551,7 @@
         what = ctx.stack_pop().ToObject()
         args = ctx.stack_pop()
         name = method.to_string()
-        r1 = what.Get(name)
+        r1 = what.get(name)
         ctx.stack_append(common_call(ctx, r1, args, what, method))
 
 class DUP(Opcode):
@@ -549,7 +562,8 @@
     _stack_change = 0
     def eval(self, ctx):
         val = ctx.stack_pop()
-        raise ThrowException(val)
+        from js.execution import JsThrowException
+        raise JsThrowException(val)
 
 class TRYCATCHBLOCK(Opcode):
     _stack_change = 0
@@ -587,8 +601,9 @@
     def eval(self, ctx):
         y = ctx.stack_pop()
         x = ctx.stack_pop()
+        from js.jsobj import W_List
         assert isinstance(y, W_List)
-        args = y.get_args()
+        args = y.to_list()
         ctx.stack_append(commonnew(ctx, x, args))
 
 class NEW_NO_ARGS(Opcode):
@@ -658,14 +673,32 @@
         self.name = name
 
     def eval(self, ctx):
-        ctx.stack_append(newbool(ctx.delete_identifier(self.name)))
+        # 11.4.1
+        ref = ctx.get_ref(self.name)
+        from js.lexical_environment import Reference
+        if not isinstance(ref, Reference):
+            res = True
+        if ref.is_unresolvable_reference():
+            if ref.is_strict_reference():
+                raise JsSyntaxError()
+            res = True
+        if ref.is_property_reference():
+            obj = ref.get_base().ToObject()
+            res = obj.delete(ref.get_referenced_name(), ref.is_strict_reference())
+        else:
+            if ref.is_strict_reference():
+                raise JsSyntaxError()
+            bindings = ref.get_base()
+            res = bindings.delete_binding(ref.get_referenced_name())
+        ctx.stack_append(_w(res))
 
 class DELETE_MEMBER(Opcode):
     _stack_change = 0
     def eval(self, ctx):
         what = ctx.stack_pop().to_string()
         obj = ctx.stack_pop().ToObject()
-        ctx.stack_append(newbool(obj.Delete(what)))
+        res = obj.delete(what, False)
+        ctx.stack_append(_w(res))
 
 class LOAD_LOCAL(Opcode):
     _immutable_fields_ = ['local']
diff --git a/js/operations.py b/js/operations.py
--- a/js/operations.py
+++ b/js/operations.py
@@ -185,7 +185,7 @@
         self.post = post
 
     def emit_store(self, bytecode):
-        bytecode.emit('STORE', self.index)
+        bytecode.emit('STORE', self.index, self.identifier)
 
 class LocalAssignmentOperation(AssignmentOperation):
     def __init__(self, pos, left, right, operand, post = False):
@@ -332,7 +332,7 @@
         #bytecode.emit('DECLARE_FUNCTION', jsfunc)
         bytecode.emit('LOAD_FUNCTION', jsfunc)
         if index is not None:
-            bytecode.emit('STORE', index)
+            bytecode.emit('STORE', index, name)
             bytecode.emit('POP')
 
 class Identifier(Expression):
@@ -519,7 +519,7 @@
     def emit(self, bytecode):
         # obscure hack to be compatible
         if isinstance(self.left, Identifier):
-            bytecode.emit('TYPEOF_VARIABLE', self.left.name)
+            bytecode.emit('TYPEOF_VARIABLE', self.left.index, self.left.name)
         else:
             self.left.emit(bytecode)
             bytecode.emit('TYPEOF')
@@ -760,7 +760,7 @@
     def emit(self, bytecode):
         if self.expr is not None:
             self.expr.emit(bytecode)
-            bytecode.emit('STORE', self.index)
+            bytecode.emit('STORE', self.index, self.identifier)
 
     def __str__(self):
         return "VariableDeclaration %s:%s" % (self.identifier, self.expr)
diff --git a/js/test/test_array.py b/js/test/test_array.py
--- a/js/test/test_array.py
+++ b/js/test/test_array.py
@@ -1,13 +1,13 @@
 from js.test.test_interp import assertv, assertp
 
-def test_array_push():
-    yield assertv, "var x = []; x.push(42); x.length;", 1
-    yield assertv, "var x = []; x.push(42); x[0];", 42
-    yield assertv, "var x = [1,2,3]; x.push(42); x[3];", 42
-    yield assertp, "var x = []; x.push(4); x.push(3); x.push(2); x.push(1); print(x)", '4,3,2,1'
+def test_array_push(capsys):
+    assertv("var x = []; x.push(42); x.length;", 1)
+    assertv("var x = []; x.push(42); x[0];", 42)
+    assertv("var x = [1,2,3]; x.push(42); x[3];", 42)
+    assertp("var x = []; x.push(4); x.push(3); x.push(2); x.push(1); print(x)", '4,3,2,1', capsys)
 
 def test_array_pop():
-    yield assertv, "var x = [4,3,2,1]; x.pop(); x.length;", 3
-    yield assertv, "var x = [4,3,2,1]; x.pop();", 1
-    yield assertv, "var x = [4,3,2,1]; x.pop(); x.pop(); x.pop(); x.pop();", 4
-    yield assertv, "var x = [4,3,2,1]; x.pop(); x.pop(); x.pop(); x.pop(); x.length", 0
+    assertv("var x = [4,3,2,1]; x.pop(); x.length;", 3)
+    assertv("var x = [4,3,2,1]; x.pop();", 1)
+    assertv("var x = [4,3,2,1]; x.pop(); x.pop(); x.pop(); x.pop();", 4)
+    assertv("var x = [4,3,2,1]; x.pop(); x.pop(); x.pop(); x.pop(); x.length", 0)
diff --git a/js/test/test_interp.py b/js/test/test_interp.py
--- a/js/test/test_interp.py
+++ b/js/test/test_interp.py
@@ -6,6 +6,8 @@
 #from js.jscode import JsCode
 #from js.baseop import AbstractEC
 
+xfail = py.test.mark.xfail
+
 def test_simple():
     from js.jscode import JsCode
     bytecode = JsCode()
@@ -73,10 +75,10 @@
     #else:
         #assert code_val.to_string() == value
 
-def asserte(code, value):
-    pass
-    #jsint = interpreter.Interpreter()
-    #py.test.raises(value, 'jsint.run(interpreter.load_source(code, ""))')
+def asserte(code, exception):
+    from js.interpreter import Interpreter
+    jsint = Interpreter()
+    py.test.raises(exception, jsint.run_src, code)
 
 def test_interp_parse(capsys):
     assertv("1+1;", 2)
@@ -207,7 +209,6 @@
     print(Object.prototype);
     """, "[object Object]", capsys)
 
- at py.test.mark.xfail
 def test_array_initializer(capsys):
     assertp("""
     x = [];
@@ -215,7 +216,6 @@
     print(x.length)
     """, '\n0', capsys)
 
- at py.test.mark.xfail
 def test_throw(capsys):
     assertp("throw(3);", "uncaught exception: 3", capsys)
 
@@ -229,7 +229,7 @@
     assertp("{print(5);}", '5', capsys)
     assertp("{3; print(5);}", '5', capsys)
 
- at py.test.mark.xfail
+ at xfail
 def test_try_catch_finally(capsys):
     assertp("""
     try {
@@ -297,7 +297,7 @@
     assertp("print(0||0); print(1||0);", "0\n1", capsys)
     assertp("print(0&&1); print(1&&1);", "0\n1", capsys)
 
-def test_while():
+def test_while(capsys):
     assertp("""
     i = 0;
     while (i<3) {
@@ -305,39 +305,40 @@
         i++;
     }
     print(i);
-    """, ["0","1","2","3"])
+    """, "0\n1\n2\n3", capsys)
 
 def test_assignments():
-    yield assertv, "var x = 3; x += 4; x;", 7
-    yield assertv, "x = 8; x -= 3; x;", 5
-    yield assertv, "x = {}; x.x = 3; x.x += 8; x.x", 8+3
-    yield assertv, "x = []; x[2] = 1; x[2]++;", 1
-    yield assertv, "x = []; x[2] = 1; x[2]++; x[2]", 2
+    assertv("var x = 3; x += 4; x;", 7)
+    assertv("x = 8; x -= 3; x;", 5)
+    assertv("x = {}; x.x = 3; x.x += 8; x.x", 8+3)
+    assertv("x = []; x[2] = 1; x[2]++;", 1)
+    assertv("x = []; x[2] = 1; x[2]++; x[2]", 2)
 
 def test_object_creation():
-    yield assertv, """
+    assertv("""
     o = new Object();
     o;
-    """, "[object Object]"
+    """, "[object Object]")
 
-def test_var_decl():
-    yield assertp, "print(x); var x;", "undefined"
-    yield assertp, """
+ at xfail
+def test_var_decl(capsys):
+    assertp("print(x); var x;", "undefined", capsys)
+    assertp("""
     try {
         print(z);
     }
     catch (e) {
         print(e);
     }
-    """, "ReferenceError: z is not defined"
+    """, "ReferenceError: z is not defined", capsys)
 
-def test_function_name():
+def test_function_name(capsys):
     assertp("""
     function x() {
         print("my name is x");
     }
     x();
-    """, "my name is x")
+    """, "my name is x", capsys)
 
 def test_new_with_function():
     c= """
@@ -347,39 +348,42 @@
     """
     assertv(c, "hello")
 
-def test_vars():
-    assertp("""
-    var x;x=3; print(x);""", ["3"])
+def test_vars(capsys):
+    assertp("var x;x=3; print(x);", "3", capsys)
 
-def test_in():
+def test_in(capsys):
     assertp("""
     x = {y:3};
     print("y" in x);
     print("z" in x);
-    """, ["true", "false"])
+    """, "true\nfalse", capsys)
 
-def test_for():
+def test_for(capsys):
     assertp("""
     i = 0;
     for (i; i<3; i++) {
         print(i);
     }
     print(i);
-    """, ["0","1","2","3"])
+    """, "0\n1\n2\n3", capsys)
 
-#def test_eval():
-    #yield assertp, """
-    #var x = 2;
-    #eval('x=x+1; print(x); z=2;');
-    #print(z);
-    #""", ["3","2"]
-    #yield asserte, "eval('var do =true;');", ThrowException
+def test_eval(capsys):
+    assertp("""
+    var x = 2;
+    eval('x=x+1; print(x); z=2;');
+    print(z);
+    """, "3\n2", capsys)
+
+ at xfail
+def test_eval_syntax_error():
+    from js.execution import JsSyntaxError
+    asserte("eval('var do =true;');", JsSyntaxError)
 
 def test_arrayobject():
     assertv("""var x = new Array();
     x.length == 0;""", 'true')
 
-def test_break():
+def test_break(capsys):
     assertp("""
     while(1){
         break;
@@ -387,25 +391,24 @@
     for(x=0;1==1;x++) {
         break;
     }
-    print('out');""", "out")
+    print('out');""", "out", capsys)
 
+ at xfail
 def test_typeof():
     assertv("""
     var x = 3;
     typeof x == 'number';
     """, True)
-    assertv("""
-    typeof x
-    """, 'undefined')
+    assertv("typeof x", 'undefined')
 
-def test_semicolon():
-    assertp(';', [])
+def test_semicolon(capsys):
+    assertp(';', '', capsys)
 
-def test_newwithargs():
+def test_newwithargs(capsys):
     assertp("""
     var x = new Object(1,2,3,4);
     print(x);
-    """, '1')
+    """, '1', capsys)
 
 def test_increment():
     assertv("""
@@ -415,21 +418,21 @@
     x;""", 2)
 
 def test_ternaryop():
-    yield assertv, "( 1 == 1 ) ? true : false;", True
-    yield assertv, "( 1 == 0 ) ? true : false;", False
+    assertv("( 1 == 1 ) ? true : false;", True)
+    assertv("( 1 == 0 ) ? true : false;", False)
 
-def test_booleanliterals():
+def test_booleanliterals(capsys):
     assertp("""
     var x = false;
     var y = true;
     print(y);
-    print(x);""", ["true", "false"])
+    print(x);""", "true\nfalse", capsys)
 
-def test_unarynot():
+def test_unarynot(capsys):
     assertp("""
     var x = false;
     print(!x);
-    print(!!x);""", ["true", "false"])
+    print(!!x);""", "true\nfalse", capsys)
 
 def test_equals():
     assertv("""
@@ -437,7 +440,7 @@
     y = z = x;
     y;""", 5)
 
-def test_math_stuff():
+def test_math_stuff(capsys):
     assertp("""
     var x = 5;
     var z = 2;
@@ -451,28 +454,27 @@
     print(Math.floor(3.2));
     print(null);
     print(-z);
-    """, ['10', '2', 'false', '3', 'NaN', 'Infinity', '-Infinity',
-    '3', 'null', '-2'])
+    """, '10\n2\nfalse\n3\nNaN\nInfinity\n-Infinity\n3\nnull\n-2', capsys)
 
-def test_globalproperties():
+def test_globalproperties(capsys):
     assertp( """
     print(NaN);
     print(Infinity);
     print(undefined);
-    """, ['NaN', 'Infinity', 'undefined'])
+    """, 'NaN\nInfinity\nundefined', capsys)
 
-def test_strangefunc():
-    assertp("""function f1() { var z; var t;}""", [])
-    assertp(""" "'t'"; """, [])
+def test_strangefunc(capsys):
+    assertp("""function f1() { var z; var t;}""", '', capsys)
+    assertp(""" "'t'"; """, '', capsys)
 
 def test_null():
+    from js.jsobj import w_Null
     assertv("null;", w_Null)
 
-def test_void():
-    assertp("print(void print('hello'));",
-                        ["hello", "undefined"])
+def test_void(capsys):
+    assertp("print(void print('hello'));", "hello\nundefined", capsys)
 
-def test_activationprob():
+def test_activationprob(capsys):
     assertp( """
     function intern (int1){
         print(int1);
@@ -485,9 +487,9 @@
     var ins = new x(1);
     print(ins.p1);
     print(ins.p2);
-    """, ['1','1', '1'])
+    """, '1\n1\n1', capsys)
 
-def test_array_acess():
+def test_array_acess(capsys):
     assertp("""
     var x = new Array();
     x[0] = 1;
@@ -498,57 +500,61 @@
     for(i=0; i<3; i++){
         print(x[i]);
     }
-    """, ['1','2', '1', '2', '3'])
+    """, '1\n2\n1\n2\n3', capsys)
 
-def test_array_length():
+def test_array_length(capsys):
     assertp("""
     var testcases = new Array();
     var tc = testcases.length;
     print('tc'+tc);
-    """, 'tc0')
+    """, 'tc0', capsys)
 
-def test_mod_op():
-    assertp("print(2%2);", '0')
+def test_mod_op(capsys):
+    assertp("print(2%2);", '0', capsys)
 
 def test_unary_plus():
-    assertp("print(+1);", '1')
+    assertv("+1;", 1)
+    assertv("-1;", -1)
 
-def test_delete():
+def test_delete(capsys):
     assertp("""
     x = 0;
     delete x;
     print(this.x)
-    """, 'undefined')
+    """, 'undefined', capsys)
     assertp("""
     var x = {};
     x.y = 1;
     delete x.y;
     print(x.y);
-    """, 'undefined')
+    """, 'undefined', capsys)
 
-def test_forin():
+ at xfail
+def test_forin(capsys):
     assertp("""
     var x = {a:5};
     for(y in x){
         print(y);
     }
-    """, ['5',])
+    """, '5', capsys)
 
-def test_forinvar():
+ at xfail
+def test_forinvar(capsys):
     assertp("""
     var x = {a:5};
     for(var y in x){
         print(y);
     }
-    """, ['5',])
+    """, '5', capsys)
 
 def test_stricteq():
-    yield assertv, "2 === 2;", True
-    yield assertv, "2 === 3;", False
-    yield assertv, "2 !== 3;", True
-    yield assertv, "2 !== 2;", False
+    assertv("2 === 2;", True)
+    assertv("2 === 3;", False)
+    assertv("2 !== 3;", True)
+    assertv("2 !== 2;", False)
 
-def test_with():
+ at xfail
+def test_with(capsys):
     assertp("""
     var mock = {x:2};
     var x=4;
@@ -564,29 +570,30 @@
         print(y);
     }
     print(x);
-    """, ['4', '2', '3', '4'])
+    """, '4\n2\n3\n4', capsys)
 
-def test_with_expr():
+ at xfail
+def test_with_expr(capsys):
     assertp("""
     var x = 4;
     with({x:2}) {
         print(x);
     }
-    """, ['2'])
+    """, '2', capsys)
 
 def test_bitops():
-    yield assertv, "2 ^ 2;", 0
-    yield assertv, "2 & 3;", 2
-    yield assertv, "2 | 3;", 3
-    yield assertv, "2 << 2;", 8
-    yield assertv, "4 >> 2;", 1
-    yield assertv, "-2 >> 31", -1
-    yield assertv, "-2 >>> 31;", 1
+    assertv("2 ^ 2;", 0)
+    assertv("2 & 3;", 2)
+    assertv("2 | 3;", 3)
+    assertv("2 << 2;", 8)
+    assertv("4 >> 2;", 1)
+    assertv("-2 >> 31", -1)
+    assertv("-2 >>> 31;", 1)
 
-def test_for_vararg():
+def test_for_vararg(capsys):
     assertp("""
     for (var arg = "", i = 0; i < 2; i++) { print(i);}
-    """, ['0', '1'])
+    """, '0\n1', capsys)
 
 def test_recursive_call():
     assertv("""
@@ -594,28 +601,28 @@
     fact(3);
     """, 6)
 
-def test_function_prototype():
+ at xfail
+def test_function_prototype(capsys):
     assertp("""
     function foo() {}; foo.prototype.bar = function() {};
-    """, [])
+    """, '', capsys)
 
-
-def test_function_this():
+def test_function_this(capsys):
     assertp("""
     function foo() {print("debug");this.bar = function() {};};
     var f = new foo();
     f.bar();
-    """, 'debug')
+    """, 'debug', capsys)
 
 def test_inplace_assign():
-    yield assertv, "x=1; x+=1; x;", 2
-    yield assertv, "x=1; x-=1; x;", 0
-    yield assertv, "x=2; x*=2; x;", 4
-    yield assertv, "x=2; x/=2; x;", 1
-    yield assertv, "x=4; x%=2; x;", 0
-    yield assertv, "x=2; x&=2; x;", 2
-    yield assertv, "x=0; x|=1; x;", 1
-    yield assertv, "x=2; x^=2; x;", 0
+    assertv("x=1; x+=1; x;", 2)
+    assertv("x=1; x-=1; x;", 0)
+    assertv("x=2; x*=2; x;", 4)
+    assertv("x=2; x/=2; x;", 1)
+    assertv("x=4; x%=2; x;", 0)
+    assertv("x=2; x&=2; x;", 2)
+    assertv("x=0; x|=1; x;", 1)
+    assertv("x=2; x^=2; x;", 0)
 
 def test_not():
     assertv("~1", -2)
@@ -623,7 +630,7 @@
 def test_delete_member():
     assertv("x = 3; delete this.x", "true")
 
-def test_twoarray():
+def test_twoarray(capsys):
     assertp("""
     a1 = new Array();
     a2 = new Array();
@@ -631,7 +638,7 @@
     print(a1[0]);
     a2[0] = 2;
     print(a1[0]);
-    """, ['1', '1'])
+    """, '1\n1', capsys)
 
 def test_semicolon():
     assertv("1", 1)
@@ -640,60 +647,60 @@
     assertv("x = Function('return 1'); x()", 1)
 
 def test_octal_and_hex():
-    yield assertv, "010;", 8
-    yield assertv, "0xF", 15
+    assertv("010;", 8)
+    assertv("0xF", 15)
 
 def test_switch():
-    yield assertv, """
+    assertv("""
     x = 1;
     switch(x){
         case 1: 15; break;
         default: 30;
-    };""", 15
-    yield assertv, """
+    };""", 15)
+    assertv("""
     x = 0;
     switch(x){
         case 1: 15; break;
         default: 30;
-    };""", 30
+    };""", 30)
 
 def test_autoboxing():
-    yield assertv, "'abc'.charAt(0)", 'a'
-    yield assertv, "true.toString()", 'true'
-    yield assertv, "x=5; x.toString();", '5'
+    assertv("'abc'.charAt(0)", 'a')
+    assertv("true.toString()", 'true')
+    assertv("x=5; x.toString();", '5')
 
 def test_proper_prototype_inheritance():
-    yield assertv, """
+    assertv("""
     Object.prototype.my = function() {return 1};
     x = {};
     x.my();
-    """, 1
-    yield assertv, """
+    """, 1)
+    assertv("""
     Function.prototype.my = function() {return 1};
     function x () {};
     x.my();
-    """, 1
+    """, 1)
 
 def test_new_without_args_really():
     assertv("var x = new Boolean; x.toString();", 'false')
 
 def test_pypy_repr():
-    yield assertv, "pypy_repr(3);", 'W_IntNumber(3)'
+    assertv("pypy_repr(3);", 'W_IntNumber(3)')
     # See optimization on astbuilder.py for a reason to the test below
-    yield assertv, "pypy_repr(3.0);", 'W_IntNumber(3)'
-    yield assertv, "pypy_repr(3.5);", 'W_FloatNumber(3.5)'
+    assertv("pypy_repr(3.0);", 'W_IntNumber(3)')
+    assertv("pypy_repr(3.5);", 'W_FloatNumber(3.5)')
     import sys
-    yield assertv, "x="+str(sys.maxint >> 1)+"; pypy_repr(x*x);", 'W_FloatNumber(2.12676479326e+37)'
+    assertv("x="+str(sys.maxint >> 1)+"; pypy_repr(x*x);", 'W_FloatNumber(2.12676479326e+37)')
 
-def test_number():
-    assertp("print(Number(void 0))", "NaN")
+def test_number(capsys):
+    assertp("print(Number(void 0))", "NaN", capsys)
     assertp("""
     function MyObject( value ) {
       this.value = value;
       this.valueOf = new Function( "return this.value" );
     }
     print (Number(new MyObject(100)));
-    """, "100")
+    """, "100", capsys)
 
 def test_decrement():
     assertv("""
@@ -702,24 +709,24 @@
     x;""", 1)
 
 def test_member_increment():
-    yield assertv, "var x = {y:1}; x.y++; x.y;", 2
-    yield assertv, "var x = {y:1}; x.y++;", 1
+    assertv("var x = {y:1}; x.y++; x.y;", 2)
+    assertv("var x = {y:1}; x.y++;", 1)
 
 def test_member_decrement():
-    yield assertv, " var x = {y:2}; x.y--; x.y;", 1
-    yield assertv, " var x = {y:2}; x.y--;", 2
+    assertv(" var x = {y:2}; x.y--; x.y;", 1)
+    assertv(" var x = {y:2}; x.y--;", 2)
 
 def test_member_preincrement():
-    yield assertv, "var x = {y:1}; ++x.y; x.y;", 2
-    yield assertv, "var x = {y:1}; ++x.y;", 2
+    assertv("var x = {y:1}; ++x.y; x.y;", 2)
+    assertv("var x = {y:1}; ++x.y;", 2)
 
 def test_member_predecrement():
-    yield assertv, "var x = {y:2}; --x.y; x.y;", 1
-    yield assertv, "var x = {y:2}; --x.y;", 1
+    assertv("var x = {y:2}; --x.y; x.y;", 1)
+    assertv("var x = {y:2}; --x.y;", 1)
 
 def test_member_sub():
-    yield assertv, "var x = {y:10}; x.y-=5; x.y", 5
-    yield assertv, "var x = {y:10}; x.y-=5;", 5
+    assertv("var x = {y:10}; x.y-=5; x.y", 5)
+    assertv("var x = {y:10}; x.y-=5;", 5)
 
 def switch_test_code(x):
     return """
@@ -744,10 +751,10 @@
 
 
 def test_more_switch():
-    yield assertv, switch_test_code(0), 42
-    yield assertv, switch_test_code(1), 1
-    yield assertv, switch_test_code(2), 2
-    yield assertv, switch_test_code(3), 42
+    assertv(switch_test_code(0), 42)
+    assertv(switch_test_code(1), 1)
+    assertv(switch_test_code(2), 2)
+    assertv(switch_test_code(3), 42)
 
 def switch_no_default_test_code(x):
     return """
@@ -764,53 +771,53 @@
     """ % {'x': x}
 
 def test_switch_no_default():
-    yield assertv, switch_no_default_test_code(0), 42
-    yield assertv, switch_no_default_test_code(1), 2
+     assertv(switch_no_default_test_code(0), 42)
+     assertv(switch_no_default_test_code(1), 2)
 
 def test_member_bitxor():
-    yield assertv, 'var i = {x:0}; i.x^=0; i.x;', 0
-    yield assertv, 'var i = {x:0}; i.x^=0;', 0
-    yield assertv, 'var i = {x:0}; i.x^=1; i.x;', 1
-    yield assertv, 'var i = {x:0}; i.x^=1;', 1
-    yield assertv, 'var i = {x:1}; i.x^=0; i.x;', 1
-    yield assertv, 'var i = {x:1}; i.x^=0;', 1
-    yield assertv, 'var i = {x:1}; i.x^=1; i.x;', 0
-    yield assertv, 'var i = {x:1}; i.x^=1;', 0
+    assertv('var i = {x:0}; i.x^=0; i.x;', 0)
+    assertv('var i = {x:0}; i.x^=0;', 0)
+    assertv('var i = {x:0}; i.x^=1; i.x;', 1)
+    assertv('var i = {x:0}; i.x^=1;', 1)
+    assertv('var i = {x:1}; i.x^=0; i.x;', 1)
+    assertv('var i = {x:1}; i.x^=0;', 1)
+    assertv('var i = {x:1}; i.x^=1; i.x;', 0)
+    assertv('var i = {x:1}; i.x^=1;', 0)
 
 def test_member_bitand():
-    yield assertv, 'var i = {x:0}; i.x&=0; i.x;', 0
-    yield assertv, 'var i = {x:0}; i.x&=0;', 0
-    yield assertv, 'var i = {x:0}; i.x&=1; i.x;', 0
-    yield assertv, 'var i = {x:0}; i.x&=1;', 0
-    yield assertv, 'var i = {x:1}; i.x&=0; i.x;', 0
-    yield assertv, 'var i = {x:1}; i.x&=0;', 0
-    yield assertv, 'var i = {x:1}; i.x&=1; i.x;', 1
-    yield assertv, 'var i = {x:1}; i.x&=1;', 1
+    assertv('var i = {x:0}; i.x&=0; i.x;', 0)
+    assertv('var i = {x:0}; i.x&=0;', 0)
+    assertv('var i = {x:0}; i.x&=1; i.x;', 0)
+    assertv('var i = {x:0}; i.x&=1;', 0)
+    assertv('var i = {x:1}; i.x&=0; i.x;', 0)
+    assertv('var i = {x:1}; i.x&=0;', 0)
+    assertv('var i = {x:1}; i.x&=1; i.x;', 1)
+    assertv('var i = {x:1}; i.x&=1;', 1)
 
 def test_member_bitor():
-    yield assertv, 'var i = {x:0}; i.x|=0; i.x;', 0
-    yield assertv, 'var i = {x:0}; i.x|=0;', 0
-    yield assertv, 'var i = {x:0}; i.x|=1; i.x;', 1
-    yield assertv, 'var i = {x:0}; i.x|=1;', 1
-    yield assertv, 'var i = {x:1}; i.x|=0; i.x;', 1
-    yield assertv, 'var i = {x:1}; i.x|=0;', 1
-    yield assertv, 'var i = {x:1}; i.x|=1; i.x;', 1
-    yield assertv, 'var i = {x:1}; i.x|=1;', 1
+    assertv('var i = {x:0}; i.x|=0; i.x;', 0)
+    assertv('var i = {x:0}; i.x|=0;', 0)
+    assertv('var i = {x:0}; i.x|=1; i.x;', 1)
+    assertv('var i = {x:0}; i.x|=1;', 1)
+    assertv('var i = {x:1}; i.x|=0; i.x;', 1)
+    assertv('var i = {x:1}; i.x|=0;', 1)
+    assertv('var i = {x:1}; i.x|=1; i.x;', 1)
+    assertv('var i = {x:1}; i.x|=1;', 1)
 
 def test_store_bitrsh():
-    yield assertv, 'var i = 1; i>>=0; i;', 1
-    yield assertv, 'var i = 1; i>>=0;', 1
-    yield assertv, 'var i = 2; i>>=1; i;', 1
-    yield assertv, 'var i = 2; i>>=1;', 1
-    yield assertv, 'var i = 4; i>>=1; i;', 2
-    yield assertv, 'var i = 4; i>>=1;', 2
-    yield assertv, 'var i = 4; i>>=2; i;', 1
-    yield assertv, 'var i = 4; i>>=2;', 1
-    yield assertv, 'var i = 4; i>>=3; i;', 0
-    yield assertv, 'var i = 4; i>>=3;', 0
+    assertv('var i = 1; i>>=0; i;', 1)
+    assertv('var i = 1; i>>=0;', 1)
+    assertv('var i = 2; i>>=1; i;', 1)
+    assertv('var i = 2; i>>=1;', 1)
+    assertv('var i = 4; i>>=1; i;', 2)
+    assertv('var i = 4; i>>=1;', 2)
+    assertv('var i = 4; i>>=2; i;', 1)
+    assertv('var i = 4; i>>=2;', 1)
+    assertv('var i = 4; i>>=3; i;', 0)
+    assertv('var i = 4; i>>=3;', 0)
 
 def test_loop_continue():
-    yield assertv, """
+    assertv("""
       i = 0;
       n = 0;
       while (i < 3) {
@@ -820,8 +827,8 @@
          n += i;
       }
       n;
-    """, 5
-    yield assertv, """
+    """, 5)
+    assertv("""
       i = 0;
       n = 0;
       while (i < 3) {
@@ -835,8 +842,8 @@
          }
       }
       n;
-    """, 80
-    yield assertv, """
+    """, 80)
+    assertv("""
       i = 0;
       n = 0;
       while (i < 3) {
@@ -856,10 +863,10 @@
          }
       }
       n;
-    """, 400
+    """, 400)
 
 def test_partial_for_loop():
-    yield assertv, """
+    assertv("""
     var i = 0;
     for(;;){
       i++;
@@ -867,16 +874,16 @@
           break;
     }
     i;
-    """, 2
-    yield assertv, """
+    """, 2)
+    assertv("""
     var i = 0;
     for(;;i++){
       if(i == 2)
           break;
     }
     i;
-    """, 2
-    yield assertv, """
+    """, 2)
+    assertv("""
     var i = 0;
     for(i = 2;;){
       if(i == 2)
@@ -884,17 +891,17 @@
       i = 99;
     }
     i;
-    """, 2
-    yield assertv, """
+    """, 2)
+    assertv("""
     var i = 0;
     for(;i <= 1;){
         i++;
     }
     i;
-    """, 2
+    """, 2)
 
 def test_compare_string_null():
-    yield assertv, """
+    assertv("""
     var x;
     if('a' == null){
         x = true;
@@ -902,26 +909,26 @@
         x = false;
     }
     x;
-    """, False
+    """, False)
 
 def test_math_random():
-    yield assertv, "var x = Math.random(); var y = Math.random(); x == y;", False
+    assertv("var x = Math.random(); var y = Math.random(); x == y;", False)
 
 def test_math_min():
-    yield assertv, "Math.min(1, 2);", 1
-    yield assertv, "Math.min(0, 2);", 0
-    yield assertv, "Math.min(-1, 1);", -1
+    assertv("Math.min(1, 2);", 1)
+    assertv("Math.min(0, 2);", 0)
+    assertv("Math.min(-1, 1);", -1)
 
 def test_math_max():
-    yield assertv, "Math.max(1, 2);", 2
-    yield assertv, "Math.max(0, 2);", 2
-    yield assertv, "Math.max(-1, 1);", 1
+    assertv("Math.max(1, 2);", 2)
+    assertv("Math.max(0, 2);", 2)
+    assertv("Math.max(-1, 1);", 1)
 
 def test_date_get_time():
-    yield assertv, "var i = new Date(); i.valueOf() == i.getTime()", True
+    assertv("var i = new Date(); i.valueOf() == i.getTime()", True)
 
 def test_declare_local_var():
-    yield assertv, """
+    assertv("""
     function f() {
         var i = 4;
         function g() {
@@ -930,8 +937,8 @@
         return g();
     }
     f();
-    """, 12
-    yield assertv, """
+    """, 12)
+    assertv("""
     function f() {
         var i;
         function g() {
@@ -941,7 +948,7 @@
         return g() + i;
     }
     f();
-    """, 12
+    """, 12)
 
 def test_empty_function_with_params():
     assertv("x = function(x) { }; x(); false", False)
diff --git a/js/test/test_jsfunciton.py b/js/test/test_jsfunciton.py
--- a/js/test/test_jsfunciton.py
+++ b/js/test/test_jsfunciton.py
@@ -2,8 +2,8 @@
 #from js.jscode import _JsFunction
 from js.jsobj import _w
 from js.jscode import JsCode
-from js.execution_context import ExecutionContext, FunctionExecutionContext, GlobalExecutionContext
-from js.functions import JsFunction, JsExecutableCode, JsNativeFunction, JsGlobalCode
+from js.execution_context import ExecutionContext, FunctionExecutionContext, GlobalExecutionContext, EvalExecutionContext
+from js.functions import JsFunction, JsExecutableCode, JsNativeFunction, JsGlobalCode, JsEvalCode
 from js.lexical_environment import DeclarativeEnvironment
 from js.astbuilder import parse_to_ast, SymbolMap
 from js.jscode import ast_to_bytecode
@@ -30,28 +30,23 @@
         code.emit('RETURN')
 
         f = JsFunction('foo', code)
-        ctx = FunctionExecutionContext()
+        ctx = FunctionExecutionContext(f)
         res = f.run(ctx)
 
         assert res == _w(2)
 
-
     def test_foo3(self):
         symbol_map = SymbolMap()


More information about the pypy-commit mailing list