bool CrossCompartmentWrapper::nativeCall(JSContext *cx, JSObject *wrapper, Class *clasp, Native native, CallArgs srcArgs) { JS_ASSERT_IF(!srcArgs.calleev().isUndefined(), srcArgs.callee().toFunction()->native() == native || srcArgs.callee().toFunction()->native() == js_generic_native_method_dispatcher); JS_ASSERT(&srcArgs.thisv().toObject() == wrapper); JS_ASSERT(!UnwrapObject(wrapper)->isCrossCompartmentWrapper()); JSObject *wrapped = wrappedObject(wrapper); AutoCompartment call(cx, wrapped); if (!call.enter()) return false; InvokeArgsGuard dstArgs; if (!cx->stack.pushInvokeArgs(cx, srcArgs.length(), &dstArgs)) return false; Value *src = srcArgs.base(); Value *srcend = srcArgs.array() + srcArgs.length(); Value *dst = dstArgs.base(); for (; src != srcend; ++src, ++dst) { *dst = *src; if (!call.destination->wrap(cx, dst)) return false; } if (!Wrapper::nativeCall(cx, wrapper, clasp, native, dstArgs)) return false; dstArgs.pop(); call.leave(); srcArgs.rval() = dstArgs.rval(); return call.origin->wrap(cx, &srcArgs.rval()); }
bool DirectProxyHandler::construct(JSContext* cx, HandleObject proxy, const CallArgs& args) const { assertEnteredPolicy(cx, proxy, JSID_VOID, CALL); RootedValue target(cx, proxy->as<ProxyObject>().private_()); return InvokeConstructor(cx, target, args.length(), args.array(), true, args.rval()); }
bool CrossCompartmentWrapper::nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, CallArgs srcArgs) { Rooted<JSObject*> wrapper(cx, &srcArgs.thisv().toObject()); JS_ASSERT(srcArgs.thisv().isMagic(JS_IS_CONSTRUCTING) || !UnwrapObject(wrapper)->isCrossCompartmentWrapper()); RootedObject wrapped(cx, wrappedObject(wrapper)); { AutoCompartment call(cx, wrapped); InvokeArgsGuard dstArgs; if (!cx->stack.pushInvokeArgs(cx, srcArgs.length(), &dstArgs)) return false; Value *src = srcArgs.base(); Value *srcend = srcArgs.array() + srcArgs.length(); Value *dst = dstArgs.base(); for (; src < srcend; ++src, ++dst) { *dst = *src; if (!cx->compartment->wrap(cx, dst)) return false; } if (!CallNonGenericMethod(cx, test, impl, dstArgs)) return false; srcArgs.rval().set(dstArgs.rval()); dstArgs.pop(); } return cx->compartment->wrap(cx, srcArgs.rval().address()); }
bool CrossCompartmentWrapper::nativeCall(JSContext *cx, JSObject *wrapper, Class *clasp, Native native, CallArgs srcArgs) { JS_ASSERT(srcArgs.thisv().isMagic(JS_IS_CONSTRUCTING) || &srcArgs.thisv().toObject() == wrapper); JS_ASSERT(!UnwrapObject(wrapper)->isCrossCompartmentWrapper()); JSObject *wrapped = wrappedObject(wrapper); AutoCompartment call(cx, wrapped); if (!call.enter()) return false; InvokeArgsGuard dstArgs; if (!cx->stack.pushInvokeArgs(cx, srcArgs.length(), &dstArgs)) return false; Value *src = srcArgs.base(); Value *srcend = srcArgs.array() + srcArgs.length(); Value *dst = dstArgs.base(); for (; src != srcend; ++src, ++dst) { *dst = *src; if (!call.destination->wrap(cx, dst)) return false; } if (!CallJSNative(cx, native, dstArgs)) return false; srcArgs.rval() = dstArgs.rval(); dstArgs.pop(); call.leave(); return cx->compartment->wrap(cx, &srcArgs.rval()); }
// ES6 (22 May, 2014) 9.5.14 Proxy.[[Construct]] bool ScriptedDirectProxyHandler::construct(JSContext* cx, HandleObject proxy, const CallArgs& args) const { // step 1 RootedObject handler(cx, GetDirectProxyHandlerObject(proxy)); // step 2 if (!handler) { JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_PROXY_REVOKED); return false; } // step 3 RootedObject target(cx, proxy->as<ProxyObject>().target()); MOZ_ASSERT(target->isConstructor()); // step 7 RootedObject argsArray(cx, NewDenseCopiedArray(cx, args.length(), args.array())); if (!argsArray) return false; // step 4-5 RootedValue trap(cx); if (!GetProperty(cx, handler, handler, cx->names().construct, &trap)) return false; // step 6 if (trap.isUndefined()) { ConstructArgs cargs(cx); if (!FillArgumentsFromArraylike(cx, cargs, args)) return false; RootedValue targetv(cx, ObjectValue(*target)); RootedObject obj(cx); if (!Construct(cx, targetv, cargs, args.newTarget(), &obj)) return false; args.rval().setObject(*obj); return true; } // step 8-9 Value constructArgv[] = { ObjectValue(*target), ObjectValue(*argsArray), args.newTarget() }; RootedValue thisValue(cx, ObjectValue(*handler)); if (!Invoke(cx, thisValue, trap, ArrayLength(constructArgv), constructArgv, args.rval())) return false; // step 10 if (!args.rval().isObject()) { JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_PROXY_CONSTRUCT_OBJECT); return false; } return true; }
// ES6 (22 May, 2014) 9.5.13 Proxy.[[Call]] bool ScriptedDirectProxyHandler::call(JSContext* cx, HandleObject proxy, const CallArgs& args) const { // step 1 RootedObject handler(cx, GetDirectProxyHandlerObject(proxy)); // step 2 if (!handler) { JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_PROXY_REVOKED); return false; } // step 3 RootedObject target(cx, proxy->as<ProxyObject>().target()); MOZ_ASSERT(target->isCallable()); // step 7 RootedObject argsArray(cx, NewDenseCopiedArray(cx, args.length(), args.array())); if (!argsArray) return false; // step 4-5 RootedValue trap(cx); if (!GetProperty(cx, handler, handler, cx->names().apply, &trap)) return false; // step 6 if (trap.isUndefined()) { RootedValue targetv(cx, ObjectValue(*target)); return Invoke(cx, args.thisv(), targetv, args.length(), args.array(), args.rval()); } // step 8 Value argv[] = { ObjectValue(*target), args.thisv(), ObjectValue(*argsArray) }; RootedValue thisValue(cx, ObjectValue(*handler)); return Invoke(cx, thisValue, trap, ArrayLength(argv), argv, args.rval()); }
static JSBool regexp_compile(JSContext *cx, uintN argc, Value *vp) { CallArgs args = CallArgsFromVp(argc, vp); bool ok; JSObject *obj = NonGenericMethodGuard(cx, args, regexp_compile, &RegExpClass, &ok); if (!obj) return ok; RegExpObjectBuilder builder(cx, obj->asRegExp()); return CompileRegExpObject(cx, builder, args.length(), args.array(), &args.rval()); }
bool CrossCompartmentWrapper::nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, CallArgs srcArgs) { RootedObject wrapper(cx, &srcArgs.thisv().toObject()); JS_ASSERT(srcArgs.thisv().isMagic(JS_IS_CONSTRUCTING) || !UncheckedUnwrap(wrapper)->isCrossCompartmentWrapper()); RootedObject wrapped(cx, wrappedObject(wrapper)); { AutoCompartment call(cx, wrapped); InvokeArgsGuard dstArgs; if (!cx->stack.pushInvokeArgs(cx, srcArgs.length(), &dstArgs)) return false; Value *src = srcArgs.base(); Value *srcend = srcArgs.array() + srcArgs.length(); Value *dst = dstArgs.base(); RootedValue source(cx); for (; src < srcend; ++src, ++dst) { source = *src; if (!cx->compartment->wrap(cx, &source)) return false; *dst = source.get(); // Handle |this| specially. When we rewrap on the other side of the // membrane, we might apply a same-compartment security wrapper that // will stymie this whole process. If that happens, unwrap the wrapper. // This logic can go away when same-compartment security wrappers go away. if ((src == srcArgs.base() + 1) && dst->isObject()) { RootedObject thisObj(cx, &dst->toObject()); if (thisObj->isWrapper() && !Wrapper::wrapperHandler(thisObj)->isSafeToUnwrap()) { JS_ASSERT(!IsCrossCompartmentWrapper(thisObj)); *dst = ObjectValue(*Wrapper::wrappedObject(thisObj)); } } } if (!CallNonGenericMethod(cx, test, impl, dstArgs)) return false; srcArgs.rval().set(dstArgs.rval()); dstArgs.pop(); } return cx->compartment->wrap(cx, srcArgs.rval()); }
static JSBool regexp_compile(JSContext *cx, uintN argc, Value *vp) { CallArgs args = CallArgsFromVp(argc, vp); bool ok; JSObject *obj = NonGenericMethodGuard(cx, args, regexp_compile, &RegExpClass, &ok); if (!obj) return ok; RegExpObject *reobj = obj->asRegExp(); ok = CompileRegExpObject(cx, reobj, args.length(), args.array(), &args.rval()); JS_ASSERT_IF(ok, reobj->getPrivate()); return ok; }
static bool XPC_WN_Shared_ToString(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); RootedObject obj(cx, JS_THIS_OBJECT(cx, vp)); if (!obj) return false; XPCCallContext ccx(cx, obj); if (!ccx.IsValid()) return Throw(NS_ERROR_XPC_BAD_OP_ON_WN_PROTO, cx); ccx.SetName(ccx.GetContext()->GetStringID(XPCJSContext::IDX_TO_STRING)); ccx.SetArgsAndResultPtr(args.length(), args.array(), vp); return ToStringGuts(ccx); }
// ES7 0c1bd3004329336774cbc90de727cd0cf5f11e93 9.5.13 Proxy.[[Call]] bool ScriptedProxyHandler::call(JSContext* cx, HandleObject proxy, const CallArgs& args) const { // Steps 1-3. RootedObject handler(cx, ScriptedProxyHandler::handlerObject(proxy)); if (!handler) { JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_PROXY_REVOKED); return false; } // Step 4. RootedObject target(cx, proxy->as<ProxyObject>().target()); MOZ_ASSERT(target); MOZ_ASSERT(target->isCallable()); // Step 5. RootedValue trap(cx); if (!GetProxyTrap(cx, handler, cx->names().apply, &trap)) return false; // Step 6. if (trap.isUndefined()) { InvokeArgs iargs(cx); if (!FillArgumentsFromArraylike(cx, iargs, args)) return false; RootedValue fval(cx, ObjectValue(*target)); return js::Call(cx, fval, args.thisv(), iargs, args.rval()); } // Step 7. RootedObject argArray(cx, NewDenseCopiedArray(cx, args.length(), args.array())); if (!argArray) return false; // Step 8. FixedInvokeArgs<3> iargs(cx); iargs[0].setObject(*target); iargs[1].set(args.thisv()); iargs[2].setObject(*argArray); RootedValue thisv(cx, ObjectValue(*handler)); return js::Call(cx, trap, thisv, iargs, args.rval()); }
NS_IMETHODIMP nsJSCID::Construct(nsIXPConnectWrappedNative* wrapper, JSContext* cx, JSObject* objArg, const CallArgs& args, bool* _retval) { RootedObject obj(cx, objArg); XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance(); if (!rt) return NS_ERROR_FAILURE; // 'push' a call context and call on it RootedId name(cx, rt->GetStringID(XPCJSRuntime::IDX_CREATE_INSTANCE)); XPCCallContext ccx(JS_CALLER, cx, obj, nullptr, name, args.length(), args.array(), args.rval().address()); *_retval = XPCWrappedNative::CallMethod(ccx); return NS_OK; }
js::ConvertArgsToArray(JSContext* cx, const CallArgs& args) { RootedObject argsArray(cx, NewDenseCopiedArray(cx, args.length(), args.array())); return argsArray; }
// ES7 0c1bd3004329336774cbc90de727cd0cf5f11e93 9.5.14 Proxy.[[Construct]] bool ScriptedProxyHandler::construct(JSContext* cx, HandleObject proxy, const CallArgs& args) const { // Steps 1-3. RootedObject handler(cx, ScriptedProxyHandler::handlerObject(proxy)); if (!handler) { JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_PROXY_REVOKED); return false; } // Step 4. RootedObject target(cx, proxy->as<ProxyObject>().target()); MOZ_ASSERT(target); MOZ_ASSERT(target->isConstructor()); // Step 5. RootedValue trap(cx); if (!GetProxyTrap(cx, handler, cx->names().construct, &trap)) return false; // Step 6. if (trap.isUndefined()) { ConstructArgs cargs(cx); if (!FillArgumentsFromArraylike(cx, cargs, args)) return false; RootedValue targetv(cx, ObjectValue(*target)); RootedObject obj(cx); if (!Construct(cx, targetv, cargs, args.newTarget(), &obj)) return false; args.rval().setObject(*obj); return true; } // Step 7. RootedObject argArray(cx, NewDenseCopiedArray(cx, args.length(), args.array())); if (!argArray) return false; // Steps 8, 10. { FixedInvokeArgs<3> iargs(cx); iargs[0].setObject(*target); iargs[1].setObject(*argArray); iargs[2].set(args.newTarget()); RootedValue thisv(cx, ObjectValue(*handler)); if (!Call(cx, trap, thisv, iargs, args.rval())) return false; } // Step 9. if (!args.rval().isObject()) { JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_PROXY_CONSTRUCT_OBJECT); return false; } return true; }