summaryrefslogtreecommitdiff
path: root/js/src/vm
diff options
context:
space:
mode:
authorBrian Smith <brian@dbsoft.org>2023-07-18 20:25:54 -0500
committerBrian Smith <brian@dbsoft.org>2023-07-18 20:25:54 -0500
commit94240c9002292911b140a962dec70a99acf664cd (patch)
tree0f3ecd52cc00a127b6b0f05feb76e5bfb1585233 /js/src/vm
parent069fa50258931976dfdfeb7f9320af1ac0b6d176 (diff)
parent7175868124c789ae6607be6244038dd6d50fe771 (diff)
downloaduxp-94240c9002292911b140a962dec70a99acf664cd.tar.gz
Merge branch 'master' into bigint-merged
Diffstat (limited to 'js/src/vm')
-rw-r--r--js/src/vm/Interpreter.cpp8
-rw-r--r--js/src/vm/SelfHosting.cpp89
-rw-r--r--js/src/vm/SelfHosting.h13
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);