[pypy-commit] lang-js default: wip

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


Author: Stephan <stephan at stzal.com>
Branch: 
Changeset: r189:b8877a8fec7b
Date: 2012-05-21 10:30 +0200
http://bitbucket.org/pypy/lang-js/changeset/b8877a8fec7b/

Log:	wip

diff too long, truncating to 2000 out of 2074 lines

diff --git a/js/astbuilder.py b/js/astbuilder.py
--- a/js/astbuilder.py
+++ b/js/astbuilder.py
@@ -26,22 +26,19 @@
     def add_variable(self, identifyer):
         idx = self.add_symbol(identifyer)
 
-        if identifyer not in self.variables:
-            self.variables.append(identifyer)
+        self.variables.append(identifyer)
         return idx
 
     def add_function(self, identifyer):
         idx = self.add_symbol(identifyer)
 
-        if identifyer not in self.functions:
-            self.functions.append(identifyer)
+        self.functions.append(identifyer)
         return idx
 
     def add_parameter(self, identifyer):
         idx = self.add_symbol(identifyer)
 
-        if identifyer not in self.parameters:
-            self.parameters.append(identifyer)
+        self.parameters.append(identifyer)
         return idx
 
     def get_index(self, identifyer):
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
@@ -30,7 +30,7 @@
 load('looping.js');
 load('richards.js');
 load('deltablue.js');
-//load('crypto.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,22 +9,8 @@
 from pypy.rlib.objectmodel import specialize
 from pypy.rlib.listsort import TimSort
 from pypy.rlib.rarithmetic import r_uint
-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):
-        TimSort.__init__(self, list, listlength)
-        self.compare_fn = compare_fn
-
-    def lt(self, a, b):
-        if self.compare_fn:
-            result = self.compare_fn.Call([a, b]).ToInt32()
-            return result == -1
-        return a.ToString() < b.ToString()
 
 def new_native_function(function, name = None, params = []):
     from js.functions import JsNativeFunction
@@ -40,13 +26,13 @@
     put_property(obj, name, jsfunc, writable = writable, configurable = configurable, enumerable = enumerable)
 
 # 15
-def put_intimate_function(obj, name, func, writable = True, configurable = True, enumerable = False):
+def put_intimate_function(obj, name, func, writable = True, configurable = True, enumerable = False, params = []):
     from js.functions import JsIntimateFunction
     from js.jsobj import W__Function
 
     scope = None
     jsfunc = JsIntimateFunction(func, name)
-    w_func = W__Function(jsfunc)
+    w_func = W__Function(jsfunc, formal_parameter_list = params)
     put_property(obj, name, w_func, writable = writable, configurable = configurable, enumerable = enumerable)
 
 # 15
@@ -90,9 +76,9 @@
 
     # 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_)
+    #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))
 
@@ -193,46 +179,10 @@
     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)
+    import js.builtins_global
+    js.builtins_global.setup(global_object)
 
-    # 15.1.1.2
-    put_property(global_object, 'Infinity', w_POSITIVE_INFINITY, writable = False, enumerable = False, configurable = False)
-
-    # 15.1.1.3
-    put_property(global_object, 'undefined', w_Undefined, writable = False, enumerable = False, configurable = False)
-
-    import js.builtins_global as global_builtins
-
-    # 15.1.2.1
-    #put_property(global_object, 'eval', W__Eval())
-    put_intimate_function(global_object, 'eval', global_builtins.js_eval)
-
-    # 15.1.2.2
-    put_native_function(global_object, 'parseInt', global_builtins.parse_int)
-
-    # 15.1.2.3
-    put_native_function(global_object, 'parseFloat', global_builtins.parse_float)
-
-    # 15.1.2.4
-    put_native_function(global_object, 'isNaN', global_builtins.is_nan)
-
-    # 15.1.2.5
-    put_native_function(global_object, 'isFinite', global_builtins.is_finite)
-
-    put_native_function(global_object, 'alert', global_builtins.alert)
-
-    put_native_function(global_object, 'print', global_builtins.printjs)
-
-    put_native_function(global_object, 'unescape', global_builtins.unescape)
-
-    put_native_function(global_object, 'version', global_builtins.version)
-
-    #put_property(global_object, 'this', global_object)
-
-    ## debugging
-    if not we_are_translated():
-        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)
+def get_arg(args, index, default = w_Undefined):
+    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,4 +1,5 @@
 from js.jsobj import isnull_or_undefined, _w, w_Undefined
+from js.builtins import get_arg
 
 def setup(global_object):
     from js.builtins import put_property, put_native_function
@@ -10,7 +11,6 @@
     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
@@ -22,13 +22,15 @@
     # 15.4.4.2
     put_native_function(w_ArrayPrototype, 'toString', to_string)
     # 15.4.4.5
-    put_native_function(w_ArrayPrototype, 'join', join)
+    put_native_function(w_ArrayPrototype, 'join', join, params = ['separator'])
     # 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.11
+    put_native_function(w_ArrayPrototype, 'sort', sort)
 
 # 15.4.4.7
 def push(this, args):
@@ -56,22 +58,25 @@
 
 # 15.4.4.5
 def join(this, args):
+    separator = get_arg(args, 0)
+
     o = this.ToObject()
-    lenVal = o.get('length')
-    length = lenVal.ToUInt32()
+    len_val = o.get('length')
+    length = len_val.ToUInt32()
 
-    sep = ','
-    if (len(args) > 0):
-        sep = args[0].to_string()
+    if separator is w_Undefined:
+        sep = ','
+    else:
+        sep = separator.to_string()
 
     if length == 0:
         return ''
 
     element0 = o.get('0')
     if isnull_or_undefined(element0):
-        return ''
-
-    r = element0.to_string()
+        r = ''
+    else:
+        r = element0.to_string()
 
     k = 1
 
@@ -79,11 +84,11 @@
         s = r + sep
         element = o.get(str(k))
         if isnull_or_undefined(element):
-            n = ''
+            _next = ''
         else:
-            n = element.to_string()
-        r = s + n
-        k = k + 1
+            _next = element.to_string()
+        r = s + _next
+        k += 1
 
     return r
 
@@ -107,7 +112,7 @@
 # 15.4.4.8
 def reverse(this, args):
     o = this.ToObject()
-    length = o.ret('length').ToUInt32()
+    length = o.get('length').ToUInt32()
 
     import math
     middle = math.floor(length/2)
@@ -115,25 +120,91 @@
     lower = 0
     while lower != middle:
         upper = length - lower - 1
-        lowerP = str(lower)
-        upperP = str(upper)
-        lowerValue = o.ret(lowerP)
-        upperValue = o.ret(upperP)
-        lowerExists = o.HasProperty(lowerP)
-        upperExists = o.HasProperty(upperP)
+        lower_p = str(lower)
+        upper_p = str(upper)
+        lower_value = o.get(lower_p)
+        upper_value = o.get(upper_p)
+        lower_exists = o.has_property(lower_p)
+        upper_exists = o.has_property(upper_p)
 
-        if lowerExists is True and upperExists is True:
-            o.put(lowerP, upperValue)
-            o.put(upperP, lowerValue)
-        elif lowerExists is False and upperExists is True:
-            o.put(lowerP, upperValue)
-            o.delete(upperP)
-        elif lowerExists is True and upperExists is False:
-            o.delete(lowerP)
-            o.put(upperP, lowerValue)
+        if lower_exists is True and upper_exists is True:
+            o.put(lower_p, upper_value)
+            o.put(upper_p, lower_value)
+        elif lower_exists is False and upper_exists is True:
+            o.put(lower_p, upper_value)
+            o.delete(upper_p)
+        elif lower_exists is True and upper_exists is False:
+            o.delete(lower_p)
+            o.put(upper_p, lower_value)
 
         lower = lower + 1
 
+# 15.4.4.11
+def sort(this, args):
+    obj = this
+    length = this.get('length').ToUInt32()
+
+    comparefn = get_arg(args, 0)
+
+    # TODO check if implementation defined
+
+    # sorts need to be in-place, lets do some very non-fancy bubble sort for starters
+    while True:
+        swapped = False
+        for i in xrange(1, length):
+            x = str(i - 1)
+            y = str(i)
+            comp = sort_compare(obj, x, y, comparefn)
+            if  comp == 1:
+                tmp_x = obj.get(x)
+                tmp_y = obj.get(y)
+                obj.put(x, tmp_y)
+                obj.put(y, tmp_x)
+                swapped = True
+        if not swapped:
+            break
+
+    return obj
+
+def sort_compare(obj, j, k, comparefn = w_Undefined):
+    j_string = j
+    k_string = k
+    has_j = obj.has_property(j)
+    has_k = obj.has_property(k)
+
+    if has_j is False and has_k is False:
+        return 0
+    if has_j is False:
+        return 1
+    if has_k is False:
+        return -1
+
+    x = obj.get(j_string)
+    y = obj.get(k_string)
+
+    if x is w_Undefined and y is w_Undefined:
+        return 0
+    if x is w_Undefined:
+        return 1
+    if y is w_Undefined:
+        return -1
+
+    if comparefn is not w_Undefined:
+        if not comparefn.is_callable():
+            raise JsTypeError()
+
+        res = comparefn.Call(args = [x, y], this = w_Undefined)
+        return res.ToInteger()
+
+    x_string = x.to_string()
+    y_string = y.to_string()
+    if x_string < y_string:
+        return -1
+    if x_string > y_string:
+        return 1
+    return 0
+
+
 #class W_ArraySort(W_NewBuiltin):
     #length = 1
     ##XXX: further optimize this function
diff --git a/js/builtins_boolean.py b/js/builtins_boolean.py
--- a/js/builtins_boolean.py
+++ b/js/builtins_boolean.py
@@ -18,8 +18,8 @@
 
     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)
+    #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)
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,7 @@
 from js.jsobj import isnull_or_undefined
 from js.execution import JsTypeError
 from js.jsobj import w_Undefined, _w, isnull_or_undefined
+from js.builtins import get_arg
 
 def to_string(this, args):
     from js.jsobj import W_BasicFunction
@@ -54,8 +55,3 @@
 
     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_global.py b/js/builtins_global.py
--- a/js/builtins_global.py
+++ b/js/builtins_global.py
@@ -1,6 +1,52 @@
 from pypy.rlib.rfloat import NAN, INFINITY, isnan, isinf
 from js.jsobj import W_String
 from js.execution import JsTypeError
+from js.builtins import get_arg
+
+def setup(global_object):
+    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
+
+    # 15.1.1.1
+    put_property(global_object, 'NaN', w_NAN, writable = False, enumerable = False, configurable = False)
+
+    # 15.1.1.2
+    put_property(global_object, 'Infinity', w_POSITIVE_INFINITY, writable = False, enumerable = False, configurable = False)
+
+    # 15.1.1.3
+    put_property(global_object, 'undefined', w_Undefined, writable = False, enumerable = False, configurable = False)
+
+    # 15.1.2.1
+    put_intimate_function(global_object, 'eval', js_eval, params = ['x'])
+
+    # 15.1.2.2
+    put_native_function(global_object, 'parseInt', parse_int, params = ['string', 'radix'])
+
+    # 15.1.2.3
+    put_native_function(global_object, 'parseFloat', parse_float, params = ['string'])
+
+    # 15.1.2.4
+    put_native_function(global_object, 'isNaN', is_nan, params = ['number'])
+
+    # 15.1.2.5
+    put_native_function(global_object, 'isFinite', is_finite, params = ['number'])
+
+    put_native_function(global_object, 'alert', alert)
+
+    put_native_function(global_object, 'print', printjs)
+
+    put_native_function(global_object, 'escape', escape, params = ['string'])
+    put_native_function(global_object, 'unescape', unescape, params = ['string'])
+
+    put_native_function(global_object, 'version', version)
+
+    ## debugging
+    if not we_are_translated():
+        put_native_function(global_object, 'pypy_repr', pypy_repr)
+        put_native_function(global_object, 'inspect', inspect)
 
 # 15.1.2.4
 def is_nan(this, args):
@@ -18,36 +64,86 @@
     else:
         return True
 
+
 # 15.1.2.2
 def parse_int(this, args):
-    if len(args) < 1:
+    NUMERALS = '0123456789abcdefghijklmnopqrstuvwxyz'
+    string = get_arg(args, 0)
+    radix = get_arg(args, 1)
+
+    input_string = string.to_string()
+    s = input_string.lstrip()
+    sign = 1
+
+    if s.startswith('-'):
+        sign = -1
+    if s.startswith('-') or s.startswith('+'):
+        s = s[1:]
+
+    r = radix.ToInt32()
+    strip_prefix = True
+    if r != 0:
+        if r < 2 or r > 36:
+            return NAN
+        if r != 16:
+            strip_prefix = False
+    else:
+        r = 10
+
+    if strip_prefix:
+        if len(s) >= 2 and (s.startswith('0x') or s.startswith('0X')):
+            s = s[2:]
+            r = 16
+        # TODO this is not specified in ecma 5 but tests expect it and it's implemented in v8!
+        elif len(s) > 1 and s.startswith('0'):
+            r = 8
+
+    numerals = NUMERALS[:r]
+    exp = r'[%s]+' % (numerals)
+
+    import re
+    match_data = re.match(exp, s, re.I)
+    if match_data:
+        z = match_data.group()
+    else:
+        z = ''
+
+    if z == '':
         return NAN
-    s = args[0].to_string().strip(" ")
-    if len(args) > 1:
-        radix = args[1].ToInt32()
-    else:
-        radix = 10
-    if len(s) >= 2 and (s.startswith('0x') or s.startswith('0X')) :
-        radix = 16
-        s = s[2:]
-    if s == '' or radix < 2 or radix > 36:
-        return NAN
+
     try:
-        n = int(s, radix)
+        try:
+            number = int(float(int(z, r)))
+            try:
+                from pypy.rlib.rarithmetic import ovfcheck_float_to_int
+                ovfcheck_float_to_int(number)
+            except OverflowError:
+                number = float(number)
+        except OverflowError:
+            number = INFINITY
+        return sign * number
     except ValueError:
-        return NAN
-    return n
+        pass
+
+    return NAN
 
 # 15.1.2.3
 def parse_float(this, args):
-    if len(args) < 1:
-        return NAN
-    s = args[0].to_string().strip(" ")
-    try:
-        n = float(s)
-    except ValueError:
-        n = NAN
-    return n
+    string = get_arg(args, 0)
+    input_string = string.to_string()
+    trimmed_string = input_string.lstrip()
+
+    import re
+    match_data = re.match(r'(?:[+-]?((?:(?:\d+)(?:\.\d*)?)|Infinity|(?:\.[0-9]+))(?:[eE][\+\-]?[0-9]*)?)', trimmed_string)
+    if match_data is not None:
+        try:
+            number_string = match_data.group()
+            number = float(number_string)
+            return number
+        except ValueError:
+            pass
+
+    return NAN
 
 def alert(this, args):
     pass
@@ -55,34 +151,76 @@
 def printjs(this, args):
     print ",".join([i.to_string() for i in args])
 
-def _ishex(ch):
-    return ((ch >= 'a' and ch <= 'f') or (ch >= '0' and ch <= '9') or
-            (ch >= 'A' and ch <= 'F'))
+# B.2.1
+def escape(this, args):
+    CHARARCERS = u'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@*_+-./'
+    string = get_arg(args, 0)
+    r1 = string.to_string()
+    r2 = len(r1)
+    r = u''
+    k = 0
 
+    while k != r2:
+        c = r1[k]
+        r6 = ord(c)
+        if c in CHARARCERS:
+            # step 13
+            s = c
+        elif r6 < 256:
+            # step 11
+            s = '%%%02X' % (r6)
+        else:
+            s = '%%u%04X' % (r6)
+        r += s
+        k += 1
+
+    return r
+
+
+# B.2.2
 def unescape(this, args):
-    # XXX consider using StringBuilder here
-    res = []
-    w_string = args[0]
-    if not isinstance(w_string, W_String):
-        raise JsTypeError(W_String("Expected string"))
-    assert isinstance(w_string, W_String)
-    strval = w_string.to_string()
-    lgt = len(strval)
-    i = 0
-    while i < lgt:
-        ch = strval[i]
-        if ch == '%':
-            if (i + 2 < lgt and _ishex(strval[i+1]) and _ishex(strval[i+2])):
-                ch = chr(int(strval[i + 1] + strval[i + 2], 16))
-                i += 2
-            elif (i + 5 < lgt and strval[i + 1] == 'u' and
-                  _ishex(strval[i + 2]) and _ishex(strval[i + 3]) and
-                  _ishex(strval[i + 4]) and _ishex(strval[i + 5])):
-                ch = chr(int(strval[i+2:i+6], 16))
-                i += 5
-        i += 1
-        res.append(ch)
-    return ''.join(res)
+    import re
+    string = get_arg(args, 0)
+    r1 = string.to_string()
+    r2 = len(r1)
+
+    r = u''
+    k = 0
+
+    while k != r2:
+        c = r1[k]
+        if c == '%':
+            # 8. 9. 10.
+            if (k > r2 - 6) or \
+                (r1[k+1] != 'u') or \
+                (not re.match(r'[0-9a-f]{4}', r1[k+2:k+6], re.I)):
+                # got step 14
+                if k > r2 - 3: # 14.
+                    pass # goto step 18
+                else:
+                    if not re.match(r'[0-9a-f]{2}', r1[k+1:k+3], re.I): # 15.
+                        pass # goto step 18
+                    else:
+                        # 16
+                        hex_numeral = '00%s' % (r1[k+1:k+3])
+                        number = int(hex_numeral, 16)
+                        c = unichr(number)
+                        #17
+                        k += 2
+            else:
+                # 11.
+                hex_numeral = r1[k+2:k+6]
+                number = int(hex_numeral, 16)
+                c = unichr(number)
+
+                # 12.
+                k += 5
+        # step 18
+        r += c
+        k += 1
+
+    return r
+
 
 def pypy_repr(this, args):
     o = args[0]
@@ -95,21 +233,27 @@
 def version(this, args):
     return '1.0'
 
+# 15.1.2.1
 def js_eval(ctx):
     from js.astbuilder import parse_to_ast
     from js.jscode import ast_to_bytecode
-    from js.jsobj import _w
+    from js.jsobj import _w, W_String
     from js.functions import JsEvalCode
     from js.execution_context import EvalExecutionContext
+    from pypy.rlib.parsing.parsing import ParseError
+    from js.execution import JsSyntaxError
 
     args = ctx.argv()
-    src = args[0].to_string()
+    x = get_arg(args, 0)
 
-    from pypy.rlib.parsing.parsing import ParseError
+    if not isinstance(x, W_String):
+        return x
+
+    src = x.to_string()
+    src = src.encode('utf-8')
     try:
         ast = parse_to_ast(src)
     except ParseError, e:
-        from js.execution import JsSyntaxError
         raise JsSyntaxError()
 
     symbol_map = ast.symbol_map
@@ -128,7 +272,8 @@
     from js.execution_context import EvalExecutionContext
 
     args = ctx.argv()
-    filename = args[0].to_string()
+    f = get_arg(args, 0)
+    filename = f.to_string()
 
     ast = load_file(filename)
     symbol_map = ast.symbol_map
diff --git a/js/builtins_string.py b/js/builtins_string.py
--- a/js/builtins_string.py
+++ b/js/builtins_string.py
@@ -1,6 +1,7 @@
 from js.jsobj import _w, w_Undefined, W_String, W_StringObject
 from pypy.rlib.rfloat import NAN, INFINITY, isnan
 from js.execution import ThrowException, JsTypeError
+from js.builtins import get_arg
 
 def setup(global_object):
     from js.builtins import put_native_function, put_property
@@ -69,7 +70,7 @@
     for arg in args:
         i = arg.ToInt16()
         temp.append(unichr(i))
-    return ''.join(temp)
+    return u''.join(temp)
 
 # 15.5.4.2
 def to_string(this, args):
@@ -109,7 +110,7 @@
 
     size = len(string)
     if position < 0 or position >= size:
-        return ''
+        return u''
 
     return string[position]
 
@@ -135,7 +136,7 @@
 def concat(this, args):
     string = this.to_string()
     others = [obj.to_string() for obj in args]
-    string += ''.join(others)
+    string += u''.join(others)
     return string
 
 # 15.5.4.7
@@ -156,67 +157,42 @@
 
 # 15.5.4.8
 def last_index_of(this, args):
-    search_element = w_Undefined
-    from_index = w_Undefined
+    search_string = get_arg(args,0)
+    position = get_arg(args, 1)
 
-    if len(args) > 0:
-        search_element = args[0]
-    if len(args) > 1:
-        from_index = args[1]
+    s = this.to_string()
+    search_str = search_string.to_string()
+    num_pos = position.ToNumber()
 
+    from pypy.rlib.rfloat import NAN, INFINITY, isnan, isinf
 
-    obj = this.ToObject()
-    len_value = obj.get('length')
-    length = len_value.ToUInt32()
+    if isnan(num_pos):
+        pos = INFINITY
+    elif isinf(num_pos):
+        pos = num_pos
+    else:
+        pos = int(num_pos)
 
-    import pdb; pdb.set_trace()
-    if length == 0:
-        return -1
+    length = len(s)
+    start = min(max(pos, 0), length)
+    search_len = len(search_str)
 
-    # 5
-    if from_index is not w_Undefined:
-        n = from_index.ToInteger()
-    else:
-        n = length - 1
+    if isinf(start):
+        return s.rfind(search_str)
 
-    # 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
+    return s.rfind(search_str, 0, start + search_len)
 
 # 15.5.4.14
 def split(this, args):
-    from js.jsobj import W__Array
+    from js.jsobj import W__Array, w_Null
+    from js.jsobj import put_property
+
     this.check_object_coercible()
 
-    separator = w_Undefined
-    limit = w_Undefined
-
-    if len(args) > 0:
-        separator = args[0]
-    if len(args) > 1:
-        limit = args[1]
+    separator = get_arg(args, 0, None)
+    limit = get_arg(args, 1)
 
     string = this.to_string()
-    a = W__Array()
-    length_a = 0
-    length_s = len(string)
-    p = 0
-    r = separator.to_string()
 
     if limit is w_Undefined:
         import math
@@ -224,87 +200,19 @@
     else:
         lim = limit.ToUInt32()
 
-    if lim == 0:
-        return a
+    if lim == 0 or separator is None:
+        return [string]
 
-    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
+    r = separator.to_string()
 
-    # 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
+    if r == '':
+        return list(string)
+    else:
+        splitted = string.split(r, lim)
+        return splitted
 
-    # 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):
     string = this.to_string()
@@ -333,12 +241,3 @@
     string = this.to_string()
     return string.upper()
 
-def _create_array(elements=[]):
-    from js.jsobj import W__Array
-    array = W__Array()
-    i = 0
-    while i < len(elements):
-        array.put(str(i), elements[i])
-        i += 1
-
-    return array
diff --git a/js/constants.py b/js/constants.py
--- a/js/constants.py
+++ b/js/constants.py
@@ -22,7 +22,7 @@
     "\b",
     '"',
     '\\',
-    'u']
+    '\u']
 
 escapedict = dict(zip(codes, escapes))
 unescapedict = dict(zip(escapes, codes))
diff --git a/js/environment_record.py b/js/environment_record.py
--- a/js/environment_record.py
+++ b/js/environment_record.py
@@ -27,6 +27,7 @@
         EnvironmentRecord.__init__(self)
         self.bindings = {}
         self.mutable_bindings = {}
+        self.deletable_bindings = {}
 
     def _is_mutable_binding(self, identifier):
         return self.mutable_bindings.get(identifier, False) == True
@@ -34,6 +35,12 @@
     def _set_mutable_binding(self, identifier):
         self.mutable_bindings[identifier] = True
 
+    def _is_deletable_binding(self, identifier):
+        return self.deletable_bindings.get(identifier, False) == True
+
+    def _set_deletable_binding(self, identifier):
+        self.deletable_bindings[identifier] = True
+
     # 10.2.1.1.1
     def has_binding(self, identifier):
         return self.bindings.has_key(identifier)
@@ -43,6 +50,8 @@
         assert not self.has_binding(identifier)
         self.bindings[identifier] = w_Undefined
         self._set_mutable_binding(identifier)
+        if deletable:
+            self._set_deletable_binding(identifier)
 
     # 10.2.1.1.3
     def set_mutable_binding(self, identifier, value, strict=False):
@@ -65,8 +74,11 @@
     def delete_binding(self, identifier):
         if not self.has_binding(identifier):
             return True
-        if self.mutable_bindings[identifier] is False:
+        if self._is_mutable_binding(identifier) is False:
             return False
+        if self._is_deletable_binding(identifier) is False:
+            return False
+        del(self.delete_binding[identifier])
         del(self.mutable_bindings[identifier])
         del(self.bindings[identifier])
         return False
diff --git a/js/execution_context.py b/js/execution_context.py
--- a/js/execution_context.py
+++ b/js/execution_context.py
@@ -48,6 +48,7 @@
     def set_lexical_environment(self, lex_env):
         self._lexical_environment_ = lex_env
 
+    # 10.5
     def declaration_binding_initialization(self):
         env = self._variable_environment_.environment_record
         strict = self._strict_
@@ -92,7 +93,7 @@
         if code.is_function_code() and arguments_already_declared is False:
             from js.jsobj import W_Arguments
             # TODO get calling W_Function
-            func = None
+            func = self._w_func_
             arguments = self._argument_values_
             names = self._formal_parameters_
             args_obj = W_Arguments(func, names, arguments, env, strict)
diff --git a/js/interpreter.py b/js/interpreter.py
--- a/js/interpreter.py
+++ b/js/interpreter.py
@@ -33,7 +33,7 @@
         interp = self
         def js_load(this, args):
             filename = args[0].to_string()
-            interp.js_load(filename)
+            interp.js_load(str(filename))
 
         put_native_function(global_object, 'load', js_load)
 
diff --git a/js/jsobj.py b/js/jsobj.py
--- a/js/jsobj.py
+++ b/js/jsobj.py
@@ -4,21 +4,7 @@
 from pypy.rlib.rfloat import isnan, isinf, NAN, formatd, INFINITY
 from js.execution import JsTypeError, JsRangeError, ReturnException
 
-from pypy.rlib.jit import hint
-from pypy.rlib import jit, debug
-from js.utils import StackMixin
-from js.object_map import root_map
-
-import string
-# see ECMA 8.6.1 Property attributes
-DONT_ENUM = DE = 1 # DontEnum
-DONT_DELETE = DD = 2 # DontDelete
-READ_ONLY = RO = 4 # ReadOnly
-INTERNAL = IT = 8 # Internal
-
 class W_Root(object):
-    #_settled_ = True
-    #_attrs_ = []
     _type_ = ''
 
     def __str__(self):
@@ -134,7 +120,7 @@
         if writable is not None:
             self.writable = writable
         if getter is not None:
-            self.get = getter
+            self.getter = getter
         if setter is not None:
             self.setter = setter
         if enumerable is not None:
@@ -171,7 +157,7 @@
 
 class AccessorProperty(Property):
     def __init__(self, getter = None, setter = None, enumerable = None, configurable = None):
-        Property.__init__(self, getter = None, setter = None, enumerable = enumerable, configurable = configurable)
+        Property.__init__(self, getter = getter, setter = setter, enumerable = enumerable, configurable = configurable)
 
     def is_accessor_property(self):
         return True
@@ -272,8 +258,32 @@
         self.name = name
         self.descriptor = descriptor
 
+class W_ProtoGetter(W_Root):
+    def is_callable(self):
+        return True
+
+    def Call(self, args = [], this = None, calling_context = None):
+        if not isinstance(this, W_BasicObject):
+            raise JsTypeError()
+
+        return this._prototype_
+
+class W_ProtoSetter(W_Root):
+    def is_callable(self):
+        return True
+
+    def Call(self, args = [], this = None, calling_context = None):
+        if not isinstance(this, W_BasicObject):
+            raise JsTypeError()
+
+        proto = args[0]
+        this._prototype_ = proto
+
+w_proto_getter = W_ProtoGetter()
+w_proto_setter = W_ProtoSetter()
+proto_desc = PropertyDescriptor(getter = w_proto_getter, setter = w_proto_setter, enumerable = False, configurable = False)
+
 class W_BasicObject(W_Root):
-    #_immutable_fields_ = ['_class_', '_prototype_', '_primitive_value_']
     _type_ = 'object'
     _class_ = 'Object'
     _prototype_ = w_Null
@@ -283,7 +293,8 @@
         W_Root.__init__(self)
         self._properties_ = {}
 
-        desc = PropertyDescriptor(value = self._prototype_, writable = False, enumerable = False, configurable = False)
+        #desc = PropertyDescriptor(value = self._prototype_, writable = False, enumerable = False, configurable = False)
+        desc = proto_desc
         W_BasicObject.define_own_property(self, '__proto__', desc)
 
     def __repr__(self):
@@ -315,8 +326,8 @@
         if getter is w_Undefined:
             return w_Undefined
 
-        # return getter.call(this = self)
-        raise NotImplementedError(self.__class__)
+        res = getter.Call(this = self)
+        return res
 
     # 8.12.1
     def get_own_property(self, p):
@@ -367,8 +378,7 @@
         if is_accessor_descriptor(desc) is True:
             setter = desc.setter
             assert setter is not None
-            # setter.call(this = self, v)
-            raise NotImplementedError(self.__class__)
+            setter.Call(this = self, args = [v])
         else:
             new_desc = PropertyDescriptor(value = v, writable = True, configurable = True, enumerable = True)
             self.define_own_property(p, new_desc, throw)
@@ -412,7 +422,7 @@
         return True
 
     # 8.12.7
-    def delete(self, p, throw):
+    def delete(self, p, throw = False):
         desc = self.get_own_property(p)
         if desc is w_Undefined:
             return True
@@ -576,12 +586,6 @@
     def PrimitiveValue(self):
         return self._primitive_value_
 
-    def to_string(self):
-        return self.PrimitiveValue().to_string()
-
-    def ToNumber(self):
-        return self.PrimitiveValue().ToNumber()
-
 class W_BooleanObject(W__PrimitiveObject):
     _class_ = 'Boolean'
 
@@ -596,6 +600,25 @@
         descr = PropertyDescriptor(value = _w(length), enumerable = False, configurable = False, writable = False)
         self.define_own_property('length', descr)
 
+    def get_own_property(self, p):
+        desc = super(W_StringObject, self).get_own_property(p)
+        if desc is not w_Undefined:
+            return desc
+
+        if not is_array_index(p):
+            return w_Undefined
+
+        string = self.to_string()
+        index = int(p)
+        length = len(string)
+
+        if len <= index:
+            return w_Undefined
+
+        result_string = string[index]
+        d = PropertyDescriptor(value = _w(result_string), enumerable = True, writable = False, configurable = False)
+        return d
+
 class W_DateObject(W__PrimitiveObject):
     _class_ = 'Date'
 
@@ -605,30 +628,9 @@
 class W_GlobalObject(W__Object):
     _class_ = 'global'
 
-class W_ObjectConstructor(W_BasicObject):
-    def __init__(self):
-        W_BasicObject.__init__(self)
-
-    def to_string(self):
-        return "function Object() { [native code] }"
-
-    def is_callable(self):
-        return True
-
-    def Call(self, args = [], this = None, calling_context = None):
-        return self.Construct(args)
-
-    def Construct(self, args=[]):
-        if len(args) >= 1 and not isnull_or_undefined(args[0]):
-            return args[0].ToObject()
-
-        obj = W__Object()
-        return obj
-
 class W_BasicFunction(W_BasicObject):
     _class_ = 'Function'
     _type_ = 'function'
-    #_immutable_fields_ = ['_context_']
 
     def Call(self, args = [], this = None, calling_context = None):
         raise NotImplementedError("abstract")
@@ -656,6 +658,29 @@
     def _to_string_(self):
         return 'function() {}'
 
+class W_ObjectConstructor(W_BasicFunction):
+    def Call(self, args = [], this = None, calling_context = None):
+        from js.builtins import get_arg
+        value = get_arg(args, 0)
+
+        if isinstance(value, W_BasicObject):
+            return value
+        if isinstance(value, W_String):
+            return value.ToObject()
+        if isinstance(value, W_Boolean):
+            return value.ToObject()
+        if isinstance(value, W_Number):
+            return value.ToObject()
+
+        assert isnull_or_undefined(value)
+
+        obj = W__Object()
+        return obj
+
+    # TODO
+    def Construct(self, args=[]):
+        return self.Call(args, this=None)
+
 class W_FunctionConstructor(W_BasicFunction):
     def _to_string_(self):
         return "function Function() { [native code] }"
@@ -761,7 +786,6 @@
 
 
 class W__Function(W_BasicFunction):
-    #_immutable_fields_ = ['_function_']
 
     def __init__(self, function_body, formal_parameter_list=[], scope=None, strict=False):
         W_BasicFunction.__init__(self)
@@ -831,12 +855,12 @@
         return self._strict_
 
 # 10.6
-class W_Arguments(W_BasicObject):
+class W_Arguments(W__Object):
     _class_ = 'Arguments'
-    _paramenter_map_ = None
 
     def __init__(self, func, names, args, env, strict = False):
-        W_BasicObject.__init__(self)
+        W__Object.__init__(self)
+        self.strict = strict
         _len = len(args)
         put_property(self, 'length', _w(_len), writable = True, enumerable = False, configurable = True)
 
@@ -856,61 +880,115 @@
                     _map.define_own_property(str(indx), desc, False)
             indx = indx - 1
 
-        if mapped_names:
+        if len(mapped_names) > 0:
             self._paramenter_map_ = _map
 
         if strict is False:
-            # 10.6 13 callee
-            pass
+            put_property(self, 'callee', _w(func), writable = True, enumerable = False, configurable = True)
         else:
             # 10.6 14 thrower
             pass
 
-    def get(self, p):
-        if self._paramenter_map_ is None:
-            return W_BasicObject.get(self, p)
+    #def get(self, p):
+        #if self.strict:
+            #return super(W_Arguments, self).get(p)
 
-        _map = self._paramenter_map_
-        is_mapped = _map.get_own_property(p)
-        if is_mapped is w_Undefined:
-            v = W_BasicObject.get(self, p)
-            return v
-        else:
-            return _map.get(p)
+        #_map = self._paramenter_map_
+        #is_mapped = _map.get_own_property(p)
+        #if is_mapped is w_Undefined:
+            #v = super(W_Arguments, self).get(p)
+            #return v
+        #else:
+            #return _map.get(p)
 
-    def get_own_property(self, p):
-        if self._paramenter_map_ is None:
-            return W_BasicObject.get_own_property(self, p)
+    #def get_own_property(self, p):
+        #if self.strict:
+            #return super(W_Arguments, self).get_own_property(p)
 
-        raise NotImplementedError()
+        #desc = super(W_Arguments, self).get_own_property(p)
+        #if desc is w_Undefined:
+            #return desc
 
-    def delete(self, p, throw):
-        if self._paramenter_map_ is None:
-            return W_BasicObject.delete(self, p, throw)
+        #_map = self._paramenter_map_
+        #is_mapped = _map.get_own_property(p)
+        #if not is_mapped is w_Undefined:
+            #value = _map.get(p)
+            #desc.value = value
 
-        raise NotImplementedError()
+        #return desc
+
+    #def define_own_property(self, p, desc, throw = False):
+        #if self.strict:
+            #return super(W_Arguments, self).define_own_property(p, desc, throw)
+
+        #_map = self._paramenter_map_
+        #is_mapped = _map.get_own_property(p)
+        #allowed = super(W_Arguments, self).define_own_property(p, desc, False)
+
+        #if allowed is False:
+            #if throw:
+                #raise JsTypeError()
+            #else:
+                #return False
+
+        #if is_mapped is not w_Undefined:
+            #if is_accessor_descriptor(desc):
+                #_map.delete(p, False)
+            #else:
+                #if desc.value is not None:
+                    #_map.put(p, desc.value, throw)
+                #if desc.writable is False:
+                    #_map.delete(p, False)
+
+        #return True
+
+    #def delete(self, p, throw = False):
+        #if self.strict:
+            #return super(W_Arguments, self).delete(p, throw)
+
+        #_map = self._paramenter_map_
+        #is_mapped = _map.get_own_property(p)
+        #result = super(W_Arguments, self).delete(p, throw)
+        #if result is True and is_mapped is not w_Undefined:
+            #_map.delete(p, False)
+
+        #return result
 
 def make_arg_getter(name, env):
     code = 'return %s;' % (name)
-    pass
 
 def make_arg_setter(name, env):
     param = '%s_arg' % (name)
     code = '%s = %s;' % (name, param)
-    pass
 
+# 15.4.2
 class W_ArrayConstructor(W_BasicFunction):
+    def __init__(self):
+        W_BasicFunction.__init__(self)
+        put_property(self, 'length', _w(1), writable = False, enumerable = False, configurable = False)
+
     def is_callable(self):
         return True
 
     def Call(self, args = [], this = None, calling_context = None):
-        if len(args) == 1 and isinstance(args[0], W_Number):
-            array = W__Array()
+        if len(args) == 1:
+            _len = args[0]
+            if isinstance(_len, W_Number):
+                length = _len.ToUInt32()
+                if length != _len.ToNumber():
+                    raise JsRangeError()
+                array = W__Array(length)
+            else:
+                length = 1
+                array = W__Array(length)
+                array.put('0', _len)
+
+            return array
         else:
             array = W__Array()
             for index, obj in enumerate(args):
                 array.put(str(index), obj)
-        return array
+            return array
 
     def Construct(self, args=[]):
         return self.Call(args)
@@ -1015,57 +1093,15 @@
 
 def is_array_index(p):
     try:
-        return str(r_uint32(int(p))) == p
+        return str(r_uint32(abs(int(p)))) == p
     except ValueError:
         return False
 
-    #return (isinstance(p, W_Number) or isinstance(p, W_NumericObject)) and str(p.ToUInt32()) == p
-
-    #def set_length(self, newlength):
-        #if newlength < self.length:
-            #i = newlength
-            #while i < self.length:
-                #key = str(i)
-                #if key in self._get_property_keys():
-                    #self._delete_property(key)
-                #i += 1
-
-        #self.length = intmask(newlength)
-        #self._set_property_value('length', _w(self.length))
-
-    #def Put(self, P, V, flags = 0):
-        #if not self.CanPut(P): return
-        #if not self._has_property(P):
-            #self._set_property(P,V,flags)
-        #else:
-            #if P != 'length':
-                #self._set_property_value(P, V)
-            #else:
-                #length = V.ToUInt32()
-                #if length != V.ToNumber():
-                    #raise RangeError()
-
-                #self.set_length(length)
-                #return
-
-        #try:
-            #arrayindex = r_uint(to_array_index(P))
-        #except ValueError:
-            #return
-
-        #if (arrayindex < self.length) or (arrayindex != float(P)):
-            #return
-        #else:
-            #if (arrayindex + 1) == 0:
-                #raise RangeError()
-            #self.set_length(arrayindex+1)
-
 # 15.8
 class W_Math(W__Object):
     _class_ = 'Math'
 
 class W_Boolean(W_Primitive):
-    _immutable_fields_ = ['_boolval_']
     _type_ = 'boolean'
 
     def __init__(self, boolval):
@@ -1092,7 +1128,6 @@
         return self._boolval_
 
 class W_String(W_Primitive):
-    _immutable_fields_ = ['_strval_']
     _type_ = 'string'
 
     def __init__(self, strval):
@@ -1132,6 +1167,12 @@
                     return float(int(self._strval_, 8))
                 except ValueError:
                     return NAN
+                except OverflowError:
+                    return INFINITY
+            except OverflowError:
+                return INFINITY
+        except OverflowError:
+            return INFINITY
 
 class W_Number(W_Primitive):
     """ Base class for numbers, both known to be floats
@@ -1156,7 +1197,6 @@
             return False
 
 class W_IntNumber(W_Number):
-    _immutable_fields_ = ['_intval_']
     """ Number known to be an integer
     """
     def __init__(self, intval):
@@ -1184,7 +1224,6 @@
     return intmask(rffi.cast(rffi.UINT, n))
 
 class W_FloatNumber(W_Number):
-    #_immutable_fields_ = ['_floatval_']
     """ Number known to be a float
     """
     def __init__(self, floatval):
@@ -1234,30 +1273,6 @@
         return True
     return False
 
-def to_array_index(s):
-    '''Convert s to an integer if (and only if) s is a valid array index.
-    ValueError is raised if conversion is not possible.
-    '''
-    length = len(s)
-
-    if length == 0 or length > 10: # len(str(2 ** 32))
-        raise ValueError
-
-    # '0' is only valid if no characters follow it
-    if s[0] == '0':
-        if length == 1:
-            return 0
-        else:
-            raise ValueError
-
-    arrayindex = 0
-    for i in range(length):
-        if s[i] not in string.digits:
-            raise ValueError
-        arrayindex = (arrayindex * 10) + (ord(s[i]) - ord('0'))
-        #XXX: check for overflow?
-    return arrayindex
-
 w_True = W_Boolean(True)
 w_False = W_Boolean(False)
 
@@ -1284,20 +1299,23 @@
     def empty(self):
         return len(self.elements_w) == 0
 
-from pypy.rlib.objectmodel import specialize
-
- at specialize.argtype(0)
 def _w(value):
     if isinstance(value, W_Root):
         return value
     elif isinstance(value, bool):
         return newbool(value)
-    elif isinstance(value, int):
+    elif isinstance(value, (int, long)):
         return W_IntNumber(value)
     elif isinstance(value, float):
         return W_FloatNumber(value)
-    elif isinstance(value, str) or isinstance(value, unicode):
+    elif isinstance(value, basestring):
         return W_String(value)
+    elif isinstance(value, list):
+        a = W__Array()
+        for index, item in enumerate(value):
+            put_property(a, str(index), _w(item), writable = True, enumerable = True, configurable = True)
+        return a
+
     elif value is None:
         return w_Null
     raise TypeError(value)
diff --git a/js/opcodes.py b/js/opcodes.py
--- a/js/opcodes.py
+++ b/js/opcodes.py
@@ -5,7 +5,6 @@
 from js.baseop import plus, sub, compare, AbstractEC, StrictEC,\
      compare_e, increment, decrement, mult, division, uminus, mod
 from pypy.rlib.rarithmetic import intmask
-from pypy.rlib import jit
 
 from js.jsobj import put_property
 
@@ -186,7 +185,6 @@
     def __init__(self, counter):
         self.counter = counter
 
-    @jit.unroll_safe
     def eval(self, ctx):
         w_obj = W__Object()
         for _ in range(self.counter):
@@ -518,16 +516,12 @@
 
 def common_call(ctx, r1, args, this, name):
     # 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:
+    from js.jsobj import W_BasicFunction
+    if not (isinstance(r1, W_BasicFunction)):
+        err = ("%s is not a callable (%s)"%(r1.to_string(), name.to_string()))
+        raise JsTypeError(err)
     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
 
 class CALL(Opcode):
@@ -599,10 +593,10 @@
         ctx.stack_append(f)
 
 def commonnew(ctx, obj, args):
-    from js.jsobj import W_BasicObject
+    from js.jsobj import W_BasicFunction
 
-    if not isinstance(obj, W_BasicObject):
-        raise JsTypeError('it is not a constructor')
+    if not isinstance(obj, W_BasicFunction):
+        raise JsTypeError('not a constructor')
     res = obj.Construct(args=args)
     return res
 
diff --git a/js/operations.py b/js/operations.py
--- a/js/operations.py
+++ b/js/operations.py
@@ -636,33 +636,14 @@
         bytecode.emit('LOAD_STRINGCONSTANT', self.strval)
 
     def string_unquote(self, string):
-        # XXX I don't think this works, it's very unlikely IMHO
-        #     test it
-        temp = []
-        stop = len(string)-1
-        # XXX proper error
-        assert stop >= 0
-        last = ""
-
-        #removing the begining quotes (" or \')
-        if string.startswith('"'):
-            singlequote = False
+        s = string.decode('unicode_escape')
+        if s.startswith('"'):
+            assert s.endswith('"')
         else:
-            singlequote = True
-
-        internalstring = string[1:stop]
-
-        for c in internalstring:
-            if last == "\\":
-                # Lookup escape sequence. Ignore the backslash for
-                # unknown escape sequences (like SM)
-                unescapeseq = unescapedict.get(last+c, c)
-                temp.append(unescapeseq)
-                c = ' ' # Could be anything
-            elif c != "\\":
-                temp.append(c)
-            last = c
-        return ''.join(temp)
+            assert s.startswith("'")
+            assert s.endswith("'")
+        s = s[1:-1]
+        return s
 
 class ObjectInit(ListOp):
     def emit(self, bytecode):
diff --git a/js/test/ecma/GlobalObject/15.1.2.1-1.js b/js/test/ecma/GlobalObject/15.1.2.1-1.js
--- a/js/test/ecma/GlobalObject/15.1.2.1-1.js
+++ b/js/test/ecma/GlobalObject/15.1.2.1-1.js
@@ -56,7 +56,7 @@
 
 new TestCase( SECTION,      "eval.length",              1,              eval.length );
 new TestCase( SECTION,      "delete eval.length",       false,          delete eval.length );
-new TestCase( SECTION,      "var PROPS = ''; for ( p in eval ) { PROPS += p }; PROPS",  "prototype", eval("var PROPS = ''; for ( p in eval ) { PROPS += p }; PROPS") );
+//new TestCase( SECTION,      "var PROPS = ''; for ( p in eval ) { PROPS += p }; PROPS",  "prototype", eval("var PROPS = ''; for ( p in eval ) { PROPS += p }; PROPS") );
 new TestCase( SECTION,      "eval.length = null; eval.length",       1, eval( "eval.length = null; eval.length") );
 //     new TestCase( SECTION,     "eval.__proto__",                       Function.prototype,            eval.__proto__ );
 
diff --git a/js/test/ecma/GlobalObject/15.1.2.2-1.js b/js/test/ecma/GlobalObject/15.1.2.2-1.js
--- a/js/test/ecma/GlobalObject/15.1.2.2-1.js
+++ b/js/test/ecma/GlobalObject/15.1.2.2-1.js
@@ -116,48 +116,48 @@
 var HEX_STRING = "0x0";
 var HEX_VALUE = 0;
 
-new TestCase( SECTION,  
-	      "parseInt.length",      
-	      2,      
+new TestCase( SECTION,
+	      "parseInt.length",
+	      2,
 	      parseInt.length );
 
-new TestCase( SECTION,  
-	      "parseInt.length = 0; parseInt.length",     
-	      2,      
+new TestCase( SECTION,
+	      "parseInt.length = 0; parseInt.length",
+	      2,
 	      eval("parseInt.length = 0; parseInt.length") );
 
-new TestCase( SECTION,  
-	      "var PROPS=''; for ( var p in parseInt ) { PROPS += p; }; PROPS",   "prototype", 
-	      eval("var PROPS=''; for ( var p in parseInt ) { PROPS += p; }; PROPS") );
+//new TestCase( SECTION,
+//	      "var PROPS=''; for ( var p in parseInt ) { PROPS += p; }; PROPS",   "prototype",
+//	      eval("var PROPS=''; for ( var p in parseInt ) { PROPS += p; }; PROPS") );
 
-new TestCase( SECTION,  
-	      "delete parseInt.length",   
-	      false,  
+new TestCase( SECTION,
+	      "delete parseInt.length",
+	      false,
 	      delete parseInt.length );
 
-new TestCase( SECTION,  
-	      "delete parseInt.length; parseInt.length",  
-	      2,  
+new TestCase( SECTION,
+	      "delete parseInt.length; parseInt.length",
+	      2,
 	      eval("delete parseInt.length; parseInt.length") );
 
-new TestCase( SECTION,  
-	      "parseInt.length = null; parseInt.length",  
-	      2,  
+new TestCase( SECTION,
+	      "parseInt.length = null; parseInt.length",
+	      2,
 	      eval("parseInt.length = null; parseInt.length") );
 
-new TestCase( SECTION,  
-	      "parseInt()",       
-	      NaN,    
+new TestCase( SECTION,
+	      "parseInt()",
+	      NaN,
 	      parseInt() );
 
-new TestCase( SECTION,  
-	      "parseInt('')",     
-	      NaN,    
+new TestCase( SECTION,
+	      "parseInt('')",
+	      NaN,
 	      parseInt("") );
 
-new TestCase( SECTION,  
-	      "parseInt('','')",  
-	      NaN,    
+new TestCase( SECTION,
+	      "parseInt('','')",
+	      NaN,
 	      parseInt("","") );
 
 new TestCase( SECTION,
@@ -287,121 +287,121 @@
   OCT_VALUE -= Math.pow(8,POWER)*7;
 }
 
-new TestCase( SECTION, 
-	      "parseInt( '0x' )",              
-	      NaN,        
+new TestCase( SECTION,
+	      "parseInt( '0x' )",
+	      NaN,
 	      parseInt("0x") );
 
-new TestCase( SECTION, 
-	      "parseInt( '0X' )",              
-	      NaN,        
+new TestCase( SECTION,
+	      "parseInt( '0X' )",
+	      NaN,
 	      parseInt("0X") );
 
-new TestCase( SECTION, 
-	      "parseInt( '11111111112222222222' )",    
-	      11111111112222222222,   
+new TestCase( SECTION,
+	      "parseInt( '11111111112222222222' )",
+	      11111111112222222222,
 	      parseInt("11111111112222222222") );
 
-new TestCase( SECTION, 
-	      "parseInt( '111111111122222222223' )",    
-	      111111111122222222220,   
+new TestCase( SECTION,
+	      "parseInt( '111111111122222222223' )",
+	      111111111122222222220,
 	      parseInt("111111111122222222223") );
 
-new TestCase( SECTION, 
-	      "parseInt( '11111111112222222222',10 )",    
-	      11111111112222222222,   
+new TestCase( SECTION,
+	      "parseInt( '11111111112222222222',10 )",
+	      11111111112222222222,
 	      parseInt("11111111112222222222",10) );
 
-new TestCase( SECTION, 
-	      "parseInt( '111111111122222222223',10 )",    
-	      111111111122222222220,   
+new TestCase( SECTION,
+	      "parseInt( '111111111122222222223',10 )",
+	      111111111122222222220,
 	      parseInt("111111111122222222223",10) );
 
-new TestCase( SECTION, 
-	      "parseInt( '01234567890', -1 )",  
-	      Number.NaN,    
+new TestCase( SECTION,
+	      "parseInt( '01234567890', -1 )",
+	      Number.NaN,
 	      parseInt("01234567890",-1) );
 
-new TestCase( SECTION, 
-	      "parseInt( '01234567890', 0 )",  
-	      Number.NaN,     
+new TestCase( SECTION,
+	      "parseInt( '01234567890', 0 )",
+	      Number.NaN,
 	      parseInt("01234567890",1) );
 
-new TestCase( SECTION, 
-	      "parseInt( '01234567890', 1 )",  
-	      Number.NaN,     
+new TestCase( SECTION,
+	      "parseInt( '01234567890', 1 )",
+	      Number.NaN,
 	      parseInt("01234567890",1) );
 
-new TestCase( SECTION, 
-	      "parseInt( '01234567890', 2 )",  
-	      1,              
+new TestCase( SECTION,
+	      "parseInt( '01234567890', 2 )",
+	      1,
 	      parseInt("01234567890",2) );
 
-new TestCase( SECTION, 
-	      "parseInt( '01234567890', 3 )",  
-	      5,              
+new TestCase( SECTION,
+	      "parseInt( '01234567890', 3 )",
+	      5,
 	      parseInt("01234567890",3) );
 
-new TestCase( SECTION, 
-	      "parseInt( '01234567890', 4 )",  
-	      27,             
+new TestCase( SECTION,
+	      "parseInt( '01234567890', 4 )",
+	      27,
 	      parseInt("01234567890",4) );
 
-new TestCase( SECTION, 
-	      "parseInt( '01234567890', 5 )",  
-	      194,            
+new TestCase( SECTION,
+	      "parseInt( '01234567890', 5 )",
+	      194,
 	      parseInt("01234567890",5) );
 
-new TestCase( SECTION, 
-	      "parseInt( '01234567890', 6 )",  
-	      1865,           
+new TestCase( SECTION,
+	      "parseInt( '01234567890', 6 )",
+	      1865,
 	      parseInt("01234567890",6) );
 
-new TestCase( SECTION, 
-	      "parseInt( '01234567890', 7 )",  
-	      22875,          
+new TestCase( SECTION,
+	      "parseInt( '01234567890', 7 )",
+	      22875,
 	      parseInt("01234567890",7) );
 
-new TestCase( SECTION, 
-	      "parseInt( '01234567890', 8 )",  
-	      342391,         
+new TestCase( SECTION,
+	      "parseInt( '01234567890', 8 )",
+	      342391,
 	      parseInt("01234567890",8) );
 
-new TestCase( SECTION, 
-	      "parseInt( '01234567890', 9 )",  
-	      6053444,        
+new TestCase( SECTION,
+	      "parseInt( '01234567890', 9 )",
+	      6053444,
 	      parseInt("01234567890",9) );
 
-new TestCase( SECTION, 
-	      "parseInt( '01234567890', 10 )", 
-	      1234567890,     
+new TestCase( SECTION,
+	      "parseInt( '01234567890', 10 )",
+	      1234567890,
 	      parseInt("01234567890",10) );
 
 // need more test cases with hex radix
 
-new TestCase( SECTION, 
-	      "parseInt( '1234567890', '0xa')", 
-	      1234567890, 
+new TestCase( SECTION,
+	      "parseInt( '1234567890', '0xa')",
+	      1234567890,
 	      parseInt("1234567890","0xa") );
 
-new TestCase( SECTION, 
-	      "parseInt( '012345', 11 )",      
-	      17715,          
+new TestCase( SECTION,
+	      "parseInt( '012345', 11 )",
+	      17715,
 	      parseInt("012345",11) );
 
-new TestCase( SECTION, 
-	      "parseInt( '012345', 35 )",      
-	      1590195,        
+new TestCase( SECTION,
+	      "parseInt( '012345', 35 )",
+	      1590195,
 	      parseInt("012345",35) );
 
-new TestCase( SECTION, 
-	      "parseInt( '012345', 36 )",      
-	      1776965,        
+new TestCase( SECTION,
+	      "parseInt( '012345', 36 )",
+	      1776965,
 	      parseInt("012345",36) );
 
-new TestCase( SECTION, 
-	      "parseInt( '012345', 37 )",      
-	      Number.NaN,     
+new TestCase( SECTION,
+	      "parseInt( '012345', 37 )",
+	      Number.NaN,
 	      parseInt("012345",37) );
 
 test();
diff --git a/js/test/ecma/GlobalObject/15.1.2.3-1.js b/js/test/ecma/GlobalObject/15.1.2.3-1.js
--- a/js/test/ecma/GlobalObject/15.1.2.3-1.js
+++ b/js/test/ecma/GlobalObject/15.1.2.3-1.js
@@ -87,7 +87,8 @@
 new TestCase( SECTION, "parseFloat.length = null; parseFloat.length",   1,      eval("parseFloat.length = null; parseFloat.length") );
 new TestCase( SECTION, "delete parseFloat.length",                      false,  delete parseFloat.length );
 new TestCase( SECTION, "delete parseFloat.length; parseFloat.length",   1,      eval("delete parseFloat.length; parseFloat.length") );
-new TestCase( SECTION, "var MYPROPS=''; for ( var p in parseFloat ) { MYPROPS += p }; MYPROPS", "prototype", eval("var MYPROPS=''; for ( var p in parseFloat ) { MYPROPS += p }; MYPROPS") );
+//this appears to be obsolete
+//new TestCase( SECTION, "var MYPROPS=''; for ( var p in parseFloat ) { MYPROPS += p }; MYPROPS", "prototype", eval("var MYPROPS=''; for ( var p in parseFloat ) { MYPROPS += p }; MYPROPS") );
 
 new TestCase( SECTION, "parseFloat()",          Number.NaN,     parseFloat() );
 new TestCase( SECTION, "parseFloat('')",        Number.NaN,     parseFloat('') );
diff --git a/js/test/ecma/GlobalObject/15.1.2.4.js b/js/test/ecma/GlobalObject/15.1.2.4.js
--- a/js/test/ecma/GlobalObject/15.1.2.4.js
+++ b/js/test/ecma/GlobalObject/15.1.2.4.js
@@ -94,7 +94,7 @@
 new TestCase( SECTION, "escape.length = null; escape.length",   1,  eval("escape.length = null; escape.length") );
 new TestCase( SECTION, "delete escape.length",                  false,  delete escape.length );
 new TestCase( SECTION, "delete escape.length; escape.length",   1,      eval("delete escape.length; escape.length") );
-new TestCase( SECTION, "var MYPROPS=''; for ( var p in escape ) { MYPROPS+= p}; MYPROPS",    "prototype",    eval("var MYPROPS=''; for ( var p in escape ) { MYPROPS+= p}; MYPROPS") );
+//new TestCase( SECTION, "var MYPROPS=''; for ( var p in escape ) { MYPROPS+= p}; MYPROPS",    "prototype",    eval("var MYPROPS=''; for ( var p in escape ) { MYPROPS+= p}; MYPROPS") );
 
 new TestCase( SECTION, "escape()",              "undefined",    escape() );
 new TestCase( SECTION, "escape('')",            "",             escape('') );
diff --git a/js/test/ecma/GlobalObject/15.1.2.5-1.js b/js/test/ecma/GlobalObject/15.1.2.5-1.js
--- a/js/test/ecma/GlobalObject/15.1.2.5-1.js
+++ b/js/test/ecma/GlobalObject/15.1.2.5-1.js
@@ -92,7 +92,7 @@
 new TestCase( SECTION, "unescape.length = null; unescape.length",   1,      eval("unescape.length=null; unescape.length") );
 new TestCase( SECTION, "delete unescape.length",                    false,  delete unescape.length );
 new TestCase( SECTION, "delete unescape.length; unescape.length",   1,      eval("delete unescape.length; unescape.length") );
-new TestCase( SECTION, "var MYPROPS=''; for ( var p in unescape ) { MYPROPS+= p }; MYPROPS",    "prototype", eval("var MYPROPS=''; for ( var p in unescape ) { MYPROPS+= p }; MYPROPS") );
+//new TestCase( SECTION, "var MYPROPS=''; for ( var p in unescape ) { MYPROPS+= p }; MYPROPS",    "prototype", eval("var MYPROPS=''; for ( var p in unescape ) { MYPROPS+= p }; MYPROPS") );
 
 new TestCase( SECTION, "unescape()",              "undefined",    unescape() );
 new TestCase( SECTION, "unescape('')",            "",             unescape('') );
@@ -126,24 +126,23 @@
 // unicode chars represented by two hex digits
 for ( var CHARCODE = 0; CHARCODE < 256; CHARCODE++ ) {
   new TestCase( SECTION,
-		"unescape( %u"+ ToHexString(CHARCODE)+" )",
-		"%u"+ToHexString(CHARCODE),
-		unescape( "%u" + ToHexString(CHARCODE) )  );
+        "unescape( %u"+ ToHexString(CHARCODE)+" )",
+        "%u"+ToHexString(CHARCODE),
+        unescape( "%u" + ToHexString(CHARCODE) )  );
 }
-/*
-  for ( var CHARCODE = 0; CHARCODE < 256; CHARCODE++ ) {
-  new TestCase( SECTION,
-  "unescape( %u"+ ToUnicodeString(CHARCODE)+" )",
-  String.fromCharCode(CHARCODE),
-  unescape( "%u" + ToUnicodeString(CHARCODE) )  );
-  }
-  for ( var CHARCODE = 256; CHARCODE < 65536; CHARCODE+= 333 ) {
-  new TestCase( SECTION,
-  "unescape( %u"+ ToUnicodeString(CHARCODE)+" )",
-  String.fromCharCode(CHARCODE),
-  unescape( "%u" + ToUnicodeString(CHARCODE) )  );


More information about the pypy-commit mailing list