Bug 1185106 - Part 1: Add AsyncFunction flag in FunctionBox, JSScript, and LazyScript. r=efaust,till

MozReview-Commit-ID: 6nOsJO3doV9
This commit is contained in:
Mariusz Kierski 2016-08-28 20:42:39 +09:00
Родитель 8f8d409007
Коммит ae79a1ae1c
7 изменённых файлов: 80 добавлений и 13 удалений

Просмотреть файл

@ -7068,7 +7068,7 @@ ParseFunction(ModuleValidator& m, ParseNode** fnOut, unsigned* line)
ParseContext* outerpc = m.parser().pc;
Directives directives(outerpc);
FunctionBox* funbox = m.parser().newFunctionBox(fn, fun, directives, NotGenerator,
/* tryAnnexB = */ false);
SyncFunction, /* tryAnnexB = */ false);
if (!funbox)
return false;
funbox->initWithEnclosingParseContext(outerpc, frontend::Statement);

Просмотреть файл

@ -436,7 +436,7 @@ UsedNameTracker::rewind(RewindToken token)
FunctionBox::FunctionBox(ExclusiveContext* cx, LifoAlloc& alloc, ObjectBox* traceListHead,
JSFunction* fun, Directives directives, bool extraWarnings,
GeneratorKind generatorKind)
GeneratorKind generatorKind, FunctionAsyncKind asyncKind)
: ObjectBox(fun, traceListHead),
SharedContext(cx, Kind::ObjectBox, directives, extraWarnings),
enclosingScope_(nullptr),
@ -450,6 +450,7 @@ FunctionBox::FunctionBox(ExclusiveContext* cx, LifoAlloc& alloc, ObjectBox* trac
startColumn(0),
length(0),
generatorKindBits_(GeneratorKindAsBits(generatorKind)),
asyncKindBits_(AsyncKindAsBits(asyncKind)),
isGenexpLambda(false),
hasDestructuringArgs(false),
hasParameterExprs(false),
@ -734,7 +735,8 @@ Parser<ParseHandler>::newObjectBox(JSObject* obj)
template <typename ParseHandler>
FunctionBox*
Parser<ParseHandler>::newFunctionBox(Node fn, JSFunction* fun, Directives inheritedDirectives,
GeneratorKind generatorKind, bool tryAnnexB)
GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
bool tryAnnexB)
{
MOZ_ASSERT(fun);
MOZ_ASSERT_IF(tryAnnexB, !pc->sc()->strict());
@ -748,7 +750,7 @@ Parser<ParseHandler>::newFunctionBox(Node fn, JSFunction* fun, Directives inheri
*/
FunctionBox* funbox =
alloc.new_<FunctionBox>(context, alloc, traceListHead, fun, inheritedDirectives,
options().extraWarningsOption, generatorKind);
options().extraWarningsOption, generatorKind, asyncKind);
if (!funbox) {
ReportOutOfMemory(context);
return nullptr;
@ -2195,6 +2197,7 @@ Parser<SyntaxParseHandler>::finishFunction()
if (pc->sc()->strict())
lazy->setStrict();
lazy->setGeneratorKind(funbox->generatorKind());
lazy->setAsyncKind(funbox->asyncKind());
if (funbox->isLikelyConstructorWrapper())
lazy->setLikelyConstructorWrapper();
if (funbox->isDerivedClassConstructor())
@ -2235,7 +2238,7 @@ Parser<FullParseHandler>::standaloneFunctionBody(HandleFunction fun,
fn->pn_body = argsbody;
FunctionBox* funbox = newFunctionBox(fn, fun, inheritedDirectives, generatorKind,
/* tryAnnexB = */ false);
SyncFunction, /* tryAnnexB = */ false);
if (!funbox)
return null();
funbox->initStandaloneFunction(enclosingScope);
@ -2921,7 +2924,7 @@ Parser<FullParseHandler>::skipLazyInnerFunction(ParseNode* pn, FunctionSyntaxKin
RootedFunction fun(context, handler.nextLazyInnerFunction());
MOZ_ASSERT(!fun->isLegacyGenerator());
FunctionBox* funbox = newFunctionBox(pn, fun, Directives(/* strict = */ false),
fun->generatorKind(), tryAnnexB);
fun->generatorKind(), fun->asyncKind(), tryAnnexB);
if (!funbox)
return false;
@ -3143,7 +3146,7 @@ Parser<FullParseHandler>::trySyntaxParseInnerFunction(ParseNode* pn, HandleFunct
// still expects a FunctionBox to be attached to it during BCE, and
// the syntax parser cannot attach one to it.
FunctionBox* funbox = newFunctionBox(pn, fun, inheritedDirectives, generatorKind,
tryAnnexB);
SyncFunction, tryAnnexB);
if (!funbox)
return false;
funbox->initWithEnclosingParseContext(pc, kind);
@ -3231,7 +3234,8 @@ Parser<ParseHandler>::innerFunction(Node pn, ParseContext* outerpc, HandleFuncti
// parser. In that case, outerpc is a ParseContext from the full parser
// instead of the current top of the stack of the syntax parser.
FunctionBox* funbox = newFunctionBox(pn, fun, inheritedDirectives, generatorKind, tryAnnexB);
FunctionBox* funbox = newFunctionBox(pn, fun, inheritedDirectives, generatorKind,
SyncFunction, tryAnnexB);
if (!funbox)
return false;
funbox->initWithEnclosingParseContext(outerpc, kind);
@ -3271,7 +3275,7 @@ Parser<FullParseHandler>::standaloneLazyFunction(HandleFunction fun, bool strict
return null();
Directives directives(strict);
FunctionBox* funbox = newFunctionBox(pn, fun, directives, generatorKind,
FunctionBox* funbox = newFunctionBox(pn, fun, directives, generatorKind, SyncFunction,
/* tryAnnexB = */ false);
if (!funbox)
return null();
@ -7817,7 +7821,7 @@ Parser<ParseHandler>::generatorComprehensionLambda(unsigned begin)
// Create box for fun->object early to root it.
Directives directives(/* strict = */ outerpc->sc()->strict());
FunctionBox* genFunbox = newFunctionBox(genfn, fun, directives, StarGenerator,
FunctionBox* genFunbox = newFunctionBox(genfn, fun, directives, StarGenerator, SyncFunction,
/* tryAnnexB = */ false);
if (!genFunbox)
return null();

Просмотреть файл

@ -498,6 +498,10 @@ class ParseContext : public Nestable<ParseContext>
return generatorKind() == StarGenerator;
}
bool isAsync() const {
return sc_->isFunctionBox() && sc_->asFunctionBox()->isAsync();
}
bool isArrowFunction() const {
return sc_->isFunctionBox() && sc_->asFunctionBox()->function()->isArrow();
}
@ -940,7 +944,8 @@ class Parser final : private JS::AutoGCRooter, public StrictModeGetter
*/
ObjectBox* newObjectBox(JSObject* obj);
FunctionBox* newFunctionBox(Node fn, JSFunction* fun, Directives directives,
GeneratorKind generatorKind, bool tryAnnexB);
GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
bool tryAnnexB);
/*
* Create a new function object given a name (which is optional if this is

Просмотреть файл

@ -453,6 +453,8 @@ class FunctionBox : public ObjectBox, public SharedContext
uint16_t length;
uint8_t generatorKindBits_; /* The GeneratorKind of this function. */
uint8_t asyncKindBits_; /* The FunctionAsyncKing of this function. */
bool isGenexpLambda:1; /* lambda from generator expression */
bool hasDestructuringArgs:1; /* parameter list contains destructuring expression */
bool hasParameterExprs:1; /* parameter list contains expressions */
@ -473,7 +475,8 @@ class FunctionBox : public ObjectBox, public SharedContext
FunctionContextFlags funCxFlags;
FunctionBox(ExclusiveContext* cx, LifoAlloc& alloc, ObjectBox* traceListHead, JSFunction* fun,
Directives directives, bool extraWarnings, GeneratorKind generatorKind);
Directives directives, bool extraWarnings, GeneratorKind generatorKind,
FunctionAsyncKind asyncKind);
MutableHandle<LexicalScope::Data*> namedLambdaBindings() {
MOZ_ASSERT(context->compartment()->runtimeFromAnyThread()->keepAtoms());
@ -532,6 +535,8 @@ class FunctionBox : public ObjectBox, public SharedContext
bool isGenerator() const { return generatorKind() != NotGenerator; }
bool isLegacyGenerator() const { return generatorKind() == LegacyGenerator; }
bool isStarGenerator() const { return generatorKind() == StarGenerator; }
FunctionAsyncKind asyncKind() const { return AsyncKindFromBits(asyncKindBits_); }
bool isAsync() const { return asyncKind() == AsyncFunction; }
bool isArrow() const { return function()->isArrow(); }
void setGeneratorKind(GeneratorKind kind) {

Просмотреть файл

@ -301,6 +301,13 @@ class JSFunction : public js::NativeObject
flags_ |= RESOLVED_NAME;
}
void setAsyncKind(js::FunctionAsyncKind asyncKind) {
if (isInterpretedLazy())
lazyScript()->setAsyncKind(asyncKind);
else
nonLazyScript()->setAsyncKind(asyncKind);
}
bool getUnresolvedLength(JSContext* cx, js::MutableHandleValue v);
JSAtom* getUnresolvedName(JSContext* cx);
@ -469,6 +476,18 @@ class JSFunction : public js::NativeObject
bool isStarGenerator() const { return generatorKind() == js::StarGenerator; }
js::FunctionAsyncKind asyncKind() const {
return isInterpretedLazy() ? lazyScript()->asyncKind() : nonLazyScript()->asyncKind();
}
bool isAsync() const {
if (isInterpretedLazy())
return lazyScript()->asyncKind() == js::AsyncFunction;
if (hasScript())
return nonLazyScript()->asyncKind() == js::AsyncFunction;
return false;
}
void setScript(JSScript* script_) {
mutableScript() = script_;
}

Просмотреть файл

@ -2615,6 +2615,7 @@ JSScript::initFromFunctionBox(ExclusiveContext* cx, HandleScript script,
script->isGeneratorExp_ = funbox->isGenexpLambda;
script->setGeneratorKind(funbox->generatorKind());
script->setAsyncKind(funbox->asyncKind());
PositionalFormalParameterIter fi(script);
while (fi && !fi.closedOver())
@ -3272,6 +3273,7 @@ js::detail::CopyScript(JSContext* cx, HandleScript src, HandleScript dst,
dst->isDerivedClassConstructor_ = src->isDerivedClassConstructor();
dst->needsHomeObject_ = src->needsHomeObject();
dst->isDefaultClassConstructor_ = src->isDefaultClassConstructor();
dst->isAsync_ = src->asyncKind() == AsyncFunction;
if (nconsts != 0) {
GCPtrValue* vector = Rebase<GCPtrValue>(dst, src, src->consts()->vector);
@ -4004,6 +4006,7 @@ LazyScript::Create(ExclusiveContext* cx, HandleFunction fun,
p.version = version;
p.shouldDeclareArguments = false;
p.hasThisBinding = false;
p.isAsync = false;
p.numClosedOverBindings = closedOverBindings.length();
p.numInnerFunctions = innerFunctions.length();
p.generatorKindBits = GeneratorKindAsBits(NotGenerator);

Просмотреть файл

@ -640,6 +640,7 @@ class ScriptSourceObject : public NativeObject
};
enum GeneratorKind { NotGenerator, LegacyGenerator, StarGenerator };
enum FunctionAsyncKind { SyncFunction, AsyncFunction };
static inline unsigned
GeneratorKindAsBits(GeneratorKind generatorKind) {
@ -652,6 +653,17 @@ GeneratorKindFromBits(unsigned val) {
return static_cast<GeneratorKind>(val);
}
static inline unsigned
AsyncKindAsBits(FunctionAsyncKind asyncKind) {
return static_cast<unsigned>(asyncKind);
}
static inline FunctionAsyncKind
AsyncKindFromBits(unsigned val) {
MOZ_ASSERT(val <= AsyncFunction);
return static_cast<FunctionAsyncKind>(val);
}
/*
* NB: after a successful XDR_DECODE, XDRScript callers must do any required
* subsequent set-up of owning function or script object and then call
@ -988,6 +1000,8 @@ class JSScript : public js::gc::TenuredCell
bool isDerivedClassConstructor_:1;
bool isDefaultClassConstructor_:1;
bool isAsync_:1;
// Add padding so JSScript is gc::Cell aligned. Make padding protected
// instead of private to suppress -Wunused-private-field compiler warnings.
protected:
@ -1276,6 +1290,14 @@ class JSScript : public js::gc::TenuredCell
generatorKindBits_ = GeneratorKindAsBits(kind);
}
js::FunctionAsyncKind asyncKind() const {
return isAsync_ ? js::AsyncFunction : js::SyncFunction;
}
void setAsyncKind(js::FunctionAsyncKind kind) {
isAsync_ = kind == js::AsyncFunction;
}
void setNeedsHomeObject() {
needsHomeObject_ = true;
}
@ -1887,7 +1909,8 @@ class LazyScript : public gc::TenuredCell
uint32_t shouldDeclareArguments : 1;
uint32_t hasThisBinding : 1;
uint32_t numClosedOverBindings : 22;
uint32_t isAsync : 1;
uint32_t numClosedOverBindings : 21;
uint32_t numInnerFunctions : 20;
uint32_t generatorKindBits : 2;
@ -2024,6 +2047,14 @@ class LazyScript : public gc::TenuredCell
p_.generatorKindBits = GeneratorKindAsBits(kind);
}
FunctionAsyncKind asyncKind() const {
return p_.isAsync ? AsyncFunction : SyncFunction;
}
void setAsyncKind(FunctionAsyncKind kind) {
p_.isAsync = kind == AsyncFunction;
}
bool strict() const {
return p_.strict;
}