static MOZ_ALWAYS_INLINE bool SetWeakMapEntryInternal(JSContext* cx, Handle<WeakMapObject*> mapObj, HandleObject key, HandleValue value) { ObjectValueMap* map = mapObj->getMap(); if (!map) { auto newMap = cx->make_unique<ObjectValueMap>(cx, mapObj.get()); if (!newMap) return false; if (!newMap->init()) { JS_ReportOutOfMemory(cx); return false; } map = newMap.release(); mapObj->setPrivate(map); } // Preserve wrapped native keys to prevent wrapper optimization. if (!TryPreserveReflector(cx, key)) return false; if (JSWeakmapKeyDelegateOp op = key->getClass()->extWeakmapKeyDelegateOp()) { RootedObject delegate(cx, op(key)); if (delegate && !TryPreserveReflector(cx, delegate)) return false; } MOZ_ASSERT(key->compartment() == mapObj->compartment()); MOZ_ASSERT_IF(value.isObject(), value.toObject().compartment() == mapObj->compartment()); if (!map->put(key, value)) { JS_ReportOutOfMemory(cx); return false; } return true; }
JS_ALWAYS_INLINE bool WeakMap_set_impl(JSContext *cx, CallArgs args) { JS_ASSERT(IsWeakMap(args.thisv())); if (args.length() < 1) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_MORE_ARGS_NEEDED, "WeakMap.set", "0", "s"); return false; } RootedObject key(cx, GetKeyArg(cx, args)); if (!key) return false; Value value = (args.length() > 1) ? args[1] : UndefinedValue(); Rooted<JSObject*> thisObj(cx, &args.thisv().toObject()); ObjectValueMap *map = GetObjectMap(thisObj); if (!map) { map = cx->new_<ObjectValueMap>(cx, thisObj.get()); if (!map->init()) { js_delete(map); JS_ReportOutOfMemory(cx); return false; } thisObj->setPrivate(map); } // Preserve wrapped native keys to prevent wrapper optimization. if (key->getClass()->ext.isWrappedNative || (key->getClass()->flags & JSCLASS_IS_DOMJSCLASS) || (key->isProxy() && GetProxyHandler(key)->family() == GetListBaseHandlerFamily())) { JS_ASSERT(cx->runtime->preserveWrapperCallback); if (!cx->runtime->preserveWrapperCallback(cx, key)) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_WEAKMAP_KEY); return false; } } JS_ASSERT(key->compartment() == thisObj->compartment()); JS_ASSERT_IF(value.isObject(), value.toObject().compartment() == thisObj->compartment()); if (!map->put(key, value)) { JS_ReportOutOfMemory(cx); return false; } HashTableWriteBarrierPost(cx->compartment, map, key); args.rval().setUndefined(); return true; }
MOZ_ALWAYS_INLINE bool WeakMap_set_impl(JSContext *cx, CallArgs args) { JS_ASSERT(IsWeakMap(args.thisv())); if (args.length() < 1) { JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED, "WeakMap.set", "0", "s"); return false; } RootedObject key(cx, GetKeyArg(cx, args)); if (!key) return false; RootedValue value(cx, (args.length() > 1) ? args[1] : UndefinedValue()); Rooted<JSObject*> thisObj(cx, &args.thisv().toObject()); ObjectValueMap *map = thisObj->as<WeakMapObject>().getMap(); if (!map) { map = cx->new_<ObjectValueMap>(cx, thisObj.get()); if (!map->init()) { js_delete(map); JS_ReportOutOfMemory(cx); return false; } thisObj->setPrivate(map); } // Preserve wrapped native keys to prevent wrapper optimization. if (!TryPreserveReflector(cx, key)) return false; if (JSWeakmapKeyDelegateOp op = key->getClass()->ext.weakmapKeyDelegateOp) { RootedObject delegate(cx, op(key)); if (delegate && !TryPreserveReflector(cx, delegate)) return false; } JS_ASSERT(key->compartment() == thisObj->compartment()); JS_ASSERT_IF(value.isObject(), value.toObject().compartment() == thisObj->compartment()); if (!map->put(key, value)) { JS_ReportOutOfMemory(cx); return false; } WeakMapPostWriteBarrier(cx->runtime(), map, key.get()); args.rval().setUndefined(); return true; }
static JSBool WeakMap_set(JSContext *cx, unsigned argc, Value *vp) { CallArgs args = CallArgsFromVp(argc, vp); bool ok; JSObject *obj = NonGenericMethodGuard(cx, args, WeakMap_set, &WeakMapClass, &ok); if (!obj) return ok; if (args.length() < 1) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_MORE_ARGS_NEEDED, "WeakMap.set", "0", "s"); return false; } JSObject *key = GetKeyArg(cx, args); if (!key) return false; Value value = (args.length() > 1) ? args[1] : UndefinedValue(); ObjectValueMap *map = GetObjectMap(obj); if (!map) { map = cx->new_<ObjectValueMap>(cx, obj); if (!map->init()) { cx->delete_(map); goto out_of_memory; } obj->setPrivate(map); } if (!map->put(key, value)) goto out_of_memory; // Preserve wrapped native keys to prevent wrapper optimization. if (key->getClass()->ext.isWrappedNative) { if (!cx->runtime->preserveWrapperCallback || !cx->runtime->preserveWrapperCallback(cx, key)) { JS_ReportWarning(cx, "Failed to preserve wrapper of wrapped native weak map key."); } } args.rval().setUndefined(); return true; out_of_memory: JS_ReportOutOfMemory(cx); return false; }
static bool WeakMap_set_impl(JSContext *cx, CallArgs args) { JS_ASSERT(IsWeakMap(args.thisv())); if (args.length() < 1) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_MORE_ARGS_NEEDED, "WeakMap.set", "0", "s"); return false; } JSObject *key = GetKeyArg(cx, args); if (!key) return false; Value value = (args.length() > 1) ? args[1] : UndefinedValue(); Rooted<JSObject*> thisObj(cx, &args.thisv().toObject()); ObjectValueMap *map = GetObjectMap(thisObj); if (!map) { map = cx->new_<ObjectValueMap>(cx, thisObj.get()); if (!map->init()) { cx->delete_(map); JS_ReportOutOfMemory(cx); return false; } thisObj->setPrivate(map); } if (!map->put(key, value)) { JS_ReportOutOfMemory(cx); return false; } // Preserve wrapped native keys to prevent wrapper optimization. if (key->getClass()->ext.isWrappedNative) { if (!cx->runtime->preserveWrapperCallback || !cx->runtime->preserveWrapperCallback(cx, key)) { JS_ReportWarning(cx, "Failed to preserve wrapper of wrapped native weak map key."); } } args.rval().setUndefined(); return true; }
static JSBool WeakMap_set(JSContext *cx, uintN argc, Value *vp) { CallArgs args = CallArgsFromVp(argc, vp); bool ok; JSObject *obj = NonGenericMethodGuard(cx, args, WeakMap_set, &WeakMapClass, &ok); if (!obj) return ok; if (args.length() < 1) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_MORE_ARGS_NEEDED, "WeakMap.set", "0", "s"); return false; } JSObject *key = NonNullObject(cx, &args[0]); if (!key) return false; Value value = (args.length() > 1) ? args[1] : UndefinedValue(); ObjectValueMap *map = GetObjectMap(obj); if (!map) { map = cx->new_<ObjectValueMap>(cx); if (!map->init()) { cx->delete_(map); goto out_of_memory; } obj->setPrivate(map); } args.thisv() = UndefinedValue(); if (!map->put(key, value)) goto out_of_memory; return true; out_of_memory: JS_ReportOutOfMemory(cx); return false; }
MOZ_ALWAYS_INLINE bool SetWeakMapEntryInternal(JSContext *cx, Handle<WeakMapObject*> mapObj, HandleObject key, HandleValue value) { ObjectValueMap *map = mapObj->getMap(); if (!map) { map = cx->new_<ObjectValueMap>(cx, mapObj.get()); if (!map) return false; if (!map->init()) { js_delete(map); JS_ReportOutOfMemory(cx); return false; } mapObj->setPrivate(map); } // Preserve wrapped native keys to prevent wrapper optimization. if (!TryPreserveReflector(cx, key)) return false; if (JSWeakmapKeyDelegateOp op = key->getClass()->ext.weakmapKeyDelegateOp) { RootedObject delegate(cx, op(key)); if (delegate && !TryPreserveReflector(cx, delegate)) return false; } JS_ASSERT(key->compartment() == mapObj->compartment()); JS_ASSERT_IF(value.isObject(), value.toObject().compartment() == mapObj->compartment()); if (!map->put(key, value)) { JS_ReportOutOfMemory(cx); return false; } WeakMapPostWriteBarrier(cx->runtime(), map, key.get()); return true; }