summaryrefslogtreecommitdiffstats
path: root/js/src/frontend
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/frontend')
-rw-r--r--js/src/frontend/BytecodeCompiler.cpp13
-rw-r--r--js/src/frontend/BytecodeCompiler.h6
-rw-r--r--js/src/frontend/BytecodeEmitter.cpp26
-rw-r--r--js/src/frontend/BytecodeEmitter.h3
-rw-r--r--js/src/frontend/Parser.cpp22
5 files changed, 54 insertions, 16 deletions
diff --git a/js/src/frontend/BytecodeCompiler.cpp b/js/src/frontend/BytecodeCompiler.cpp
index 7760c4b2e..ccfe3cd2e 100644
--- a/js/src/frontend/BytecodeCompiler.cpp
+++ b/js/src/frontend/BytecodeCompiler.cpp
@@ -729,3 +729,16 @@ frontend::CompileStandaloneAsyncFunction(JSContext* cx, MutableHandleFunction fu
TraceLogger_ParserCompileFunction);
return compiler.compileStandaloneFunction(fun, NotGenerator, AsyncFunction, parameterListEnd);
}
+
+bool
+frontend::CompileStandaloneAsyncGenerator(JSContext* cx, MutableHandleFunction fun,
+ const ReadOnlyCompileOptions& options,
+ JS::SourceBufferHolder& srcBuf,
+ Maybe<uint32_t> parameterListEnd)
+{
+ RootedScope emptyGlobalScope(cx, &cx->global()->emptyGlobalScope());
+
+ BytecodeCompiler compiler(cx, cx->tempLifoAlloc(), options, srcBuf, emptyGlobalScope,
+ TraceLogger_ParserCompileFunction);
+ return compiler.compileStandaloneFunction(fun, StarGenerator, AsyncFunction, parameterListEnd);
+}
diff --git a/js/src/frontend/BytecodeCompiler.h b/js/src/frontend/BytecodeCompiler.h
index 0bc1ab2ab..029fbe632 100644
--- a/js/src/frontend/BytecodeCompiler.h
+++ b/js/src/frontend/BytecodeCompiler.h
@@ -85,6 +85,12 @@ CompileStandaloneAsyncFunction(JSContext* cx, MutableHandleFunction fun,
mozilla::Maybe<uint32_t> parameterListEnd);
MOZ_MUST_USE bool
+CompileStandaloneAsyncGenerator(JSContext* cx, MutableHandleFunction fun,
+ const ReadOnlyCompileOptions& options,
+ JS::SourceBufferHolder& srcBuf,
+ mozilla::Maybe<uint32_t> parameterListEnd);
+
+MOZ_MUST_USE bool
CompileAsyncFunctionBody(JSContext* cx, MutableHandleFunction fun,
const ReadOnlyCompileOptions& options,
Handle<PropertyNameVector> formals, JS::SourceBufferHolder& srcBuf);
diff --git a/js/src/frontend/BytecodeEmitter.cpp b/js/src/frontend/BytecodeEmitter.cpp
index a98016d63..9d6a68609 100644
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -8067,7 +8067,8 @@ BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto)
MOZ_ASSERT(fun->isArrow() == (pn->getOp() == JSOP_LAMBDA_ARROW));
if (funbox->isAsync()) {
MOZ_ASSERT(!needsProto);
- return emitAsyncWrapper(index, funbox->needsHomeObject(), fun->isArrow());
+ return emitAsyncWrapper(index, funbox->needsHomeObject(), fun->isArrow(),
+ fun->isStarGenerator());
}
if (fun->isArrow()) {
@@ -8122,8 +8123,11 @@ BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto)
MOZ_ASSERT(pn->getOp() == JSOP_NOP);
switchToPrologue();
if (funbox->isAsync()) {
- if (!emitAsyncWrapper(index, fun->isMethod(), fun->isArrow()))
+ if (!emitAsyncWrapper(index, fun->isMethod(), fun->isArrow(),
+ fun->isStarGenerator()))
+ {
return false;
+ }
} else {
if (!emitIndex32(JSOP_LAMBDA, index))
return false;
@@ -8139,10 +8143,12 @@ BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto)
// initialize the binding name of the function in the current scope.
bool isAsync = funbox->isAsync();
- auto emitLambda = [index, isAsync](BytecodeEmitter* bce, const NameLocation&, bool) {
+ bool isStarGenerator = funbox->isStarGenerator();
+ auto emitLambda = [index, isAsync, isStarGenerator](BytecodeEmitter* bce,
+ const NameLocation&, bool) {
if (isAsync) {
return bce->emitAsyncWrapper(index, /* needsHomeObject = */ false,
- /* isArrow = */ false);
+ /* isArrow = */ false, isStarGenerator);
}
return bce->emitIndexOp(JSOP_LAMBDA, index);
};
@@ -8177,7 +8183,8 @@ BytecodeEmitter::emitAsyncWrapperLambda(unsigned index, bool isArrow) {
}
bool
-BytecodeEmitter::emitAsyncWrapper(unsigned index, bool needsHomeObject, bool isArrow)
+BytecodeEmitter::emitAsyncWrapper(unsigned index, bool needsHomeObject, bool isArrow,
+ bool isStarGenerator)
{
// needsHomeObject can be true for propertyList for extended class.
// In that case push both unwrapped and wrapped function, in order to
@@ -8209,8 +8216,13 @@ BytecodeEmitter::emitAsyncWrapper(unsigned index, bool needsHomeObject, bool isA
if (!emit1(JSOP_DUP))
return false;
}
- if (!emit1(JSOP_TOASYNC))
- return false;
+ if (isStarGenerator) {
+ if (!emit1(JSOP_TOASYNCGEN))
+ return false;
+ } else {
+ if (!emit1(JSOP_TOASYNC))
+ return false;
+ }
return true;
}
diff --git a/js/src/frontend/BytecodeEmitter.h b/js/src/frontend/BytecodeEmitter.h
index f3f78df16..67e329489 100644
--- a/js/src/frontend/BytecodeEmitter.h
+++ b/js/src/frontend/BytecodeEmitter.h
@@ -620,7 +620,8 @@ struct MOZ_STACK_CLASS BytecodeEmitter
MOZ_MUST_USE bool emitPropIncDec(ParseNode* pn);
MOZ_MUST_USE bool emitAsyncWrapperLambda(unsigned index, bool isArrow);
- MOZ_MUST_USE bool emitAsyncWrapper(unsigned index, bool needsHomeObject, bool isArrow);
+ MOZ_MUST_USE bool emitAsyncWrapper(unsigned index, bool needsHomeObject, bool isArrow,
+ bool isStarGenerator);
MOZ_MUST_USE bool emitComputedPropertyName(ParseNode* computedPropName);
diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp
index 3ae5890ac..7704cf65a 100644
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -3785,10 +3785,12 @@ Parser<ParseHandler>::functionStmt(uint32_t toStringStart, YieldHandling yieldHa
GeneratorKind generatorKind = NotGenerator;
if (tt == TOK_MUL) {
+#ifdef RELEASE_OR_BETA
if (asyncKind != SyncFunction) {
error(JSMSG_ASYNC_GENERATOR);
return null();
}
+#endif
generatorKind = StarGenerator;
if (!tokenStream.getToken(&tt))
return null();
@@ -3857,10 +3859,12 @@ Parser<ParseHandler>::functionExpr(uint32_t toStringStart, InvokedPrediction inv
return null();
if (tt == TOK_MUL) {
+#ifdef RELEASE_OR_BETA
if (asyncKind != SyncFunction) {
error(JSMSG_ASYNC_GENERATOR);
return null();
}
+#endif
generatorKind = StarGenerator;
if (!tokenStream.getToken(&tt))
return null();
@@ -9468,11 +9472,6 @@ Parser<ParseHandler>::propertyName(YieldHandling yieldHandling,
bool isGenerator = false;
bool isAsync = false;
- if (ltok == TOK_MUL) {
- isGenerator = true;
- if (!tokenStream.getToken(&ltok))
- return null();
- }
if (ltok == TOK_ASYNC) {
// AsyncMethod[Yield, Await]:
@@ -9500,9 +9499,16 @@ Parser<ParseHandler>::propertyName(YieldHandling yieldHandling,
}
}
- if (isAsync && isGenerator) {
- error(JSMSG_ASYNC_GENERATOR);
- return null();
+ if (ltok == TOK_MUL) {
+#ifdef RELEASE_OR_BETA
+ if (isAsync) {
+ error(JSMSG_ASYNC_GENERATOR);
+ return null();
+ }
+#endif
+ isGenerator = true;
+ if (!tokenStream.getToken(&ltok))
+ return null();
}
propAtom.set(nullptr);