[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