Author: Stephan <step...@stzal.com> Branch: Changeset: r337:8a151cf97de6 Date: 2013-01-08 20:06 +0100 http://bitbucket.org/pypy/lang-js/changeset/8a151cf97de6/
Log: refactored boxing diff --git a/js/builtins/__init__.py b/js/builtins/__init__.py --- a/js/builtins/__init__.py +++ b/js/builtins/__init__.py @@ -1,4 +1,3 @@ -from js.jsobj import w_Undefined from js.object_space import _w #from pypy.rlib import jit @@ -127,7 +126,10 @@ js.builtins.js_global.setup(global_object) -def get_arg(args, index, default=w_Undefined): +from js.object_space import newundefined + + +def get_arg(args, index, default=newundefined()): if len(args) > index: return args[index] return default diff --git a/js/builtins/array.py b/js/builtins/array.py --- a/js/builtins/array.py +++ b/js/builtins/array.py @@ -1,6 +1,5 @@ -from js.jsobj import isnull_or_undefined, w_Undefined from js.builtins import get_arg -from js.object_space import w_return, _w +from js.object_space import w_return, _w, isnull_or_undefined, newundefined def setup(global_object): @@ -73,13 +72,15 @@ # 15.4.4.5 @w_return def join(this, args): + from js.object_space import isundefined + separator = get_arg(args, 0) o = this.ToObject() len_val = o.get(u'length') length = len_val.ToUInt32() - if separator is w_Undefined: + if isundefined(separator): sep = u',' else: sep = separator.to_string() @@ -117,7 +118,7 @@ if l == 0: o.put(u'length', _w(0)) - return w_Undefined + return newundefined() else: indx = l - 1 indxs = unicode(str(indx)) @@ -188,7 +189,9 @@ return obj -def sort_compare(obj, j, k, comparefn=w_Undefined): +def sort_compare(obj, j, k, comparefn=newundefined()): + from js.object_space import isundefined + j_string = j k_string = k has_j = obj.has_property(j) @@ -204,19 +207,19 @@ x = obj.get(j_string) y = obj.get(k_string) - if x is w_Undefined and y is w_Undefined: + if isundefined(x) and isundefined(y): return 0 - if x is w_Undefined: + if isundefined(x): return 1 - if y is w_Undefined: + if isundefined(y): return -1 - if comparefn is not w_Undefined: + if not isundefined(comparefn): if not comparefn.is_callable(): from js.execution import JsTypeError raise JsTypeError(u'') - res = comparefn.Call(args=[x, y], this=w_Undefined) + res = comparefn.Call(args=[x, y], this=newundefined()) return res.ToInteger() x_string = x.to_string() diff --git a/js/builtins/function.py b/js/builtins/function.py --- a/js/builtins/function.py +++ b/js/builtins/function.py @@ -1,6 +1,4 @@ -from js.jsobj import isnull_or_undefined from js.execution import JsTypeError -from js.jsobj import w_Undefined from js.builtins import get_arg from js.completion import NormalCompletion from js.object_space import w_return, _w @@ -17,7 +15,8 @@ @w_return def empty(this, args): - return w_Undefined + from js.object_space import newundefined + return newundefined() # 15.3.4.4 Function.prototype.call @@ -38,6 +37,7 @@ # 15.3.4.3 Function.prototype.apply (thisArg, argArray) def js_apply(ctx): + from js.object_space import isnull_or_undefined func = ctx.this_binding() args = ctx.argv() diff --git a/js/builtins/js_global.py b/js/builtins/js_global.py --- a/js/builtins/js_global.py +++ b/js/builtins/js_global.py @@ -10,8 +10,8 @@ from js.builtins import put_intimate_function, put_native_function, put_property from js.builtins.number import w_NAN from js.builtins.number import w_POSITIVE_INFINITY - from js.jsobj import w_Undefined from pypy.rlib.objectmodel import we_are_translated + from js.object_space import newundefined # 15.1.1.1 put_property(global_object, u'NaN', w_NAN, writable=False, enumerable=False, configurable=False) @@ -20,7 +20,7 @@ put_property(global_object, u'Infinity', w_POSITIVE_INFINITY, writable=False, enumerable=False, configurable=False) # 15.1.1.3 - put_property(global_object, u'undefined', w_Undefined, writable=False, enumerable=False, configurable=False) + put_property(global_object, u'undefined', newundefined(), writable=False, enumerable=False, configurable=False) # 15.1.2.1 put_intimate_function(global_object, u'eval', js_eval, params=[u'x']) diff --git a/js/builtins/string.py b/js/builtins/string.py --- a/js/builtins/string.py +++ b/js/builtins/string.py @@ -1,4 +1,4 @@ -from js.jsobj import w_Undefined, W_String, W_StringObject +from js.jsobj import W_String, W_StringObject from pypy.rlib.rfloat import NAN from js.execution import JsTypeError from js.builtins import get_arg @@ -111,10 +111,7 @@ # 15.5.4.4 @w_return def char_at(this, args): - pos = w_Undefined - - if len(args) > 0: - pos = args[0] + pos = get_arg(args, 0) position = pos.ToInt32() @@ -230,6 +227,8 @@ # 15.5.4.14 @w_return def split(this, args): + from js.object_space import isundefined + this.check_object_coercible() separator = get_arg(args, 0, None) @@ -237,7 +236,7 @@ string = this.to_string() - if limit is w_Undefined: + if isundefined(limit): import math lim = int(math.pow(2, 32) - 1) else: diff --git a/js/environment_record.py b/js/environment_record.py --- a/js/environment_record.py +++ b/js/environment_record.py @@ -1,4 +1,3 @@ -from js.jsobj import w_Undefined from js.object_map import ROOT_MAP @@ -89,9 +88,10 @@ # 10.2.1.1.2 def create_mutuable_binding(self, identifier, deletable): + from js.object_space import newundefined assert identifier is not None and isinstance(identifier, unicode) assert not self.has_binding(identifier) - self._add_binding(identifier, w_Undefined) + self._add_binding(identifier, newundefined()) self._set_mutable_binding(identifier) if deletable: self._set_deletable_binding(identifier) @@ -107,13 +107,14 @@ # 10.2.1.1.4 def get_binding_value(self, identifier, strict=False): + from js.object_space import newundefined assert identifier is not None and isinstance(identifier, unicode) if not self.has_binding(identifier): if strict: from js.execution import JsReferenceError raise JsReferenceError(identifier) else: - return w_Undefined + return newundefined() return self._get_binding(identifier) # 10.2.1.1.5 @@ -132,7 +133,8 @@ # 10.2.1.1.6 def implicit_this_value(self): - return w_Undefined + from js.object_space import newundefined + return newundefined() # 10.2.1.1.7 def create_immutable_bining(self, identifier): @@ -169,7 +171,8 @@ config_value = True from js.jsobj import PropertyDescriptor - desc = PropertyDescriptor(value=w_Undefined, writable=True, enumerable=True, configurable=config_value) + from js.object_space import newundefined + desc = PropertyDescriptor(value=newundefined(), writable=True, enumerable=True, configurable=config_value) bindings.define_own_property(n, desc, True) # 10.2.1.2.3 @@ -180,12 +183,13 @@ # 10.2.1.2.4 def get_binding_value(self, n, s=False): + from js.object_space import newundefined assert n is not None and isinstance(n, unicode) bindings = self.binding_object value = bindings.has_property(n) if value is False: if s is False: - return w_Undefined + return newundefined() else: from execution import JsReferenceError raise JsReferenceError(self.__class__) @@ -200,9 +204,10 @@ # 10.2.1.2.6 def implicit_this_value(self): + from js.object_space import newundefined if self.provide_this is True: return self.binding_object - return w_Undefined + return newundefined() class GlobalEnvironmentRecord(ObjectEnvironmentRecord): diff --git a/js/execution_context.py b/js/execution_context.py --- a/js/execution_context.py +++ b/js/execution_context.py @@ -1,5 +1,5 @@ -from js.jsobj import w_Undefined from js.utils import StackMixin +from js.object_space import newundefined class ExecutionContext(StackMixin): @@ -52,6 +52,8 @@ # 10.5 def declaration_binding_initialization(self): + from js.object_space import newundefined + env = self._variable_environment_.environment_record strict = self._strict_ code = self._code_ @@ -71,7 +73,7 @@ for arg_name in names: n += 1 if n > arg_count: - v = w_Undefined + v = newundefined() else: v = args[n - 1] arg_already_declared = env.has_binding(arg_name) @@ -113,7 +115,7 @@ var_already_declared = env.has_binding(dn) if var_already_declared is False: env.create_mutuable_binding(dn, configurable_bindings) - env.set_mutable_binding(dn, w_Undefined, False) + env.set_mutable_binding(dn, newundefined(), False) def _get_refs(self, index): assert index <= len(self._refs_) @@ -191,9 +193,9 @@ _immutable_fields_ = ['_scope_', '_calling_context_'] _refs_resizable_ = False - def __init__(self, code, formal_parameters=[], argv=[], this=w_Undefined, strict=False, scope=None, w_func=None): - from js.jsobj import isnull_or_undefined, W_BasicObject - from js.object_space import object_space + def __init__(self, code, formal_parameters=[], argv=[], this=newundefined(), strict=False, scope=None, w_func=None): + from js.jsobj import W_BasicObject + from js.object_space import object_space, isnull_or_undefined stack_size = code.estimated_stack_size() env_size = code.env_size() + 1 # neet do add one for the arguments object diff --git a/js/jsobj.py b/js/jsobj.py --- a/js/jsobj.py +++ b/js/jsobj.py @@ -132,12 +132,6 @@ def ToObject(self): raise JsTypeError(u'W_Null.ToObject') -w_Undefined = W_Undefined() -jit.promote(w_Undefined) - -w_Null = W_Null() -jit.promote(w_Null) - class PropertyIdenfidier(object): def __init__(self, name, descriptor): @@ -187,10 +181,11 @@ _immutable_fields_ = ['_type_', '_class_', '_extensible_'] def __init__(self): + from js.object_space import newnull self._property_map_ = _new_map() self._property_slots_ = [] - self._prototype_ = w_Null + self._prototype_ = newnull() W_BasicObject.define_own_property(self, u'__proto__', proto_desc) def __str__(self): @@ -209,17 +204,18 @@ # 8.12.3 def get(self, p): + from js.object_space import newundefined assert p is not None and isinstance(p, unicode) desc = self.get_property(p) if desc is None: - return w_Undefined + return newundefined() if is_data_descriptor(desc): return desc.value if desc.has_set_getter() is False: - return w_Undefined + return newundefined() getter = desc.getter res = getter.Call(this=self) @@ -271,6 +267,7 @@ # 8.12.2 def get_property(self, p): + from js.object_space import isnull assert p is not None and isinstance(p, unicode) prop = self.get_own_property(p) @@ -278,7 +275,7 @@ return prop proto = self.prototype() - if proto is w_Null: + if isnull(proto): return None assert isinstance(proto, W_BasicObject) @@ -311,10 +308,11 @@ # 8.12.4 def can_put(self, p): + from js.object_space import isundefined, isnull_or_undefined desc = self.get_own_property(p) if desc is not None: if is_accessor_descriptor(desc) is True: - if desc.setter is w_Undefined: + if isundefined(desc.setter): return False else: return True @@ -322,7 +320,7 @@ proto = self.prototype() - if proto is w_Null or proto is w_Undefined: + if isnull_or_undefined(proto): return self.extensible() assert isinstance(proto, W_BasicObject) @@ -331,7 +329,7 @@ return self.extensible() if is_accessor_descriptor(inherited) is True: - if inherited.setter is w_Undefined: + if isundefined(inherited.setter): return False else: return True @@ -511,6 +509,7 @@ ### def _named_properties_dict(self): + from js.object_space import isnull_or_undefined my_d = {} for i in self._property_map_.keys(): my_d[i] = None @@ -637,6 +636,7 @@ # 15.3.5.3 def has_instance(self, v): + from js.object_space import isnull_or_undefined if not isinstance(v, W_BasicObject): return False @@ -656,6 +656,7 @@ class W_ObjectConstructor(W_BasicFunction): def Call(self, args=[], this=None, calling_context=None): + from js.object_space import isnull_or_undefined from js.builtins import get_arg value = get_arg(args, 0) @@ -732,10 +733,11 @@ class W_NumberConstructor(W_BasicFunction): # 15.7.1.1 def Call(self, args=[], this=None, calling_context=None): - from js.object_space import _w + from js.object_space import _w, isnull_or_undefined, isundefined + 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: + elif len(args) >= 1 and isundefined(args[0]): return _w(NAN) else: return _w(0.0) @@ -767,7 +769,7 @@ # 15.6.2 class W_BooleanConstructor(W_BasicFunction): def Call(self, args=[], this=None, calling_context=None): - from js.object_space import _w + from js.object_space import _w, isnull_or_undefined if len(args) >= 1 and not isnull_or_undefined(args[0]): boolval = args[0].to_boolean() return _w(boolval) @@ -833,8 +835,7 @@ def __init__(self, function_body, formal_parameter_list=[], scope=None, strict=False): W_BasicFunction.__init__(self) - from js.object_space import object_space - from js.object_space import _w + from js.object_space import _w, newnull, object_space self._function_ = function_body self._scope_ = scope self._params_ = formal_parameter_list @@ -855,8 +856,8 @@ if strict is True: raise NotImplementedError() else: - put_property(self, u'caller', w_Null, writable=True, enumerable=False, configurable=False) - put_property(self, u'arguments', w_Null, writable=True, enumerable=False, configurable=False) + put_property(self, u'caller', newnull(), writable=True, enumerable=False, configurable=False) + put_property(self, u'arguments', newnull(), writable=True, enumerable=False, configurable=False) def _to_string(self): return self._function_.to_string() @@ -1220,24 +1221,6 @@ return intmask(int(self._floatval_)) -def isnull_or_undefined(obj): - if obj is w_Null or obj is w_Undefined: - return True - return False - -w_True = W_Boolean(True) -jit.promote(w_True) - -w_False = W_Boolean(False) -jit.promote(w_False) - - -def newbool(val): - if val: - return w_True - return w_False - - class W_List(W_Root): def __init__(self, values): self.values = values diff --git a/js/object_space.py b/js/object_space.py --- a/js/object_space.py +++ b/js/object_space.py @@ -1,24 +1,102 @@ -from pypy.rlib.objectmodel import specialize +from pypy.rlib.objectmodel import specialize, enforceargs +from pypy.rlib import jit + + +@enforceargs(int) +def newint(i): + from js.jsobj import W_IntNumber + return W_IntNumber(i) + + +@enforceargs(float) +def newfloat(f): + from js.jsobj import W_FloatNumber + return W_FloatNumber(f) + + +@enforceargs(unicode) +def newstring(s): + from js.jsobj import W_String + return W_String(s) + + +@enforceargs(bool) +def _makebool(b): + from js.jsobj import W_Boolean + return W_Boolean(b) + + +w_True = _makebool(True) +jit.promote(w_True) + + +w_False = _makebool(False) +jit.promote(w_False) + + +def _makeundefined(): + from js.jsobj import W_Undefined + return W_Undefined() + +w_Undefined = _makeundefined() +jit.promote(w_Undefined) + + +def _makenull(): + from js.jsobj import W_Null + return W_Null() + +w_Null = _makenull() +jit.promote(w_Null) + + +def isnull(value): + return value is w_Null + + +def newnull(): + return w_Null + + +def isundefined(value): + return value is w_Undefined + + +def newundefined(): + return w_Undefined + + +def isnull_or_undefined(obj): + if isnull(obj) or isundefined(obj): + return True + return False + + +@enforceargs(bool) +def newbool(val): + if val is True: + return w_True + return w_False @specialize.argtype(0) def _w(value): - from js.jsobj import w_Null, newbool, W_IntNumber, W_FloatNumber, W_String, W_Root, put_property + from js.jsobj import W_Root, put_property if value is None: - return w_Null + return newnull() elif isinstance(value, W_Root): return value elif isinstance(value, bool): return newbool(value) elif isinstance(value, int): - return W_IntNumber(value) + return newint(value) elif isinstance(value, float): - return W_FloatNumber(value) + return newfloat(value) elif isinstance(value, unicode): - return W_String(value) + return newstring(value) elif isinstance(value, str): u_str = unicode(value) - return W_String(u_str) + return newstring(u_str) elif isinstance(value, list): a = object_space.new_array() for index, item in enumerate(value): @@ -30,16 +108,15 @@ class ObjectSpace(object): def __init__(self): - from js.jsobj import w_Null self.global_context = None self.global_object = None - self.proto_function = w_Null - self.proto_boolean = w_Null - self.proto_number = w_Null - self.proto_string = w_Null - self.proto_array = w_Null - self.proto_date = w_Null - self.proto_object = w_Null + self.proto_function = newnull() + self.proto_boolean = newnull() + self.proto_number = newnull() + self.proto_string = newnull() + self.proto_array = newnull() + self.proto_date = newnull() + self.proto_object = newnull() self.interpreter = None def get_global_environment(self): diff --git a/js/opcodes.py b/js/opcodes.py --- a/js/opcodes.py +++ b/js/opcodes.py @@ -1,5 +1,3 @@ -from js.jsobj import W_IntNumber, W_FloatNumber, W_String, \ - w_Undefined, newbool, w_Null from js.object_space import _w from js.execution import JsTypeError from js.baseop import plus, sub, compare, AbstractEC, StrictEC,\ @@ -31,9 +29,13 @@ _stack_change = 0 def eval(self, ctx): + from js.object_space import newbool s4 = ctx.stack_pop() s2 = ctx.stack_pop() - ctx.stack_append(self.decision(ctx, s2, s4)) + res = self.decision(ctx, s2, s4) + # XXX mimik behaviour of old newbool + res_true = res is True + ctx.stack_append(newbool(res_true)) def decision(self, ctx, op1, op2): raise NotImplementedError @@ -66,14 +68,16 @@ class Undefined(Opcode): def eval(self, ctx): - ctx.stack_append(w_Undefined) + from js.object_space import newundefined + ctx.stack_append(newundefined()) class LOAD_INTCONSTANT(Opcode): _immutable_fields_ = ['w_intvalue'] def __init__(self, value): - self.w_intvalue = W_IntNumber(int(value)) + from js.object_space import newint + self.w_intvalue = newint(int(value)) def eval(self, ctx): ctx.stack_append(self.w_intvalue) @@ -84,20 +88,22 @@ class LOAD_BOOLCONSTANT(Opcode): def __init__(self, value): - self.boolval = value + from js.object_space import newbool + self.w_boolval = newbool(value) def eval(self, ctx): - ctx.stack_append(newbool(self.boolval)) + ctx.stack_append(self.w_boolval) def __str__(self): - if self.boolval: + if self.w_boolval.to_boolean(): return 'LOAD_BOOLCONSTANT true' return 'LOAD_BOOLCONSTANT false' class LOAD_FLOATCONSTANT(Opcode): def __init__(self, value): - self.w_floatvalue = W_FloatNumber(float(value)) + from js.object_space import newfloat + self.w_floatvalue = newfloat(float(value)) def eval(self, ctx): ctx.stack_append(self.w_floatvalue) @@ -110,27 +116,27 @@ _immutable_fields_ = ['strval'] def __init__(self, value): - #assert isinstance(value, unicode) - self.strval = value + from js.object_space import newstring + self.w_strval = newstring(value) def eval(self, ctx): - strval = self.strval - #assert isinstance(strval, unicode) - w_string = W_String(strval) - ctx.stack_append(w_string) + w_strval = self.w_strval + ctx.stack_append(w_strval) def __str__(self): - return u'LOAD_STRINGCONSTANT "%s"' % (self.strval) + return u'LOAD_STRINGCONSTANT "%s"' % (self.w_strval.to_string()) class LOAD_UNDEFINED(Opcode): def eval(self, ctx): - ctx.stack_append(w_Undefined) + from js.object_space import newundefined + ctx.stack_append(newundefined()) class LOAD_NULL(Opcode): def eval(self, ctx): - ctx.stack_append(w_Null) + from js.object_space import newnull + ctx.stack_append(newnull()) class LOAD_VARIABLE(Opcode): @@ -264,6 +270,7 @@ class IN(BaseBinaryOperation): def operation(self, ctx, left, right): from js.jsobj import W_BasicObject + from js.object_space import newbool if not isinstance(right, W_BasicObject): raise JsTypeError(u"TypeError: fffuuu!") # + repr(right) name = left.to_string() @@ -292,6 +299,7 @@ self.name = name def eval(self, ctx): + from js.object_space import newstring ref = ctx.get_ref(self.name) if ref.is_unresolvable_reference(): var_type = u'undefined' @@ -299,7 +307,7 @@ var = ref.get_value() var_type = type_of(var) - w_string = W_String(var_type) + w_string = newstring(var_type) ctx.stack_append(w_string) def __str__(self): @@ -313,23 +321,27 @@ class BITAND(BaseBinaryBitwiseOp): def operation(self, ctx, op1, op2): - return W_IntNumber(op1 & op2) + from js.object_space import newint + return newint(op1 & op2) class BITXOR(BaseBinaryBitwiseOp): def operation(self, ctx, op1, op2): - return W_IntNumber(op1 ^ op2) + from js.object_space import newint + return newint(op1 ^ op2) class BITOR(BaseBinaryBitwiseOp): def operation(self, ctx, op1, op2): - return W_IntNumber(op1 | op2) + from js.object_space import newint + return newint(op1 | op2) class BITNOT(BaseUnaryOperation): def eval(self, ctx): op = ctx.stack_pop().ToInt32() - ctx.stack_append(W_IntNumber(~op)) + from js.object_space import newint + ctx.stack_append(newint(~op)) class URSH(BaseBinaryBitwiseOp): @@ -436,42 +448,42 @@ class GT(BaseBinaryComparison): def decision(self, ctx, op1, op2): - return newbool(compare(ctx, op1, op2)) + return compare(ctx, op1, op2) class GE(BaseBinaryComparison): def decision(self, ctx, op1, op2): - return newbool(compare_e(ctx, op1, op2)) + return compare_e(ctx, op1, op2) class LT(BaseBinaryComparison): def decision(self, ctx, op1, op2): - return newbool(compare(ctx, op2, op1)) + return compare(ctx, op2, op1) class LE(BaseBinaryComparison): def decision(self, ctx, op1, op2): - return newbool(compare_e(ctx, op2, op1)) + return compare_e(ctx, op2, op1) class EQ(BaseBinaryComparison): def decision(self, ctx, op1, op2): - return newbool(AbstractEC(ctx, op1, op2)) + return AbstractEC(ctx, op1, op2) class NE(BaseBinaryComparison): def decision(self, ctx, op1, op2): - return newbool(not AbstractEC(ctx, op1, op2)) + return not AbstractEC(ctx, op1, op2) class IS(BaseBinaryComparison): def decision(self, ctx, op1, op2): - return newbool(StrictEC(op1, op2)) + return StrictEC(op1, op2) class ISNOT(BaseBinaryComparison): def decision(self, ctx, op1, op2): - return newbool(not StrictEC(op1, op2)) + return not StrictEC(op1, op2) class STORE_MEMBER(Opcode): diff --git a/test/test_interp.py b/test/test_interp.py --- a/test/test_interp.py +++ b/test/test_interp.py @@ -1,10 +1,4 @@ import py -#from js import interpreter -#from js.operations import IntNumber, FloatNumber, Position, Plus -#from js.jsobj import W_Root, w_Null, W___Root -#from js.execution import ThrowException -#from js.jscode import JsCode -#from js.baseop import AbstractEC xfail = py.test.mark.xfail @@ -527,7 +521,7 @@ def test_null(): - from js.jsobj import w_Null + from js.object_space import w_Null assertv("null;", w_Null) diff --git a/test/test_lexical_environment.py b/test/test_lexical_environment.py --- a/test/test_lexical_environment.py +++ b/test/test_lexical_environment.py @@ -1,5 +1,5 @@ from js.lexical_environment import DeclarativeEnvironment, ObjectEnvironment -from js.jsobj import w_Undefined, W_BasicObject +from js.jsobj import W_BasicObject class TestDeclarativeEnvironment(object): _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit