static bool pm_construct(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); uint32_t mask; if (!args.hasDefined(0)) { ReportMissingArg(cx, args.calleev(), 0); return false; } if (!JS::ToUint32(cx, args[0], &mask)) return false; JS::RootedObject obj(cx, JS_NewObjectForConstructor(cx, &pm_class, args)); if (!obj) return false; if (!JS_FreezeObject(cx, obj)) return false; PerfMeasurement* p = cx->new_<PerfMeasurement>(PerfMeasurement::EventMask(mask)); if (!p) { JS_ReportOutOfMemory(cx); return false; } JS_SetPrivate(obj, p); args.rval().setObject(*obj); return true; }
bool SharedArrayBufferObject::class_constructor(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (!args.isConstructing()) { if (args.hasDefined(0)) { ESClassValue cls; if (!GetClassOfValue(cx, args[0], &cls)) return false; if (cls == ESClass_SharedArrayBuffer) { args.rval().set(args[0]); return true; } } JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_SHARED_ARRAY_BAD_OBJECT); return false; } // Bugs 1068458, 1161298: Limit length to 2^31-1. uint32_t length; bool overflow_unused; if (!ToLengthClamped(cx, args.get(0), &length, &overflow_unused) || length > INT32_MAX) { JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_SHARED_ARRAY_BAD_LENGTH); return false; } JSObject* bufobj = New(cx, length); if (!bufobj) return false; args.rval().setObject(*bufobj); return true; }
bool SharedArrayBufferObject::class_constructor(JSContext *cx, unsigned argc, Value *vp) { CallArgs args = CallArgsFromVp(argc, vp); if (!args.isConstructing()) { if (args.hasDefined(0) && IsObjectWithClass(args[0], ESClass_SharedArrayBuffer, cx)) { args.rval().set(args[0]); return true; } JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_SHARED_ARRAY_BAD_OBJECT); return false; } uint32_t length; bool overflow; if (!ToLengthClamped(cx, args.get(0), &length, &overflow)) { // Bug 1068458: Limit length to 2^31-1. if (overflow || length > INT32_MAX) JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_SHARED_ARRAY_BAD_LENGTH); return false; } JSObject *bufobj = New(cx, length); if (!bufobj) return false; args.rval().setObject(*bufobj); return true; }
static bool Error(JSContext *cx, unsigned argc, Value *vp) { CallArgs args = CallArgsFromVp(argc, vp); /* Compute the error message, if any. */ RootedString message(cx, nullptr); if (args.hasDefined(0)) { message = ToString<CanGC>(cx, args[0]); if (!message) return false; } /* Find the scripted caller. */ NonBuiltinScriptFrameIter iter(cx); /* Set the 'fileName' property. */ RootedScript script(cx, iter.done() ? nullptr : iter.script()); RootedString fileName(cx); if (args.length() > 1) { fileName = ToString<CanGC>(cx, args[1]); } else { fileName = cx->runtime()->emptyString; if (!iter.done()) { if (const char *cfilename = script->filename()) fileName = JS_NewStringCopyZ(cx, cfilename); } } if (!fileName) return false; /* Set the 'lineNumber' property. */ uint32_t lineNumber, columnNumber = 0; if (args.length() > 2) { if (!ToUint32(cx, args[2], &lineNumber)) return false; } else { lineNumber = iter.done() ? 0 : PCToLineNumber(script, iter.pc(), &columnNumber); } Rooted<JSString*> stack(cx, ComputeStackString(cx)); if (!stack) return false; /* * ECMA ed. 3, 15.11.1 requires Error, etc., to construct even when * called as functions, without operator new. But as we do not give * each constructor a distinct JSClass, we must get the exception type * ourselves. */ JSExnType exnType = JSExnType(args.callee().as<JSFunction>().getExtendedSlot(0).toInt32()); RootedObject obj(cx, ErrorObject::create(cx, exnType, stack, fileName, lineNumber, columnNumber, nullptr, message)); if (!obj) return false; args.rval().setObject(*obj); return true; }
/* ES6 B.2.5.1. */ MOZ_ALWAYS_INLINE bool regexp_compile_impl(JSContext* cx, const CallArgs& args) { MOZ_ASSERT(IsRegExpObject(args.thisv())); Rooted<RegExpObject*> regexp(cx, &args.thisv().toObject().as<RegExpObject>()); // Step 3. RootedValue patternValue(cx, args.get(0)); ESClassValue cls; if (!GetClassOfValue(cx, patternValue, &cls)) return false; if (cls == ESClass_RegExp) { // Step 3a. if (args.hasDefined(1)) { JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_NEWREGEXP_FLAGGED); return false; } // Beware! |patternObj| might be a proxy into another compartment, so // don't assume |patternObj.is<RegExpObject>()|. For the same reason, // don't reuse the RegExpShared below. RootedObject patternObj(cx, &patternValue.toObject()); RootedAtom sourceAtom(cx); RegExpFlag flags; { // Step 3b. RegExpGuard g(cx); if (!RegExpToShared(cx, patternObj, &g)) return false; sourceAtom = g->getSource(); flags = g->getFlags(); } // Step 5, minus lastIndex zeroing. regexp->initIgnoringLastIndex(sourceAtom, flags); } else { // Step 4. RootedValue P(cx, patternValue); RootedValue F(cx, args.get(1)); // Step 5, minus lastIndex zeroing. if (!RegExpInitializeIgnoringLastIndex(cx, regexp, P, F, UseRegExpStatics)) return false; } if (regexp->lookupPure(cx->names().lastIndex)->writable()) { regexp->zeroLastIndex(cx); } else { RootedValue zero(cx, Int32Value(0)); if (!SetProperty(cx, regexp, cx->names().lastIndex, zero)) return false; } args.rval().setObject(*regexp); return true; }
bool js::IsAsmJSFunction(JSContext *cx, unsigned argc, Value *vp) { CallArgs args = CallArgsFromVp(argc, vp); bool rval = args.hasDefined(0) && IsMaybeWrappedNativeFunction(args[0], CallAsmJS); args.rval().set(BooleanValue(rval)); return true; }
bool js::math_imul(JSContext *cx, unsigned argc, Value *vp) { CallArgs args = CallArgsFromVp(argc, vp); uint32_t a = 0, b = 0; if (args.hasDefined(0) && !ToUint32(cx, args[0], &a)) return false; if (args.hasDefined(1) && !ToUint32(cx, args[1], &b)) return false; uint32_t product = a * b; args.rval().setInt32(product > INT32_MAX ? int32_t(INT32_MIN + (product - INT32_MAX - 1)) : int32_t(product)); return true; }
static JSBool regexp_construct(JSContext *cx, unsigned argc, Value *vp) { CallArgs args = CallArgsFromVp(argc, vp); if (!IsConstructing(args)) { /* * If first arg is regexp and no flags are given, just return the arg. * Otherwise, delegate to the standard constructor. * See ECMAv5 15.10.3.1. */ if (args.hasDefined(0) && IsObjectWithClass(args[0], ESClass_RegExp, cx) && !args.hasDefined(1)) { args.rval().set(args[0]); return true; } } RegExpObjectBuilder builder(cx); return CompileRegExpObject(cx, builder, args); }
bool WeakSetObject::construct(JSContext *cx, unsigned argc, Value *vp) { Rooted<WeakSetObject*> obj(cx, WeakSetObject::create(cx)); if (!obj) return false; // Based on our "Set" implementation instead of the more general ES6 steps. CallArgs args = CallArgsFromVp(argc, vp); if (!args.isConstructing()) { JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_NOT_FUNCTION, "WeakSet"); return false; } if (args.hasDefined(0)) { RootedObject map(cx, &obj->getReservedSlot(WEAKSET_MAP_SLOT).toObject()); ForOfIterator iter(cx); if (!iter.init(args[0])) return false; RootedValue keyVal(cx); RootedObject keyObject(cx); RootedValue placeholder(cx, BooleanValue(true)); while (true) { bool done; if (!iter.next(&keyVal, &done)) return false; if (done) break; if (keyVal.isPrimitive()) { JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT); return false; } keyObject = &keyVal.toObject(); if (!SetWeakMapEntry(cx, map, keyObject, placeholder)) return false; } } args.rval().setObject(*obj); return true; }
bool js::IsAsmJSModuleLoadedFromCache(JSContext *cx, unsigned argc, Value *vp) { CallArgs args = CallArgsFromVp(argc, vp); JSFunction *fun; if (!args.hasDefined(0) || !IsMaybeWrappedNativeFunction(args[0], LinkAsmJS, &fun)) { JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_USE_ASM_TYPE_FAIL, "argument passed to isAsmJSModuleLoadedFromCache is not a " "validated asm.js module"); return false; } bool loadedFromCache = ModuleFunctionToModuleObject(fun).module().loadedFromCache(); args.rval().set(BooleanValue(loadedFromCache)); return true; }
bool js::IsAsmJSModuleLoadedFromCache(JSContext *cx, unsigned argc, Value *vp) { CallArgs args = CallArgsFromVp(argc, vp); JSFunction *fun; if (!args.hasDefined(0) || !IsMaybeWrappedNativeFunction(args[0], LinkAsmJS, &fun)) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_USE_ASM_TYPE_FAIL, "argument passed to isAsmJSModuleLoadedFromCache is not a " "validated asm.js module"); return false; } JSObject &moduleObj = fun->getExtendedSlot(MODULE_FUN_SLOT).toObject(); bool loadedFromCache = moduleObj.as<AsmJSModuleObject>().module().loadedFromCache(); args.rval().set(BooleanValue(loadedFromCache)); return true; }
// ES6 draft rev34 (2015/02/20) 19.1.2.2 Object.create(O [, Properties]) bool js::obj_create(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); // Step 1. if (args.length() == 0) { JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED, "Object.create", "0", "s"); return false; } if (!args[0].isObjectOrNull()) { RootedValue v(cx, args[0]); UniquePtr<char[], JS::FreePolicy> bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, nullptr); if (!bytes) return false; JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_UNEXPECTED_TYPE, bytes.get(), "not an object or null"); return false; } // Step 2. RootedObject proto(cx, args[0].toObjectOrNull()); RootedPlainObject obj(cx, ObjectCreateImpl(cx, proto)); if (!obj) return false; // Step 3. if (args.hasDefined(1)) { RootedValue val(cx, args[1]); RootedObject props(cx, ToObject(cx, val)); if (!props || !DefineProperties(cx, obj, props)) return false; } // Step 4. args.rval().setObject(*obj); return true; }
/* * Shared{Type}Array(object) * * new Shared{Type}Array(length) * new Shared{Type}Array(SharedArrayBuffer, [optional] byteOffset, [optional] length) */ static bool class_constructor(JSContext *cx, unsigned argc, Value *vp) { CallArgs args = CallArgsFromVp(argc, vp); if (!args.isConstructing()) { if (args.hasDefined(0) && args[0].isObject() && args[0].toObject().is<SharedTypedArrayObject>() && AnyTypedArrayType(&args[0].toObject()) == ArrayTypeID()) { args.rval().set(args[0]); return true; } JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_SHARED_TYPED_ARRAY_BAD_LENGTH); return false; } JSObject *obj = create(cx, args); if (!obj) return false; args.rval().setObject(*obj); return true; }
/* * Compile a new |RegExpShared| for the |RegExpObject|. * * Per ECMAv5 15.10.4.1, we act on combinations of (pattern, flags) as * arguments: * * RegExp, undefined => flags := pattern.flags * RegExp, _ => throw TypeError * _ => pattern := ToString(pattern) if defined(pattern) else '' * flags := ToString(flags) if defined(flags) else '' */ static bool CompileRegExpObject(JSContext *cx, RegExpObjectBuilder &builder, CallArgs args) { if (args.length() == 0) { RegExpStatics *res = cx->regExpStatics(); Rooted<JSAtom*> empty(cx, cx->runtime->emptyString); RegExpObject *reobj = builder.build(empty, res->getFlags()); if (!reobj) return false; args.rval().setObject(*reobj); return true; } RootedValue sourceValue(cx, args[0]); /* * If we get passed in an object whose internal [[Class]] property is * "RegExp", return a new object with the same source/flags. */ if (IsObjectWithClass(sourceValue, ESClass_RegExp, cx)) { /* * Beware, sourceObj may be a (transparent) proxy to a RegExp, so only * use generic (proxyable) operations on sourceObj that do not assume * sourceObj.isRegExp(). */ RootedObject sourceObj(cx, &sourceValue.toObject()); if (args.hasDefined(1)) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NEWREGEXP_FLAGGED); return false; } /* * Only extract the 'flags' out of sourceObj; do not reuse the * RegExpShared since it may be from a different compartment. */ RegExpFlag flags; { RegExpGuard g(cx); if (!RegExpToShared(cx, sourceObj, &g)) return false; flags = g->getFlags(); } /* * 'toSource' is a permanent read-only property, so this is equivalent * to executing RegExpObject::getSource on the unwrapped object. */ RootedValue v(cx); if (!JSObject::getProperty(cx, sourceObj, sourceObj, cx->names().source, &v)) return false; Rooted<JSAtom*> sourceAtom(cx, &v.toString()->asAtom()); RegExpObject *reobj = builder.build(sourceAtom, flags); if (!reobj) return false; args.rval().setObject(*reobj); return true; } RootedAtom source(cx); if (sourceValue.isUndefined()) { source = cx->runtime->emptyString; } else { /* Coerce to string and compile. */ JSString *str = ToString<CanGC>(cx, sourceValue); if (!str) return false; source = AtomizeString<CanGC>(cx, str); if (!source) return false; } RegExpFlag flags = RegExpFlag(0); if (args.hasDefined(1)) { RootedString flagStr(cx, ToString<CanGC>(cx, args[1])); if (!flagStr) return false; args[1].setString(flagStr); if (!ParseRegExpFlags(cx, flagStr, &flags)) return false; } RootedAtom escapedSourceStr(cx, EscapeNakedForwardSlashes(cx, source)); if (!escapedSourceStr) return false; if (!js::RegExpShared::checkSyntax(cx, NULL, escapedSourceStr)) return false; RegExpStatics *res = cx->regExpStatics(); RegExpObject *reobj = builder.build(escapedSourceStr, RegExpFlag(flags | res->getFlags())); if (!reobj) return false; args.rval().setObject(*reobj); return true; }
/* ES6 21.2.3.1. */ bool js::regexp_construct(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); // Steps 1-2. bool patternIsRegExp; if (!IsRegExp(cx, args.get(0), &patternIsRegExp)) return false; // We can delay step 3 and step 4a until later, during // GetPrototypeFromCallableConstructor calls. Accessing the new.target // and the callee from the stack is unobservable. if (!args.isConstructing()) { // Step 4b. if (patternIsRegExp && !args.hasDefined(1)) { RootedObject patternObj(cx, &args[0].toObject()); // Steps 4b.i-ii. RootedValue patternConstructor(cx); if (!GetProperty(cx, patternObj, patternObj, cx->names().constructor, &patternConstructor)) return false; // Step 4b.iii. if (patternConstructor.isObject() && patternConstructor.toObject() == args.callee()) { args.rval().set(args[0]); return true; } } } RootedValue patternValue(cx, args.get(0)); // Step 5. ESClassValue cls; if (!GetClassOfValue(cx, patternValue, &cls)) return false; if (cls == ESClass_RegExp) { // Beware! |patternObj| might be a proxy into another compartment, so // don't assume |patternObj.is<RegExpObject>()|. For the same reason, // don't reuse the RegExpShared below. RootedObject patternObj(cx, &patternValue.toObject()); // Step 5 RootedAtom sourceAtom(cx); RegExpFlag flags; { // Step 5.a. RegExpGuard g(cx); if (!RegExpToShared(cx, patternObj, &g)) return false; sourceAtom = g->getSource(); if (!args.hasDefined(1)) { // Step 5b. flags = g->getFlags(); } } // Steps 8-9. RootedObject proto(cx); if (!GetPrototypeFromCallableConstructor(cx, args, &proto)) return false; Rooted<RegExpObject*> regexp(cx, RegExpAlloc(cx, proto)); if (!regexp) return false; // Step 10. if (args.hasDefined(1)) { // Step 5c / 21.2.3.2.2 RegExpInitialize step 5. flags = RegExpFlag(0); RootedString flagStr(cx, ToString<CanGC>(cx, args[1])); if (!flagStr) return false; if (!ParseRegExpFlags(cx, flagStr, &flags)) return false; } if (!RegExpObject::initFromAtom(cx, regexp, sourceAtom, flags)) return false; args.rval().setObject(*regexp); return true; } RootedValue P(cx); RootedValue F(cx); // Step 6. if (patternIsRegExp) { RootedObject patternObj(cx, &patternValue.toObject()); // Steps 6a-b. if (!GetProperty(cx, patternObj, patternObj, cx->names().source, &P)) return false; // Steps 6c-d. F = args.get(1); if (F.isUndefined()) { if (!GetProperty(cx, patternObj, patternObj, cx->names().flags, &F)) return false; } } else { // Steps 7a-b. P = patternValue; F = args.get(1); } // Steps 8-9. RootedObject proto(cx); if (!GetPrototypeFromCallableConstructor(cx, args, &proto)) return false; Rooted<RegExpObject*> regexp(cx, RegExpAlloc(cx, proto)); if (!regexp) return false; // Step 10. if (!RegExpInitialize(cx, regexp, P, F, UseRegExpStatics)) return false; args.rval().setObject(*regexp); return true; }
static JSBool Exception(JSContext *cx, unsigned argc, Value *vp) { CallArgs args = CallArgsFromVp(argc, vp); /* * ECMA ed. 3, 15.11.1 requires Error, etc., to construct even when * called as functions, without operator new. But as we do not give * each constructor a distinct JSClass, whose .name member is used by * NewNativeClassInstance to find the class prototype, we must get the * class prototype ourselves. */ Value protov; if (!args.callee().getProperty(cx, cx->runtime->atomState.classPrototypeAtom, &protov)) return false; if (!protov.isObject()) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_PROTOTYPE, "Error"); return false; } JSObject *errProto = &protov.toObject(); JSObject *obj = NewObjectWithGivenProto(cx, &ErrorClass, errProto, NULL); if (!obj) return false; /* Set the 'message' property. */ JSString *message; if (args.hasDefined(0)) { message = ToString(cx, args[0]); if (!message) return false; args[0].setString(message); } else { message = NULL; } /* Find the scripted caller. */ FrameRegsIter iter(cx); while (!iter.done() && !iter.fp()->isScriptFrame()) ++iter; /* Set the 'fileName' property. */ JSString *filename; if (args.length() > 1) { filename = ToString(cx, args[1]); if (!filename) return false; args[1].setString(filename); } else { if (!iter.done()) { filename = FilenameToString(cx, iter.fp()->script()->filename); if (!filename) return false; } else { filename = cx->runtime->emptyString; } } /* Set the 'lineNumber' property. */ uint32_t lineno; if (args.length() > 2) { if (!ToUint32(cx, args[2], &lineno)) return false; } else { lineno = iter.done() ? 0 : PCToLineNumber(iter.fp()->script(), iter.pc()); } int exnType = args.callee().toFunction()->getExtendedSlot(0).toInt32(); if (!InitExnPrivate(cx, obj, message, filename, lineno, NULL, exnType)) return false; args.rval().setObject(*obj); return true; }
static JSBool Exception(JSContext *cx, unsigned argc, Value *vp) { CallArgs args = CallArgsFromVp(argc, vp); /* * ECMA ed. 3, 15.11.1 requires Error, etc., to construct even when * called as functions, without operator new. But as we do not give * each constructor a distinct JSClass, whose .name member is used by * NewNativeClassInstance to find the class prototype, we must get the * class prototype ourselves. */ RootedObject callee(cx, &args.callee()); RootedValue protov(cx); if (!JSObject::getProperty(cx, callee, callee, cx->names().classPrototype, &protov)) return false; if (!protov.isObject()) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_PROTOTYPE, "Error"); return false; } RootedObject obj(cx, NewObjectWithGivenProto(cx, &ErrorClass, &protov.toObject(), NULL)); if (!obj) return false; /* Set the 'message' property. */ RootedString message(cx); if (args.hasDefined(0)) { message = ToString<CanGC>(cx, args[0]); if (!message) return false; args[0].setString(message); } else { message = NULL; } /* Find the scripted caller. */ NonBuiltinScriptFrameIter iter(cx); /* Set the 'fileName' property. */ RootedScript script(cx, iter.script()); RootedString filename(cx); if (args.length() > 1) { filename = ToString<CanGC>(cx, args[1]); if (!filename) return false; args[1].setString(filename); } else { filename = cx->runtime->emptyString; if (!iter.done()) { if (const char *cfilename = script->filename()) { filename = FilenameToString(cx, cfilename); if (!filename) return false; } } } /* Set the 'lineNumber' property. */ uint32_t lineno, column = 0; if (args.length() > 2) { if (!ToUint32(cx, args[2], &lineno)) return false; } else { lineno = iter.done() ? 0 : PCToLineNumber(script, iter.pc(), &column); } int exnType = args.callee().toFunction()->getExtendedSlot(0).toInt32(); if (!InitExnPrivate(cx, obj, message, filename, lineno, column, NULL, exnType)) return false; args.rval().setObject(*obj); return true; }
bool Error(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); // ES6 19.5.1.1 mandates the .prototype lookup happens before the toString RootedObject proto(cx); if (!GetPrototypeFromCallableConstructor(cx, args, &proto)) return false; /* Compute the error message, if any. */ RootedString message(cx, nullptr); if (args.hasDefined(0)) { message = ToString<CanGC>(cx, args[0]); if (!message) return false; } /* Find the scripted caller, but only ones we're allowed to know about. */ NonBuiltinFrameIter iter(cx, cx->compartment()->principals()); /* Set the 'fileName' property. */ RootedString fileName(cx); if (args.length() > 1) { fileName = ToString<CanGC>(cx, args[1]); } else { fileName = cx->runtime()->emptyString; if (!iter.done()) { if (const char* cfilename = iter.filename()) fileName = JS_NewStringCopyZ(cx, cfilename); } } if (!fileName) return false; /* Set the 'lineNumber' property. */ uint32_t lineNumber, columnNumber = 0; if (args.length() > 2) { if (!ToUint32(cx, args[2], &lineNumber)) return false; } else { lineNumber = iter.done() ? 0 : iter.computeLine(&columnNumber); // XXX: Make the column 1-based as in other browsers, instead of 0-based // which is how SpiderMonkey stores it internally. This will be // unnecessary once bug 1144340 is fixed. ++columnNumber; } RootedObject stack(cx); if (!CaptureStack(cx, &stack)) return false; /* * ECMA ed. 3, 15.11.1 requires Error, etc., to construct even when * called as functions, without operator new. But as we do not give * each constructor a distinct JSClass, we must get the exception type * ourselves. */ JSExnType exnType = JSExnType(args.callee().as<JSFunction>().getExtendedSlot(0).toInt32()); RootedObject obj(cx, ErrorObject::create(cx, exnType, stack, fileName, lineNumber, columnNumber, nullptr, message, proto)); if (!obj) return false; args.rval().setObject(*obj); return true; }