bool SetObject::construct(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (!ThrowIfNotConstructing(cx, args, "Set")) return false; RootedObject proto(cx); RootedObject newTarget(cx, &args.newTarget().toObject()); if (!GetPrototypeFromConstructor(cx, newTarget, &proto)) return false; Rooted<SetObject*> obj(cx, SetObject::create(cx, proto)); if (!obj) return false; if (!args.get(0).isNullOrUndefined()) { RootedValue iterable(cx, args[0]); bool optimized = false; if (!IsOptimizableInitForSet<GlobalObject::getOrCreateSetPrototype, isBuiltinAdd>(cx, obj, iterable, &optimized)) return false; if (optimized) { RootedValue keyVal(cx); Rooted<HashableValue> key(cx); ValueSet* set = obj->getData(); ArrayObject* array = &iterable.toObject().as<ArrayObject>(); for (uint32_t index = 0; index < array->getDenseInitializedLength(); ++index) { keyVal.set(array->getDenseElement(index)); MOZ_ASSERT(!keyVal.isMagic(JS_ELEMENTS_HOLE)); if (!key.setValue(cx, keyVal)) return false; if (!WriteBarrierPost(cx->runtime(), obj, keyVal) || !set->put(key)) { ReportOutOfMemory(cx); return false; } } } else { FixedInvokeArgs<1> args2(cx); args2[0].set(args[0]); RootedValue thisv(cx, ObjectValue(*obj)); if (!CallSelfHostedFunction(cx, cx->names().SetConstructorInit, thisv, args2, args2.rval())) return false; } } args.rval().setObject(*obj); return true; }
bool SetObject::add(JSContext* cx, HandleObject obj, HandleValue k) { ValueSet* set = obj->as<SetObject>().getData(); if (!set) return false; Rooted<HashableValue> key(cx); if (!key.setValue(cx, k)) return false; if (!set->put(key)) { ReportOutOfMemory(cx); return false; } WriteBarrierPost(cx->runtime(), set, key.value()); return true; }
// management of the killed-bitset for global value numbering void kill_value(Value v) { if (is_global_value_numbering()) _killed_values.put(v); }
bool SetObject::construct(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (!ThrowIfNotConstructing(cx, args, "Set")) return false; RootedObject proto(cx); RootedObject newTarget(cx, &args.newTarget().toObject()); if (!GetPrototypeFromConstructor(cx, newTarget, &proto)) return false; Rooted<SetObject*> obj(cx, SetObject::create(cx, proto)); if (!obj) return false; if (!args.get(0).isNullOrUndefined()) { RootedValue adderVal(cx); if (!GetProperty(cx, obj, obj, cx->names().add, &adderVal)) return false; if (!IsCallable(adderVal)) return ReportIsNotFunction(cx, adderVal); bool isOriginalAdder = IsNativeFunction(adderVal, SetObject::add); RootedValue setVal(cx, ObjectValue(*obj)); FastCallGuard fig(cx, adderVal); InvokeArgs& args2 = fig.args(); RootedValue keyVal(cx); ForOfIterator iter(cx); if (!iter.init(args[0])) return false; Rooted<HashableValue> key(cx); RootedValue dummy(cx); ValueSet* set = obj->getData(); while (true) { bool done; if (!iter.next(&keyVal, &done)) return false; if (done) break; if (isOriginalAdder) { if (!key.setValue(cx, keyVal)) return false; if (!set->put(key)) { ReportOutOfMemory(cx); return false; } WriteBarrierPost(cx->runtime(), set, keyVal); } else { if (!args2.init(1)) return false; args2[0].set(keyVal); if (!fig.call(cx, adderVal, setVal, &dummy)) return false; } } } args.rval().setObject(*obj); return true; }
void set_processed(Value v) { _processed_values.put(v); }