Example #1
0
bool
MapObject::set(JSContext* cx, HandleObject obj, HandleValue k, HandleValue v)
{
    ValueMap* map = obj->as<MapObject>().getData();
    if (!map)
        return false;

    Rooted<HashableValue> key(cx);
    if (!key.setValue(cx, k))
        return false;

    HeapPtr<Value> rval(v);
    if (!map->put(key, rval)) {
        ReportOutOfMemory(cx);
        return false;
    }
    WriteBarrierPost(cx->runtime(), map, key.value());
    return true;
}
Example #2
0
bool
MapObject::construct(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);

    if (!ThrowIfNotConstructing(cx, args, "Map"))
        return false;

    RootedObject proto(cx);
    RootedObject newTarget(cx, &args.newTarget().toObject());
    if (!GetPrototypeFromConstructor(cx, newTarget, &proto))
        return false;

    Rooted<MapObject*> obj(cx, MapObject::create(cx, proto));
    if (!obj)
        return false;

    if (!args.get(0).isNullOrUndefined()) {
        RootedValue adderVal(cx);
        if (!GetProperty(cx, obj, obj, cx->names().set, &adderVal))
            return false;

        if (!IsCallable(adderVal))
            return ReportIsNotFunction(cx, adderVal);

        bool isOriginalAdder = IsNativeFunction(adderVal, MapObject::set);
        RootedValue mapVal(cx, ObjectValue(*obj));
        FastCallGuard fig(cx, adderVal);
        InvokeArgs& args2 = fig.args();

        ForOfIterator iter(cx);
        if (!iter.init(args[0]))
            return false;

        RootedValue pairVal(cx);
        RootedObject pairObj(cx);
        RootedValue dummy(cx);
        Rooted<HashableValue> hkey(cx);
        ValueMap* map = obj->getData();
        while (true) {
            bool done;
            if (!iter.next(&pairVal, &done))
                return false;
            if (done)
                break;
            if (!pairVal.isObject()) {
                JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
                                     JSMSG_INVALID_MAP_ITERABLE, "Map");
                return false;
            }

            pairObj = &pairVal.toObject();
            if (!pairObj)
                return false;

            RootedValue key(cx);
            if (!GetElement(cx, pairObj, pairObj, 0, &key))
                return false;

            RootedValue val(cx);
            if (!GetElement(cx, pairObj, pairObj, 1, &val))
                return false;

            if (isOriginalAdder) {
                if (!hkey.setValue(cx, key))
                    return false;

                HeapPtr<Value> rval(val);
                if (!map->put(hkey, rval)) {
                    ReportOutOfMemory(cx);
                    return false;
                }
                WriteBarrierPost(cx->runtime(), map, key);
            } else {
                if (!args2.init(2))
                    return false;

                args2[0].set(key);
                args2[1].set(val);

                if (!fig.call(cx, adderVal, mapVal, &dummy))
                    return false;
            }
        }
    }

    args.rval().setObject(*obj);
    return true;
}