Remove obsolete wrappedObject extended class hook (604523, r=mrbkap/vlad/dvander).
authorAndreas Gal <gal@mozilla.com>
Fri, 22 Oct 2010 15:40:11 -0700
changeset 56474 139dcd10518f1d22fa9e9ea75d975ca85cf0e6d1
parent 56473 1b0dcd03247911b2ee0167bd9ee69740cab92fde
child 56475 eaf6f9566f2eb59e647f03630a21a056b75899b8
push id16567
push usermrbkap@mozilla.com
push dateMon, 25 Oct 2010 23:41:30 +0000
treeherdermozilla-central@eaf6f9566f2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmrbkap, vlad, dvander
bugs604523
milestone2.0b8pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Remove obsolete wrappedObject extended class hook (604523, r=mrbkap/vlad/dvander).
content/base/src/nsContentUtils.cpp
js/src/jsapi.cpp
js/src/jsarray.cpp
js/src/jsdbgapi.cpp
js/src/jsfun.cpp
js/src/jsgc.cpp
js/src/jsinterp.cpp
js/src/jsiter.cpp
js/src/jsobj.cpp
js/src/jsobj.h
js/src/jsproxy.cpp
js/src/jstracer.cpp
js/src/jstypedarray.cpp
js/src/jsvalue.h
js/src/jswrapper.h
js/src/methodjit/Compiler.cpp
js/src/tests/js1_8_5/extensions/typedarray.js
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -5849,17 +5849,17 @@ CloneSimpleValues(JSContext* cx,
   // Do we support FileList?
 
   // Function objects don't get cloned.
   if (JS_ObjectIsFunction(cx, obj)) {
     return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
   }
 
   // Security wrapped objects are not allowed either.
-  if (obj->getClass()->ext.wrappedObject)
+  if (obj->isWrapper() && !obj->getClass()->ext.innerObject)
     return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
 
   // See if this JSObject is backed by some C++ object. If it is then we assume
   // that it is inappropriate to clone.
   nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
   nsContentUtils::XPConnect()->
     GetWrappedNativeOfJSObject(cx, obj, getter_AddRefs(wrapper));
   if (wrapper) {
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -4080,17 +4080,18 @@ JS_NewArrayObject(JSContext *cx, jsint l
     assertSameCompartment(cx, JSValueArray(vector, vector ? (jsuint)length : 0));
     return js_NewArrayObject(cx, (jsuint)length, Valueify(vector));
 }
 
 JS_PUBLIC_API(JSBool)
 JS_IsArrayObject(JSContext *cx, JSObject *obj)
 {
     assertSameCompartment(cx, obj);
-    return obj->wrappedObject(cx)->isArray();
+    return obj->isArray() ||
+           (obj->isWrapper() && JSWrapper::wrappedObject(obj)->isArray());
 }
 
 JS_PUBLIC_API(JSBool)
 JS_GetArrayLength(JSContext *cx, JSObject *obj, jsuint *lengthp)
 {
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj);
     return js_GetLengthProperty(cx, obj, lengthp);
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -96,16 +96,17 @@
 #include "jsiter.h"
 #include "jslock.h"
 #include "jsnum.h"
 #include "jsobj.h"
 #include "jsscope.h"
 #include "jsstr.h"
 #include "jsstaticcheck.h"
 #include "jsvector.h"
+#include "jswrapper.h"
 
 #include "jsatominlines.h"
 #include "jscntxtinlines.h"
 #include "jsinterpinlines.h"
 #include "jsobjinlines.h"
 
 using namespace js;
 using namespace js::gc;
@@ -2389,21 +2390,19 @@ array_concat(JSContext *cx, uintN argc, 
     AutoValueRooter tvr(cx);
 
     /* Loop over [0, argc] to concat args into nobj, expanding all Arrays. */
     for (uintN i = 0; i <= argc; i++) {
         if (!JS_CHECK_OPERATION_LIMIT(cx))
             return false;
         const Value &v = p[i];
         if (v.isObject()) {
-            JSObject *wobj;
-
             aobj = &v.toObject();
-            wobj = aobj->wrappedObject(cx);
-            if (wobj->isArray()) {
+            if (aobj->isArray() ||
+                (aobj->isWrapper() && JSWrapper::wrappedObject(aobj)->isArray())) {
                 jsid id = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
                 if (!aobj->getProperty(cx, id, tvr.addr()))
                     return false;
                 jsuint alength = ValueIsLength(cx, tvr.addr());
                 if (tvr.value().isNull())
                     return false;
                 for (jsuint slot = 0; slot < alength; slot++) {
                     JSBool hole;
@@ -2822,20 +2821,22 @@ array_every(JSContext *cx, uintN argc, V
 {
     return array_extra(cx, EVERY, argc, vp);
 }
 #endif
 
 static JSBool
 array_isArray(JSContext *cx, uintN argc, Value *vp)
 {
+    JSObject *obj;
     vp->setBoolean(argc > 0 &&
                    vp[2].isObject() &&
-                   vp[2].toObject().wrappedObject(cx)->isArray());
-    return JS_TRUE;
+                   ((obj = &vp[2].toObject())->isArray() ||
+                    (obj->isWrapper() && JSWrapper::wrappedObject(obj)->isArray())));
+    return true;
 }
 
 static JSFunctionSpec array_methods[] = {
 #if JS_HAS_TOSOURCE
     JS_FN(js_toSource_str,      array_toSource,     0,0),
 #endif
     JS_FN(js_toString_str,      array_toString,     0,0),
     JS_FN(js_toLocaleString_str,array_toLocaleString,0,0),
--- a/js/src/jsdbgapi.cpp
+++ b/js/src/jsdbgapi.cpp
@@ -781,17 +781,16 @@ JS_SetWatchPoint(JSContext *cx, JSObject
     JSProperty *prop;
     const Shape *shape;
     JSRuntime *rt;
     JSBool ok;
     JSWatchPoint *wp;
     PropertyOp watcher;
 
     origobj = obj;
-    obj = obj->wrappedObject(cx);
     OBJ_TO_INNER_OBJECT(cx, obj);
     if (!obj)
         return JS_FALSE;
 
     AutoValueRooter idroot(cx);
     if (JSID_IS_INT(id)) {
         propid = id;
     } else {
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -2299,17 +2299,17 @@ js_fun_apply(JSContext *cx, uintN argc, 
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_APPLY_ARGS, js_apply_str);
         return false;
     }
 
     /*
      * Steps 4-5 (note erratum removing steps originally numbered 5 and 7 in
      * original version of ES5).
      */
-    JSObject *aobj = vp[3].toObject().wrappedObject(cx);
+    JSObject *aobj = &vp[3].toObject();
     jsuint length;
     if (aobj->isArray()) {
         length = aobj->getArrayLength();
     } else if (aobj->isArguments() && !aobj->isArgsLengthOverridden()) {
         length = aobj->getArgsInitialLength();
     } else {
         Value &lenval = vp[0];
         if (!aobj->getProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.lengthAtom), &lenval))
@@ -2491,17 +2491,17 @@ JSBool
 fun_bind(JSContext *cx, uintN argc, Value *vp)
 {
     /* Step 1. */
     JSObject *target = ComputeThisFromVp(cx, vp);
     if (!target)
         return false;
 
     /* Step 2. */
-    if (!target->wrappedObject(cx)->isCallable()) {
+    if (!target->isCallable()) {
         if (JSString *str = js_ValueToString(cx, vp[1])) {
             if (const char *bytes = js_GetStringBytes(cx, str)) {
                 JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
                                      JSMSG_INCOMPATIBLE_PROTO,
                                      js_Function_str, "bind", bytes);
             }
         }
         return false;
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -2632,17 +2632,16 @@ SetProtoCheckingForCycles(JSContext *cx,
 
     JSRuntime *rt = cx->runtime;
     AutoLockGC lock(rt);
     AutoGCSession gcsession(cx);
     AutoUnlockGC unlock(rt);
 
     bool cycle = false;
     for (JSObject *obj2 = proto; obj2;) {
-        obj2 = obj2->wrappedObject(cx);
         if (obj2 == obj) {
             cycle = true;
             break;
         }
         obj2 = obj2->getProto();
     }
     if (!cycle)
         obj->setProto(proto);
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -1119,18 +1119,17 @@ HasInstance(JSContext *cx, JSObject *obj
     js_ReportValueError(cx, JSMSG_BAD_INSTANCEOF_RHS,
                         JSDVG_SEARCH_STACK, ObjectValue(*obj), NULL);
     return JS_FALSE;
 }
 
 static JS_ALWAYS_INLINE bool
 EqualObjects(JSContext *cx, JSObject *lobj, JSObject *robj)
 {
-    return lobj == robj ||
-           lobj->wrappedObject(cx) == robj->wrappedObject(cx);
+    return lobj == robj;
 }
 
 bool
 StrictlyEqual(JSContext *cx, const Value &lref, const Value &rref)
 {
     Value lval = lref, rval = rref;
     if (SameType(lval, rval)) {
         if (lval.isString())
--- a/js/src/jsiter.cpp
+++ b/js/src/jsiter.cpp
@@ -106,17 +106,17 @@ Class js_IteratorClass = {
     NULL,           /* xdrObject   */
     NULL,           /* hasInstance */
     JS_CLASS_TRACE(iterator_trace),
     {
         NULL,       /* equality       */
         NULL,       /* outerObject    */
         NULL,       /* innerObject    */
         iterator_iterator,
-        NULL        /* wrappedObject  */
+        NULL        /* unused */
     }
 };
 
 void
 NativeIterator::mark(JSTracer *trc)
 {
     if (isKeyIter())
         MarkIdRange(trc, beginKey(), endKey(), "props");
@@ -1165,17 +1165,17 @@ Class js_GeneratorClass = {
     NULL,           /* xdrObject   */
     NULL,           /* hasInstance */
     JS_CLASS_TRACE(generator_trace),
     {
         NULL,       /* equality       */
         NULL,       /* outerObject    */
         NULL,       /* innerObject    */
         iterator_iterator,
-        NULL,       /* wrappedObject  */
+        NULL        /* unused */
     }
 };
 
 static inline void
 RebaseRegsFromTo(JSFrameRegs *regs, JSStackFrame *from, JSStackFrame *to)
 {
     regs->fp = to;
     regs->sp = to->slots() + (regs->sp - from->slots());
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -807,17 +807,17 @@ obj_toSource(JSContext *cx, uintN argc, 
 namespace js {
 
 JSString *
 obj_toStringHelper(JSContext *cx, JSObject *obj)
 {
     if (obj->isProxy())
         return JSProxy::obj_toString(cx, obj);
 
-    const char *clazz = obj->wrappedObject(cx)->getClass()->name;
+    const char *clazz = obj->getClass()->name;
     size_t nchars = 9 + strlen(clazz); /* 9 for "[object ]" */
     jschar *chars = (jschar *) cx->malloc((nchars + 1) * sizeof(jschar));
     if (!chars)
         return NULL;
 
     const char *prefix = "[object ";
     nchars = 0;
     while ((chars[nchars] = (jschar)*prefix) != 0)
@@ -5855,23 +5855,16 @@ CheckAccess(JSContext *cx, JSObject *obj
 }
 
 }
 
 JSType
 js_TypeOf(JSContext *cx, JSObject *obj)
 {
     /*
-     * Unfortunately we have wrappers that are native objects and thus don't
-     * overwrite js_TypeOf (i.e. XPCCrossOriginWrapper), so we have to
-     * unwrap here.
-     */
-    obj = obj->wrappedObject(cx);
-
-    /*
      * ECMA 262, 11.4.3 says that any native object that implements
      * [[Call]] should be of type "function". However, RegExp is of
      * type "object", not "function", for Web compatibility.
      */
     if (obj->isCallable()) {
         return (obj->getClass() != &js_RegExpClass)
                ? JSTYPE_FUNCTION
                : JSTYPE_OBJECT;
@@ -5888,17 +5881,17 @@ js_DropProperty(JSContext *cx, JSObject 
 }
 #endif
 
 bool
 js_IsDelegate(JSContext *cx, JSObject *obj, const Value &v)
 {
     if (v.isPrimitive())
         return false;
-    JSObject *obj2 = v.toObject().wrappedObject(cx);
+    JSObject *obj2 = &v.toObject();
     while ((obj2 = obj2->getProto()) != NULL) {
         if (obj2 == obj)
             return true;
     }
     return false;
 }
 
 bool
@@ -6384,26 +6377,16 @@ js_SetReservedSlot(JSContext *cx, JSObje
 
     obj->setSlot(slot, v);
     GC_POKE(cx, JS_NULL);
     JS_UNLOCK_OBJ(cx, obj);
     return true;
 }
 
 JSObject *
-JSObject::wrappedObject(JSContext *cx) const
-{
-    if (JSObjectOp op = getClass()->ext.wrappedObject) {
-        if (JSObject *obj = op(cx, const_cast<JSObject *>(this)))
-            return obj;
-    }
-    return const_cast<JSObject *>(this);
-}
-
-JSObject *
 JSObject::getGlobal() const
 {
     JSObject *obj = const_cast<JSObject *>(this);
     while (JSObject *parent = obj->getParent())
         obj = parent;
     return obj;
 }
 
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -1092,18 +1092,16 @@ struct JSObject : js::gc::Cell {
         return (op ? op : js_Enumerate)(cx, this, iterop, statep, idp);
     }
 
     JSType typeOf(JSContext *cx) {
         js::TypeOfOp op = getOps()->typeOf;
         return (op ? op : js_TypeOf)(cx, this);
     }
 
-    JSObject *wrappedObject(JSContext *cx) const;
-
     /* These four are time-optimized to avoid stub calls. */
     JSObject *thisObject(JSContext *cx) {
         JSObjectOp op = getOps()->thisObject;
         return op ? op(cx, this) : this;
     }
 
     static bool thisObject(JSContext *cx, const js::Value &v, js::Value *vp);
 
--- a/js/src/jsproxy.cpp
+++ b/js/src/jsproxy.cpp
@@ -995,17 +995,17 @@ JS_FRIEND_API(Class) OuterWindowProxyCla
     NULL,           /* construct   */
     NULL,           /* xdrObject   */
     NULL,           /* hasInstance */
     NULL,           /* mark        */
     {
         NULL,       /* equality    */
         NULL,       /* outerObject */
         proxy_innerObject,
-        NULL,       /* wrappedObject */
+        NULL        /* unused */
     },
     {
         proxy_LookupProperty,
         proxy_DefineProperty,
         proxy_GetProperty,
         proxy_SetProperty,
         proxy_GetAttributes,
         proxy_SetAttributes,
--- a/js/src/jstracer.cpp
+++ b/js/src/jstracer.cpp
@@ -10206,24 +10206,19 @@ TraceRecorder::getThis(LIns*& this_ins)
      * trace-constant. getThisObject writes back to fp->thisValue(), so do
      * the same on trace.
      */
     if (!fp->computeThis(cx))
         RETURN_ERROR("computeThis failed");
 
     /* thisv is a reference, so it'll see the newly computed |this|. */
 #ifdef DEBUG
-    /*
-     * Check that thisv is our global. It could be a XPCCrossOriginWrapper around an outer
-     * window object whose inner object is our global, so follow all the links as needed.
-     */
     JS_ASSERT(thisv.isObject());
-    JSObject *thisObj = thisv.toObject().wrappedObject(cx);
-    OBJ_TO_INNER_OBJECT(cx, thisObj);
-    JS_ASSERT(thisObj == globalObj);
+    JSObject *thisObj = &thisv.toObject();
+    JS_ASSERT(thisObj->getClass()->ext.innerObject);
 #endif
     this_ins = INS_CONSTOBJ(globalObj);
     set(&thisv, this_ins);
     return RECORD_CONTINUE;
 }
 
 JS_REQUIRES_STACK void
 TraceRecorder::guardClassHelper(bool cond, LIns* obj_ins, Class* clasp, VMSideExit* exit,
--- a/js/src/jstypedarray.cpp
+++ b/js/src/jstypedarray.cpp
@@ -924,34 +924,30 @@ class TypedArrayTemplate
             {
                 JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
                                      JSMSG_TYPED_ARRAY_BAD_ARGS);
                 return false;
             }
 
             if (!tarray->copyFrom(cx, src, offset))
                 return false;
-        } else if (arg0->wrappedObject(cx)->isArray()) {
+        } else {
             jsuint len;
             if (!js_GetLengthProperty(cx, arg0, &len))
                 return false;
 
             // avoid overflow; we know that offset <= length
             if (len > tarray->length - offset) {
                 JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
                                      JSMSG_TYPED_ARRAY_BAD_ARGS);
                 return false;
             }
 
             if (!tarray->copyFrom(cx, arg0, len, offset))
                 return false;
-        } else {
-            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
-                                 JSMSG_TYPED_ARRAY_BAD_ARGS);
-            return false;
         }
 
         vp->setUndefined();
         return true;
     }
 
     static ThisTypeArray *
     fromJSObject(JSObject *obj)
@@ -984,47 +980,28 @@ class TypedArrayTemplate
         type = ArrayTypeID();
         return createBufferWithSizeAndCount(cx, sizeof(NativeType), len);
     }
 
     bool
     init(JSContext *cx, JSObject *other, int32 byteOffsetInt = -1, int32 lengthInt = -1)
     {
         type = ArrayTypeID();
-
-        //printf ("Constructing with type %d other %p offset %d length %d\n", type, other, byteOffset, length);
+        ArrayBuffer *abuf;
 
-        if (other->wrappedObject(cx)->isArray()) {
-            jsuint len;
-            if (!js_GetLengthProperty(cx, other, &len))
-                return false;
-            if (!createBufferWithSizeAndCount(cx, sizeof(NativeType), len))
-                return false;
-            if (!copyFrom(cx, other, len))
-                return false;
-        } else if (js_IsTypedArray(other)) {
+        if (js_IsTypedArray(other)) {
             TypedArray *tarray = TypedArray::fromJSObject(other);
             JS_ASSERT(tarray);
 
-            //printf ("SizeAndCount: %d %d\n", sizeof(NativeType), tarray->length);
-
             if (!createBufferWithSizeAndCount(cx, sizeof(NativeType), tarray->length))
                 return false;
             if (!copyFrom(cx, tarray))
                 return false;
-        } else if (other->getClass() == &ArrayBuffer::jsclass) {
-            ArrayBuffer *abuf = ArrayBuffer::fromJSObject(other);
-
-            if (!abuf) {
-                // the arg isn't a real arraybuffer
-                JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
-                                     JSMSG_TYPED_ARRAY_BAD_ARGS);
-                return false;
-            }
-
+        } else if (other->getClass() == &ArrayBuffer::jsclass &&
+                   ((abuf = ArrayBuffer::fromJSObject(other)) != NULL)) {
             uint32 boffset = (byteOffsetInt < 0) ? 0 : uint32(byteOffsetInt);
 
             if (boffset > abuf->byteLength || boffset % sizeof(NativeType) != 0) {
                 JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
                                      JSMSG_TYPED_ARRAY_BAD_ARGS);
                 return false; // invalid byteOffset
             }
 
@@ -1058,19 +1035,23 @@ class TypedArrayTemplate
 
             buffer = abuf;
             bufferJS = other;
             byteOffset = boffset;
             byteLength = arrayByteLength;
             length = len;
             data = abuf->offsetData(boffset);
         } else {
-            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
-                                 JSMSG_TYPED_ARRAY_BAD_ARGS);
-            return false;
+            jsuint len;
+            if (!js_GetLengthProperty(cx, other, &len))
+                return false;
+            if (!createBufferWithSizeAndCount(cx, sizeof(NativeType), len))
+                return false;
+            if (!copyFrom(cx, other, len))
+                return false;
         }
 
         return true;
     }
 
     const NativeType
     getIndex(uint32 index) const
     {
--- a/js/src/jsvalue.h
+++ b/js/src/jsvalue.h
@@ -982,18 +982,17 @@ struct ClassSizeMeasurement {
     JS_CLASS_MEMBERS;
 };
 
 struct ClassExtension {
     EqualityOp          equality;
     JSObjectOp          outerObject;
     JSObjectOp          innerObject;
     JSIteratorOp        iteratorObject;
-    JSObjectOp          wrappedObject;  /* NB: infallible, null returns are
-                                           treated as the original object */
+    void               *unused;
 };
 
 #define JS_NULL_CLASS_EXT   {NULL,NULL,NULL,NULL,NULL}
 
 struct ObjectOps {
     js::LookupPropOp        lookupProperty;
     js::DefinePropOp        defineProperty;
     js::PropertyIdOp        getProperty;
--- a/js/src/jswrapper.h
+++ b/js/src/jswrapper.h
@@ -94,17 +94,17 @@ class JS_FRIEND_API(JSWrapper) : public 
     virtual bool enter(JSContext *cx, JSObject *wrapper, jsid id, Action act);
     virtual void leave(JSContext *cx, JSObject *wrapper);
 
     static JSWrapper singleton;
 
     static JSObject *New(JSContext *cx, JSObject *obj, JSObject *proto, JSObject *parent,
                          JSWrapper *handler);
 
-    static inline JSObject *wrappedObject(JSObject *wrapper) {
+    static inline JSObject *wrappedObject(const JSObject *wrapper) {
         return wrapper->getProxyPrivate().toObjectOrNull();
     }
 
     static void *getWrapperFamily();
 };
 
 /* Base class for all cross compartment wrapper handlers. */
 class JS_FRIEND_API(JSCrossCompartmentWrapper) : public JSWrapper {
--- a/js/src/methodjit/Compiler.cpp
+++ b/js/src/methodjit/Compiler.cpp
@@ -4254,23 +4254,16 @@ mjit::Compiler::jsop_instanceof()
     obj = frame.copyDataIntoReg(lhs);
     RegisterID proto = frame.copyDataIntoReg(rhs);
     RegisterID temp = frame.allocReg();
 
     MaybeJump isFalse;
     if (!lhs->isTypeKnown())
         isFalse = frame.testPrimitive(Assembler::Equal, lhs);
 
-    /* Quick test to avoid wrapped objects. */
-    masm.loadPtr(Address(obj, offsetof(JSObject, clasp)), temp);
-    masm.loadPtr(Address(temp, offsetof(Class, ext) +
-                              offsetof(ClassExtension, wrappedObject)), temp);
-    j = masm.branchTestPtr(Assembler::NonZero, temp, temp);
-    stubcc.linkExit(j, Uses(3));
-
     Address protoAddr(obj, offsetof(JSObject, proto));
     Label loop = masm.label();
 
     /* Walk prototype chain, break out on NULL or hit. */
     masm.loadPayload(protoAddr, obj);
     Jump isFalse2 = masm.branchTestPtr(Assembler::Zero, obj, obj);
     Jump isTrue = masm.branchPtr(Assembler::NotEqual, obj, proto);
     isTrue.linkTo(loop, &masm);
--- a/js/src/tests/js1_8_5/extensions/typedarray.js
+++ b/js/src/tests/js1_8_5/extensions/typedarray.js
@@ -255,19 +255,19 @@ function test()
     checkThrows(function() a.set([1,2,3,4,5,6,7,8,9,10], 0));
     checkThrows(function() a.set([1,2,3,4,5,6,7,8,9,10], 0x7fffffff));
     checkThrows(function() a.set([1,2,3,4,5,6,7,8,9,10], 0xffffffff));
     checkThrows(function() a.set([1,2,3,4,5,6], 6));
 
     checkThrows(function() a.set(new Array(0x7fffffff)));
     checkThrows(function() a.set([1,2,3], 2147483647));
 
-    checkThrows(function() a.set(ArrayBuffer.prototype));
-    checkThrows(function() a.set(UInt16Array.prototype));
-    checkThrows(function() a.set(Int32Array.prototype));
+    a.set(ArrayBuffer.prototype);
+    a.set(Int16Array.prototype);
+    a.set(Int32Array.prototype);
 
     a.set([1,2,3]);
     a.set([4,5,6], 3);
     check(function()
           a[0] == 1 && a[1] == 2 && a[2] == 3 &&
           a[3] == 4 && a[4] == 5 && a[5] == 6 &&
           a[6] == 0 && a[7] == 0 && a[8] == 0);
 
@@ -300,22 +300,26 @@ function test()
     a = new ArrayBuffer(0x10);
     checkThrows(function() new Uint32Array(buffer, 4, 0x3FFFFFFF));
 
     checkThrows(function() new Float32Array(null));
 
     a = new Uint8Array(0x100);
     checkThrows(function() Uint32Array.prototype.slice.apply(a, [0, 0x100]));
 
-    checkThrows(function() new Int32Array(ArrayBuffer.prototype));
-    checkThrows(function() new Int32Array(Int32Array.prototype));
-    checkThrows(function() new Int32Array(Float64Array.prototype));
-    checkThrows(function() new Int32Array(ArrayBuffer));
-    checkThrows(function() new Int32Array(Int32Array));
-    checkThrows(function() new Int32Array(Float64Array));
+    // The prototypes are objects that don't have a length property, so they act
+    // like empty arrays.
+    check(function() new Int32Array(ArrayBuffer.prototype).length == 0);
+    check(function() new Int32Array(Int32Array.prototype).length == 0);
+    check(function() new Int32Array(Float64Array.prototype).length == 0);
+
+    // ArrayBuffer, Int32Array and Float64Array are native functions and have a .length
+    // checkThrows(function() new Int32Array(ArrayBuffer));
+    // checkThrows(function() new Int32Array(Int32Array));
+    // checkThrows(function() new Int32Array(Float64Array));
 
     check(function() Int32Array.BYTES_PER_ELEMENT == 4);
     check(function() (new Int32Array(4)).BYTES_PER_ELEMENT == 4);
     check(function() (new Int32Array()).BYTES_PER_ELEMENT == 4);
     check(function() (new Int32Array(0)).BYTES_PER_ELEMENT == 4);
     check(function() Int16Array.BYTES_PER_ELEMENT == Uint16Array.BYTES_PER_ELEMENT);
 
     print ("done");