diff options
author | Brian Smith <brian@dbsoft.org> | 2023-07-18 20:25:54 -0500 |
---|---|---|
committer | Brian Smith <brian@dbsoft.org> | 2023-07-18 20:25:54 -0500 |
commit | 94240c9002292911b140a962dec70a99acf664cd (patch) | |
tree | 0f3ecd52cc00a127b6b0f05feb76e5bfb1585233 /js/src/vm | |
parent | 069fa50258931976dfdfeb7f9320af1ac0b6d176 (diff) | |
parent | 7175868124c789ae6607be6244038dd6d50fe771 (diff) | |
download | uxp-94240c9002292911b140a962dec70a99acf664cd.tar.gz |
Merge branch 'master' into bigint-merged
Diffstat (limited to 'js/src/vm')
-rw-r--r-- | js/src/vm/Interpreter.cpp | 8 | ||||
-rw-r--r-- | js/src/vm/SelfHosting.cpp | 89 | ||||
-rw-r--r-- | js/src/vm/SelfHosting.h | 13 |
3 files changed, 77 insertions, 33 deletions
diff --git a/js/src/vm/Interpreter.cpp b/js/src/vm/Interpreter.cpp index acde6d8ae8..b00f50971c 100644 --- a/js/src/vm/Interpreter.cpp +++ b/js/src/vm/Interpreter.cpp @@ -4313,7 +4313,13 @@ js::Lambda(JSContext* cx, HandleFunction fun, HandleObject parent) { MOZ_ASSERT(!fun->isArrow()); - RootedObject clone(cx, CloneFunctionObjectIfNotSingleton(cx, fun, parent)); + JSFunction* clone; + if (fun->isNative()) { + MOZ_ASSERT(IsAsmJSModule(fun)); + clone = CloneAsmJSModuleFunction(cx, fun); + } else { + clone = CloneFunctionObjectIfNotSingleton(cx, fun, parent); + } if (!clone) return nullptr; diff --git a/js/src/vm/SelfHosting.cpp b/js/src/vm/SelfHosting.cpp index 357e151bde..de497d02e1 100644 --- a/js/src/vm/SelfHosting.cpp +++ b/js/src/vm/SelfHosting.cpp @@ -903,6 +903,22 @@ intrinsic_NewRegExpStringIterator(JSContext* cx, unsigned argc, Value* vp) return true; } +JSAtom* +js::GetSelfHostedFunctionName(JSFunction* fun) +{ + Value name = fun->getExtendedSlot(LAZY_FUNCTION_NAME_SLOT); + if (!name.isString()) { + return nullptr; + } + return &name.toString()->asAtom(); +} + +static void +SetSelfHostedFunctionName(JSFunction* fun, JSAtom* name) +{ + fun->setExtendedSlot(LAZY_FUNCTION_NAME_SLOT, StringValue(name)); +} + static bool intrinsic_SetCanonicalName(JSContext* cx, unsigned argc, Value* vp) { @@ -915,10 +931,18 @@ intrinsic_SetCanonicalName(JSContext* cx, unsigned argc, Value* vp) if (!atom) return false; + // _SetCanonicalName can only be called on top-level function declarations. + MOZ_ASSERT(fun->kind() == JSFunction::NormalFunction); + MOZ_ASSERT(!fun->isLambda()); + + // It's an error to call _SetCanonicalName multiple times. + MOZ_ASSERT(!GetSelfHostedFunctionName(fun)); + + // Set the lazy function name so we can later retrieve the script from the + // self-hosting global. + SetSelfHostedFunctionName(fun, fun->explicitName()); fun->setAtom(atom); -#ifdef DEBUG - fun->setExtendedSlot(HAS_SELFHOSTED_CANONICAL_NAME_SLOT, BooleanValue(true)); -#endif + args.rval().setUndefined(); return true; } @@ -2909,23 +2933,33 @@ CloneObject(JSContext* cx, HandleNativeObject selfHostedObject) RootedObject clone(cx); if (selfHostedObject->is<JSFunction>()) { RootedFunction selfHostedFunction(cx, &selfHostedObject->as<JSFunction>()); - bool hasName = selfHostedFunction->explicitName() != nullptr; - - // Arrow functions use the first extended slot for their lexical |this| value. - MOZ_ASSERT(!selfHostedFunction->isArrow()); - js::gc::AllocKind kind = hasName - ? gc::AllocKind::FUNCTION_EXTENDED - : selfHostedFunction->getAllocKind(); - MOZ_ASSERT(!CanReuseScriptForClone(cx->compartment(), selfHostedFunction, cx->global())); - Rooted<LexicalEnvironmentObject*> globalLexical(cx, &cx->global()->lexicalEnvironment()); - RootedScope emptyGlobalScope(cx, &cx->global()->emptyGlobalScope()); - clone = CloneFunctionAndScript(cx, selfHostedFunction, globalLexical, emptyGlobalScope, - kind); - // To be able to re-lazify the cloned function, its name in the - // self-hosting compartment has to be stored on the clone. - if (clone && hasName) { - clone->as<JSFunction>().setExtendedSlot(LAZY_FUNCTION_NAME_SLOT, - StringValue(selfHostedFunction->explicitName())); + if (selfHostedFunction->isInterpreted()) { + // Arrow functions use the first extended slot for their lexical |this| value. + // And methods use the first extended slot for their home-object. + // We only expect to see normal functions here. + MOZ_ASSERT(selfHostedFunction->kind() == JSFunction::NormalFunction); + js::gc::AllocKind kind = selfHostedFunction->getAllocKind(); + + Handle<GlobalObject*> global = cx->global(); + Rooted<LexicalEnvironmentObject*> globalLexical(cx, &global->lexicalEnvironment()); + RootedScope emptyGlobalScope(cx, &global->emptyGlobalScope()); + MOZ_ASSERT(!CanReuseScriptForClone(cx->compartment(), selfHostedFunction, global)); + clone = CloneFunctionAndScript(cx, selfHostedFunction, globalLexical, emptyGlobalScope, + kind); + // To be able to re-lazify the cloned function, its name in the + // self-hosting compartment has to be stored on the clone. Re-lazification + // is only possible if this isn't a function expression. + if (clone && !selfHostedFunction->isLambda()) { + // If |_SetCanonicalName| was called on the function, the self-hosted + // name is stored in the extended slot. + JSAtom* name = GetSelfHostedFunctionName(selfHostedFunction); + if (!name) { + name = selfHostedFunction->explicitName(); + } + SetSelfHostedFunctionName(&clone->as<JSFunction>(), name); + } + } else { + clone = CloneSelfHostingIntrinsic(cx, selfHostedFunction); } } else if (selfHostedObject->is<RegExpObject>()) { RegExpObject& reobj = selfHostedObject->as<RegExpObject>(); @@ -3010,7 +3044,7 @@ JSRuntime::createLazySelfHostedFunctionClone(JSContext* cx, HandlePropertyName s if (!selfHostedFun->isClassConstructor() && !selfHostedFun->hasGuessedAtom() && selfHostedFun->explicitName() != selfHostedName) { - MOZ_ASSERT(selfHostedFun->getExtendedSlot(HAS_SELFHOSTED_CANONICAL_NAME_SLOT).toBoolean()); + MOZ_ASSERT(GetSelfHostedFunctionName(selfHostedFun) == selfHostedName); funName = selfHostedFun->explicitName(); } @@ -3019,7 +3053,7 @@ JSRuntime::createLazySelfHostedFunctionClone(JSContext* cx, HandlePropertyName s if (!fun) return false; fun->setIsSelfHostedBuiltin(); - fun->setExtendedSlot(LAZY_FUNCTION_NAME_SLOT, StringValue(selfHostedName)); + SetSelfHostedFunctionName(fun, selfHostedName); return true; } @@ -3105,7 +3139,7 @@ JSRuntime::assertSelfHostedFunctionHasCanonicalName(JSContext* cx, HandlePropert #ifdef DEBUG JSFunction* selfHostedFun = getUnclonedSelfHostedFunction(cx, name); MOZ_ASSERT(selfHostedFun); - MOZ_ASSERT(selfHostedFun->getExtendedSlot(HAS_SELFHOSTED_CANONICAL_NAME_SLOT).toBoolean()); + MOZ_ASSERT(GetSelfHostedFunctionName(selfHostedFun) == name); #endif } @@ -3127,15 +3161,6 @@ js::IsSelfHostedFunctionWithName(JSFunction* fun, JSAtom* name) return fun->isSelfHostedBuiltin() && GetSelfHostedFunctionName(fun) == name; } -JSAtom* -js::GetSelfHostedFunctionName(JSFunction* fun) -{ - Value name = fun->getExtendedSlot(LAZY_FUNCTION_NAME_SLOT); - if (!name.isString()) - return nullptr; - return &name.toString()->asAtom(); -} - static_assert(JSString::MAX_LENGTH <= INT32_MAX, "StringIteratorNext in builtin/String.js assumes the stored index " "into the string is an Int32Value"); diff --git a/js/src/vm/SelfHosting.h b/js/src/vm/SelfHosting.h index 6b1a03e851..04962f4445 100644 --- a/js/src/vm/SelfHosting.h +++ b/js/src/vm/SelfHosting.h @@ -22,6 +22,19 @@ namespace js { bool IsSelfHostedFunctionWithName(JSFunction* fun, JSAtom* name); +/* + * Returns the name of the function's binding in the self-hosted global. + * + * This returns a non-null value only when: + * * This is a top level function declaration in the self-hosted global. + * * And either: + * * This function is not cloned and `_SetCanonicalName` has been called to + * set a different function name. + * * This function is cloned. + * + * For functions not cloned and not `_SetCanonicalName`ed, use + * `fun->explicitName()` instead. + */ JSAtom* GetSelfHostedFunctionName(JSFunction* fun); |