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;
}
Exemple #2
0
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);
 }
Exemple #4
0
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;
}
Exemple #5
0
 void          set_processed(Value v)           { _processed_values.put(v); }