bool CrossCompartmentWrapper::call(JSContext* cx, HandleObject wrapper, const CallArgs& args) const { RootedObject wrapped(cx, wrappedObject(wrapper)); { AutoCompartment call(cx, wrapped); args.setCallee(ObjectValue(*wrapped)); if (!cx->compartment()->wrap(cx, args.mutableThisv())) return false; for (size_t n = 0; n < args.length(); ++n) { if (!cx->compartment()->wrap(cx, args[n])) return false; } if (!Wrapper::call(cx, wrapper, args)) return false; } return cx->compartment()->wrap(cx, args.rval()); }
bool CrossCompartmentWrapper::call(JSContext *cx, HandleObject wrapper, unsigned argc, Value *vp) { RootedObject wrapped(cx, wrappedObject(wrapper)); CallArgs args = CallArgsFromVp(argc, vp); { AutoCompartment call(cx, wrapped); args.setCallee(ObjectValue(*wrapped)); if (!cx->compartment->wrap(cx, args.mutableThisv())) return false; for (size_t n = 0; n < args.length(); ++n) { if (!cx->compartment->wrap(cx, args.handleAt(n))) return false; } if (!Wrapper::call(cx, wrapper, argc, vp)) return false; } return cx->compartment->wrap(cx, args.rval()); }
static bool HandleDynamicLinkFailure(JSContext* cx, const CallArgs& args, AsmJSModule& module, HandlePropertyName name) { if (cx->isExceptionPending()) return false; // Source discarding is allowed to affect JS semantics because it is never // enabled for normal JS content. bool haveSource = module.scriptSource()->hasSourceData(); if (!haveSource && !JSScript::loadSource(cx, module.scriptSource(), &haveSource)) return false; if (!haveSource) { JS_ReportError(cx, "asm.js link failure with source discarding enabled"); return false; } uint32_t begin = module.srcBodyStart(); // starts right after 'use asm' uint32_t end = module.srcEndBeforeCurly(); Rooted<JSFlatString*> src(cx, module.scriptSource()->substringDontDeflate(cx, begin, end)); if (!src) return false; RootedFunction fun(cx, NewScriptedFunction(cx, 0, JSFunction::INTERPRETED_NORMAL, name, gc::AllocKind::FUNCTION, TenuredObject)); if (!fun) return false; Rooted<PropertyNameVector> formals(cx, PropertyNameVector(cx)); if (!formals.reserve(3)) return false; if (module.globalArgumentName()) formals.infallibleAppend(module.globalArgumentName()); if (module.importArgumentName()) formals.infallibleAppend(module.importArgumentName()); if (module.bufferArgumentName()) formals.infallibleAppend(module.bufferArgumentName()); CompileOptions options(cx); options.setMutedErrors(module.scriptSource()->mutedErrors()) .setFile(module.scriptSource()->filename()) .setNoScriptRval(false); // The exported function inherits an implicit strict context if the module // also inherited it somehow. if (module.strict()) options.strictOption = true; AutoStableStringChars stableChars(cx); if (!stableChars.initTwoByte(cx, src)) return false; const char16_t* chars = stableChars.twoByteRange().start().get(); SourceBufferHolder::Ownership ownership = stableChars.maybeGiveOwnershipToCaller() ? SourceBufferHolder::GiveOwnership : SourceBufferHolder::NoOwnership; SourceBufferHolder srcBuf(chars, end - begin, ownership); if (!frontend::CompileFunctionBody(cx, &fun, options, formals, srcBuf, /* enclosingScope = */ nullptr)) return false; // Call the function we just recompiled. args.setCallee(ObjectValue(*fun)); return Invoke(cx, args, args.isConstructing() ? CONSTRUCT : NO_CONSTRUCT); }