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

Reply via email to