зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1371591 - Part 3: Store dynamic function names into the name atom instead of a property. r=jorendorff
--HG-- extra : rebase_source : 35f52619df56eb432a5dc3413c30eeae4324ada3
This commit is contained in:
Родитель
9fff6441bc
Коммит
129ae0e65a
|
@ -5493,18 +5493,18 @@ BytecodeEmitter::setOrEmitSetFunName(ParseNode* maybeFun, HandleAtom name,
|
|||
// Single node can be emitted multiple times if it appears in
|
||||
// array destructuring default. If function already has a name,
|
||||
// just return.
|
||||
if (fun->hasCompileTimeName()) {
|
||||
if (fun->hasInferredName()) {
|
||||
#ifdef DEBUG
|
||||
RootedFunction rootedFun(cx, fun);
|
||||
JSAtom* funName = NameToFunctionName(cx, name, prefixKind);
|
||||
if (!funName)
|
||||
return false;
|
||||
MOZ_ASSERT(funName == rootedFun->compileTimeName());
|
||||
MOZ_ASSERT(funName == rootedFun->inferredName());
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
fun->setCompileTimeName(name);
|
||||
fun->setInferredName(name);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -278,7 +278,11 @@ class NameResolver
|
|||
retAtom.set(buf.finishAtom());
|
||||
if (!retAtom)
|
||||
return false;
|
||||
fun->setGuessedAtom(retAtom);
|
||||
|
||||
// Skip assigning the guessed name if the function has a (dynamically)
|
||||
// computed inferred name.
|
||||
if (!pn->isDirectRHSAnonFunction())
|
||||
fun->setGuessedAtom(retAtom);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -130,7 +130,7 @@ assertName(z[0], 'z<');
|
|||
odeURIL:(function(){})
|
||||
|
||||
a = { 1: function () {} };
|
||||
assertName(a[1], 'a[1]');
|
||||
assertName(a[1], '1');
|
||||
|
||||
a = {
|
||||
"embedded spaces": function(){},
|
||||
|
|
|
@ -138,8 +138,8 @@ js::WrapAsyncFunctionWithProto(JSContext* cx, HandleFunction unwrapped, HandleOb
|
|||
if (!wrapped)
|
||||
return nullptr;
|
||||
|
||||
if (unwrapped->hasCompileTimeName())
|
||||
wrapped->setCompileTimeName(unwrapped->compileTimeName());
|
||||
if (unwrapped->hasInferredName())
|
||||
wrapped->setInferredName(unwrapped->inferredName());
|
||||
|
||||
// Link them to each other to make GetWrappedAsyncFunction and
|
||||
// GetUnwrappedAsyncFunction work.
|
||||
|
|
|
@ -83,8 +83,8 @@ js::WrapAsyncGeneratorWithProto(JSContext* cx, HandleFunction unwrapped, HandleO
|
|||
if (!wrapped)
|
||||
return nullptr;
|
||||
|
||||
if (unwrapped->hasCompileTimeName())
|
||||
wrapped->setCompileTimeName(unwrapped->compileTimeName());
|
||||
if (unwrapped->hasInferredName())
|
||||
wrapped->setInferredName(unwrapped->inferredName());
|
||||
|
||||
// Link them to each other to make GetWrappedAsyncGenerator and
|
||||
// GetUnwrappedAsyncGenerator work.
|
||||
|
|
|
@ -590,7 +590,7 @@ js::XDRInterpretedFunction(XDRState<mode>* xdr, HandleScope enclosingScope,
|
|||
if (!fun->isInterpreted())
|
||||
return xdr->fail(JS::TranscodeResult_Failure_NotInterpretedFun);
|
||||
|
||||
if (fun->explicitName() || fun->hasCompileTimeName() || fun->hasGuessedAtom())
|
||||
if (fun->explicitName() || fun->hasInferredName() || fun->hasGuessedAtom())
|
||||
firstword |= HasAtom;
|
||||
|
||||
if (fun->isGenerator() || fun->isAsync())
|
||||
|
@ -1327,12 +1327,8 @@ JSFunction::getUnresolvedName(JSContext* cx, HandleFunction fun, MutableHandleAt
|
|||
MOZ_ASSERT(!IsInternalFunctionObject(*fun));
|
||||
MOZ_ASSERT(!fun->hasResolvedName());
|
||||
|
||||
JSAtom* name = fun->explicitOrCompileTimeName();
|
||||
JSAtom* name = fun->explicitOrInferredName();
|
||||
if (fun->isClassConstructor()) {
|
||||
// It's impossible to have an empty named class expression. We use
|
||||
// empty as a sentinel when creating default class constructors.
|
||||
MOZ_ASSERT(name != cx->names().empty);
|
||||
|
||||
// Unnamed class expressions should not get a .name property at all.
|
||||
if (name)
|
||||
v.set(name);
|
||||
|
@ -2307,9 +2303,8 @@ js::SetFunctionNameIfNoOwnName(JSContext* cx, HandleFunction fun, HandleValue na
|
|||
if (!funNameAtom)
|
||||
return false;
|
||||
|
||||
RootedValue funNameVal(cx, StringValue(funNameAtom));
|
||||
if (!NativeDefineDataProperty(cx, fun, cx->names().name, funNameVal, JSPROP_READONLY))
|
||||
return false;
|
||||
MOZ_ASSERT(!fun->hasResolvedName());
|
||||
fun->setInferredName(funNameAtom);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -70,9 +70,9 @@ class JSFunction : public js::NativeObject
|
|||
function-statement) */
|
||||
SELF_HOSTED = 0x0080, /* function is self-hosted builtin and must not be
|
||||
decompilable nor constructible. */
|
||||
HAS_COMPILE_TIME_NAME = 0x0100, /* function had no explicit name, but a
|
||||
name was set by SetFunctionName
|
||||
at compile time */
|
||||
HAS_INFERRED_NAME = 0x0100, /* function had no explicit name, but a name was
|
||||
set by SetFunctionName at compile time or
|
||||
SetFunctionNameIfNoOwnName at runtime. */
|
||||
INTERPRETED_LAZY = 0x0200, /* function is interpreted but doesn't have a script yet */
|
||||
RESOLVED_LENGTH = 0x0400, /* f.length has been resolved (see fun_resolve). */
|
||||
RESOLVED_NAME = 0x0800, /* f.name has been resolved (see fun_resolve). */
|
||||
|
@ -106,8 +106,7 @@ class JSFunction : public js::NativeObject
|
|||
INTERPRETED_GENERATOR_OR_ASYNC = INTERPRETED,
|
||||
NO_XDR_FLAGS = RESOLVED_LENGTH | RESOLVED_NAME,
|
||||
|
||||
STABLE_ACROSS_CLONES = CONSTRUCTOR | LAMBDA | SELF_HOSTED | HAS_COMPILE_TIME_NAME |
|
||||
FUNCTION_KIND_MASK
|
||||
STABLE_ACROSS_CLONES = CONSTRUCTOR | LAMBDA | SELF_HOSTED | FUNCTION_KIND_MASK
|
||||
};
|
||||
|
||||
static_assert((INTERPRETED | INTERPRETED_LAZY) == js::JS_FUNCTION_INTERPRETED_BITS,
|
||||
|
@ -205,7 +204,7 @@ class JSFunction : public js::NativeObject
|
|||
|
||||
/* Possible attributes of an interpreted function: */
|
||||
bool isBoundFunction() const { return flags() & BOUND_FUN; }
|
||||
bool hasCompileTimeName() const { return flags() & HAS_COMPILE_TIME_NAME; }
|
||||
bool hasInferredName() const { return flags() & HAS_INFERRED_NAME; }
|
||||
bool hasGuessedAtom() const {
|
||||
static_assert(HAS_GUESSED_ATOM == HAS_BOUND_FUNCTION_NAME_PREFIX,
|
||||
"HAS_GUESSED_ATOM is unused for bound functions");
|
||||
|
@ -259,7 +258,7 @@ class JSFunction : public js::NativeObject
|
|||
}
|
||||
|
||||
bool isNamedLambda() const {
|
||||
return isLambda() && displayAtom() && !hasCompileTimeName() && !hasGuessedAtom();
|
||||
return isLambda() && displayAtom() && !hasInferredName() && !hasGuessedAtom();
|
||||
}
|
||||
|
||||
bool hasLexicalThis() const {
|
||||
|
@ -346,9 +345,9 @@ class JSFunction : public js::NativeObject
|
|||
js::MutableHandleAtom v);
|
||||
|
||||
JSAtom* explicitName() const {
|
||||
return (hasCompileTimeName() || hasGuessedAtom()) ? nullptr : atom_.get();
|
||||
return (hasInferredName() || hasGuessedAtom()) ? nullptr : atom_.get();
|
||||
}
|
||||
JSAtom* explicitOrCompileTimeName() const {
|
||||
JSAtom* explicitOrInferredName() const {
|
||||
return hasGuessedAtom() ? nullptr : atom_.get();
|
||||
}
|
||||
|
||||
|
@ -366,16 +365,21 @@ class JSFunction : public js::NativeObject
|
|||
return atom_;
|
||||
}
|
||||
|
||||
void setCompileTimeName(JSAtom* atom) {
|
||||
void setInferredName(JSAtom* atom) {
|
||||
MOZ_ASSERT(!atom_);
|
||||
MOZ_ASSERT(atom);
|
||||
MOZ_ASSERT(!hasGuessedAtom());
|
||||
MOZ_ASSERT(!isClassConstructor());
|
||||
setAtom(atom);
|
||||
flags_ |= HAS_COMPILE_TIME_NAME;
|
||||
flags_ |= HAS_INFERRED_NAME;
|
||||
}
|
||||
JSAtom* compileTimeName() const {
|
||||
MOZ_ASSERT(hasCompileTimeName());
|
||||
void clearInferredName() {
|
||||
MOZ_ASSERT(hasInferredName());
|
||||
MOZ_ASSERT(atom_);
|
||||
setAtom(nullptr);
|
||||
flags_ &= ~HAS_INFERRED_NAME;
|
||||
}
|
||||
JSAtom* inferredName() const {
|
||||
MOZ_ASSERT(hasInferredName());
|
||||
MOZ_ASSERT(atom_);
|
||||
return atom_;
|
||||
}
|
||||
|
@ -383,7 +387,7 @@ class JSFunction : public js::NativeObject
|
|||
void setGuessedAtom(JSAtom* atom) {
|
||||
MOZ_ASSERT(!atom_);
|
||||
MOZ_ASSERT(atom);
|
||||
MOZ_ASSERT(!hasCompileTimeName());
|
||||
MOZ_ASSERT(!hasInferredName());
|
||||
MOZ_ASSERT(!hasGuessedAtom());
|
||||
MOZ_ASSERT(!isBoundFunction());
|
||||
setAtom(atom);
|
||||
|
|
|
@ -480,10 +480,10 @@ intrinsic_MakeDefaultConstructor(JSContext* cx, unsigned argc, Value* vp)
|
|||
|
||||
// Because self-hosting code does not allow top-level lexicals,
|
||||
// class constructors are class expressions in top-level vars.
|
||||
// Because of this, we give them a guessed atom. Since they
|
||||
// Because of this, we give them an inferred atom. Since they
|
||||
// will always be cloned, and given an explicit atom, instead
|
||||
// overrule that.
|
||||
ctor->clearGuessedAtom();
|
||||
ctor->clearInferredName();
|
||||
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
|
|
Загрузка…
Ссылка в новой задаче