summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--js/src/builtin/ReflectParse.cpp7
-rw-r--r--js/src/frontend/Parser.cpp18
-rw-r--r--js/src/frontend/SharedContext.h8
-rw-r--r--js/src/jsfun.cpp2
-rw-r--r--js/src/jsfun.h10
-rw-r--r--js/src/jsscript.cpp9
-rw-r--r--js/src/jsscript.h22
-rw-r--r--js/src/shell/js.cpp2
-rw-r--r--js/src/wasm/AsmJS.cpp3
9 files changed, 55 insertions, 26 deletions
diff --git a/js/src/builtin/ReflectParse.cpp b/js/src/builtin/ReflectParse.cpp
index beff58e13..2a0a08a5d 100644
--- a/js/src/builtin/ReflectParse.cpp
+++ b/js/src/builtin/ReflectParse.cpp
@@ -3407,12 +3407,7 @@ ASTSerializer::function(ParseNode* pn, ASTType type, MutableHandleValue dst)
: GeneratorStyle::None;
bool isAsync = pn->pn_funbox->isAsync();
- bool isExpression =
-#if JS_HAS_EXPR_CLOSURES
- func->isExprBody();
-#else
- false;
-#endif
+ bool isExpression = pn->pn_funbox->isExprBody();
RootedValue id(cx);
RootedAtom funcAtom(cx, func->explicitName());
diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp
index c86d9ca7b..2a80afbf1 100644
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -474,6 +474,7 @@ FunctionBox::FunctionBox(ExclusiveContext* cx, LifoAlloc& alloc, ObjectBox* trac
usesThis(false),
usesReturn(false),
hasRest_(false),
+ isExprBody_(false),
funCxFlags()
{
// 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());
if (funbox->hasRest())
lazy->setHasRest();
+ if (funbox->isExprBody())
+ lazy->setIsExprBody();
if (funbox->isLikelyConstructorWrapper())
lazy->setLikelyConstructorWrapper();
if (funbox->isDerivedClassConstructor())
@@ -3030,6 +3033,8 @@ Parser<FullParseHandler>::skipLazyInnerFunction(ParseNode* pn, uint32_t preludeS
LazyScript* lazy = fun->lazyScript();
if (lazy->needsHomeObject())
funbox->setNeedsHomeObject();
+ if (lazy->isExprBody())
+ funbox->setIsExprBody();
PropagateTransitiveParseFlags(lazy, pc->sc());
@@ -3042,10 +3047,15 @@ Parser<FullParseHandler>::skipLazyInnerFunction(ParseNode* pn, uint32_t preludeS
if (!tokenStream.advance(fun->lazyScript()->end() - userbufBase))
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())
return false;
}
+#endif
return true;
}
@@ -3490,9 +3500,7 @@ Parser<ParseHandler>::functionFormalParametersAndBody(InHandling inHandling,
tokenStream.ungetToken();
bodyType = ExpressionBody;
-#if JS_HAS_EXPR_CLOSURES
- fun->setIsExprBody();
-#endif
+ funbox->setIsExprBody();
}
// Arrow function parameters inherit yieldHandling from the enclosing
@@ -6130,7 +6138,7 @@ Parser<ParseHandler>::yieldExpression(InHandling inHandling)
if (pc->funHasReturnExpr
#if JS_HAS_EXPR_CLOSURES
- || pc->functionBox()->function()->isExprBody()
+ || pc->functionBox()->isExprBody()
#endif
)
{
diff --git a/js/src/frontend/SharedContext.h b/js/src/frontend/SharedContext.h
index b20417d5d..f5a74e18c 100644
--- a/js/src/frontend/SharedContext.h
+++ b/js/src/frontend/SharedContext.h
@@ -473,6 +473,9 @@ class FunctionBox : public ObjectBox, public SharedContext
bool usesThis:1; /* contains 'this' */
bool usesReturn:1; /* contains a 'return' statement */
bool hasRest_:1; /* has rest parameter */
+ bool isExprBody_:1; /* arrow function with expression
+ * body or expression closure:
+ * function(x) x*x */
FunctionContextFlags funCxFlags;
@@ -546,6 +549,11 @@ class FunctionBox : public ObjectBox, public SharedContext
hasRest_ = true;
}
+ bool isExprBody() const { return isExprBody_; }
+ void setIsExprBody() {
+ isExprBody_ = true;
+ }
+
void setGeneratorKind(GeneratorKind kind) {
// A generator kind can be set at initialization, or when "yield" is
// first seen. In both cases the transition can only happen from
diff --git a/js/src/jsfun.cpp b/js/src/jsfun.cpp
index 3cba3434d..304700da2 100644
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -980,8 +980,6 @@ js::FunctionToString(JSContext* cx, HandleFunction fun, bool prettyPrint)
return nullptr;
}
} else {
- MOZ_ASSERT(!fun->isExprBody());
-
bool derived = fun->infallibleIsDefaultClassConstructor(cx);
if (derived && fun->isDerivedClassConstructor()) {
if (!AppendPrelude() ||
diff --git a/js/src/jsfun.h b/js/src/jsfun.h
index 62b285806..b91c69d33 100644
--- a/js/src/jsfun.h
+++ b/js/src/jsfun.h
@@ -58,8 +58,6 @@ class JSFunction : public js::NativeObject
CONSTRUCTOR = 0x0002, /* function that can be called as a constructor */
EXTENDED = 0x0004, /* structure is FunctionExtended */
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
name was guessed for it anyway */
LAMBDA = 0x0040, /* function comes from a FunctionExpression, ArrowFunction, or
@@ -102,7 +100,7 @@ class JSFunction : public js::NativeObject
INTERPRETED_GENERATOR = INTERPRETED,
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
};
@@ -187,7 +185,6 @@ class JSFunction : public js::NativeObject
bool isAsmJSNative() const { return kind() == AsmJS; }
/* Possible attributes of an interpreted function: */
- bool isExprBody() const { return flags() & EXPR_BODY; }
bool hasCompileTimeName() const { return flags() & HAS_COMPILE_TIME_NAME; }
bool hasGuessedAtom() const { return flags() & HAS_GUESSED_ATOM; }
bool isLambda() const { return flags() & LAMBDA; }
@@ -290,11 +287,6 @@ class JSFunction : public js::NativeObject
flags_ |= SELF_HOSTED;
}
- // Can be called multiple times by the parser.
- void setIsExprBody() {
- flags_ |= EXPR_BODY;
- }
-
void setArrow() {
setKind(Arrow);
}
diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp
index 33ae56d6f..899820a0d 100644
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -319,6 +319,7 @@ js::XDRScript(XDRState<mode>* xdr, HandleScope scriptEnclosingScope, HandleScrip
IsStarGenerator,
IsAsync,
HasRest,
+ IsExprBody,
OwnSource,
ExplicitUseStrict,
SelfHosted,
@@ -436,6 +437,8 @@ js::XDRScript(XDRState<mode>* xdr, HandleScope scriptEnclosingScope, HandleScrip
scriptBits |= (1 << IsAsync);
if (script->hasRest())
scriptBits |= (1 << HasRest);
+ if (script->isExprBody())
+ scriptBits |= (1 << IsExprBody);
if (script->hasSingletons())
scriptBits |= (1 << HasSingleton);
if (script->treatAsRunOnce())
@@ -589,6 +592,8 @@ js::XDRScript(XDRState<mode>* xdr, HandleScope scriptEnclosingScope, HandleScrip
script->setAsyncKind(AsyncFunction);
if (scriptBits & (1 << HasRest))
script->setHasRest();
+ if (scriptBits & (1 << IsExprBody))
+ script->setIsExprBody();
}
JS_STATIC_ASSERT(sizeof(jsbytecode) == 1);
@@ -2660,6 +2665,8 @@ JSScript::initFromFunctionBox(ExclusiveContext* cx, HandleScript script,
script->setAsyncKind(funbox->asyncKind());
if (funbox->hasRest())
script->setHasRest();
+ if (funbox->isExprBody())
+ script->setIsExprBody();
PositionalFormalParameterIter fi(script);
while (fi && !fi.closedOver())
@@ -3320,6 +3327,7 @@ js::detail::CopyScript(JSContext* cx, HandleScript src, HandleScript dst,
dst->isDefaultClassConstructor_ = src->isDefaultClassConstructor();
dst->isAsync_ = src->asyncKind() == AsyncFunction;
dst->hasRest_ = src->hasRest_;
+ dst->isExprBody_ = src->isExprBody_;
if (nconsts != 0) {
GCPtrValue* vector = Rebase<GCPtrValue>(dst, src, src->consts()->vector);
@@ -4059,6 +4067,7 @@ LazyScript::Create(ExclusiveContext* cx, HandleFunction fun,
p.hasThisBinding = false;
p.isAsync = false;
p.hasRest = false;
+ p.isExprBody = false;
p.numClosedOverBindings = closedOverBindings.length();
p.numInnerFunctions = innerFunctions.length();
p.generatorKindBits = GeneratorKindAsBits(NotGenerator);
diff --git a/js/src/jsscript.h b/js/src/jsscript.h
index bb8635581..c3298a884 100644
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -1021,6 +1021,7 @@ class JSScript : public js::gc::TenuredCell
bool isAsync_:1;
bool hasRest_:1;
+ bool isExprBody_:1;
// Add padding so JSScript is gc::Cell aligned. Make padding protected
// instead of private to suppress -Wunused-private-field compiler warnings.
@@ -1329,6 +1330,13 @@ class JSScript : public js::gc::TenuredCell
hasRest_ = true;
}
+ bool isExprBody() const {
+ return isExprBody_;
+ }
+ void setIsExprBody() {
+ isExprBody_ = true;
+ }
+
void setNeedsHomeObject() {
needsHomeObject_ = true;
}
@@ -1936,7 +1944,7 @@ class LazyScript : public gc::TenuredCell
#endif
private:
- static const uint32_t NumClosedOverBindingsBits = 21;
+ static const uint32_t NumClosedOverBindingsBits = 20;
static const uint32_t NumInnerFunctionsBits = 20;
struct PackedView {
@@ -1946,7 +1954,12 @@ class LazyScript : public gc::TenuredCell
uint32_t shouldDeclareArguments : 1;
uint32_t hasThisBinding : 1;
uint32_t isAsync : 1;
+ uint32_t isExprBody : 1;
+
uint32_t numClosedOverBindings : NumClosedOverBindingsBits;
+
+ // -- 32bit boundary --
+
uint32_t numInnerFunctions : NumInnerFunctionsBits;
uint32_t generatorKindBits : 2;
@@ -2104,6 +2117,13 @@ class LazyScript : public gc::TenuredCell
p_.hasRest = true;
}
+ bool isExprBody() const {
+ return p_.isExprBody;
+ }
+ void setIsExprBody() {
+ p_.isExprBody = true;
+ }
+
bool strict() const {
return p_.strict;
}
diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp
index 617b5e902..f6a13623c 100644
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -2689,7 +2689,7 @@ DisassembleScript(JSContext* cx, HandleScript script, HandleFunction fun,
if (sp->put(" CONSTRUCTOR") < 0)
return false;
}
- if (fun->isExprBody()) {
+ if (script->isExprBody()) {
if (sp->put(" EXPRESSION_CLOSURE") < 0)
return false;
}
diff --git a/js/src/wasm/AsmJS.cpp b/js/src/wasm/AsmJS.cpp
index a318d67a9..6483d6ec3 100644
--- a/js/src/wasm/AsmJS.cpp
+++ b/js/src/wasm/AsmJS.cpp
@@ -3250,10 +3250,9 @@ CheckModuleLevelName(ModuleValidator& m, ParseNode* usepn, PropertyName* name)
static bool
CheckFunctionHead(ModuleValidator& m, ParseNode* fn)
{
- JSFunction* fun = FunctionObject(fn);
if (fn->pn_funbox->hasRest())
return m.fail(fn, "rest args not allowed");
- if (fun->isExprBody())
+ if (fn->pn_funbox->isExprBody())
return m.fail(fn, "expression closures not allowed");
if (fn->pn_funbox->hasDestructuringArgs)
return m.fail(fn, "destructuring args not allowed");