Bug 804279 - Part4: Support monkey-patched/overridden adder in WeakSet constructor. r=evilpie
☠☠ backed out by 44d7ea20541f ☠ ☠
authorTooru Fujisawa <arai_a@mac.com>
Mon, 01 Dec 2014 17:02:15 +0900
changeset 218446 d74f3695730383f64e2622cf0c4e81ffe673fd46
parent 218445 7dcbacf3d65967ed40f8d5c23a3132545ce753fe
child 218447 6717479ac35a71dbe82bf63dd489ea0718cf43e6
push idunknown
push userunknown
push dateunknown
reviewersevilpie
bugs804279
milestone37.0a1
Bug 804279 - Part4: Support monkey-patched/overridden adder in WeakSet constructor. r=evilpie
js/src/builtin/WeakSetObject.cpp
js/src/vm/CommonPropertyNames.h
--- a/js/src/builtin/WeakSetObject.cpp
+++ b/js/src/builtin/WeakSetObject.cpp
@@ -7,16 +7,17 @@
 #include "builtin/WeakSetObject.h"
 
 #include "jsapi.h"
 #include "jscntxt.h"
 #include "jsiter.h"
 
 #include "builtin/SelfHostingDefines.h"
 #include "vm/GlobalObject.h"
+#include "vm/SelfHosting.h"
 
 #include "jsobjinlines.h"
 
 #include "vm/NativeObject-inl.h"
 
 using namespace js;
 
 const Class WeakSetObject::class_ = {
@@ -93,38 +94,64 @@ WeakSetObject::construct(JSContext *cx, 
     if (!args.isConstructing()) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_NOT_FUNCTION, "WeakSet");
         return false;
     }
 
     if (!args.get(0).isNullOrUndefined()) {
         RootedObject map(cx, &obj->getReservedSlot(WEAKSET_MAP_SLOT).toObject());
 
+        RootedValue adderVal(cx);
+        if (!JSObject::getProperty(cx, obj, obj, cx->names().add, &adderVal))
+            return false;
+
+        if (!IsCallable(adderVal))
+            return ReportIsNotFunction(cx, adderVal);
+
+        JSFunction *adder;
+        bool isOriginalAdder = IsFunctionObject(adderVal, &adder) &&
+                               IsSelfHostedFunctionWithName(adder, cx->names().WeakSet_add);
+        RootedValue setVal(cx, ObjectValue(*obj));
+        FastInvokeGuard fig(cx, adderVal);
+        InvokeArgs &args2 = fig.args();
+
         JS::ForOfIterator iter(cx);
         if (!iter.init(args[0]))
             return false;
 
         RootedValue keyVal(cx);
         RootedObject keyObject(cx);
         RootedValue placeholder(cx, BooleanValue(true));
         while (true) {
             bool done;
             if (!iter.next(&keyVal, &done))
                 return false;
             if (done)
                 break;
 
-            if (keyVal.isPrimitive()) {
-                JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT);
-                return false;
+            if (isOriginalAdder) {
+                if (keyVal.isPrimitive()) {
+                    JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT);
+                    return false;
+                }
+
+                keyObject = &keyVal.toObject();
+                if (!SetWeakMapEntry(cx, map, keyObject, placeholder))
+                    return false;
+            } else {
+                if (!args2.init(1))
+                    return false;
+
+                args2.setCallee(adderVal);
+                args2.setThis(setVal);
+                args2[0].set(keyVal);
+
+                if (!fig.invoke(cx))
+                    return false;
             }
-
-            keyObject = &keyVal.toObject();
-            if (!SetWeakMapEntry(cx, map, keyObject, placeholder))
-                return false;
         }
     }
 
     args.rval().setObject(*obj);
     return true;
 }
 
 
--- a/js/src/vm/CommonPropertyNames.h
+++ b/js/src/vm/CommonPropertyNames.h
@@ -209,16 +209,17 @@
     macro(useAsm, useAsm, "use asm") \
     macro(useStrict, useStrict, "use strict") \
     macro(value, value, "value") \
     macro(valueOf, valueOf, "valueOf") \
     macro(var, var, "var") \
     macro(variable, variable, "variable") \
     macro(void0, void0, "(void 0)") \
     macro(watch, watch, "watch") \
+    macro(WeakSet_add, WeakSet_add, "WeakSet_add") \
     macro(writable, writable, "writable") \
     macro(w, w, "w") \
     macro(x, x, "x") \
     macro(y, y, "y") \
     macro(yield, yield, "yield") \
     macro(z, z, "z") \
     macro(raw, raw, "raw") \
     /* Type names must be contiguous and ordered; see js::TypeName. */ \