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, obj); if (!map->init()) { cx->delete_(map); goto out_of_memory; } obj->setPrivate(map); } if (!map->put(key, value)) goto out_of_memory; args.rval().setUndefined(); return true; out_of_memory: JS_ReportOutOfMemory(cx); return false; }
JS_NondeterministicGetWeakMapKeys(JSContext *cx, JSObject *obj, JSObject **ret) { obj = UnwrapObject(obj); if (!obj || !obj->isWeakMap()) { *ret = NULL; return true; } RootedObject arr(cx, NewDenseEmptyArray(cx)); if (!arr) return false; ObjectValueMap *map = GetObjectMap(obj); if (map) { for (ObjectValueMap::Base::Range r = map->all(); !r.empty(); r.popFront()) { RootedObject key(cx, r.front().key); if (!JS_WrapObject(cx, key.address())) return false; if (!js_NewbornArrayPush(cx, arr, ObjectValue(*key))) return false; } } *ret = arr; return true; }
static MOZ_ALWAYS_INLINE bool SetWeakMapEntryInternal(JSContext* cx, Handle<WeakMapObject*> mapObj, HandleObject key, HandleValue value) { ObjectValueMap* map = mapObj->getMap(); if (!map) { AutoInitGCManagedObject<ObjectValueMap> 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()->ext.weakmapKeyDelegateOp) { 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; } WeakMapPostWriteBarrier(cx->runtime(), map, key.get()); return true; }
JS_NondeterministicGetWeakMapKeys(JSContext *cx, JSObject *obj, JSObject **ret) { if (!obj || !obj->isWeakMap()) { *ret = NULL; return true; } RootedVarObject arr(cx, NewDenseEmptyArray(cx)); if (!arr) return false; ObjectValueMap *map = GetObjectMap(obj); if (map) { for (ObjectValueMap::Range r = map->nondeterministicAll(); !r.empty(); r.popFront()) { JSObject *key = r.front().key; // Re-wrapping the key (see comment of GetKeyArg) if (!JS_WrapObject(cx, &key)) return false; if (!js_NewbornArrayPush(cx, arr, ObjectValue(*key))) return false; } } *ret = arr; return true; }