1320403 - Move JSFunction::EXPR_BODY to JSScript, LazyScript, and FunctionBox.
parent
8b786c6485
commit
07c18a52b1
|
@ -3407,12 +3407,7 @@ ASTSerializer::function(ParseNode* pn, ASTType type, MutableHandleValue dst)
|
||||||
: GeneratorStyle::None;
|
: GeneratorStyle::None;
|
||||||
|
|
||||||
bool isAsync = pn->pn_funbox->isAsync();
|
bool isAsync = pn->pn_funbox->isAsync();
|
||||||
bool isExpression =
|
bool isExpression = pn->pn_funbox->isExprBody();
|
||||||
#if JS_HAS_EXPR_CLOSURES
|
|
||||||
func->isExprBody();
|
|
||||||
#else
|
|
||||||
false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RootedValue id(cx);
|
RootedValue id(cx);
|
||||||
RootedAtom funcAtom(cx, func->explicitName());
|
RootedAtom funcAtom(cx, func->explicitName());
|
||||||
|
|
|
@ -474,6 +474,7 @@ FunctionBox::FunctionBox(ExclusiveContext* cx, LifoAlloc& alloc, ObjectBox* trac
|
||||||
usesThis(false),
|
usesThis(false),
|
||||||
usesReturn(false),
|
usesReturn(false),
|
||||||
hasRest_(false),
|
hasRest_(false),
|
||||||
|
isExprBody_(false),
|
||||||
funCxFlags()
|
funCxFlags()
|
||||||
{
|
{
|
||||||
// Functions created at parse time may be set singleton after parsing and
|
// Functions created at parse time may be set singleton after parsing and
|
||||||
|
@ -2264,6 +2265,8 @@ Parser<SyntaxParseHandler>::finishFunction(bool isStandaloneFunction /* = false
|
||||||
lazy->setAsyncKind(funbox->asyncKind());
|
lazy->setAsyncKind(funbox->asyncKind());
|
||||||
if (funbox->hasRest())
|
if (funbox->hasRest())
|
||||||
lazy->setHasRest();
|
lazy->setHasRest();
|
||||||
|
if (funbox->isExprBody())
|
||||||
|
lazy->setIsExprBody();
|
||||||
if (funbox->isLikelyConstructorWrapper())
|
if (funbox->isLikelyConstructorWrapper())
|
||||||
lazy->setLikelyConstructorWrapper();
|
lazy->setLikelyConstructorWrapper();
|
||||||
if (funbox->isDerivedClassConstructor())
|
if (funbox->isDerivedClassConstructor())
|
||||||
|
@ -3030,6 +3033,8 @@ Parser<FullParseHandler>::skipLazyInnerFunction(ParseNode* pn, uint32_t preludeS
|
||||||
LazyScript* lazy = fun->lazyScript();
|
LazyScript* lazy = fun->lazyScript();
|
||||||
if (lazy->needsHomeObject())
|
if (lazy->needsHomeObject())
|
||||||
funbox->setNeedsHomeObject();
|
funbox->setNeedsHomeObject();
|
||||||
|
if (lazy->isExprBody())
|
||||||
|
funbox->setIsExprBody();
|
||||||
|
|
||||||
PropagateTransitiveParseFlags(lazy, pc->sc());
|
PropagateTransitiveParseFlags(lazy, pc->sc());
|
||||||
|
|
||||||
|
@ -3042,10 +3047,15 @@ Parser<FullParseHandler>::skipLazyInnerFunction(ParseNode* pn, uint32_t preludeS
|
||||||
if (!tokenStream.advance(fun->lazyScript()->end() - userbufBase))
|
if (!tokenStream.advance(fun->lazyScript()->end() - userbufBase))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (kind == Statement && fun->isExprBody()) {
|
#if JS_HAS_EXPR_CLOSURES
|
||||||
|
// Only expression closure can be Statement kind.
|
||||||
|
// If we remove expression closure, we can remove isExprBody flag from
|
||||||
|
// LazyScript and JSScript.
|
||||||
|
if (kind == Statement && funbox->isExprBody()) {
|
||||||
if (!matchOrInsertSemicolonAfterExpression())
|
if (!matchOrInsertSemicolonAfterExpression())
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -3490,9 +3500,7 @@ Parser<ParseHandler>::functionFormalParametersAndBody(InHandling inHandling,
|
||||||
|
|
||||||
tokenStream.ungetToken();
|
tokenStream.ungetToken();
|
||||||
bodyType = ExpressionBody;
|
bodyType = ExpressionBody;
|
||||||
#if JS_HAS_EXPR_CLOSURES
|
funbox->setIsExprBody();
|
||||||
fun->setIsExprBody();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Arrow function parameters inherit yieldHandling from the enclosing
|
// Arrow function parameters inherit yieldHandling from the enclosing
|
||||||
|
@ -6130,7 +6138,7 @@ Parser<ParseHandler>::yieldExpression(InHandling inHandling)
|
||||||
|
|
||||||
if (pc->funHasReturnExpr
|
if (pc->funHasReturnExpr
|
||||||
#if JS_HAS_EXPR_CLOSURES
|
#if JS_HAS_EXPR_CLOSURES
|
||||||
|| pc->functionBox()->function()->isExprBody()
|
|| pc->functionBox()->isExprBody()
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
|
|
@ -473,6 +473,9 @@ class FunctionBox : public ObjectBox, public SharedContext
|
||||||
bool usesThis:1; /* contains 'this' */
|
bool usesThis:1; /* contains 'this' */
|
||||||
bool usesReturn:1; /* contains a 'return' statement */
|
bool usesReturn:1; /* contains a 'return' statement */
|
||||||
bool hasRest_:1; /* has rest parameter */
|
bool hasRest_:1; /* has rest parameter */
|
||||||
|
bool isExprBody_:1; /* arrow function with expression
|
||||||
|
* body or expression closure:
|
||||||
|
* function(x) x*x */
|
||||||
|
|
||||||
FunctionContextFlags funCxFlags;
|
FunctionContextFlags funCxFlags;
|
||||||
|
|
||||||
|
@ -546,6 +549,11 @@ class FunctionBox : public ObjectBox, public SharedContext
|
||||||
hasRest_ = true;
|
hasRest_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isExprBody() const { return isExprBody_; }
|
||||||
|
void setIsExprBody() {
|
||||||
|
isExprBody_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
void setGeneratorKind(GeneratorKind kind) {
|
void setGeneratorKind(GeneratorKind kind) {
|
||||||
// A generator kind can be set at initialization, or when "yield" is
|
// A generator kind can be set at initialization, or when "yield" is
|
||||||
// first seen. In both cases the transition can only happen from
|
// first seen. In both cases the transition can only happen from
|
||||||
|
|
|
@ -980,8 +980,6 @@ js::FunctionToString(JSContext* cx, HandleFunction fun, bool prettyPrint)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
MOZ_ASSERT(!fun->isExprBody());
|
|
||||||
|
|
||||||
bool derived = fun->infallibleIsDefaultClassConstructor(cx);
|
bool derived = fun->infallibleIsDefaultClassConstructor(cx);
|
||||||
if (derived && fun->isDerivedClassConstructor()) {
|
if (derived && fun->isDerivedClassConstructor()) {
|
||||||
if (!AppendPrelude() ||
|
if (!AppendPrelude() ||
|
||||||
|
|
|
@ -58,8 +58,6 @@ class JSFunction : public js::NativeObject
|
||||||
CONSTRUCTOR = 0x0002, /* function that can be called as a constructor */
|
CONSTRUCTOR = 0x0002, /* function that can be called as a constructor */
|
||||||
EXTENDED = 0x0004, /* structure is FunctionExtended */
|
EXTENDED = 0x0004, /* structure is FunctionExtended */
|
||||||
BOUND_FUN = 0x0008, /* function was created with Function.prototype.bind. */
|
BOUND_FUN = 0x0008, /* function was created with Function.prototype.bind. */
|
||||||
EXPR_BODY = 0x0010, /* arrow function with expression body or
|
|
||||||
* expression closure: function(x) x*x */
|
|
||||||
HAS_GUESSED_ATOM = 0x0020, /* function had no explicit name, but a
|
HAS_GUESSED_ATOM = 0x0020, /* function had no explicit name, but a
|
||||||
name was guessed for it anyway */
|
name was guessed for it anyway */
|
||||||
LAMBDA = 0x0040, /* function comes from a FunctionExpression, ArrowFunction, or
|
LAMBDA = 0x0040, /* function comes from a FunctionExpression, ArrowFunction, or
|
||||||
|
@ -102,7 +100,7 @@ class JSFunction : public js::NativeObject
|
||||||
INTERPRETED_GENERATOR = INTERPRETED,
|
INTERPRETED_GENERATOR = INTERPRETED,
|
||||||
NO_XDR_FLAGS = RESOLVED_LENGTH | RESOLVED_NAME,
|
NO_XDR_FLAGS = RESOLVED_LENGTH | RESOLVED_NAME,
|
||||||
|
|
||||||
STABLE_ACROSS_CLONES = CONSTRUCTOR | EXPR_BODY | HAS_GUESSED_ATOM | LAMBDA |
|
STABLE_ACROSS_CLONES = CONSTRUCTOR | HAS_GUESSED_ATOM | LAMBDA |
|
||||||
SELF_HOSTED | HAS_COMPILE_TIME_NAME | FUNCTION_KIND_MASK
|
SELF_HOSTED | HAS_COMPILE_TIME_NAME | FUNCTION_KIND_MASK
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -187,7 +185,6 @@ class JSFunction : public js::NativeObject
|
||||||
bool isAsmJSNative() const { return kind() == AsmJS; }
|
bool isAsmJSNative() const { return kind() == AsmJS; }
|
||||||
|
|
||||||
/* Possible attributes of an interpreted function: */
|
/* Possible attributes of an interpreted function: */
|
||||||
bool isExprBody() const { return flags() & EXPR_BODY; }
|
|
||||||
bool hasCompileTimeName() const { return flags() & HAS_COMPILE_TIME_NAME; }
|
bool hasCompileTimeName() const { return flags() & HAS_COMPILE_TIME_NAME; }
|
||||||
bool hasGuessedAtom() const { return flags() & HAS_GUESSED_ATOM; }
|
bool hasGuessedAtom() const { return flags() & HAS_GUESSED_ATOM; }
|
||||||
bool isLambda() const { return flags() & LAMBDA; }
|
bool isLambda() const { return flags() & LAMBDA; }
|
||||||
|
@ -290,11 +287,6 @@ class JSFunction : public js::NativeObject
|
||||||
flags_ |= SELF_HOSTED;
|
flags_ |= SELF_HOSTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can be called multiple times by the parser.
|
|
||||||
void setIsExprBody() {
|
|
||||||
flags_ |= EXPR_BODY;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setArrow() {
|
void setArrow() {
|
||||||
setKind(Arrow);
|
setKind(Arrow);
|
||||||
}
|
}
|
||||||
|
|
|
@ -319,6 +319,7 @@ js::XDRScript(XDRState<mode>* xdr, HandleScope scriptEnclosingScope, HandleScrip
|
||||||
IsStarGenerator,
|
IsStarGenerator,
|
||||||
IsAsync,
|
IsAsync,
|
||||||
HasRest,
|
HasRest,
|
||||||
|
IsExprBody,
|
||||||
OwnSource,
|
OwnSource,
|
||||||
ExplicitUseStrict,
|
ExplicitUseStrict,
|
||||||
SelfHosted,
|
SelfHosted,
|
||||||
|
@ -436,6 +437,8 @@ js::XDRScript(XDRState<mode>* xdr, HandleScope scriptEnclosingScope, HandleScrip
|
||||||
scriptBits |= (1 << IsAsync);
|
scriptBits |= (1 << IsAsync);
|
||||||
if (script->hasRest())
|
if (script->hasRest())
|
||||||
scriptBits |= (1 << HasRest);
|
scriptBits |= (1 << HasRest);
|
||||||
|
if (script->isExprBody())
|
||||||
|
scriptBits |= (1 << IsExprBody);
|
||||||
if (script->hasSingletons())
|
if (script->hasSingletons())
|
||||||
scriptBits |= (1 << HasSingleton);
|
scriptBits |= (1 << HasSingleton);
|
||||||
if (script->treatAsRunOnce())
|
if (script->treatAsRunOnce())
|
||||||
|
@ -589,6 +592,8 @@ js::XDRScript(XDRState<mode>* xdr, HandleScope scriptEnclosingScope, HandleScrip
|
||||||
script->setAsyncKind(AsyncFunction);
|
script->setAsyncKind(AsyncFunction);
|
||||||
if (scriptBits & (1 << HasRest))
|
if (scriptBits & (1 << HasRest))
|
||||||
script->setHasRest();
|
script->setHasRest();
|
||||||
|
if (scriptBits & (1 << IsExprBody))
|
||||||
|
script->setIsExprBody();
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_STATIC_ASSERT(sizeof(jsbytecode) == 1);
|
JS_STATIC_ASSERT(sizeof(jsbytecode) == 1);
|
||||||
|
@ -2660,6 +2665,8 @@ JSScript::initFromFunctionBox(ExclusiveContext* cx, HandleScript script,
|
||||||
script->setAsyncKind(funbox->asyncKind());
|
script->setAsyncKind(funbox->asyncKind());
|
||||||
if (funbox->hasRest())
|
if (funbox->hasRest())
|
||||||
script->setHasRest();
|
script->setHasRest();
|
||||||
|
if (funbox->isExprBody())
|
||||||
|
script->setIsExprBody();
|
||||||
|
|
||||||
PositionalFormalParameterIter fi(script);
|
PositionalFormalParameterIter fi(script);
|
||||||
while (fi && !fi.closedOver())
|
while (fi && !fi.closedOver())
|
||||||
|
@ -3320,6 +3327,7 @@ js::detail::CopyScript(JSContext* cx, HandleScript src, HandleScript dst,
|
||||||
dst->isDefaultClassConstructor_ = src->isDefaultClassConstructor();
|
dst->isDefaultClassConstructor_ = src->isDefaultClassConstructor();
|
||||||
dst->isAsync_ = src->asyncKind() == AsyncFunction;
|
dst->isAsync_ = src->asyncKind() == AsyncFunction;
|
||||||
dst->hasRest_ = src->hasRest_;
|
dst->hasRest_ = src->hasRest_;
|
||||||
|
dst->isExprBody_ = src->isExprBody_;
|
||||||
|
|
||||||
if (nconsts != 0) {
|
if (nconsts != 0) {
|
||||||
GCPtrValue* vector = Rebase<GCPtrValue>(dst, src, src->consts()->vector);
|
GCPtrValue* vector = Rebase<GCPtrValue>(dst, src, src->consts()->vector);
|
||||||
|
@ -4059,6 +4067,7 @@ LazyScript::Create(ExclusiveContext* cx, HandleFunction fun,
|
||||||
p.hasThisBinding = false;
|
p.hasThisBinding = false;
|
||||||
p.isAsync = false;
|
p.isAsync = false;
|
||||||
p.hasRest = false;
|
p.hasRest = false;
|
||||||
|
p.isExprBody = false;
|
||||||
p.numClosedOverBindings = closedOverBindings.length();
|
p.numClosedOverBindings = closedOverBindings.length();
|
||||||
p.numInnerFunctions = innerFunctions.length();
|
p.numInnerFunctions = innerFunctions.length();
|
||||||
p.generatorKindBits = GeneratorKindAsBits(NotGenerator);
|
p.generatorKindBits = GeneratorKindAsBits(NotGenerator);
|
||||||
|
|
|
@ -1021,6 +1021,7 @@ class JSScript : public js::gc::TenuredCell
|
||||||
bool isAsync_:1;
|
bool isAsync_:1;
|
||||||
|
|
||||||
bool hasRest_:1;
|
bool hasRest_:1;
|
||||||
|
bool isExprBody_:1;
|
||||||
|
|
||||||
// Add padding so JSScript is gc::Cell aligned. Make padding protected
|
// Add padding so JSScript is gc::Cell aligned. Make padding protected
|
||||||
// instead of private to suppress -Wunused-private-field compiler warnings.
|
// instead of private to suppress -Wunused-private-field compiler warnings.
|
||||||
|
@ -1329,6 +1330,13 @@ class JSScript : public js::gc::TenuredCell
|
||||||
hasRest_ = true;
|
hasRest_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isExprBody() const {
|
||||||
|
return isExprBody_;
|
||||||
|
}
|
||||||
|
void setIsExprBody() {
|
||||||
|
isExprBody_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
void setNeedsHomeObject() {
|
void setNeedsHomeObject() {
|
||||||
needsHomeObject_ = true;
|
needsHomeObject_ = true;
|
||||||
}
|
}
|
||||||
|
@ -1936,7 +1944,7 @@ class LazyScript : public gc::TenuredCell
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const uint32_t NumClosedOverBindingsBits = 21;
|
static const uint32_t NumClosedOverBindingsBits = 20;
|
||||||
static const uint32_t NumInnerFunctionsBits = 20;
|
static const uint32_t NumInnerFunctionsBits = 20;
|
||||||
|
|
||||||
struct PackedView {
|
struct PackedView {
|
||||||
|
@ -1946,7 +1954,12 @@ class LazyScript : public gc::TenuredCell
|
||||||
uint32_t shouldDeclareArguments : 1;
|
uint32_t shouldDeclareArguments : 1;
|
||||||
uint32_t hasThisBinding : 1;
|
uint32_t hasThisBinding : 1;
|
||||||
uint32_t isAsync : 1;
|
uint32_t isAsync : 1;
|
||||||
|
uint32_t isExprBody : 1;
|
||||||
|
|
||||||
uint32_t numClosedOverBindings : NumClosedOverBindingsBits;
|
uint32_t numClosedOverBindings : NumClosedOverBindingsBits;
|
||||||
|
|
||||||
|
// -- 32bit boundary --
|
||||||
|
|
||||||
uint32_t numInnerFunctions : NumInnerFunctionsBits;
|
uint32_t numInnerFunctions : NumInnerFunctionsBits;
|
||||||
|
|
||||||
uint32_t generatorKindBits : 2;
|
uint32_t generatorKindBits : 2;
|
||||||
|
@ -2104,6 +2117,13 @@ class LazyScript : public gc::TenuredCell
|
||||||
p_.hasRest = true;
|
p_.hasRest = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isExprBody() const {
|
||||||
|
return p_.isExprBody;
|
||||||
|
}
|
||||||
|
void setIsExprBody() {
|
||||||
|
p_.isExprBody = true;
|
||||||
|
}
|
||||||
|
|
||||||
bool strict() const {
|
bool strict() const {
|
||||||
return p_.strict;
|
return p_.strict;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2689,7 +2689,7 @@ DisassembleScript(JSContext* cx, HandleScript script, HandleFunction fun,
|
||||||
if (sp->put(" CONSTRUCTOR") < 0)
|
if (sp->put(" CONSTRUCTOR") < 0)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (fun->isExprBody()) {
|
if (script->isExprBody()) {
|
||||||
if (sp->put(" EXPRESSION_CLOSURE") < 0)
|
if (sp->put(" EXPRESSION_CLOSURE") < 0)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3250,10 +3250,9 @@ CheckModuleLevelName(ModuleValidator& m, ParseNode* usepn, PropertyName* name)
|
||||||
static bool
|
static bool
|
||||||
CheckFunctionHead(ModuleValidator& m, ParseNode* fn)
|
CheckFunctionHead(ModuleValidator& m, ParseNode* fn)
|
||||||
{
|
{
|
||||||
JSFunction* fun = FunctionObject(fn);
|
|
||||||
if (fn->pn_funbox->hasRest())
|
if (fn->pn_funbox->hasRest())
|
||||||
return m.fail(fn, "rest args not allowed");
|
return m.fail(fn, "rest args not allowed");
|
||||||
if (fun->isExprBody())
|
if (fn->pn_funbox->isExprBody())
|
||||||
return m.fail(fn, "expression closures not allowed");
|
return m.fail(fn, "expression closures not allowed");
|
||||||
if (fn->pn_funbox->hasDestructuringArgs)
|
if (fn->pn_funbox->hasDestructuringArgs)
|
||||||
return m.fail(fn, "destructuring args not allowed");
|
return m.fail(fn, "destructuring args not allowed");
|
||||||
|
|
Loading…
Reference in New Issue