Example #1
0
JS_NondeterministicGetWeakMapKeys(JSContext* cx, HandleObject objArg, MutableHandleObject ret)
{
    RootedObject obj(cx, objArg);
    obj = UncheckedUnwrap(obj);
    if (!obj || !obj->is<WeakMapObject>()) {
        ret.set(nullptr);
        return true;
    }
    RootedObject arr(cx, NewDenseEmptyArray(cx));
    if (!arr)
        return false;
    ObjectValueMap* map = obj->as<WeakMapObject>().getMap();
    if (map) {
        // Prevent GC from mutating the weakmap while iterating.
        AutoSuppressGC suppress(cx);
        for (ObjectValueMap::Base::Range r = map->all(); !r.empty(); r.popFront()) {
            JS::ExposeObjectToActiveJS(r.front().key());
            RootedObject key(cx, r.front().key());
            if (!cx->compartment()->wrap(cx, &key))
                return false;
            if (!NewbornArrayPush(cx, arr, ObjectValue(*key)))
                return false;
        }
    }
    ret.set(arr);
    return true;
}
Example #2
0
bool
WrapperFactory::WaiveXrayAndWrap(JSContext *cx, MutableHandleObject argObj)
{
    MOZ_ASSERT(argObj);
    RootedObject obj(cx, js::UncheckedUnwrap(argObj));
    MOZ_ASSERT(!js::IsInnerObject(obj));
    if (js::IsObjectInContextCompartment(obj, cx)) {
        argObj.set(obj);
        return true;
    }

    // Even though waivers have no effect on access by scopes that don't subsume
    // the underlying object, good defense-in-depth dictates that we should avoid
    // handing out waivers to callers that can't use them. The transitive waiving
    // machinery unconditionally calls WaiveXrayAndWrap on return values from
    // waived functions, even though the return value might be not be same-origin
    // with the function. So if we find ourselves trying to create a waiver for
    // |cx|, we should check whether the caller has any business with waivers
    // to things in |obj|'s compartment.
    JSCompartment *target = js::GetContextCompartment(cx);
    JSCompartment *origin = js::GetObjectCompartment(obj);
    obj = AccessCheck::subsumes(target, origin) ? WaiveXray(cx, obj) : obj;
    if (!obj)
        return false;

    if (!JS_WrapObject(cx, &obj))
        return false;
    argObj.set(obj);
    return true;
}
Example #3
0
static bool
strictargs_resolve(JSContext *cx, HandleObject obj, HandleId id, MutableHandleObject objp)
{
    objp.set(nullptr);

    Rooted<StrictArgumentsObject*> argsobj(cx, &obj->as<StrictArgumentsObject>());

    unsigned attrs = JSPROP_SHARED | JSPROP_SHADOWABLE;
    PropertyOp getter = StrictArgGetter;
    StrictPropertyOp setter = StrictArgSetter;

    if (JSID_IS_INT(id)) {
        uint32_t arg = uint32_t(JSID_TO_INT(id));
        if (arg >= argsobj->initialLength() || argsobj->isElementDeleted(arg))
            return true;

        attrs |= JSPROP_ENUMERATE;
    } else if (JSID_IS_ATOM(id, cx->names().length)) {
        if (argsobj->hasOverriddenLength())
            return true;
    } else {
        if (!JSID_IS_ATOM(id, cx->names().callee) && !JSID_IS_ATOM(id, cx->names().caller))
            return true;

        attrs = JSPROP_PERMANENT | JSPROP_GETTER | JSPROP_SETTER | JSPROP_SHARED;
        getter = CastAsPropertyOp(argsobj->global().getThrowTypeError());
        setter = CastAsStrictPropertyOp(argsobj->global().getThrowTypeError());
    }

    if (!baseops::DefineGeneric(cx, argsobj, id, UndefinedHandleValue, getter, setter, attrs))
        return false;

    objp.set(argsobj);
    return true;
}
Example #4
0
static JSBool
args_resolve(JSContext *cx, HandleObject obj, HandleId id, unsigned flags,
             MutableHandleObject objp)
{
    objp.set(NULL);

    Rooted<NormalArgumentsObject*> argsobj(cx, &obj->as<NormalArgumentsObject>());

    unsigned attrs = JSPROP_SHARED | JSPROP_SHADOWABLE;
    if (JSID_IS_INT(id)) {
        uint32_t arg = uint32_t(JSID_TO_INT(id));
        if (arg >= argsobj->initialLength() || argsobj->isElementDeleted(arg))
            return true;

        attrs |= JSPROP_ENUMERATE;
    } else if (JSID_IS_ATOM(id, cx->names().length)) {
        if (argsobj->hasOverriddenLength())
            return true;
    } else {
        if (!JSID_IS_ATOM(id, cx->names().callee))
            return true;

        if (argsobj->callee().isMagic(JS_OVERWRITTEN_CALLEE))
            return true;
    }

    RootedValue undef(cx, UndefinedValue());
    if (!baseops::DefineGeneric(cx, argsobj, id, undef, ArgGetter, ArgSetter, attrs))
        return JS_FALSE;

    objp.set(argsobj);
    return true;
}
Example #5
0
static bool
WrapForSameCompartment(JSContext *cx, MutableHandleObject obj, const JSWrapObjectCallbacks *cb)
{
    JS_ASSERT(cx->compartment() == obj->compartment());
    if (!cb->sameCompartmentWrap)
        return true;

    RootedObject wrapped(cx, cb->sameCompartmentWrap(cx, obj));
    if (!wrapped)
        return false;
    obj.set(wrapped);
    return true;
}
Example #6
0
bool
JSCompartment::getNonWrapperObjectForCurrentCompartment(JSContext* cx, MutableHandleObject obj)
{
    // Ensure that we have entered a compartment.
    MOZ_ASSERT(cx->global());

    // If we have a cross-compartment wrapper, make sure that the cx isn't
    // associated with the self-hosting global. We don't want to create
    // wrappers for objects in other runtimes, which may be the case for the
    // self-hosting global.
    MOZ_ASSERT(!cx->runtime()->isSelfHostingGlobal(cx->global()));
    MOZ_ASSERT(!cx->runtime()->isSelfHostingGlobal(&obj->global()));

    // The object is already in the right compartment. Normally same-
    // compartment returns the object itself, however, windows are always
    // wrapped by a proxy, so we have to check for that case here manually.
    if (obj->compartment() == this) {
        obj.set(ToWindowProxyIfWindow(obj));
        return true;
    }

    // Note that if the object is same-compartment, but has been wrapped into a
    // different compartment, we need to unwrap it and return the bare same-
    // compartment object. Note again that windows are always wrapped by a
    // WindowProxy even when same-compartment so take care not to strip this
    // particular wrapper.
    RootedObject objectPassedToWrap(cx, obj);
    obj.set(UncheckedUnwrap(obj, /* stopAtWindowProxy = */ true));
    if (obj->compartment() == this) {
        MOZ_ASSERT(!IsWindow(obj));
        return true;
    }

    // Invoke the prewrap callback. The prewrap callback is responsible for
    // doing similar reification as above, but can account for any additional
    // embedder requirements.
    //
    // We're a bit worried about infinite recursion here, so we do a check -
    // see bug 809295.
    auto preWrap = cx->runtime()->wrapObjectCallbacks->preWrap;
    if (!CheckSystemRecursionLimit(cx))
        return false;
    if (preWrap) {
        preWrap(cx, cx->global(), obj, objectPassedToWrap, obj);
        if (!obj)
            return false;
    }
    MOZ_ASSERT(!IsWindow(obj));

    return true;
}
Example #7
0
static bool
WrapForSameCompartment(JSContext *cx, MutableHandleObject obj)
{
    JS_ASSERT(cx->compartment() == obj->compartment());
    if (!cx->runtime()->sameCompartmentWrapObjectCallback)
        return true;

    RootedObject wrapped(cx);
    wrapped = cx->runtime()->sameCompartmentWrapObjectCallback(cx, obj);
    if (!wrapped)
        return false;
    obj.set(wrapped);
    return true;
}
Example #8
0
static bool
CreateExportObject(JSContext* cx, Handle<WasmModuleObject*> moduleObj, const ExportMap& exportMap,
                   const ExportVector& exports, MutableHandleObject exportObj)
{
    MOZ_ASSERT(exportMap.exportNames.length() == exports.length());
    MOZ_ASSERT(exportMap.fieldNames.length() == exportMap.fieldsToExports.length());

    for (size_t fieldIndex = 0; fieldIndex < exportMap.fieldNames.length(); fieldIndex++) {
        const char* fieldName = exportMap.fieldNames[fieldIndex].get();
        if (!*fieldName) {
            MOZ_ASSERT(!exportObj);
            uint32_t exportIndex = exportMap.fieldsToExports[fieldIndex];
            exportObj.set(NewExportedFunction(cx, moduleObj, exportMap, exportIndex));
            if (!exportObj)
                return false;
            break;
        }
    }

    Rooted<ValueVector> vals(cx, ValueVector(cx));
    for (size_t exportIndex = 0; exportIndex < exports.length(); exportIndex++) {
        JSFunction* fun = NewExportedFunction(cx, moduleObj, exportMap, exportIndex);
        if (!fun || !vals.append(ObjectValue(*fun)))
            return false;
    }

    if (!exportObj) {
        exportObj.set(JS_NewPlainObject(cx));
        if (!exportObj)
            return false;
    }

    for (size_t fieldIndex = 0; fieldIndex < exportMap.fieldNames.length(); fieldIndex++) {
        const char* fieldName = exportMap.fieldNames[fieldIndex].get();
        if (!*fieldName)
            continue;

        JSAtom* atom = AtomizeUTF8Chars(cx, fieldName, strlen(fieldName));
        if (!atom)
            return false;

        RootedId id(cx, AtomToId(atom));
        HandleValue val = vals[exportMap.fieldsToExports[fieldIndex]];
        if (!JS_DefinePropertyById(cx, exportObj, id, val, JSPROP_ENUMERATE))
            return false;
    }

    return true;
}
Example #9
0
bool
ModuleNamespaceObject::ProxyHandler::getPrototype(JSContext* cx, HandleObject proxy,
                                                  MutableHandleObject protop) const
{
    protop.set(nullptr);
    return true;
}
bool
OpaqueCrossCompartmentWrapper::getPrototype(JSContext* cx, HandleObject proxy,
                                            MutableHandleObject protop) const
{
    protop.set(nullptr);
    return true;
}
Example #11
0
bool
JSCompartment::wrap(JSContext* cx, MutableHandleObject obj)
{
    MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(this));
    MOZ_ASSERT(cx->compartment() == this);

    if (!obj)
        return true;

    AutoDisableProxyCheck adpc(cx->runtime());

    // Anything we're wrapping has already escaped into script, so must have
    // been unmarked-gray at some point in the past.
    MOZ_ASSERT(!ObjectIsMarkedGray(obj));

    // The passed object may already be wrapped, or may fit a number of special
    // cases that we need to check for and manually correct.
    if (!getNonWrapperObjectForCurrentCompartment(cx, obj))
        return false;

    // If the reification above did not result in a same-compartment object,
    // get or create a new wrapper object in this compartment for it.
    if (obj->compartment() != this) {
        if (!getOrCreateWrapper(cx, nullptr, obj))
            return false;
    }

    // Ensure that the wrapper is also exposed.
    ExposeObjectToActiveJS(obj);
    return true;
}
Example #12
0
/*
 * HasInstance hooks need to find an appropriate reflector in order to function
 * properly. There are two complexities that we need to handle:
 *
 * 1 - Cross-compartment wrappers. Chrome uses over 100 compartments, all with
 *     system principal. The success of an instanceof check should not depend
 *     on which compartment an object comes from. At the same time, we want to
 *     make sure we don't unwrap important security wrappers.
 *     CheckedUnwrap does the right thing here.
 *
 * 2 - Prototype chains. Suppose someone creates a vanilla JS object |a| and
 *     sets its __proto__ to some WN |b|. If |b instanceof nsIFoo| returns true,
 *     one would expect |a instanceof nsIFoo| to return true as well, since
 *     instanceof is transitive up the prototype chain in ECMAScript. Moreover,
 *     there's chrome code that relies on this.
 *
 * This static method handles both complexities, returning either an XPCWN, a
 * DOM object, or null. The object may well be cross-compartment from |cx|.
 */
static nsresult
FindObjectForHasInstance(JSContext* cx, HandleObject objArg, MutableHandleObject target)
{
    RootedObject obj(cx, objArg), proto(cx);

    while (obj && !IS_WN_REFLECTOR(obj) &&
           !IsDOMObject(obj) && !mozilla::jsipc::IsCPOW(obj))
    {
        if (js::IsWrapper(obj)) {
            obj = js::CheckedUnwrap(obj, /* stopAtWindowProxy = */ false);
            continue;
        }

        {
            JSAutoCompartment ac(cx, obj);
            if (!js::GetObjectProto(cx, obj, &proto))
                return NS_ERROR_FAILURE;
        }

        obj = proto;
    }

    target.set(obj);
    return NS_OK;
}
Example #13
0
static bool
proxy_LookupProperty(JSContext* cx, HandleObject obj, HandleId id,
                     MutableHandleObject objp, MutableHandle<JS::PropertyResult> propp)
{
    bool found;
    if (!Proxy::has(cx, obj, id, &found))
        return false;

    if (found) {
        propp.setNonNativeProperty();
        objp.set(obj);
    } else {
        propp.setNotFound();
        objp.set(nullptr);
    }
    return true;
}
js::GetOriginalEval(JSContext *cx, HandleObject scope, MutableHandleObject eval)
{
    assertSameCompartment(cx, scope);
    if (!scope->global().getOrCreateObjectPrototype(cx))
        return false;
    eval.set(&scope->global().getOriginalEval().toObject());
    return true;
}
Example #15
0
JS_NondeterministicGetWeakSetKeys(JSContext* cx, HandleObject objArg, MutableHandleObject ret)
{
    RootedObject obj(cx, UncheckedUnwrap(objArg));
    if (!obj || !obj->is<WeakSetObject>()) {
        ret.set(nullptr);
        return true;
    }
    return WeakCollectionObject::nondeterministicGetKeys(cx, obj.as<WeakCollectionObject>(), ret);
}
Example #16
0
/* static */ bool
GlobalObject::getOrCreateEval(JSContext* cx, Handle<GlobalObject*> global,
                              MutableHandleObject eval)
{
    if (!global->getOrCreateObjectPrototype(cx))
        return false;
    eval.set(&global->getSlot(EVAL).toObject());
    return true;
}
Example #17
0
bool
XDRState<mode>::codeFunction(MutableHandleObject objp)
{
    if (mode == XDR_DECODE)
        objp.set(NULL);

    if (!VersionCheck(this))
        return false;

    return XDRInterpretedFunction(this, NullPtr(), NullPtr(), objp);
}
Example #18
0
bool
CrossCompartmentWrapper::getPrototypeOf(JSContext *cx, HandleObject wrapper,
                                        MutableHandleObject protop)
{
    if (!wrapper->getTaggedProto().isLazy()) {
        protop.set(wrapper->getTaggedProto().toObjectOrNull());
        return true;
    }

    {
        RootedObject wrapped(cx, wrappedObject(wrapper));
        AutoCompartment call(cx, wrapped);
        if (!JSObject::getProto(cx, wrapped, protop))
            return false;
        if (protop)
            protop->setDelegate(cx);
    }

    return cx->compartment->wrap(cx, protop.address());
}
Example #19
0
bool
JSCompartment::getOrCreateWrapper(JSContext* cx, HandleObject existing, MutableHandleObject obj)
{
    // If we already have a wrapper for this value, use it.
    RootedValue key(cx, ObjectValue(*obj));
    if (WrapperMap::Ptr p = crossCompartmentWrappers.lookup(CrossCompartmentKey(key))) {
        obj.set(&p->value().get().toObject());
        MOZ_ASSERT(obj->is<CrossCompartmentWrapperObject>());
        return true;
    }

    // Ensure that the wrappee is exposed in case we are creating a new wrapper
    // for a gray object.
    ExposeObjectToActiveJS(obj);

    // Create a new wrapper for the object.
    auto wrap = cx->runtime()->wrapObjectCallbacks->wrap;
    RootedObject wrapper(cx, wrap(cx, existing, obj));
    if (!wrapper)
        return false;

    // We maintain the invariant that the key in the cross-compartment wrapper
    // map is always directly wrapped by the value.
    MOZ_ASSERT(Wrapper::wrappedObject(wrapper) == &key.get().toObject());

    if (!putWrapper(cx, CrossCompartmentKey(key), ObjectValue(*wrapper))) {
        // Enforce the invariant that all cross-compartment wrapper object are
        // in the map by nuking the wrapper if we couldn't add it.
        // Unfortunately it's possible for the wrapper to still be marked if we
        // took this path, for example if the object metadata callback stashes a
        // reference to it.
        if (wrapper->is<CrossCompartmentWrapperObject>())
            NukeCrossCompartmentWrapper(cx, wrapper);
        return false;
    }

    obj.set(wrapper);
    return true;
}
Example #20
0
bool
JSCompartment::rewrap(JSContext* cx, MutableHandleObject obj, HandleObject existingArg)
{
    MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(this));
    MOZ_ASSERT(cx->compartment() == this);
    MOZ_ASSERT(obj);
    MOZ_ASSERT(existingArg);
    MOZ_ASSERT(existingArg->compartment() == cx->compartment());
    MOZ_ASSERT(IsDeadProxyObject(existingArg));

    AutoDisableProxyCheck adpc(cx->runtime());

    // It may not be possible to re-use existing; if so, clear it so that we
    // are forced to create a new wrapper. Note that this cannot call out to
    // |wrap| because of the different gray unmarking semantics.
    RootedObject existing(cx, existingArg);
    if (existing->hasStaticPrototype() ||
        // Note: Class asserted above, so all that's left to check is callability
        existing->isCallable() ||
        obj->isCallable())
    {
        existing.set(nullptr);
    }

    // The passed object may already be wrapped, or may fit a number of special
    // cases that we need to check for and manually correct.
    if (!getNonWrapperObjectForCurrentCompartment(cx, obj))
        return false;

    // If the reification above resulted in a same-compartment object, we do
    // not need to create or return an existing wrapper.
    if (obj->compartment() == this)
        return true;

    return getOrCreateWrapper(cx, existing, obj);
}
bool
CrossCompartmentWrapper::getPrototype(JSContext* cx, HandleObject wrapper,
                                      MutableHandleObject protop) const
{
    {
        RootedObject wrapped(cx, wrappedObject(wrapper));
        AutoCompartment call(cx, wrapped);
        if (!GetPrototype(cx, wrapped, protop))
            return false;
        if (protop)
            protop->setDelegate(cx);
    }

    return cx->compartment()->wrap(cx, protop);
}
Example #22
0
js::ExecuteInGlobalAndReturnScope(JSContext* cx, HandleObject global, HandleScript scriptArg,
                                  MutableHandleObject scopeArg)
{
    CHECK_REQUEST(cx);
    assertSameCompartment(cx, global);
    MOZ_ASSERT(global->is<GlobalObject>());
    MOZ_RELEASE_ASSERT(scriptArg->hasNonSyntacticScope());

    RootedScript script(cx, scriptArg);
    Rooted<GlobalObject*> globalRoot(cx, &global->as<GlobalObject>());
    if (script->compartment() != cx->compartment()) {
        Rooted<StaticScope*> staticScope(cx, &globalRoot->lexicalScope().staticBlock());
        staticScope = StaticNonSyntacticScope::create(cx, staticScope);
        if (!staticScope)
            return false;
        script = CloneGlobalScript(cx, staticScope, script);
        if (!script)
            return false;

        Debugger::onNewScript(cx, script);
    }

    Rooted<ClonedBlockObject*> globalLexical(cx, &globalRoot->lexicalScope());
    Rooted<ScopeObject*> scope(cx, NonSyntacticVariablesObject::create(cx, globalLexical));
    if (!scope)
        return false;

    // Unlike the non-syntactic scope chain API used by the subscript loader,
    // this API creates a fresh block scope each time.
    Rooted<StaticNonSyntacticScope*> enclosingStaticScope(cx,
        &script->enclosingStaticScope()->as<StaticNonSyntacticScope>());
    scope = ClonedBlockObject::createNonSyntactic(cx, enclosingStaticScope, scope);
    if (!scope)
        return false;

    RootedValue rval(cx);
    if (!ExecuteKernel(cx, script, *scope, UndefinedValue(),
                       NullFramePtr() /* evalInFrame */, rval.address()))
    {
        return false;
    }

    scopeArg.set(scope);
    return true;
}
Example #23
0
static bool
CreateInstance(JSContext* cx, HandleObject exportObj, MutableHandleObject instance)
{
    instance.set(JS_NewPlainObject(cx));
    if (!instance)
        return false;

    JSAtom* atom = Atomize(cx, ExportField, strlen(ExportField));
    if (!atom)
        return false;

    RootedId id(cx, AtomToId(atom));
    RootedValue val(cx, ObjectValue(*exportObj));
    if (!JS_DefinePropertyById(cx, instance, id, val, JSPROP_ENUMERATE))
        return false;

    return true;
}
// ES6 (14 October, 2014) 9.5.11 Proxy.[[Enumerate]]
bool
ScriptedDirectProxyHandler::enumerate(JSContext* cx, HandleObject proxy,
                                      MutableHandleObject objp) const
{
    // step 1
    RootedObject handler(cx, GetDirectProxyHandlerObject(proxy));

    // step 2
    if (!handler) {
        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_PROXY_REVOKED);
        return false;
    }

    // step 3: unnecessary assert
    // step 4
    RootedObject target(cx, proxy->as<ProxyObject>().target());

    // step 5-6
    RootedValue trap(cx);
    if (!GetProperty(cx, handler, handler, cx->names().enumerate, &trap))
        return false;

    // step 7
    if (trap.isUndefined())
        return GetIterator(cx, target, 0, objp);

    // step 8-9
    Value argv[] = {
        ObjectOrNullValue(target)
    };
    RootedValue trapResult(cx);
    if (!Invoke(cx, ObjectValue(*handler), trap, ArrayLength(argv), argv, &trapResult))
        return false;

    // step 10
    if (trapResult.isPrimitive()) {
        ReportInvalidTrapResult(cx, proxy, cx->names().enumerate);
        return false;
    }

    // step 11
    objp.set(&trapResult.toObject());
    return true;
}
Example #25
0
bool
WrapperOwner::getPrototype(JSContext* cx, HandleObject proxy, MutableHandleObject objp)
{
    ObjectId objId = idOf(proxy);

    ObjectOrNullVariant val;
    ReturnStatus status;
    if (!SendGetPrototype(objId, &status, &val))
        return ipcfail(cx);

    LOG_STACK();

    if (!ok(cx, status))
        return false;

    objp.set(fromObjectOrNullVariant(cx, val));

    return true;
}
Example #26
0
static bool
FindErrorInstanceOrPrototype(JSContext* cx, HandleObject obj, MutableHandleObject result)
{
    // Walk up the prototype chain until we find an error object instance or
    // prototype object. This allows code like:
    //  Object.create(Error.prototype).stack
    // or
    //   function NYI() { }
    //   NYI.prototype = new Error;
    //   (new NYI).stack
    // to continue returning stacks that are useless, but at least don't throw.

    RootedObject target(cx, CheckedUnwrap(obj));
    if (!target) {
        ReportAccessDenied(cx);
        return false;
    }

    RootedObject proto(cx);
    while (!IsErrorProtoKey(StandardProtoKeyOrNull(target))) {
        if (!GetPrototype(cx, target, &proto))
            return false;

        if (!proto) {
            // We walked the whole prototype chain and did not find an Error
            // object.
            JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
                                      js_Error_str, "(get stack)", obj->getClass()->name);
            return false;
        }

        target = CheckedUnwrap(proto);
        if (!target) {
            ReportAccessDenied(cx);
            return false;
        }
    }

    result.set(target);
    return true;
}
Example #27
0
js::ExecuteInGlobalAndReturnScope(JSContext* cx, HandleObject global, HandleScript scriptArg,
                                  MutableHandleObject scopeArg)
{
    CHECK_REQUEST(cx);
    assertSameCompartment(cx, global);
    MOZ_ASSERT(global->is<GlobalObject>());

    RootedScript script(cx, scriptArg);
    if (script->compartment() != cx->compartment()) {
        script = CloneScript(cx, NullPtr(), NullPtr(), script);
        if (!script)
            return false;

        Debugger::onNewScript(cx, script);
    }

    RootedObject scope(cx, JS_NewPlainObject(cx));
    if (!scope)
        return false;

    if (!scope->setQualifiedVarObj(cx))
        return false;

    if (!scope->setUnqualifiedVarObj(cx))
        return false;

    JSObject* thisobj = GetThisObject(cx, global);
    if (!thisobj)
        return false;

    RootedValue thisv(cx, ObjectValue(*thisobj));
    RootedValue rval(cx);
    if (!ExecuteKernel(cx, script, *scope, thisv, EXECUTE_GLOBAL,
                       NullFramePtr() /* evalInFrame */, rval.address()))
    {
        return false;
    }

    scopeArg.set(scope);
    return true;
}
bool
CrossCompartmentWrapper::getPrototypeIfOrdinary(JSContext* cx, HandleObject wrapper,
        bool* isOrdinary, MutableHandleObject protop) const
{
    {
        RootedObject wrapped(cx, wrappedObject(wrapper));
        AutoCompartment call(cx, wrapped);
        if (!GetPrototypeIfOrdinary(cx, wrapped, isOrdinary, protop))
            return false;

        if (!*isOrdinary)
            return true;

        if (protop) {
            if (!protop->setDelegate(cx))
                return false;
        }
    }

    return cx->compartment()->wrap(cx, protop);
}
Example #29
0
js::ExecuteInGlobalAndReturnScope(JSContext* cx, HandleObject global, HandleScript scriptArg,
                                  MutableHandleObject scopeArg)
{
    CHECK_REQUEST(cx);
    assertSameCompartment(cx, global);
    MOZ_ASSERT(global->is<GlobalObject>());
    MOZ_RELEASE_ASSERT(scriptArg->hasNonSyntacticScope());

    RootedScript script(cx, scriptArg);
    if (script->compartment() != cx->compartment()) {
        Rooted<ScopeObject*> staticScope(cx, StaticNonSyntacticScopeObjects::create(cx, nullptr));
        if (!staticScope)
            return false;
        script = CloneGlobalScript(cx, staticScope, script);
        if (!script)
            return false;

        Debugger::onNewScript(cx, script);
    }

    Rooted<GlobalObject*> globalRoot(cx, &global->as<GlobalObject>());
    Rooted<ScopeObject*> scope(cx, NonSyntacticVariablesObject::create(cx, globalRoot));
    if (!scope)
        return false;

    JSObject* thisobj = GetThisObject(cx, global);
    if (!thisobj)
        return false;

    RootedValue thisv(cx, ObjectValue(*thisobj));
    RootedValue rval(cx);
    if (!ExecuteKernel(cx, script, *scope, thisv, UndefinedValue(), EXECUTE_GLOBAL,
                       NullFramePtr() /* evalInFrame */, rval.address()))
    {
        return false;
    }

    scopeArg.set(scope);
    return true;
}
Example #30
0
bool
WeakCollectionObject::nondeterministicGetKeys(JSContext* cx, Handle<WeakCollectionObject*> obj,
                                              MutableHandleObject ret)
{
    RootedObject arr(cx, NewDenseEmptyArray(cx));
    if (!arr)
        return false;
    if (ObjectValueMap* map = obj->getMap()) {
        // Prevent GC from mutating the weakmap while iterating.
        AutoSuppressGC suppress(cx);
        for (ObjectValueMap::Base::Range r = map->all(); !r.empty(); r.popFront()) {
            JS::ExposeObjectToActiveJS(r.front().key());
            RootedObject key(cx, r.front().key());
            if (!cx->compartment()->wrap(cx, &key))
                return false;
            if (!NewbornArrayPush(cx, arr, ObjectValue(*key)))
                return false;
        }
    }
    ret.set(arr);
    return true;
}