Author: Stephan <[email protected]>
Branch:
Changeset: r188:17080c32e143
Date: 2012-05-19 11:10 +0200
http://bitbucket.org/pypy/lang-js/changeset/17080c32e143/
Log: wip
diff --git a/js/baseop.py b/js/baseop.py
--- a/js/baseop.py
+++ b/js/baseop.py
@@ -189,7 +189,7 @@
r = x.ToNumber() == y.ToNumber()
return r
-def StrictEC(ctx, x, y):
+def StrictEC(x, y):
"""
Implements the Strict Equality Comparison x === y
trying to be fully to the spec
diff --git a/js/bench/v8/v1/run.js b/js/bench/v8/v1/run.js
--- a/js/bench/v8/v1/run.js
+++ b/js/bench/v8/v1/run.js
@@ -28,8 +28,8 @@
load('base.js');
load('looping.js');
-//load('richards.js');
-//load('deltablue.js');
+load('richards.js');
+load('deltablue.js');
//load('crypto.js');
//load('raytrace.js');
//load('earley-boyer.js');
diff --git a/js/builtins.py b/js/builtins.py
--- a/js/builtins.py
+++ b/js/builtins.py
@@ -9,10 +9,11 @@
from pypy.rlib.objectmodel import specialize
from pypy.rlib.listsort import TimSort
from pypy.rlib.rarithmetic import r_uint
-from pypy.rlib.rfloat import NAN, INFINITY
from pypy.rlib.objectmodel import we_are_translated
from pypy.rlib import jit
+from js.builtins_number import w_NAN
+from js.builtins_number import w_POSITIVE_INFINITY
class Sorter(TimSort):
def __init__(self, list, listlength=None, compare_fn=None):
@@ -25,35 +26,31 @@
return result == -1
return a.ToString() < b.ToString()
-def new_native_function(function, name = None):
+def new_native_function(function, name = None, params = []):
from js.functions import JsNativeFunction
from js.jsobj import W__Function
scope = None
- jsfunc = JsNativeFunction(native_function(function), name)
- return W__Function(jsfunc)
+ jsfunc = JsNativeFunction(function, name)
+ return W__Function(jsfunc, formal_parameter_list = params)
-def native_function(func):
- from js.jsobj import _w
- def f(*args):
- return _w(func(*args))
- return f
-
-def put_native_function(obj, name, func, writable = False, configurable =
False, enumerable = False):
- jsfunc = new_native_function(func, name)
+# 15
+def put_native_function(obj, name, func, writable = True, configurable = True,
enumerable = False, params = []):
+ jsfunc = new_native_function(func, name, params)
put_property(obj, name, jsfunc, writable = writable, configurable =
configurable, enumerable = enumerable)
-def put_intimate_function(obj, name, func, writable = False, configurable =
False, enumerable = False):
+# 15
+def put_intimate_function(obj, name, func, writable = True, configurable =
True, enumerable = False):
from js.functions import JsIntimateFunction
from js.jsobj import W__Function
scope = None
- jsfunc = JsIntimateFunction(native_function(func), name)
+ jsfunc = JsIntimateFunction(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):
+def put_property(obj, name, value, writable = True, configurable = True,
enumerable = False):
from js.jsobj import put_property as _put_property
_put_property(obj, name, value, writable, configurable, enumerable)
@@ -79,7 +76,7 @@
w_FunctionPrototype = new_native_function(function_builtins.empty, 'Empty')
# 15.2.4 Properties of the Object Prototype Object
- w_ObjectPrototype._prototype_ = w_Undefined
+ w_ObjectPrototype._prototype_ = w_Null
# 15.3.4 Properties of the Function Prototype Object
w_FunctionPrototype._prototype_ = w_ObjectPrototype
@@ -87,12 +84,15 @@
# initial prototype
from js.jsobj import W__Object, W__Function, W_BasicFunction
W__Object._prototype_ = w_ObjectPrototype
+
W__Function._prototype_ = w_FunctionPrototype
W_BasicFunction._prototype_ = w_FunctionPrototype
# 15.2 Object Objects
# 15.2.3 Properties of the Object Constructor
w_Object._prototype_ = w_FunctionPrototype
+ del(w_Object._properties_['__proto__'])
+ put_property(w_Object, '__proto__', w_Object._prototype_)
put_property(w_Object, 'length', _w(1))
@@ -122,160 +122,28 @@
# 14.3.4.1 Function.prototype.constructor
put_property(w_FunctionPrototype, 'constructor', w_Function)
+ import js.builtins_function as function_builtins
+
# 15.3.4.2 Function.prototype.toString()
- import js.builtins_function as function_builtins
put_native_function(w_FunctionPrototype, 'toString',
function_builtins.to_string)
# 15.3.4.3 Function.prototype.apply
put_native_function(w_FunctionPrototype, 'apply', function_builtins.apply)
# 15.3.4.4 Function.prototype.call
- put_native_function(w_FunctionPrototype, 'call', function_builtins.call)
+ put_intimate_function(w_FunctionPrototype, 'call', function_builtins.call)
- # 15.6.2
- from js.jsobj import W_BooleanConstructor
- w_Boolean = W_BooleanConstructor()
- put_property(global_object, 'Boolean', w_Boolean)
+ import js.builtins_boolean
+ js.builtins_boolean.setup(global_object)
- # 15.6.3
- put_property(w_Boolean, 'length', _w(1), writable = False, enumerable =
False, configurable = False)
+ import js.builtins_number
+ js.builtins_number.setup(global_object)
- # 15.6.4
- from js.jsobj import W_BooleanObject
- w_BooleanPrototype = W_BooleanObject(False)
- w_BooleanPrototype._prototype_ = W__Object._prototype_
- put_property(w_BooleanPrototype, '__proto__',
w_BooleanPrototype._prototype_, writable = False, enumerable = False,
configurable = False)
+ import js.builtins_string
+ js.builtins_string.setup(global_object)
- # 15.6.3.1
- put_property(w_Boolean, 'prototype', w_BooleanPrototype, writable = False,
enumerable = False, configurable = False)
-
- # 15.6.4.1
- put_property(w_BooleanPrototype, 'constructor', w_Boolean)
-
- import js.builtins_boolean as boolean_builtins
- # 15.6.4.2
- put_native_function(w_BooleanPrototype, 'toString',
boolean_builtins.to_string)
-
- # 15.6.4.3
- put_native_function(w_BooleanPrototype, 'valueOf',
boolean_builtins.value_of)
-
- # 15.6.3.1
- W_BooleanObject._prototype_ = w_BooleanPrototype
-
- # 15.7.2
- from js.jsobj import W_NumberConstructor
- w_Number = W_NumberConstructor()
- put_property(global_object, 'Number', w_Number)
-
- # 15.7.4
- from js.jsobj import W_NumericObject
- w_NumberPrototype = W_NumericObject(0)
- w_NumberPrototype._prototype_ = W__Object._prototype_
-
- # 15.7.4.1
- put_property(w_NumberPrototype, 'constructor', w_NumberPrototype)
-
- import js.builtins_number as number_builtins
- # 15.7.4.2
- put_native_function(w_NumberPrototype, 'toString',
number_builtins.to_string)
-
- # 15.7.3.1
- put_property(w_Number, 'prototype', w_NumberPrototype)
- W_NumericObject._prototype_ = w_NumberPrototype
-
- # 15.7.3.2
- put_property(w_Number, 'MAX_VALUE', _w(1.7976931348623157e308), writable =
False, configurable = False)
-
- # 15.7.3.3
- put_property(w_Number, 'MIN_VALUE', _w(5e-320), writable = False,
configurable = False)
-
- # 15.7.3.4
- w_NAN = _w(NAN)
- put_property(w_Number, 'NaN', w_NAN, writable = False, configurable =
False)
-
- # 15.7.3.5
- w_POSITIVE_INFINITY = _w(INFINITY)
- put_property(w_Number, 'POSITIVE_INFINITY', w_POSITIVE_INFINITY, writable
= False, configurable = False)
-
- # 15.7.3.6
- w_NEGATIVE_INFINITY = _w(-INFINITY)
- put_property(w_Number, 'NEGATIVE_INFINITY', w_NEGATIVE_INFINITY, writable
= False, configurable = False)
-
- #String
- # 15.5.1
- from js.jsobj import W_StringConstructor
- w_String = W_StringConstructor()
- put_property(global_object, 'String', w_String)
-
- import js.builtins_string as string_builtins
- # 15.5.3.2
- put_native_function(w_String, 'fromCharCode',
string_builtins.from_char_code)
-
- # 15.5.4
- from js.jsobj import W_StringObject
- w_StringPrototype = W_StringObject('')
- w_StringPrototype._prototype_ = W__Object._prototype_
-
- # 15.5.3.1
- W_StringObject._prototype_ = w_StringPrototype
-
- # 15.5.4.1
- put_property(w_StringPrototype, 'constructor', w_String)
-
- # 15.5.4.4
- put_native_function(w_StringPrototype, 'charAt', string_builtins.char_at)
-
- # 15.5.4.5
- put_native_function(w_StringPrototype, 'charCodeAt',
string_builtins.char_code_at)
-
- # 15.5.4.6
- put_native_function(w_StringPrototype, 'concat', string_builtins.concat)
-
- # 15.5.4.7
- put_native_function(w_StringPrototype, 'indexOf', string_builtins.index_of)
-
- # 15.5.4.8
- put_native_function(w_StringPrototype, 'lastIndexOf',
string_builtins.last_index_of)
-
- # 15.5.4.14
- put_native_function(w_StringPrototype, 'split', string_builtins.split)
-
- # 15.5.4.15
- put_native_function(w_StringPrototype, 'substring',
string_builtins.substring)
-
- # 15.5.4.16
- put_native_function(w_StringPrototype, 'toLowerCase',
string_builtins.to_lower_case)
-
- # 15.5.4.18
- put_native_function(w_StringPrototype, 'toUpperCase',
string_builtins.to_upper_case)
-
- from js.jsobj import W_ArrayConstructor, W__Array
- w_Array = W_ArrayConstructor()
- put_property(global_object, 'Array', w_Array)
-
- # 15.4.4
- w_ArrayPrototype = W__Array()
-
- w_ArrayPrototype._prototype_ = W__Object._prototype_
- put_property(w_ArrayPrototype, '__proto__', w_ArrayPrototype._prototype_)
-
- # 15.4.3.1
- W__Array._prototype_ = w_ArrayPrototype
-
- # 15.4.4.1
- put_property(w_ArrayPrototype, 'constructor', w_Array)
-
- import js.builtins_array as array_builtins
- # 15.4.4.2
- put_native_function(w_ArrayPrototype, 'toString', array_builtins.to_string)
- # 15.4.4.5
- put_native_function(w_ArrayPrototype, 'join', array_builtins.join)
- # 15.4.4.6
- put_native_function(w_ArrayPrototype, 'pop', array_builtins.pop)
- # 15.4.4.7
- put_native_function(w_ArrayPrototype, 'push', array_builtins.push)
- # 15.4.4.8
- put_native_function(w_ArrayPrototype, 'reverse', array_builtins.reverse)
+ import js.builtins_array
+ js.builtins_array.setup(global_object)
#Math
from js.jsobj import W_Math
@@ -322,23 +190,8 @@
# 15.8.1.8
put_property(w_Math, 'SQRT2', _w(math_builtins.SQRT2), writable = False,
enumerable = False, configurable = False)
- ##Date
-
- # 15.9.5
- from js.jsobj import W_DateObject, W_DateConstructor
-
- w_DatePrototype = W_DateObject(w_NAN)
- w_DatePrototype._prototype_ = W__Object._prototype_
-
- W_DateObject._prototype_ = w_DatePrototype
-
- import js.builtins_date as date_builtins
- # 15.9.5.9
- put_native_function(w_DatePrototype, 'getTime', date_builtins.get_time)
-
- # 15.9.3
- w_Date = W_DateConstructor()
- put_property(global_object, 'Date', w_Date)
+ import js.builtins_date
+ js.builtins_date.setup(global_object)
# 15.1.1.1
put_property(global_object, 'NaN', w_NAN, writable = False, enumerable =
False, configurable = False)
@@ -382,4 +235,4 @@
put_native_function(global_object, 'pypy_repr',
global_builtins.pypy_repr)
put_native_function(global_object, 'inspect', global_builtins.inspect)
- put_intimate_function(global_object, 'load', global_builtins.js_load)
+ #put_intimate_function(global_object, 'load', global_builtins.js_load)
diff --git a/js/builtins_array.py b/js/builtins_array.py
--- a/js/builtins_array.py
+++ b/js/builtins_array.py
@@ -1,5 +1,35 @@
from js.jsobj import isnull_or_undefined, _w, w_Undefined
+def setup(global_object):
+ from js.builtins import put_property, put_native_function
+ from js.jsobj import W_ArrayConstructor, W__Array, W__Object
+ w_Array = W_ArrayConstructor()
+ put_property(global_object, 'Array', w_Array)
+
+ # 15.4.4
+ w_ArrayPrototype = W__Array()
+
+ w_ArrayPrototype._prototype_ = W__Object._prototype_
+ #put_property(w_ArrayPrototype, '__proto__', w_ArrayPrototype._prototype_,
writable = False, enumerable = False, configurable = False)
+
+ # 15.4.3.1
+ W__Array._prototype_ = w_ArrayPrototype
+ put_property(w_Array, 'prototype', w_ArrayPrototype, writable = False,
enumerable = False, configurable = False)
+
+ # 15.4.4.1
+ put_property(w_ArrayPrototype, 'constructor', w_Array)
+
+ # 15.4.4.2
+ put_native_function(w_ArrayPrototype, 'toString', to_string)
+ # 15.4.4.5
+ put_native_function(w_ArrayPrototype, 'join', join)
+ # 15.4.4.6
+ put_native_function(w_ArrayPrototype, 'pop', pop)
+ # 15.4.4.7
+ put_native_function(w_ArrayPrototype, 'push', push)
+ # 15.4.4.8
+ put_native_function(w_ArrayPrototype, 'reverse', reverse)
+
# 15.4.4.7
def push(this, args):
o = this.ToObject()
diff --git a/js/builtins_boolean.py b/js/builtins_boolean.py
--- a/js/builtins_boolean.py
+++ b/js/builtins_boolean.py
@@ -1,5 +1,40 @@
from js.jsobj import W_Boolean, W_BooleanObject
from js.execution import JsTypeError
+from js.jsobj import _w
+
+def setup(global_object):
+ from js.builtins import put_property, put_native_function
+
+ # 15.6.2
+ from js.jsobj import W_BooleanConstructor
+ w_Boolean = W_BooleanConstructor()
+ put_property(global_object, 'Boolean', w_Boolean)
+
+ # 15.6.3
+ put_property(w_Boolean, 'length', _w(1), writable = False, enumerable =
False, configurable = False)
+
+ # 15.6.4
+ w_BooleanPrototype = W_BooleanObject(False)
+
+ from js.jsobj import W__Object
+ w_BooleanPrototype._prototype_ = W__Object._prototype_
+ del(w_BooleanPrototype._properties_['__proto__'])
+ put_property(w_BooleanPrototype, '__proto__',
w_BooleanPrototype._prototype_, writable = False, enumerable = False,
configurable = False)
+
+ # 15.6.3.1
+ put_property(w_Boolean, 'prototype', w_BooleanPrototype, writable = False,
enumerable = False, configurable = False)
+
+ # 15.6.4.1
+ put_property(w_BooleanPrototype, 'constructor', w_Boolean)
+
+ # 15.6.4.2
+ put_native_function(w_BooleanPrototype, 'toString', to_string)
+
+ # 15.6.4.3
+ put_native_function(w_BooleanPrototype, 'valueOf', value_of)
+
+ # 15.6.3.1
+ W_BooleanObject._prototype_ = w_BooleanPrototype
# 15.6.4.2
def to_string(this, args):
@@ -15,6 +50,7 @@
else:
return 'false'
+# 15.6.4.3
def value_of(this, args):
if isinstance(this, W_Boolean):
b = this
diff --git a/js/builtins_date.py b/js/builtins_date.py
--- a/js/builtins_date.py
+++ b/js/builtins_date.py
@@ -1,3 +1,29 @@
+def setup(global_object):
+ from js.builtins import put_property, put_native_function
+ from js.builtins_number import w_NAN
+ from js.jsobj import W_DateObject, W_DateConstructor, W__Object
+ ##Date
+ # 15.9.5
+
+ w_DatePrototype = W_DateObject(w_NAN)
+ w_DatePrototype._prototype_ = W__Object._prototype_
+
+ W_DateObject._prototype_ = w_DatePrototype
+
+ # 15.9.5.9
+ put_native_function(w_DatePrototype, 'getTime', get_time)
+
+ # 15.9.5.26
+ put_native_function(w_DatePrototype, 'getTimezoneOffset',
get_timezone_offset)
+
+ # 15.9.3
+ w_Date = W_DateConstructor()
+ put_property(global_object, 'Date', w_Date)
+
# 15.9.5.9
def get_time(this, args):
return this
+
+# 15.9.5.26
+def get_timezone_offset(this, args):
+ return 0
diff --git a/js/builtins_function.py b/js/builtins_function.py
--- a/js/builtins_function.py
+++ b/js/builtins_function.py
@@ -1,45 +1,61 @@
from js.jsobj import isnull_or_undefined
+from js.execution import JsTypeError
+from js.jsobj import w_Undefined, _w, isnull_or_undefined
def to_string(this, args):
from js.jsobj import W_BasicFunction
if not isinstance(this, W_BasicFunction):
- from js.execution import JsTypeError
raise JsTypeError()
return this._to_string_()
def empty(this, args):
- from js.jsobj import w_Undefined
return w_Undefined
# 15.3.4.4 Function.prototype.call
-def call(this, args):
- raise NotImplementedError()
- #if len(args) >= 1:
- #if isnull_or_undefined(args[0]):
- #thisArg = this.ctx.get_global()
- #else:
- #thisArg = args[0]
- #callargs = args[1:]
- #else:
- #thisArg = this.ctx.get_global()
- #callargs = []
- #return this.Call(callargs, this = thisArg)
+def call(ctx):
+ func = ctx.this_binding()
+ args = ctx.argv()
+
+ if not func.is_callable():
+ raise JsTypeError()
+
+ this_arg = get_arg(args, 0)
+ arg_list = args[1:]
+
+ res = func.Call(args = arg_list, this = this_arg, calling_context = ctx)
+ return _w(res)
# 15.3.4.3 Function.prototype.apply (thisArg, argArray)
-def apply(this, args):
- raise NotImplementedError()
- #try:
- #if isnull_or_undefined(args[0]):
- #thisArg = this.ctx.get_global()
- #else:
- #thisArg = args[0].ToObject()
- #except IndexError:
- #thisArg = this.ctx.get_global()
+def apply(ctx):
+ func = ctx.this_binding()
+ args = ctx.argv()
- #try:
- #arrayArgs = args[1]
- #callargs = arrayArgs.tolist()
- #except IndexError:
- #callargs = []
- #return this.Call(callargs, this=thisArg)
+ this_arg = get_arg(args, 0)
+ arg_array = get_arg(args, 1)
+
+ if isnull_or_undefined(arg_array):
+ res = func.Call(args = [], this = this_arg, calling_context = ctx)
+ return _w(res)
+
+ from js.jsobj import W_BasicObject
+ if not isinstance(arg_array, W_BasicObject):
+ raise JsTypeError()
+
+ length = arg_array.get('length')
+ n = length.ToUInt32()
+ arg_list = []
+ index = 0
+ while index < n:
+ index_name = str(index)
+ next_arg = arg_array.get(index_name)
+ arg_list.append(next_arg)
+ index += 1
+
+ res = func.Call(args = arg_list, this = this_arg, calling_context = ctx)
+ return _w(res)
+
+def get_arg(args, index):
+ if len(args) > index:
+ return args[index]
+ return w_Undefined
diff --git a/js/builtins_number.py b/js/builtins_number.py
--- a/js/builtins_number.py
+++ b/js/builtins_number.py
@@ -1,4 +1,93 @@
+from pypy.rlib.rfloat import NAN, INFINITY
+from js.execution import JsRangeError, JsTypeError
+from js.jsobj import W_Number, W_NumericObject, _w
+
+def setup(global_object):
+ from js.builtins import put_property, put_native_function
+
+ # 15.7.2
+ from js.jsobj import W_NumberConstructor
+ w_Number = W_NumberConstructor()
+ put_property(global_object, 'Number', w_Number)
+
+ #put_property(w_Number, '__proto__', w_Number._prototype_, writable =
False, enumerable = False, configurable = False)
+
+ # 15.7.3
+ put_property(w_Number, 'length', _w(1), writable = False, enumerable =
False, configurable = False)
+
+ # 15.7.4
+ from js.jsobj import W__Object
+ w_NumberPrototype = W_NumericObject(0)
+ w_NumberPrototype._prototype_ = W__Object._prototype_
+ #put_property(w_NumberPrototype, '__proto__',
w_NumberPrototype._prototype_, writable = False, enumerable = False,
configurable = False)
+
+ # 15.7.4.1
+ put_property(w_NumberPrototype, 'constructor', w_Number)
+
+ # 15.7.4.2
+ put_native_function(w_NumberPrototype, 'toString', to_string)
+
+ # 15.7.4.4
+ put_native_function(w_NumberPrototype, 'valueOf', value_of)
+
+ # 15.7.3.1
+ put_property(w_Number, 'prototype', w_NumberPrototype, writable = False,
enumerable = False, configurable = False)
+ W_NumericObject._prototype_ = w_NumberPrototype
+
+ # 15.7.3.2
+ put_property(w_Number, 'MAX_VALUE', w_MAX_VALUE, writable = False,
configurable = False, enumerable = False)
+
+ # 15.7.3.3
+ put_property(w_Number, 'MIN_VALUE', w_MIN_VALUE, writable = False,
configurable = False, enumerable = False)
+
+ # 15.7.3.4
+ put_property(w_Number, 'NaN', w_NAN, writable = False, configurable =
False, enumerable = False)
+
+ # 15.7.3.5
+ put_property(w_Number, 'POSITIVE_INFINITY', w_POSITIVE_INFINITY, writable
= False, configurable = False, enumerable = False)
+
+ # 15.7.3.6
+ put_property(w_Number, 'NEGATIVE_INFINITY', w_NEGATIVE_INFINITY, writable
= False, configurable = False, enumerable = False)
+
+# 15.7.3.2
+w_MAX_VALUE = _w(1.7976931348623157e308)
+
+# 15.7.3.3
+w_MIN_VALUE = _w(5e-320)
+
+# 15.7.3.4
+w_NAN = _w(NAN)
+
+# 15.7.3.5
+w_POSITIVE_INFINITY = _w(INFINITY)
+
+# 15.7.3.6
+w_NEGATIVE_INFINITY = _w(-INFINITY)
+
# 15.7.4.2
def to_string(this, args):
+ if len(args) > 0:
+ radix = args[0].ToInteger()
+ if radix < 2 or radix > 36:
+ raise JsRangeError
+
+ if isinstance(this, W_Number):
+ num = this
+ elif isinstance(this, W_NumericObject):
+ num = this.PrimitiveValue()
+ else:
+ raise JsTypeError()
+
# TODO radix, see 15.7.4.2
- return this.to_string()
+ return num.to_string()
+
+# 15.7.4.4
+def value_of(this, args):
+ if isinstance(this, W_Number):
+ num = this
+ elif isinstance(this, W_NumericObject):
+ num = this.PrimitiveValue()
+ else:
+ raise JsTypeError()
+
+ return num.ToNumber()
diff --git a/js/builtins_string.py b/js/builtins_string.py
--- a/js/builtins_string.py
+++ b/js/builtins_string.py
@@ -1,36 +1,134 @@
-from js.jsobj import _w, w_Undefined, W_String
+from js.jsobj import _w, w_Undefined, W_String, W_StringObject
from pypy.rlib.rfloat import NAN, INFINITY, isnan
-from js.execution import ThrowException
+from js.execution import ThrowException, JsTypeError
+
+def setup(global_object):
+ from js.builtins import put_native_function, put_property
+
+ #String
+ # 15.5.1
+ from js.jsobj import W_StringConstructor
+ w_String = W_StringConstructor()
+ #put_property(w_String, '__proto__', w_String._prototype_, writable =
False, enumerable = False, configurable = False)
+ put_property(w_String, 'length', _w(1), writable = False, enumerable =
False, configurable = False)
+
+ put_property(global_object, 'String', w_String)
+
+
+ # 15.5.4
+ from js.jsobj import W_StringObject, W__Object
+ w_StringPrototype = W_StringObject('')
+ w_StringPrototype._prototype_ = W__Object._prototype_
+
+ # 15.5.3.1
+ W_StringObject._prototype_ = w_StringPrototype
+ put_property(w_String, 'prototype', w_StringPrototype, writable = False,
enumerable = False, configurable = False)
+
+ # 15.5.3.2
+ put_native_function(w_String, 'fromCharCode', from_char_code, params =
['char1'])
+
+ # 15.5.4.1
+ put_property(w_StringPrototype, 'constructor', w_String)
+
+ # 15.5.4.2
+ put_native_function(w_StringPrototype, 'toString', to_string)
+
+ # 15.5.4.3
+ put_native_function(w_StringPrototype, 'valueOf', value_of)
+
+ # 15.5.4.4
+ put_native_function(w_StringPrototype, 'charAt', char_at, params = ['pos'])
+
+ # 15.5.4.5
+ put_native_function(w_StringPrototype, 'charCodeAt', char_code_at, params
= ['pos'])
+
+ # 15.5.4.6
+ put_native_function(w_StringPrototype, 'concat', concat, params =
['string1'])
+
+ # 15.5.4.7
+ put_native_function(w_StringPrototype, 'indexOf', index_of, params =
['searchstring'])
+
+ # 15.5.4.8
+ put_native_function(w_StringPrototype, 'lastIndexOf', last_index_of,
params = ['searchstring'])
+
+ # 15.5.4.14
+ put_native_function(w_StringPrototype, 'split', split, params =
['separator', 'limit'])
+
+ # 15.5.4.15
+ put_native_function(w_StringPrototype, 'substring', substring, params =
['start', 'end'])
+
+ # 15.5.4.16
+ put_native_function(w_StringPrototype, 'toLowerCase', to_lower_case)
+
+ # 15.5.4.18
+ put_native_function(w_StringPrototype, 'toUpperCase', to_upper_case)
# 15.5.3.2
def from_char_code(this, args):
temp = []
for arg in args:
- i = arg.ToInt32() % 65536 # XXX should be uint16
- temp.append(chr(i))
+ i = arg.ToInt16()
+ temp.append(unichr(i))
return ''.join(temp)
+# 15.5.4.2
+def to_string(this, args):
+ if isinstance(this, W_String):
+ s = this
+ elif isinstance(this, W_StringObject):
+ s = this.PrimitiveValue()
+ else:
+ raise JsTypeError()
+
+ assert isinstance(s, W_String)
+ return s.to_string()
+
+# 15.5.4.3
+def value_of(this, args):
+ if isinstance(this, W_String):
+ s = this
+ elif isinstance(this, W_StringObject):
+ s = this.PrimitiveValue()
+ else:
+ raise JsTypeError()
+
+ assert isinstance(s, W_String)
+ return s
+
# 15.5.4.4
def char_at(this, args):
+ pos = w_Undefined
+
+ if len(args) > 0:
+ pos = args[0]
+
+ position = pos.ToInt32()
+
+ this.check_object_coercible()
string = this.to_string()
- if len(args)>=1:
- pos = args[0].ToInt32()
- if (not pos >=0) or (pos > len(string) - 1):
- return ''
- else:
+
+ size = len(string)
+ if position < 0 or position >= size:
return ''
- return string[pos]
+
+ return string[position]
#15.5.4.5
def char_code_at(this, args):
+ pos = w_Undefined
+
+ if len(args) > 0:
+ pos = args[0]
+
+ this.check_object_coercible()
string = this.to_string()
- if len(args)>=1:
- pos = args[0].ToInt32()
- if pos < 0 or pos > len(string) - 1:
- return NAN
- else:
+ position = pos.ToInt32()
+ size = len(string)
+
+ if position < 0 or position >= size:
return NAN
- char = string[pos]
+
+ char = string[position]
return ord(char)
#15.5.4.6
@@ -58,49 +156,154 @@
# 15.5.4.8
def last_index_of(this, args):
- string = this.to_string()
- if len(args) < 1:
+ search_element = w_Undefined
+ from_index = w_Undefined
+
+ if len(args) > 0:
+ search_element = args[0]
+ if len(args) > 1:
+ from_index = args[1]
+
+
+ obj = this.ToObject()
+ len_value = obj.get('length')
+ length = len_value.ToUInt32()
+
+ import pdb; pdb.set_trace()
+ if length == 0:
return -1
- substr = args[0].to_string()
- if len(args) < 2:
- pos = INFINITY
+
+ # 5
+ if from_index is not w_Undefined:
+ n = from_index.ToInteger()
else:
- val = args[1].ToNumber()
- if isnan(val):
- pos = INFINITY
- else:
- pos = args[1].ToInteger()
- size = len(string)
- pos = int(min(max(pos, 0), size))
- subsize = len(substr)
- endpos = pos+subsize
- assert endpos >= 0
- return string.rfind(substr, 0, endpos)
+ n = length - 1
+
+ # 6
+ if n >= 0:
+ k = min(n, length-1)
+ else:
+ k = length - abs(n)
+
+ while k >= 0:
+ k_str = str(k)
+ k_present = obj.has_property(k_str)
+ if k_present:
+ element_k = obj.get(k_str)
+ from js.baseop import StrictEC
+ same = StrictEC(search_element, element_k)
+ if same:
+ return k
+ k -= 1
+
+ return -1
# 15.5.4.14
def split(this, args):
+ from js.jsobj import W__Array
+ this.check_object_coercible()
+
+ separator = w_Undefined
+ limit = w_Undefined
+
+ if len(args) > 0:
+ separator = args[0]
+ if len(args) > 1:
+ limit = args[1]
+
string = this.to_string()
+ a = W__Array()
+ length_a = 0
+ length_s = len(string)
+ p = 0
+ r = separator.to_string()
- if len(args) < 1 or args[0] is w_Undefined:
- return _create_array([_w(string)])
+ if limit is w_Undefined:
+ import math
+ lim = int(math.pow(2,32) - 1)
else:
- separator = args[0].to_string()
+ lim = limit.ToUInt32()
- if len(args) >= 2:
- limit = args[1].ToUInt32()
- raise ThrowException(W_String("limit not implemented"))
- # array = string.split(separator, limit)
- else:
- array = string.split(separator)
+ if lim == 0:
+ return a
- w_array = _create_array()
- i = 0
- while i < len(array):
- w_str = W_String(array[i])
- w_array.Put(str(i), w_str)
- i += 1
+ from js.jsobj import put_property
+ # 10
+ if separator is w_Undefined:
+ put_property(a, '0', _w(string), writable = True, enumerable = True,
configurable = True)
+ return a
- return w_array
+ # 11
+ if length_s == 0:
+ z = split_match(string, 0, r)
+ if not z.is_failure():
+ return a
+ put_property(a, '0', _w(string), writable = True, enumerable = True,
configurable = True)
+ return a
+
+ # 12
+ q = p
+
+ # 13
+ while q != length_s:
+ z = split_match(string, q, r)
+ if z.is_failure():
+ q = q + 1
+ else:
+ # ii
+ e = z.end_index
+ cap = z.captures
+ # ii
+ if e == p:
+ q = q + 1
+ # iii
+ else:
+ t = string[p:q]
+ put_property(a, str(length_a), _w(t), writable = True,
enumerable = True, configurable = True)
+ length_a += 1
+ if length_a == lim:
+ return a
+ p = e
+ i = 0
+ # 7
+ while(i != len(cap)):
+ i = i + 1
+ put_property(a, str(length_a), _w(cap[i]), writable =
True, enumerable = True, configurable = True)
+ length_a += 1
+ if length_a == lim:
+ return a
+ # 8
+ q = p
+ # 14
+ t = string[p:length_s]
+ put_property(a, str(length_a), _w(t), writable = True, enumerable = True,
configurable = True)
+ return a
+
+def split_match(s, q, r):
+ assert isinstance(r, str)
+ len_r = len(r)
+ len_s = len(s)
+ if q + len_r > len_s :
+ return MatchResultFailure()
+
+ for i in xrange(len_r):
+ if s[q+i] != r[i]:
+ return MatchResultFailure()
+ cap = []
+ return MatchResultState(q + len_r, cap)
+
+class MatchResult(object):
+ def is_failure(self):
+ return False
+
+class MatchResultFailure(MatchResult):
+ def is_failure(self):
+ return True
+
+class MatchResultState(MatchResult):
+ def __init__(self, end_index, captures):
+ self.end_index = end_index
+ self.captures = captures
# 15.5.4.15
def substring(this, args):
@@ -135,8 +338,7 @@
array = W__Array()
i = 0
while i < len(elements):
- array.Put(str(i), elements[i])
+ array.put(str(i), elements[i])
i += 1
return array
-
diff --git a/js/functions.py b/js/functions.py
--- a/js/functions.py
+++ b/js/functions.py
@@ -1,4 +1,5 @@
from js.opcodes import BaseJump
+from js.jsobj import _w
class JsBaseFunction(object):
eval_code = False
@@ -57,7 +58,8 @@
def run(self, ctx):
args = ctx.argv()
this = ctx.this_binding()
- return self._function_(this, args)
+ res = self._function_(this, args)
+ return _w(res)
def to_string(self):
name = self.name()
diff --git a/js/interpreter.py b/js/interpreter.py
--- a/js/interpreter.py
+++ b/js/interpreter.py
@@ -14,21 +14,33 @@
f.close()
return ast
-def add_interpreter_builtins(global_object):
- from js.builtins import new_native_function, native_function,
put_native_function
- def trace(this, args):
- import pdb; pdb.set_trace()
-
- put_native_function(global_object, 'trace', trace)
-
class Interpreter(object):
"""Creates a js interpreter"""
def __init__(self):
- from js.jsobj import W_BasicObject
- self.global_object = W_BasicObject()
+ from js.jsobj import W_GlobalObject
+ self.global_object = W_GlobalObject()
from js.builtins import setup_builtins
setup_builtins(self.global_object)
- add_interpreter_builtins(self.global_object)
+ self.setup_interpreter_builtins()
+
+ def setup_interpreter_builtins(self):
+ global_object = self.global_object
+ from js.builtins import put_native_function
+ def js_trace(this, args):
+ import pdb; pdb.set_trace()
+ put_native_function(global_object, 'trace', js_trace)
+
+ interp = self
+ def js_load(this, args):
+ filename = args[0].to_string()
+ interp.js_load(filename)
+
+ put_native_function(global_object, 'load', js_load)
+
+
+ def js_load(self, filename):
+ ast = load_file(filename)
+ return self.run_ast(ast)
def run_ast(self, ast):
symbol_map = ast.symbol_map
diff --git a/js/js_interactive.py b/js/js_interactive.py
--- a/js/js_interactive.py
+++ b/js/js_interactive.py
@@ -72,11 +72,7 @@
from js.execution import JsException
try:
res = self.interpreter.run_ast(ast)
- #if DEBUG:
- #print self.interpreter._code
try:
- #if DEBUG:
- #print repr(res)
print res.to_string()
except JsException, exc:
self.showtraceback(exc)
@@ -105,7 +101,7 @@
return True # True means that more input is needed
else:
# Case 1
- self.showsyntaxerror(filename, exc)
+ self.showsyntaxerror(filename, exc, source)
return False
# Case 3
@@ -116,12 +112,16 @@
# XXX format exceptions nicier
print exc.value.to_string()
- def showsyntaxerror(self, filename, exc):
+ def showsyntaxerror(self, filename, exc, source):
# XXX format syntax errors nicier
- print ' '*4 + \
- ' '*exc.source_pos.columnno + \
- '^'
- print 'Syntax Error:', exc.errorinformation.failure_reasons
+ marker_indent = ' ' * exc.source_pos.columnno
+ error = exc.errorinformation.failure_reasons
+ error_lineno = exc.source_pos.lineno
+ error_line = (source.splitlines())[error_lineno]
+ print 'Syntax Error in: %s:%d' % (filename, error_lineno)
+ print '%s' % (error_line)
+ print '%s^' %(marker_indent)
+ print 'Error: %s' %(error)
def interact(self, banner=None):
if banner is None:
diff --git a/js/jsobj.py b/js/jsobj.py
--- a/js/jsobj.py
+++ b/js/jsobj.py
@@ -1,7 +1,7 @@
# encoding: utf-8
from pypy.rpython.lltypesystem import rffi
from pypy.rlib.rarithmetic import r_uint, intmask, ovfcheck_float_to_int
-from pypy.rlib.rfloat import isnan, isinf, NAN, formatd
+from pypy.rlib.rfloat import isnan, isinf, NAN, formatd, INFINITY
from js.execution import JsTypeError, JsRangeError, ReturnException
from pypy.rlib.jit import hint
@@ -43,17 +43,50 @@
return 0.0
def ToInteger(self):
- return int(self.ToNumber())
+ num = self.ToNumber()
+ if num == NAN:
+ return 0
+ if num == INFINITY or num == -INFINITY:
+ return num
+
+ return int(num)
def ToInt32(self):
- return r_int32(self.ToInteger())
+ num = self.ToInteger()
+ if num == NAN or num == INFINITY or num == -INFINITY:
+ return 0
+
+ return r_int32(num)
def ToUInt32(self):
- return r_uint32(self.ToInteger())
+ num = self.ToInteger()
+ if num == NAN or num == INFINITY or num == -INFINITY:
+ return 0
+ return r_uint32(num)
+
+ def ToInt16(self):
+ def sign(i):
+ if i > 0:
+ return 1
+ if i < 0:
+ return -1
+ return 0
+
+ num = self.ToInteger()
+ if num == NAN or num == INFINITY or num == -INFINITY:
+ return 0
+
+ import math
+ pos_int = sign(num) * math.floor(abs(num))
+ int_16_bit = pos_int % math.pow(2, 16)
+ return int(int_16_bit)
def is_callable(self):
return False
+ def check_object_coercible(self):
+ pass
+
class W_Primitive(W_Root):
pass
@@ -68,6 +101,9 @@
def to_string(self):
return self._type_
+ def check_object_coercible(self):
+ raise JsTypeError()
+
class W_Null(W_Primitive):
_type_ = 'null'
@@ -77,6 +113,9 @@
def to_string(self):
return self._type_
+ def check_object_coercible(self):
+ raise JsTypeError()
+
w_Undefined = W_Undefined()
w_Null = W_Null()
@@ -237,13 +276,16 @@
#_immutable_fields_ = ['_class_', '_prototype_', '_primitive_value_']
_type_ = 'object'
_class_ = 'Object'
- _prototype_ = w_Undefined
+ _prototype_ = w_Null
_extensible_ = True
def __init__(self):
W_Root.__init__(self)
self._properties_ = {}
+ desc = PropertyDescriptor(value = self._prototype_, writable = False,
enumerable = False, configurable = False)
+ W_BasicObject.define_own_property(self, '__proto__', desc)
+
def __repr__(self):
return "%s: %s" % (object.__repr__(self), self.klass())
@@ -302,7 +344,7 @@
return prop
proto = self.prototype()
- if proto is w_Undefined:
+ if proto is w_Null:
return w_Undefined
return proto.get_property(p)
@@ -312,15 +354,17 @@
if self.can_put(p) is False:
if throw is True:
raise JsTypeError()
+ else:
+ return
own_desc = self.get_own_property(p)
- if is_data_descriptor(own_desc):
+ if is_data_descriptor(own_desc) is True:
value_desc = PropertyDescriptor(value = v)
self.define_own_property(p, value_desc, throw)
return
desc = self.get_property(p)
- if is_accessor_descriptor(desc):
+ if is_accessor_descriptor(desc) is True:
setter = desc.setter
assert setter is not None
# setter.call(this = self, v)
@@ -333,7 +377,7 @@
def can_put(self, p):
desc = self.get_own_property(p)
if desc is not w_Undefined:
- if is_accessor_descriptor(desc):
+ if is_accessor_descriptor(desc) is True:
if desc.setter is w_Undefined:
return False
else:
@@ -349,7 +393,7 @@
if inherited is w_Undefined:
return self.extensible()
- if is_accessor_descriptor(inherited):
+ if is_accessor_descriptor(inherited) is True:
if inherited.setter is w_Undefined:
return False
else:
@@ -395,7 +439,6 @@
if res is not None:
return res
- import pdb; pdb.set_trace()
raise JsTypeError()
def _default_value_string_(self):
@@ -559,6 +602,9 @@
class W__Object(W_BasicObject):
pass
+class W_GlobalObject(W__Object):
+ _class_ = 'global'
+
class W_ObjectConstructor(W_BasicObject):
def __init__(self):
W_BasicObject.__init__(self)
@@ -584,9 +630,6 @@
_type_ = 'function'
#_immutable_fields_ = ['_context_']
- def __init__(self):
- W_BasicObject.__init__(self)
-
def Call(self, args = [], this = None, calling_context = None):
raise NotImplementedError("abstract")
@@ -624,7 +667,7 @@
if arg_count == 0:
body = ''
elif arg_count == 1:
- body = args[0]
+ body = args[0].to_string()
else:
first_arg = args[0]
p = first_arg.to_string()
@@ -633,9 +676,8 @@
next_arg = args[k-1]
p = "%s, %s" % (p, next_arg.to_string())
k = k + 1
- body = args[k-1]
+ body = args[k-1].to_string()
- body = body.to_string()
src = "function (%s) { %s }" % (p, body)
from js.astbuilder import parse_to_ast
@@ -734,14 +776,18 @@
# 15.
put_property(self, 'length', _w(_len), writable = False, enumerable =
False, configurable = False)
# 16.
- proto = W__Object()
+ proto_obj = W__Object()
# 17.
- put_property(proto, 'constructor', self, writable = True, enumerable =
False, configurable = True)
+ put_property(proto_obj, 'constructor', self, writable = True,
enumerable = False, configurable = True)
# 18.
- put_property(self, 'prototype', self, writable = True, enumerable =
False, configurable = False)
+ put_property(self, 'prototype', proto_obj, writable = True, enumerable
= False, configurable = False)
if strict is True:
raise NotImplementedError()
+ else:
+ put_property(self, 'caller', w_Null, writable = True, enumerable =
False, configurable = False)
+ put_property(self, 'arguments', w_Null, writable = True,
enumerable = False, configurable = False)
+
def _to_string(self):
return self._function_.to_string()
@@ -778,9 +824,6 @@
raise JsTypeError()
return v
- def to_string(self):
- return self._function_.to_string()
-
def scope(self):
return self._scope_
@@ -856,7 +899,7 @@
code = '%s = %s;' % (name, param)
pass
-class W_ArrayConstructor(W_BasicObject):
+class W_ArrayConstructor(W_BasicFunction):
def is_callable(self):
return True
@@ -866,7 +909,7 @@
else:
array = W__Array()
for index, obj in enumerate(args):
- array.Put(str(index), obj)
+ array.put(str(index), obj)
return array
def Construct(self, args=[]):
@@ -885,7 +928,7 @@
def define_own_property(self, p, desc, throw = False):
def reject():
if throw:
- raise JsTypeError(self.__class__)
+ raise JsTypeError()
else:
return False
@@ -1053,7 +1096,7 @@
_type_ = 'string'
def __init__(self, strval):
- assert isinstance(strval, str)
+ assert isinstance(strval, str) or isinstance(strval, unicode)
W_Primitive.__init__(self)
self._strval_ = strval
@@ -1253,7 +1296,7 @@
return W_IntNumber(value)
elif isinstance(value, float):
return W_FloatNumber(value)
- elif isinstance(value, str):
+ elif isinstance(value, str) or isinstance(value, unicode):
return W_String(value)
elif value is None:
return w_Null
diff --git a/js/opcodes.py b/js/opcodes.py
--- a/js/opcodes.py
+++ b/js/opcodes.py
@@ -352,11 +352,11 @@
class IS(BaseBinaryComparison):
def decision(self, ctx, op1, op2):
- return newbool(StrictEC(ctx, op1, op2))
+ return newbool(StrictEC(op1, op2))
class ISNOT(BaseBinaryComparison):
def decision(self, ctx, op1, op2):
- return newbool(not StrictEC(ctx, op1, op2))
+ return newbool(not StrictEC(op1, op2))
class STORE_MEMBER(Opcode):
_stack_change = 0
@@ -520,10 +520,12 @@
# TODO
from js.jsobj import W_BasicFunction, W_BasicObject
if not (isinstance(r1, W_BasicFunction) or isinstance(r1, W_BasicObject)):
+ #import pdb; pdb.set_trace()
raise ThrowException(W_String("%s is not a callable
(%s)"%(r1.to_string(), name.to_string())))
#jit.promote(r1)
#try:
- res = r1.Call(args = args.to_list(), this = this, calling_context = ctx)
+ argv = args.to_list()
+ res = r1.Call(args = argv, 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
@@ -534,7 +536,8 @@
r1 = ctx.stack_pop()
args = ctx.stack_pop()
this = ctx.this_binding()
- ctx.stack_append(common_call(ctx, r1, args, this, r1))
+ res = common_call(ctx, r1, args, this, r1)
+ ctx.stack_append(res)
class CALL_METHOD(Opcode):
_stack_change = -2
@@ -544,7 +547,8 @@
args = ctx.stack_pop()
name = method.to_string()
r1 = what.get(name)
- ctx.stack_append(common_call(ctx, r1, args, what, method))
+ res = common_call(ctx, r1, args, what, method)
+ ctx.stack_append(res)
class DUP(Opcode):
def eval(self, ctx):
@@ -596,6 +600,7 @@
def commonnew(ctx, obj, args):
from js.jsobj import W_BasicObject
+
if not isinstance(obj, W_BasicObject):
raise JsTypeError('it is not a constructor')
res = obj.Construct(args=args)
@@ -604,9 +609,10 @@
class NEW(Opcode):
_stack_change = 0
def eval(self, ctx):
+ from js.jsobj import W_List
+
y = ctx.stack_pop()
x = ctx.stack_pop()
- from js.jsobj import W_List
assert isinstance(y, W_List)
args = y.to_list()
res = commonnew(ctx, x, args)
diff --git a/js/test/ecma/String/15.5.4.js b/js/test/ecma/String/15.5.4.js
--- a/js/test/ecma/String/15.5.4.js
+++ b/js/test/ecma/String/15.5.4.js
@@ -60,24 +60,24 @@
delete String.prototype.getClass;
-new TestCase( SECTION,
- "typeof String.prototype",
- "object",
+new TestCase( SECTION,
+ "typeof String.prototype",
+ "object",
typeof String.prototype );
-new TestCase( SECTION,
- "String.prototype.valueOf()",
- "",
+new TestCase( SECTION,
+ "String.prototype.valueOf()",
+ "",
String.prototype.valueOf() );
-new TestCase( SECTION,
- "String.prototype +''",
- "",
+new TestCase( SECTION,
+ "String.prototype +''",
+ "",
String.prototype + '' );
-new TestCase( SECTION,
- "String.prototype.length",
- 0,
+new TestCase( SECTION,
+ "String.prototype.length",
+ 0,
String.prototype.length );
var prop;
diff --git a/js/test/ecma/conftest.py b/js/test/ecma/conftest.py
--- a/js/test/ecma/conftest.py
+++ b/js/test/ecma/conftest.py
@@ -48,7 +48,7 @@
try:
return js_eval(ctx)
except JsException:
- return "error"
+ return _w("error")
global_object = interp.global_object
del(global_object._properties_['eval'])
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit