bool GlobalObject::getSelfHostedFunction(JSContext *cx, HandleAtom selfHostedName, HandleAtom name, unsigned nargs, MutableHandleValue funVal) { RootedId shId(cx, AtomToId(selfHostedName)); RootedObject holder(cx, cx->global()->intrinsicsHolder()); if (HasDataProperty(cx, holder, shId, funVal.address())) return true; if (!cx->runtime()->maybeWrappedSelfHostedFunction(cx, shId, funVal)) return false; if (!funVal.isUndefined()) return true; JSFunction *fun = NewFunction(cx, NullPtr(), nullptr, nargs, JSFunction::INTERPRETED_LAZY, holder, name, JSFunction::ExtendedFinalizeKind, SingletonObject); if (!fun) return false; fun->setIsSelfHostedBuiltin(); fun->setExtendedSlot(0, StringValue(selfHostedName)); funVal.setObject(*fun); return JSObject::defineGeneric(cx, holder, shId, funVal, nullptr, nullptr, 0); }
bool ChromeObjectWrapper::get(JSContext *cx, HandleObject wrapper, HandleObject receiver, HandleId id, MutableHandleValue vp) { assertEnteredPolicy(cx, wrapper, id); vp.setUndefined(); JSPropertyDescriptor desc; // Only call through to the get trap on the underlying object if we're // allowed to see the property, and if what we'll find is not on a standard // prototype. if (AllowedByBase(cx, wrapper, id, js::Wrapper::GET) && !PropIsFromStandardPrototype(cx, wrapper, id)) { // Call the get trap. if (!ChromeObjectWrapperBase::get(cx, wrapper, receiver, id, vp)) return false; // If we found something, we're done. if (!vp.isUndefined()) return true; } // If we have no proto, we're done. RootedObject wrapperProto(cx); if (!JS_GetPrototype(cx, wrapper, wrapperProto.address())) return false; if (!wrapperProto) return true; // Try the prototype. MOZ_ASSERT(js::IsObjectInContextCompartment(wrapper, cx)); return js::GetGeneric(cx, wrapperProto, receiver, id, vp.address()); }
// ES8 rev 0c1bd3004329336774cbc90de727cd0cf5f11e93 7.3.9 GetMethod, // reimplemented for proxy handler trap-getting to produce better error // messages. static bool GetProxyTrap(JSContext* cx, HandleObject handler, HandlePropertyName name, MutableHandleValue func) { // Steps 2, 5. if (!GetProperty(cx, handler, handler, name, func)) return false; // Step 3. if (func.isUndefined()) return true; if (func.isNull()) { func.setUndefined(); return true; } // Step 4. if (!IsCallable(func)) { JSAutoByteString bytes(cx, name); if (!bytes) return false; JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_BAD_TRAP, bytes.ptr()); return false; } return true; }
static EvalJSONResult ParseEvalStringAsJSON(JSContext *cx, const mozilla::Range<const CharT> chars, MutableHandleValue rval) { size_t len = chars.length(); MOZ_ASSERT((chars[0] == '(' && chars[len - 1] == ')') || (chars[0] == '[' && chars[len - 1] == ']')); auto jsonChars = (chars[0] == '[') ? chars : mozilla::Range<const CharT>(chars.start().get() + 1U, len - 2); JSONParser<CharT> parser(cx, jsonChars, JSONParserBase::NoError); if (!parser.parse(rval)) return EvalJSON_Failure; return rval.isUndefined() ? EvalJSON_NotJSON : EvalJSON_Success; }
bool ArrayShiftDense(JSContext *cx, HandleObject obj, MutableHandleValue rval) { JS_ASSERT(obj->is<ArrayObject>()); AutoDetectInvalidation adi(cx, rval.address()); Value argv[] = { UndefinedValue(), ObjectValue(*obj) }; AutoValueArray ava(cx, argv, 2); if (!js::array_shift(cx, 0, argv)) return false; // If the result is |undefined|, the array was probably empty and we // have to monitor the return value. rval.set(argv[0]); if (rval.isUndefined()) types::TypeScript::Monitor(cx, rval); return true; }
bool ArrayPopDense(JSContext *cx, HandleObject obj, MutableHandleValue rval) { JS_ASSERT(obj->is<ArrayObject>()); AutoDetectInvalidation adi(cx, rval.address()); JS::AutoValueArray<2> argv(cx); argv[0].setUndefined(); argv[1].setObject(*obj); if (!js::array_pop(cx, 0, argv.begin())) return false; // If the result is |undefined|, the array was probably empty and we // have to monitor the return value. rval.set(argv[0]); if (rval.isUndefined()) types::TypeScript::Monitor(cx, rval); return true; }
bool EvalInWindow(JSContext *cx, const nsAString &source, HandleObject scope, MutableHandleValue rval) { // If we cannot unwrap we must not eval in it. RootedObject targetScope(cx, CheckedUnwrap(scope)); if (!targetScope) { JS_ReportError(cx, "Permission denied to eval in target scope"); return false; } // Make sure that we have a window object. RootedObject inner(cx, CheckedUnwrap(targetScope, /* stopAtOuter = */ false)); nsCOMPtr<nsIGlobalObject> global; nsCOMPtr<nsPIDOMWindow> window; if (!JS_IsGlobalObject(inner) || !(global = GetNativeForGlobal(inner)) || !(window = do_QueryInterface(global))) { JS_ReportError(cx, "Second argument must be a window"); return false; } nsCOMPtr<nsIScriptContext> context = (static_cast<nsGlobalWindow*>(window.get()))->GetScriptContext(); if (!context) { JS_ReportError(cx, "Script context needed"); return false; } nsCString filename; unsigned lineNo; if (!GetFilenameAndLineNumber(cx, filename, lineNo)) { // Default values for non-scripted callers. filename.AssignLiteral("Unknown"); lineNo = 0; } RootedObject cxGlobal(cx, JS::CurrentGlobalOrNull(cx)); { // CompileOptions must be created from the context // we will execute this script in. JSContext *wndCx = context->GetNativeContext(); AutoCxPusher pusher(wndCx); JS::CompileOptions compileOptions(wndCx); compileOptions.setFileAndLine(filename.get(), lineNo); // We don't want the JS engine to automatically report // uncaught exceptions. nsJSUtils::EvaluateOptions evaluateOptions; evaluateOptions.setReportUncaught(false); nsresult rv = nsJSUtils::EvaluateString(wndCx, source, targetScope, compileOptions, evaluateOptions, rval); if (NS_FAILED(rv)) { // If there was an exception we get it as a return value, if // the evaluation failed for some other reason, then a default // exception is raised. MOZ_ASSERT(!JS_IsExceptionPending(wndCx), "Exception should be delivered as return value."); if (rval.isUndefined()) { MOZ_ASSERT(rv == NS_ERROR_OUT_OF_MEMORY); return false; } // If there was an exception thrown we should set it // on the calling context. RootedValue exn(wndCx, rval); // First we should reset the return value. rval.set(UndefinedValue()); // Then clone the exception. JSAutoCompartment ac(wndCx, cxGlobal); StackScopedCloneOptions cloneOptions; cloneOptions.wrapReflectors = true; if (StackScopedClone(wndCx, cloneOptions, &exn)) js::SetPendingExceptionCrossContext(cx, exn); return false; } } // Let's clone the return value back to the callers compartment. StackScopedCloneOptions cloneOptions; cloneOptions.wrapReflectors = true; if (!StackScopedClone(cx, cloneOptions, rval)) { rval.set(UndefinedValue()); return false; } return true; }