[async-await] desugar Await in BytecodeGenerator

This includes several changes. From most to least interesting:

- No longer implement AwaitExpressions using a do-expression.
- Reduces frame-size of async generators by not allocating temporary
  variables to hold results of Await epxressions.
- Streamline and reduce generated bytecodes for Await.
- Debugger no longer emits a debug::kCallBreakLocation breakpoint for
the JS-builtin call performed for Await, and instead only emits such
a breakpoint if the operand of Await is actually a call.
- Push fewer parameters to Await* builtins, using the receiver for the
  first parameter (possible now that the CallRuntime invocation not
  part of the AST).
- Adds a new Await AST node. No new members or anything, but it seemed
  palatable to avoid having `if (is_await())` in a number of
  VisitSuspend functions.

BUG=v8:5855, v8:5099, v8:4483
R=rmcilroy@chromium.org, kozyatinskiy@chromium.org, yangguo@chromium.org
TBR=bmeurer@chromium.org

Change-Id: I9cd3fda99cd40295c04fdf1aea01b5d83fac6caf
Reviewed-on: https://chromium-review.googlesource.com/558806
Commit-Queue: Georg Neis <neis@chromium.org>
Reviewed-by: Georg Neis <neis@chromium.org>
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: Aleksey Kozyatinskiy <kozyatinskiy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46666}
This commit is contained in:
Caitlin Potter 2017-07-13 09:53:13 -04:00 committed by Commit Bot
parent 8cfd7d4449
commit 8b5b444a4c
28 changed files with 789 additions and 851 deletions

View File

@ -274,6 +274,8 @@ void AstExpressionRewriter::VisitYieldStar(YieldStar* node) {
VisitSuspend(node);
}
void AstExpressionRewriter::VisitAwait(Await* node) { VisitSuspend(node); }
void AstExpressionRewriter::VisitThrow(Throw* node) {
REWRITE_THIS(node);
AST_REWRITE_PROPERTY(Expression, node, exception);

View File

@ -242,6 +242,8 @@ void AstNumberingVisitor::VisitYieldStar(YieldStar* node) {
ReserveFeedbackSlots(node);
}
void AstNumberingVisitor::VisitAwait(Await* node) { VisitSuspend(node); }
void AstNumberingVisitor::VisitThrow(Throw* node) {
IncrementNodeCount();
Visit(node->exception());

View File

@ -371,6 +371,12 @@ void AstTraversalVisitor<Subclass>::VisitYieldStar(YieldStar* expr) {
RECURSE_EXPRESSION(Visit(expr->expression()));
}
template <class Subclass>
void AstTraversalVisitor<Subclass>::VisitAwait(Await* expr) {
PROCESS_EXPRESSION(expr);
RECURSE_EXPRESSION(Visit(expr->expression()));
}
template <class Subclass>
void AstTraversalVisitor<Subclass>::VisitThrow(Throw* expr) {
PROCESS_EXPRESSION(expr);

View File

@ -92,6 +92,7 @@ namespace internal {
V(Literal) \
V(Suspend) \
V(YieldStar) \
V(Await) \
V(Throw) \
V(CallRuntime) \
V(UnaryOperation) \
@ -2290,6 +2291,7 @@ class Suspend : public Expression {
private:
friend class AstNodeFactory;
friend class YieldStar;
friend class Await;
Suspend(NodeType node_type, Expression* expression, int pos,
OnAbruptResume on_abrupt_resume, SuspendFlags flags)
@ -2377,6 +2379,14 @@ class YieldStar final : public Suspend {
FeedbackSlot call_iterator_throw_slot_;
};
class Await final : public Suspend {
private:
friend class AstNodeFactory;
Await(Expression* expression, int pos, SuspendFlags flags)
: Suspend(kAwait, expression, pos, Suspend::kOnExceptionThrow, flags) {}
};
class Throw final : public Expression {
public:
Expression* exception() const { return exception_; }
@ -3404,6 +3414,12 @@ class AstNodeFactory final BASE_EMBEDDED {
return new (zone_) YieldStar(expression, pos, flags);
}
Await* NewAwait(Expression* expression, int pos, SuspendFlags flags) {
DCHECK(IsAwait(flags));
if (!expression) expression = NewUndefinedLiteral(pos);
return new (zone_) Await(expression, pos, flags);
}
Throw* NewThrow(Expression* exception, int pos) {
return new (zone_) Throw(exception, pos);
}

View File

@ -265,6 +265,8 @@ void CallPrinter::VisitSuspend(Suspend* node) { Find(node->expression()); }
void CallPrinter::VisitYieldStar(YieldStar* node) { Find(node->expression()); }
void CallPrinter::VisitAwait(Await* node) { Find(node->expression()); }
void CallPrinter::VisitThrow(Throw* node) { Find(node->exception()); }
@ -1124,6 +1126,13 @@ void AstPrinter::VisitYieldStar(YieldStar* node) {
Visit(node->expression());
}
void AstPrinter::VisitAwait(Await* node) {
EmbeddedVector<char, 128> buf;
SNPrintF(buf, "AWAIT id %d", node->suspend_id());
IndentedScope indent(this, buf.start(), node->position());
Visit(node->expression());
}
void AstPrinter::VisitThrow(Throw* node) {
IndentedScope indent(this, "THROW", node->position());
Visit(node->exception());

View File

@ -769,16 +769,6 @@ Variable* DeclarationScope::DeclarePromiseVar(const AstRawString* name) {
return result;
}
Variable* DeclarationScope::DeclareAsyncGeneratorAwaitVar(
const AstRawString* name) {
DCHECK(is_function_scope());
DCHECK_NULL(async_generator_await_var());
Variable* result = EnsureRareData()->promise = NewTemporary(name);
DCHECK_NULL(promise_var()); // promise is alias for generator await var
result->set_is_used();
return result;
}
bool Scope::HasBeenRemoved() const {
if (sibling() == this) {
DCHECK_NULL(inner_scope_);

View File

@ -734,7 +734,6 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
// Ignition without ScopeInfo.
Variable* DeclareGeneratorObjectVar(const AstRawString* name);
Variable* DeclarePromiseVar(const AstRawString* name);
Variable* DeclareAsyncGeneratorAwaitVar(const AstRawString* name);
// Declare a parameter in this scope. When there are duplicated
// parameters the rightmost one 'wins'. However, the implementation
@ -792,12 +791,6 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
return GetRareVariable(RareVariable::kPromise);
}
Variable* async_generator_await_var() const {
DCHECK(is_function_scope());
DCHECK(IsAsyncGeneratorFunction(function_kind_));
return GetRareVariable(RareVariable::kAsyncGeneratorAwaitResult);
}
// Parameters. The left-most parameter has index 0.
// Only valid for function and module scopes.
Variable* parameter(int index) const {
@ -991,8 +984,7 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
enum class RareVariable {
kThisFunction = offsetof(RareData, this_function),
kGeneratorObject = offsetof(RareData, generator_object),
kPromise = offsetof(RareData, promise),
kAsyncGeneratorAwaitResult = kPromise
kPromise = offsetof(RareData, promise)
};
V8_INLINE RareData* EnsureRareData() {

View File

@ -1461,12 +1461,12 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
{ // --- A s y n c G e n e r a t o r ---
Handle<JSFunction> await_caught =
SimpleCreateFunction(isolate, factory->empty_string(),
Builtins::kAsyncGeneratorAwaitCaught, 2, false);
Builtins::kAsyncGeneratorAwaitCaught, 1, false);
native_context()->set_async_generator_await_caught(*await_caught);
Handle<JSFunction> await_uncaught =
SimpleCreateFunction(isolate, factory->empty_string(),
Builtins::kAsyncGeneratorAwaitUncaught, 2, false);
Builtins::kAsyncGeneratorAwaitUncaught, 1, false);
native_context()->set_async_generator_await_uncaught(*await_uncaught);
Handle<Code> code(builtins->AsyncGeneratorAwaitResolveClosure());
@ -3950,14 +3950,14 @@ void Bootstrapper::ExportFromRuntime(Isolate* isolate,
{
Handle<JSFunction> function =
SimpleCreateFunction(isolate, factory->empty_string(),
Builtins::kAsyncFunctionAwaitCaught, 3, false);
Builtins::kAsyncFunctionAwaitCaught, 2, false);
native_context->set_async_function_await_caught(*function);
}
{
Handle<JSFunction> function =
SimpleCreateFunction(isolate, factory->empty_string(),
Builtins::kAsyncFunctionAwaitUncaught, 3, false);
Builtins::kAsyncFunctionAwaitUncaught, 2, false);
native_context->set_async_function_await_uncaught(*function);
}

View File

@ -116,19 +116,21 @@ void AsyncFunctionBuiltinsAssembler::AsyncFunctionAwait(
// TODO(jgruber): Use a faster specialized version of
// InternalPerformPromiseThen.
Node* const result = Await(
context, generator, awaited, outer_promise, AwaitContext::kLength,
init_closure_context, Context::ASYNC_FUNCTION_AWAIT_RESOLVE_SHARED_FUN,
Context::ASYNC_FUNCTION_AWAIT_REJECT_SHARED_FUN, is_predicted_as_caught);
Await(context, generator, awaited, outer_promise, AwaitContext::kLength,
init_closure_context, Context::ASYNC_FUNCTION_AWAIT_RESOLVE_SHARED_FUN,
Context::ASYNC_FUNCTION_AWAIT_REJECT_SHARED_FUN,
is_predicted_as_caught);
Return(result);
// Return outer promise to avoid adding an load of the outer promise before
// suspending in BytecodeGenerator.
Return(outer_promise);
}
// Called by the parser from the desugaring of 'await' when catch
// prediction indicates that there is a locally surrounding catch block.
TF_BUILTIN(AsyncFunctionAwaitCaught, AsyncFunctionBuiltinsAssembler) {
CSA_ASSERT_JS_ARGC_EQ(this, 3);
Node* const generator = Parameter(Descriptor::kGenerator);
CSA_ASSERT_JS_ARGC_EQ(this, 2);
Node* const generator = Parameter(Descriptor::kReceiver);
Node* const awaited = Parameter(Descriptor::kAwaited);
Node* const outer_promise = Parameter(Descriptor::kOuterPromise);
Node* const context = Parameter(Descriptor::kContext);
@ -142,8 +144,8 @@ TF_BUILTIN(AsyncFunctionAwaitCaught, AsyncFunctionBuiltinsAssembler) {
// Called by the parser from the desugaring of 'await' when catch
// prediction indicates no locally surrounding catch block.
TF_BUILTIN(AsyncFunctionAwaitUncaught, AsyncFunctionBuiltinsAssembler) {
CSA_ASSERT_JS_ARGC_EQ(this, 3);
Node* const generator = Parameter(Descriptor::kGenerator);
CSA_ASSERT_JS_ARGC_EQ(this, 2);
Node* const generator = Parameter(Descriptor::kReceiver);
Node* const awaited = Parameter(Descriptor::kAwaited);
Node* const outer_promise = Parameter(Descriptor::kOuterPromise);
Node* const context = Parameter(Descriptor::kContext);

View File

@ -240,9 +240,9 @@ void AsyncGeneratorBuiltinsAssembler::AsyncGeneratorAwaitResumeClosure(
template <typename Descriptor>
void AsyncGeneratorBuiltinsAssembler::AsyncGeneratorAwait(bool is_catchable) {
Node* generator = Parameter(1);
Node* value = Parameter(2);
Node* context = Parameter(5);
Node* generator = Parameter(Descriptor::kReceiver);
Node* value = Parameter(Descriptor::kAwaited);
Node* context = Parameter(Descriptor::kContext);
CSA_SLOW_ASSERT(this,
HasInstanceType(generator, JS_ASYNC_GENERATOR_OBJECT_TYPE));

View File

@ -343,8 +343,8 @@ namespace internal {
CPP(ArrayBufferPrototypeSlice) \
\
/* AsyncFunction */ \
TFJ(AsyncFunctionAwaitCaught, 3, kGenerator, kAwaited, kOuterPromise) \
TFJ(AsyncFunctionAwaitUncaught, 3, kGenerator, kAwaited, kOuterPromise) \
TFJ(AsyncFunctionAwaitCaught, 2, kAwaited, kOuterPromise) \
TFJ(AsyncFunctionAwaitUncaught, 2, kAwaited, kOuterPromise) \
TFJ(AsyncFunctionAwaitRejectClosure, 1, kSentError) \
TFJ(AsyncFunctionAwaitResolveClosure, 1, kSentValue) \
TFJ(AsyncFunctionPromiseCreate, 0) \
@ -1054,8 +1054,8 @@ namespace internal {
\
/* Await (proposal-async-iteration/#await), with resume behaviour */ \
/* specific to Async Generators. Internal / Not exposed to JS code. */ \
TFJ(AsyncGeneratorAwaitCaught, 2, kGenerator, kAwaited) \
TFJ(AsyncGeneratorAwaitUncaught, 2, kGenerator, kAwaited) \
TFJ(AsyncGeneratorAwaitCaught, 1, kAwaited) \
TFJ(AsyncGeneratorAwaitUncaught, 1, kAwaited) \
TFJ(AsyncGeneratorAwaitResolveClosure, 1, kValue) \
TFJ(AsyncGeneratorAwaitRejectClosure, 1, kValue) \
\

View File

@ -1375,6 +1375,11 @@ void AstGraphBuilder::VisitYieldStar(YieldStar* expr) {
UNREACHABLE();
}
void AstGraphBuilder::VisitAwait(Await* expr) {
// Generator functions are supported only by going through Ignition first.
UNREACHABLE();
}
void AstGraphBuilder::VisitThrow(Throw* expr) {
VisitForValue(expr->exception());
Node* exception = environment()->Pop();

View File

@ -153,6 +153,8 @@ void ALAA::VisitSuspend(Suspend* e) { Visit(e->expression()); }
void ALAA::VisitYieldStar(YieldStar* e) { Visit(e->expression()); }
void ALAA::VisitAwait(Await* e) { Visit(e->expression()); }
void ALAA::VisitThrow(Throw* stmt) { Visit(stmt->exception()); }

View File

@ -1356,6 +1356,11 @@ void FullCodeGenerator::VisitYieldStar(YieldStar* expr) {
UNREACHABLE();
}
void FullCodeGenerator::VisitAwait(Await* expr) {
// Resumable functions are not supported.
UNREACHABLE();
}
bool FullCodeGenerator::TryLiteralCompare(CompareOperation* expr) {
Expression* sub_expr;
Literal* literal;

View File

@ -1401,6 +1401,35 @@ inline const char* SuspendTypeFor(SuspendFlags flags) {
UNREACHABLE();
}
inline bool IsAwait(SuspendFlags flags) {
return (flags & SuspendFlags::kSuspendTypeMask) == SuspendFlags::kAwait;
}
inline bool IsAsyncGenerator(SuspendFlags flags) {
return (flags & SuspendFlags::kGeneratorTypeMask) ==
SuspendFlags::kAsyncGenerator;
}
inline std::ostream& operator<<(std::ostream& os, SuspendFlags flags) {
os << "SuspendFlags::k";
if (IsAsyncGenerator(flags)) {
os << "Async";
}
os << "Generator";
switch (flags & SuspendFlags::kSuspendTypeMask) {
case SuspendFlags::kYield:
return os << "Yield";
case SuspendFlags::kYieldStar:
return os << "YieldStar";
case SuspendFlags::kAwait:
return os << "Await";
default:
break;
}
UNREACHABLE();
}
struct AssemblerDebugInfo {
AssemblerDebugInfo(const char* name, const char* file, int line)
: name(name), file(file), line(line) {}

View File

@ -2955,6 +2955,88 @@ void BytecodeGenerator::VisitYieldStar(YieldStar* expr) {
builder()->LoadAccumulatorWithRegister(output_value);
}
void BytecodeGenerator::VisitAwait(Await* expr) {
// Rather than HandlerTable::UNCAUGHT, async functions use
// HandlerTable::ASYNC_AWAIT to communicate that top-level exceptions are
// transformed into promise rejections. This is necessary to prevent emitting
// multiple debbug events for the same uncaught exception. There is no point
// in the body of an async function where catch prediction is
// HandlerTable::UNCAUGHT.
DCHECK(catch_prediction() != HandlerTable::UNCAUGHT);
builder()->SetExpressionPosition(expr);
Register operand = VisitForRegisterValue(expr->expression());
RegisterList registers(0, operand.index());
{
// Await(operand) and suspend.
RegisterAllocationScope register_scope(this);
int await_builtin_context_index;
RegisterList args;
if (expr->is_async_generator()) {
await_builtin_context_index =
catch_prediction() == HandlerTable::ASYNC_AWAIT
? Context::ASYNC_GENERATOR_AWAIT_UNCAUGHT
: Context::ASYNC_GENERATOR_AWAIT_CAUGHT;
args = register_allocator()->NewRegisterList(2);
builder()
->MoveRegister(generator_object_, args[0])
.MoveRegister(operand, args[1]);
} else {
await_builtin_context_index =
catch_prediction() == HandlerTable::ASYNC_AWAIT
? Context::ASYNC_FUNCTION_AWAIT_UNCAUGHT_INDEX
: Context::ASYNC_FUNCTION_AWAIT_CAUGHT_INDEX;
args = register_allocator()->NewRegisterList(3);
builder()
->MoveRegister(generator_object_, args[0])
.MoveRegister(operand, args[1]);
// AsyncFunction Await builtins require a 3rd parameter to hold the outer
// promise.
Variable* var_promise = closure_scope()->promise_var();
BuildVariableLoadForAccumulatorValue(var_promise, FeedbackSlot::Invalid(),
HoleCheckMode::kElided);
builder()->StoreAccumulatorInRegister(args[2]);
}
builder()
->CallJSRuntime(await_builtin_context_index, args)
.StoreAccumulatorInRegister(operand);
BuildGeneratorSuspend(expr, operand, registers);
}
builder()->Bind(generator_jump_table_, static_cast<int>(expr->suspend_id()));
// Upon resume, we continue here, with received value in accumulator.
BuildGeneratorResume(expr, registers);
Register input = register_allocator()->NewRegister();
Register resume_mode = register_allocator()->NewRegister();
// Now dispatch on resume mode.
BytecodeLabel resume_next;
builder()
->StoreAccumulatorInRegister(input)
.CallRuntime(Runtime::kInlineGeneratorGetResumeMode, generator_object_)
.StoreAccumulatorInRegister(resume_mode)
.LoadLiteral(Smi::FromInt(JSGeneratorObject::kNext))
.CompareOperation(Token::EQ_STRICT, resume_mode)
.JumpIfTrue(ToBooleanMode::kAlreadyBoolean, &resume_next);
// Resume with "throw" completion (rethrow the received value).
// TODO(leszeks): Add a debug-only check that the accumulator is
// JSGeneratorObject::kThrow.
builder()->SetExpressionPosition(expr);
builder()->LoadAccumulatorWithRegister(input).ReThrow();
// Resume with next.
builder()->Bind(&resume_next);
builder()->LoadAccumulatorWithRegister(input);
}
void BytecodeGenerator::VisitThrow(Throw* expr) {
AllocateBlockCoverageSlotIfEnabled(expr, SourceRangeKind::kContinuation);
VisitForAccumulatorValue(expr->exception());
@ -3258,49 +3340,15 @@ void BytecodeGenerator::VisitCallNew(CallNew* expr) {
}
}
int BytecodeGenerator::UpdateRuntimeFunctionForAsyncAwait(int context_index) {
// To support catch prediction within async/await:
//
// BytecodeGenerator models catch prediction (see VisitTryCatchstatement).
// Certain runtime calls need to be rewritten to invoke different functions,
// depending on the currently tracked catch prediction state. Take the
// following two cases of catch prediction:
//
// try { await fn(); } catch (e) { }
// try { await fn(); } finally { }
//
// When parsing the await that we want to mark as caught or uncaught, it's
// not yet known whether it will be followed by a 'finally' or a 'catch.
// The BytecodeGenerator has learned whether or not this Await is caught or
// not, and is responsible for invoking the correct function depending on
// those findings. It does that here.
if (catch_prediction() == HandlerTable::ASYNC_AWAIT) {
switch (context_index) {
case Context::ASYNC_FUNCTION_AWAIT_CAUGHT_INDEX:
context_index = Context::ASYNC_FUNCTION_AWAIT_UNCAUGHT_INDEX;
break;
case Context::ASYNC_GENERATOR_AWAIT_CAUGHT:
context_index = Context::ASYNC_GENERATOR_AWAIT_UNCAUGHT;
break;
default:
break;
}
}
return context_index;
}
void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) {
if (expr->is_jsruntime()) {
int context_index =
UpdateRuntimeFunctionForAsyncAwait(expr->context_index());
RegisterList args = register_allocator()->NewGrowableRegisterList();
// Allocate a register for the receiver and load it with undefined.
// TODO(leszeks): If CallJSRuntime always has an undefined receiver, use the
// same mechanism as CallUndefinedReceiver.
BuildPushUndefinedIntoRegisterList(&args);
VisitArguments(expr->arguments(), &args);
builder()->CallJSRuntime(context_index, args);
builder()->CallJSRuntime(expr->context_index(), args);
} else {
// Evaluate all arguments to the runtime call.
RegisterList args = register_allocator()->NewGrowableRegisterList();

View File

@ -218,8 +218,6 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
Register* out_register));
void VisitInSameTestExecutionScope(Expression* expr);
int UpdateRuntimeFunctionForAsyncAwait(int context_index);
// Returns the runtime function id for a store to super for the function's
// language mode.
inline Runtime::FunctionId StoreToSuperRuntimeId();

View File

@ -236,6 +236,7 @@ class ParserBase {
typedef typename Types::ObjectLiteralProperty ObjectLiteralPropertyT;
typedef typename Types::ClassLiteralProperty ClassLiteralPropertyT;
typedef typename Types::Suspend SuspendExpressionT;
typedef typename Types::Await AwaitExpressionT;
typedef typename Types::ExpressionList ExpressionListT;
typedef typename Types::FormalParameters FormalParametersT;
typedef typename Types::Statement StatementT;
@ -1332,6 +1333,13 @@ class ParserBase {
return factory()->NewSuspend(expr, pos, on_abrupt_resume, suspend_type);
}
inline AwaitExpressionT BuildAwait(ExpressionT expr, int pos) {
SuspendFlags flags = is_async_generator()
? SuspendFlags::kAsyncGeneratorAwait
: SuspendFlags::kGeneratorAwait;
return factory()->NewAwait(expr, pos, flags);
}
// Validation per ES6 object literals.
class ObjectLiteralChecker {
public:
@ -3103,7 +3111,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseUnaryExpression(
ExpressionT value = ParseUnaryExpression(CHECK_OK);
return impl()->RewriteAwaitExpression(value, await_pos);
return BuildAwait(value, await_pos);
} else {
return ParsePostfixExpression(ok);
}

View File

@ -1897,7 +1897,7 @@ Expression* Parser::BuildIteratorNextResult(Expression* iterator,
Expression* next_call =
factory()->NewCall(next_property, next_arguments, kNoSourcePosition);
if (type == IteratorType::kAsync) {
next_call = RewriteAwaitExpression(next_call, pos);
next_call = BuildAwait(next_call, pos);
}
Expression* result_proxy = factory()->NewVariableProxy(result);
Expression* left =
@ -3180,15 +3180,6 @@ Variable* Parser::PromiseVariable() {
return promise;
}
Variable* Parser::AsyncGeneratorAwaitVariable() {
Variable* result = function_state_->scope()->async_generator_await_var();
if (result == nullptr) {
result = function_state_->scope()->DeclareAsyncGeneratorAwaitVar(
ast_value_factory()->empty_string());
}
return result;
}
Expression* Parser::BuildInitialYield(int pos, FunctionKind kind) {
Expression* yield_result = factory()->NewVariableProxy(
function_state_->scope()->generator_object_var());
@ -3867,83 +3858,6 @@ void Parser::RewriteAsyncFunctionBody(ZoneList<Statement*>* body, Block* block,
body->Add(block, zone());
}
Expression* Parser::RewriteAwaitExpression(Expression* value, int await_pos) {
// In an Async Function:
// yield do {
// %AsyncFunctionAwait(.generator_object, <operand>, .promise);
// .promise
// }
//
// In an Async Generator:
// yield do {
// %AsyncGeneratorAwait(.generator_object, <operand>)
// .await_result_var
// }
//
// The value of the expression is returned to the caller of the async
// function for the first yield statement; for this, .promise is the
// appropriate return value, being a Promise that will be fulfilled or
// rejected with the appropriate value by the desugaring. Subsequent yield
// occurrences will return to the AsyncFunctionNext call within the
// implemementation of the intermediate throwaway Promise's then handler.
// This handler has nothing useful to do with the value, as the Promise is
// ignored. If we yielded the value of the throwawayPromise that
// AsyncFunctionAwait creates as an intermediate, it would create a memory
// leak; we must return .promise instead;
//
// In the case of Async Generators, `.await_result_var` is not actually used
// for anything, but exists because of the current requirement that
// Do Expressions have a result variable.
Variable* generator_object_variable =
function_state_->scope()->generator_object_var();
DCHECK_NOT_NULL(generator_object_variable);
const int nopos = kNoSourcePosition;
Block* do_block = factory()->NewBlock(nullptr, 2, false, nopos);
Expression* generator_object =
factory()->NewVariableProxy(generator_object_variable);
if (is_async_generator()) {
// AsyncGeneratorAwaitCaught will be rewritten to
// AsyncGeneratorAwaitUncaught by AstNumberingVisitor if there is no local
// enclosing try/catch block (not counting the one implicitly added in
// ParseAndRewriteGeneratorFunctionBody)
ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
args->Add(generator_object, zone());
args->Add(value, zone());
Expression* await = factory()->NewCallRuntime(
Context::ASYNC_GENERATOR_AWAIT_CAUGHT, args, nopos);
do_block->statements()->Add(factory()->NewExpressionStatement(await, nopos),
zone());
Expression* do_expr = factory()->NewDoExpression(
do_block, AsyncGeneratorAwaitVariable(), nopos);
return BuildSuspend(do_expr, await_pos, Suspend::kOnExceptionRethrow,
SuspendFlags::kAwait);
}
// The parser emits calls to AsyncFunctionAwaitCaught or but the
// AstNumberingVisitor will rewrite this to AsyncFunctionAwaitUncaught or if
// there is no local enclosing try/catch block.
ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(3, zone());
args->Add(generator_object, zone());
args->Add(value, zone());
args->Add(factory()->NewVariableProxy(PromiseVariable()), zone());
Expression* await = factory()->NewCallRuntime(
Context::ASYNC_FUNCTION_AWAIT_CAUGHT_INDEX, args, nopos);
do_block->statements()->Add(factory()->NewExpressionStatement(await, nopos),
zone());
Expression* do_expr =
factory()->NewDoExpression(do_block, PromiseVariable(), nopos);
return factory()->NewSuspend(do_expr, await_pos, Suspend::kOnExceptionRethrow,
SuspendFlags::kAwait);
}
class NonPatternRewriter : public AstExpressionRewriter {
public:
NonPatternRewriter(uintptr_t stack_limit, Parser* parser)
@ -4379,7 +4293,7 @@ Expression* Parser::RewriteYieldStar(Expression* iterable, int pos) {
args->Add(input_proxy, zone());
Expression* call = factory()->NewCall(next_property, args, nopos);
if (type == IteratorType::kAsync) {
call = RewriteAwaitExpression(call, nopos);
call = BuildAwait(call, nopos);
}
Expression* output_proxy = factory()->NewVariableProxy(var_output);
Expression* assignment =
@ -4460,7 +4374,7 @@ Expression* Parser::RewriteYieldStar(Expression* iterable, int pos) {
Expression* call =
factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
if (type == IteratorType::kAsync) {
call = RewriteAwaitExpression(call, nopos);
call = BuildAwait(call, nopos);
}
Expression* assignment = factory()->NewAssignment(
Token::ASSIGN, factory()->NewVariableProxy(var_output), call, nopos);
@ -4741,7 +4655,7 @@ void Parser::BuildIteratorClose(ZoneList<Statement*>* statements,
Expression* call =
factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
if (type == IteratorType::kAsync) {
call = RewriteAwaitExpression(call, nopos);
call = BuildAwait(call, nopos);
}
Expression* output_proxy = factory()->NewVariableProxy(var_output);
Expression* assignment =
@ -4962,7 +4876,7 @@ void Parser::BuildIteratorCloseForCompletion(Scope* scope,
factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
if (type == IteratorType::kAsync) {
call = RewriteAwaitExpression(call, nopos);
call = BuildAwait(call, nopos);
}
Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos);
@ -4990,7 +4904,7 @@ void Parser::BuildIteratorCloseForCompletion(Scope* scope,
Expression* call =
factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
if (type == IteratorType::kAsync) {
call = RewriteAwaitExpression(call, nopos);
call = BuildAwait(call, nopos);
}
Expression* output_proxy = factory()->NewVariableProxy(var_output);

View File

@ -165,6 +165,7 @@ struct ParserTypes<Parser> {
typedef ObjectLiteral::Property* ObjectLiteralProperty;
typedef ClassLiteral::Property* ClassLiteralProperty;
typedef v8::internal::Suspend* Suspend;
typedef v8::internal::Await* Await;
typedef ZoneList<v8::internal::Expression*>* ExpressionList;
typedef ZoneList<ObjectLiteral::Property*>* ObjectPropertyList;
typedef ZoneList<ClassLiteral::Property*>* ClassPropertyList;

View File

@ -732,6 +732,7 @@ NOT_A_PATTERN(WhileStatement)
NOT_A_PATTERN(WithStatement)
NOT_A_PATTERN(Suspend)
NOT_A_PATTERN(YieldStar)
NOT_A_PATTERN(Await)
#undef NOT_A_PATTERN
} // namespace internal

View File

@ -651,6 +651,10 @@ class PreParserFactory {
SuspendFlags flags) {
return PreParserExpression::Default();
}
PreParserExpression NewAwait(PreParserExpression expression, int pos,
SuspendFlags flags) {
return PreParserExpression::Default();
}
PreParserExpression NewConditional(PreParserExpression condition,
PreParserExpression then_expression,
PreParserExpression else_expression,
@ -859,6 +863,7 @@ struct ParserTypes<PreParser> {
typedef PreParserExpression ObjectLiteralProperty;
typedef PreParserExpression ClassLiteralProperty;
typedef PreParserExpression Suspend;
typedef PreParserExpression Await;
typedef PreParserExpressionList ExpressionList;
typedef PreParserExpressionList ObjectPropertyList;
typedef PreParserExpressionList ClassPropertyList;
@ -1024,10 +1029,6 @@ class PreParser : public ParserBase<PreParser> {
return left;
}
V8_INLINE PreParserExpression
RewriteAwaitExpression(PreParserExpression value, int pos) {
return value;
}
V8_INLINE void PrepareAsyncFunctionBody(PreParserStatementList body,
FunctionKind kind, int pos) {}
V8_INLINE void RewriteAsyncFunctionBody(PreParserStatementList body,

View File

@ -565,49 +565,49 @@ snippet: "
async function* f() { yield* g() }
f();
"
frame size: 22
frame size: 20
parameter count: 1
bytecode array length: 948
bytecode array length: 918
bytecodes: [
B(Mov), R(new_target), R(10),
B(Mov), R(new_target), R(9),
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(25),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetContext), R(10), U8(1),
B(PushContext), R(12),
B(RestoreGeneratorState), R(10),
B(Star), R(11),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetContext), R(9), U8(1),
B(PushContext), R(11),
B(RestoreGeneratorState), R(9),
B(Star), R(10),
B(SwitchOnSmiNoFeedback), U8(0), U8(7), I8(0),
B(LdaSmi), I8(81),
B(Star), R(12),
B(CallRuntime), U16(Runtime::kAbort), R(12), U8(1),
B(LdaSmi), I8(-2),
B(Star), R(11),
B(Mov), R(closure), R(12),
B(Mov), R(this), R(13),
B(InvokeIntrinsic), U8(Runtime::k_CreateJSGeneratorObject), R(12), U8(2),
B(CallRuntime), U16(Runtime::kAbort), R(11), U8(1),
B(LdaSmi), I8(-2),
B(Star), R(10),
B(Mov), R(closure), R(11),
B(Mov), R(this), R(12),
B(InvokeIntrinsic), U8(Runtime::k_CreateJSGeneratorObject), R(11), U8(2),
B(Star), R(0),
/* 44 E> */ B(StackCheck),
B(Star), R(10),
B(Star), R(9),
B(Mov), R(context), R(13),
B(Mov), R(context), R(14),
B(Mov), R(context), R(15),
B(LdaZero),
B(Mov), R(0), R(16),
/* 44 E> */ B(SuspendGenerator), R(10), R(0), U8(16), U8(4),
B(Ldar), R(16),
B(Mov), R(0), R(15),
/* 44 E> */ B(SuspendGenerator), R(9), R(0), U8(15), U8(4),
B(Ldar), R(15),
/* 60 S> */ B(Return),
B(RestoreGeneratorRegisters), R(10), R(0), U8(16),
B(RestoreGeneratorRegisters), R(9), R(0), U8(15),
B(LdaSmi), I8(-2),
B(Star), R(11),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetInputOrDebugPos), R(10), U8(1),
B(Star), R(16),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(10), U8(1),
B(Star), R(10),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetInputOrDebugPos), R(9), U8(1),
B(Star), R(15),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(9), U8(1),
B(SwitchOnSmiNoFeedback), U8(7), U8(2), I8(0),
B(Ldar), R(16),
B(Ldar), R(15),
/* 44 E> */ B(Throw),
B(LdaZero),
B(Star), R(12),
B(Mov), R(16), R(13),
B(JumpConstant), U8(40),
B(Star), R(11),
B(Mov), R(15), R(12),
B(JumpConstant), U8(30),
/* 49 S> */ B(LdaUndefined),
B(Star), R(1),
B(LdaZero),
@ -615,337 +615,327 @@ bytecodes: [
B(LdaUndefined),
B(Star), R(3),
B(LdaGlobal), U8(9), U8(6),
B(Star), R(18),
/* 56 E> */ B(CallUndefinedReceiver0), R(18), U8(4),
B(Star), R(16),
B(LdaNamedProperty), R(16), U8(10), U8(12),
B(Star), R(17),
/* 56 E> */ B(CallUndefinedReceiver0), R(17), U8(4),
B(Star), R(15),
B(LdaNamedProperty), R(15), U8(10), U8(12),
B(JumpIfUndefined), U8(17),
B(JumpIfNull), U8(15),
B(Star), R(17),
B(CallProperty0), R(17), R(16), U8(14),
B(Star), R(16),
B(CallProperty0), R(16), R(15), U8(14),
B(JumpIfJSReceiver), U8(23),
B(CallRuntime), U16(Runtime::kThrowSymbolAsyncIteratorInvalid), R(0), U8(0),
B(LdaNamedProperty), R(16), U8(11), U8(8),
B(Star), R(17),
B(CallProperty0), R(17), R(16), U8(10),
B(Star), R(17),
B(InvokeIntrinsic), U8(Runtime::k_CreateAsyncFromSyncIterator), R(17), U8(1),
B(LdaNamedProperty), R(15), U8(11), U8(8),
B(Star), R(16),
B(CallProperty0), R(16), R(15), U8(10),
B(Star), R(16),
B(InvokeIntrinsic), U8(Runtime::k_CreateAsyncFromSyncIterator), R(16), U8(1),
B(Star), R(4),
B(Ldar), R(11),
B(Ldar), R(10),
B(SwitchOnSmiNoFeedback), U8(12), U8(6), I8(1),
B(LdaSmi), I8(-2),
B(TestEqualStrictNoFeedback), R(11),
B(TestEqualStrictNoFeedback), R(10),
B(JumpIfTrue), U8(11),
B(LdaSmi), I8(81),
B(Star), R(16),
B(CallRuntime), U16(Runtime::kAbort), R(16), U8(1),
B(Star), R(15),
B(CallRuntime), U16(Runtime::kAbort), R(15), U8(1),
B(StackCheck),
B(LdaZero),
B(TestEqualStrict), R(2), U8(20),
B(Mov), R(2), R(16),
B(Mov), R(2), R(15),
B(JumpIfTrue), U8(18),
B(LdaSmi), I8(1),
B(TestEqualStrict), R(16), U8(24),
B(JumpIfTrue), U8(98),
B(TestEqualStrict), R(15), U8(24),
B(JumpIfTrue), U8(92),
B(LdaSmi), I8(2),
B(TestEqualStrict), R(16), U8(33),
B(JumpIfTrue), U8(197),
B(JumpConstant), U8(34),
B(LdaUndefined),
B(Star), R(17),
B(TestEqualStrict), R(15), U8(33),
B(JumpIfTrue), U8(185),
B(JumpConstant), U8(24),
B(LdaNamedProperty), R(4), U8(18), U8(18),
B(Star), R(19),
B(CallProperty1), R(19), R(4), R(1), U8(16),
B(Star), R(19),
B(Mov), R(0), R(18),
B(CallJSRuntime), U8(%async_generator_await_uncaught), R(17), U8(3),
B(Star), R(16),
B(CallProperty1), R(16), R(4), R(1), U8(16),
B(Star), R(16),
B(Mov), R(9), R(17),
B(Mov), R(16), R(18),
B(CallJSRuntime), U8(%async_generator_await_uncaught), R(17), U8(2),
B(Star), R(16),
B(LdaSmi), I8(1),
B(Mov), R(5), R(17),
B(SuspendGenerator), R(10), R(0), U8(17), U8(6),
B(Ldar), R(17),
B(SuspendGenerator), R(9), R(0), U8(16), U8(6),
B(Ldar), R(16),
/* 60 S> */ B(Return),
B(RestoreGeneratorRegisters), R(10), R(0), U8(17),
B(RestoreGeneratorRegisters), R(9), R(0), U8(16),
B(LdaSmi), I8(-2),
B(Star), R(11),
B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorGetAwaitInputOrDebugPos), R(10), U8(1),
B(Star), R(10),
B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorGetAwaitInputOrDebugPos), R(9), U8(1),
B(Star), R(17),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(10), U8(1),
B(SwitchOnSmiNoFeedback), U8(19), U8(2), I8(0),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(9), U8(1),
B(Star), R(18),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(18),
B(JumpIfTrue), U8(5),
B(Ldar), R(17),
B(ReThrow),
B(LdaZero),
B(Star), R(12),
B(Mov), R(17), R(13),
B(JumpConstant), U8(41),
B(Mov), R(17), R(3),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(17), U8(1),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(3), U8(1),
B(JumpIfToBooleanFalse), U8(4),
B(Jump), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(3), U8(1),
B(JumpConstant), U8(35),
B(LdaNamedProperty), R(4), U8(21), U8(21),
B(JumpConstant), U8(25),
B(LdaNamedProperty), R(4), U8(19), U8(21),
B(Star), R(3),
B(TestUndetectable),
B(JumpIfFalse), U8(10),
B(LdaZero),
B(Star), R(12),
B(Mov), R(1), R(13),
B(JumpConstant), U8(42),
B(LdaUndefined),
B(Star), R(17),
B(Mov), R(3), R(19),
B(Mov), R(4), R(20),
B(Mov), R(1), R(21),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(19), U8(3),
B(Star), R(19),
B(Mov), R(0), R(18),
B(CallJSRuntime), U8(%async_generator_await_uncaught), R(17), U8(3),
B(LdaSmi), I8(2),
B(Mov), R(5), R(17),
B(SuspendGenerator), R(10), R(0), U8(17), U8(6),
B(Ldar), R(17),
/* 60 S> */ B(Return),
B(RestoreGeneratorRegisters), R(10), R(0), U8(17),
B(LdaSmi), I8(-2),
B(Star), R(11),
B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorGetAwaitInputOrDebugPos), R(10), U8(1),
B(Mov), R(1), R(12),
B(JumpConstant), U8(31),
B(Mov), R(3), R(16),
B(Mov), R(4), R(17),
B(Mov), R(1), R(18),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(16), U8(3),
B(Star), R(16),
B(Mov), R(9), R(17),
B(Mov), R(16), R(18),
B(CallJSRuntime), U8(%async_generator_await_uncaught), R(17), U8(2),
B(Star), R(16),
B(LdaSmi), I8(2),
B(SuspendGenerator), R(9), R(0), U8(16), U8(6),
B(Ldar), R(16),
/* 60 S> */ B(Return),
B(RestoreGeneratorRegisters), R(9), R(0), U8(16),
B(LdaSmi), I8(-2),
B(Star), R(10),
B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorGetAwaitInputOrDebugPos), R(9), U8(1),
B(Star), R(17),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(10), U8(1),
B(SwitchOnSmiNoFeedback), U8(22), U8(2), I8(0),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(9), U8(1),
B(Star), R(18),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(18),
B(JumpIfTrue), U8(5),
B(Ldar), R(17),
B(ReThrow),
B(LdaZero),
B(Star), R(12),
B(Mov), R(17), R(13),
B(JumpConstant), U8(43),
B(Mov), R(17), R(3),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(17), U8(1),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(3), U8(1),
B(JumpIfToBooleanFalse), U8(4),
B(Jump), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(3), U8(1),
B(JumpConstant), U8(36),
B(LdaNamedProperty), R(4), U8(24), U8(25),
B(JumpConstant), U8(26),
B(LdaNamedProperty), R(4), U8(20), U8(25),
B(Star), R(5),
B(TestUndetectable),
B(JumpIfFalse), U8(230),
B(LdaNamedProperty), R(4), U8(19), U8(28),
B(Star), R(6),
B(TestUndetectable),
B(JumpIfFalse), U8(242),
B(LdaNamedProperty), R(4), U8(21), U8(28),
B(Star), R(7),
B(TestUndetectable),
B(JumpIfFalse), U8(4),
B(Jump), U8(215),
B(Jump), U8(203),
B(LdaZero),
B(Star), R(17),
B(Star), R(16),
B(LdaSmi), I8(1),
B(TestEqualStrict), R(17), U8(31),
B(JumpIfFalse), U8(121),
B(Ldar), R(7),
B(TestEqualStrict), R(16), U8(31),
B(JumpIfFalse), U8(115),
B(Ldar), R(6),
B(TestTypeOf), U8(5),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(131),
B(Star), R(16),
B(LdaConstant), U8(21),
B(Star), R(17),
B(LdaConstant), U8(25),
B(Star), R(18),
B(CallRuntime), U16(Runtime::kNewTypeError), R(17), U8(2),
B(CallRuntime), U16(Runtime::kNewTypeError), R(16), U8(2),
B(Throw),
B(Mov), R(context), R(17),
B(LdaUndefined),
B(Star), R(18),
B(Mov), R(7), R(20),
B(Mov), R(4), R(21),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(20), U8(2),
B(Star), R(20),
B(Mov), R(0), R(19),
B(CallJSRuntime), U8(%async_generator_await_caught), R(18), U8(3),
B(Mov), R(context), R(16),
B(Mov), R(6), R(17),
B(Mov), R(4), R(18),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(17), U8(2),
B(Star), R(17),
B(Mov), R(9), R(18),
B(Mov), R(17), R(19),
B(CallJSRuntime), U8(%async_generator_await_caught), R(18), U8(2),
B(Star), R(17),
B(LdaSmi), I8(3),
B(Mov), R(5), R(18),
B(SuspendGenerator), R(10), R(0), U8(18), U8(6),
B(Ldar), R(18),
B(SuspendGenerator), R(9), R(0), U8(17), U8(6),
B(Ldar), R(17),
/* 60 S> */ B(Return),
B(RestoreGeneratorRegisters), R(10), R(0), U8(18),
B(RestoreGeneratorRegisters), R(9), R(0), U8(17),
B(LdaSmi), I8(-2),
B(Star), R(11),
B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorGetAwaitInputOrDebugPos), R(10), U8(1),
B(Star), R(10),
B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorGetAwaitInputOrDebugPos), R(9), U8(1),
B(Star), R(18),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(10), U8(1),
B(SwitchOnSmiNoFeedback), U8(26), U8(2), I8(0),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(9), U8(1),
B(Star), R(19),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(19),
B(JumpIfTrue), U8(5),
B(Ldar), R(18),
B(ReThrow),
B(LdaZero),
B(Star), R(12),
B(Mov), R(18), R(13),
B(JumpConstant), U8(44),
B(Ldar), R(18),
B(Jump), U8(20),
B(Star), R(18),
B(Ldar), R(closure),
B(CreateCatchContext), R(18), U8(28), U8(29),
B(Star), R(17),
B(Ldar), R(closure),
B(CreateCatchContext), R(17), U8(22), U8(23),
B(Star), R(16),
B(LdaTheHole),
B(SetPendingMessage),
B(Ldar), R(17),
B(PushContext), R(18),
B(PopContext), R(18),
B(Jump), U8(86),
B(LdaUndefined),
B(Star), R(17),
B(Mov), R(7), R(19),
B(Mov), R(4), R(20),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(19), U8(2),
B(Star), R(19),
B(Mov), R(0), R(18),
B(CallJSRuntime), U8(%async_generator_await_uncaught), R(17), U8(3),
B(Ldar), R(16),
B(PushContext), R(17),
B(PopContext), R(17),
B(Jump), U8(80),
B(Mov), R(6), R(16),
B(Mov), R(4), R(17),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(16), U8(2),
B(Star), R(16),
B(Mov), R(9), R(17),
B(Mov), R(16), R(18),
B(CallJSRuntime), U8(%async_generator_await_uncaught), R(17), U8(2),
B(Star), R(16),
B(LdaSmi), I8(4),
B(Mov), R(5), R(17),
B(SuspendGenerator), R(10), R(0), U8(17), U8(6),
B(Ldar), R(17),
B(SuspendGenerator), R(9), R(0), U8(16), U8(6),
B(Ldar), R(16),
/* 60 S> */ B(Return),
B(RestoreGeneratorRegisters), R(10), R(0), U8(17),
B(RestoreGeneratorRegisters), R(9), R(0), U8(16),
B(LdaSmi), I8(-2),
B(Star), R(11),
B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorGetAwaitInputOrDebugPos), R(10), U8(1),
B(Star), R(10),
B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorGetAwaitInputOrDebugPos), R(9), U8(1),
B(Star), R(17),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(10), U8(1),
B(SwitchOnSmiNoFeedback), U8(30), U8(2), I8(0),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(9), U8(1),
B(Star), R(18),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(18),
B(JumpIfTrue), U8(5),
B(Ldar), R(17),
B(ReThrow),
B(LdaZero),
B(Star), R(12),
B(Mov), R(17), R(13),
B(JumpConstant), U8(45),
B(Mov), R(17), R(8),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(17), U8(1),
B(Mov), R(17), R(7),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(7), U8(1),
B(JumpIfToBooleanFalse), U8(4),
B(Jump), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(8), U8(1),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(7), U8(1),
B(Wide), B(LdaSmi), I16(145),
B(Star), R(16),
B(LdaConstant), U8(21),
B(Star), R(17),
B(LdaConstant), U8(25),
B(Star), R(18),
B(CallRuntime), U16(Runtime::kNewTypeError), R(17), U8(2),
B(CallRuntime), U16(Runtime::kNewTypeError), R(16), U8(2),
B(Throw),
B(LdaUndefined),
B(Star), R(17),
B(Mov), R(6), R(19),
B(Mov), R(4), R(20),
B(Mov), R(1), R(21),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(19), U8(3),
B(Star), R(19),
B(Mov), R(0), R(18),
B(CallJSRuntime), U8(%async_generator_await_uncaught), R(17), U8(3),
B(Mov), R(5), R(16),
B(Mov), R(4), R(17),
B(Mov), R(1), R(18),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(16), U8(3),
B(Star), R(16),
B(Mov), R(9), R(17),
B(Mov), R(16), R(18),
B(CallJSRuntime), U8(%async_generator_await_uncaught), R(17), U8(2),
B(Star), R(16),
B(LdaSmi), I8(5),
B(Mov), R(5), R(17),
B(SuspendGenerator), R(10), R(0), U8(17), U8(6),
B(Ldar), R(17),
B(SuspendGenerator), R(9), R(0), U8(16), U8(6),
B(Ldar), R(16),
/* 60 S> */ B(Return),
B(RestoreGeneratorRegisters), R(10), R(0), U8(17),
B(RestoreGeneratorRegisters), R(9), R(0), U8(16),
B(LdaSmi), I8(-2),
B(Star), R(11),
B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorGetAwaitInputOrDebugPos), R(10), U8(1),
B(Star), R(10),
B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorGetAwaitInputOrDebugPos), R(9), U8(1),
B(Star), R(17),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(10), U8(1),
B(SwitchOnSmiNoFeedback), U8(32), U8(2), I8(0),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(9), U8(1),
B(Star), R(18),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(18),
B(JumpIfTrue), U8(5),
B(Ldar), R(17),
B(ReThrow),
B(LdaZero),
B(Star), R(12),
B(Mov), R(17), R(13),
B(Jump), U8(171),
B(Mov), R(17), R(3),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(17), U8(1),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(3), U8(1),
B(JumpIfToBooleanFalse), U8(4),
B(Jump), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(3), U8(1),
B(Jump), U8(2),
B(LdaNamedProperty), R(3), U8(37), U8(34),
B(LdaNamedProperty), R(3), U8(27), U8(34),
B(JumpIfToBooleanFalse), U8(4),
B(Jump), U8(62),
B(LdaNamedProperty), R(3), U8(38), U8(36),
B(LdaNamedProperty), R(3), U8(28), U8(36),
B(Star), R(3),
B(LdaSmi), I8(6),
B(Mov), R(3), R(16),
B(SuspendGenerator), R(10), R(0), U8(16), U8(4),
B(Mov), R(3), R(15),
B(SuspendGenerator), R(9), R(0), U8(15), U8(4),
B(LdaFalse),
B(Star), R(19),
B(Mov), R(10), R(17),
B(Mov), R(16), R(18),
B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorResolve), R(17), U8(3),
B(Star), R(18),
B(Mov), R(9), R(16),
B(Mov), R(15), R(17),
B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorResolve), R(16), U8(3),
/* 60 S> */ B(Return),
B(RestoreGeneratorRegisters), R(10), R(0), U8(16),
B(RestoreGeneratorRegisters), R(9), R(0), U8(15),
B(LdaSmi), I8(-2),
B(Star), R(11),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetInputOrDebugPos), R(10), U8(1),
B(Star), R(10),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetInputOrDebugPos), R(9), U8(1),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetInputOrDebugPos), R(0), U8(1),
B(Star), R(1),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(0), U8(1),
B(Star), R(2),
B(Wide), B(JumpLoop), U16(641), I16(0),
B(Wide), B(JumpLoop), U16(611), I16(0),
B(LdaSmi), I8(1),
B(TestEqualStrict), R(2), U8(38),
B(JumpIfFalse), U8(13),
B(LdaNamedProperty), R(3), U8(38), U8(39),
B(Star), R(13),
B(LdaZero),
B(LdaNamedProperty), R(3), U8(28), U8(39),
B(Star), R(12),
B(LdaZero),
B(Star), R(11),
B(Jump), U8(67),
B(LdaNamedProperty), R(3), U8(38), U8(41),
B(Star), R(9),
B(LdaNamedProperty), R(3), U8(28), U8(41),
B(Star), R(8),
B(LdaUndefined),
B(Star), R(13),
B(LdaZero),
B(Star), R(12),
B(LdaZero),
B(Star), R(11),
B(Jump), U8(53),
B(Jump), U8(39),
B(Star), R(16),
B(Ldar), R(closure),
B(CreateCatchContext), R(16), U8(28), U8(39),
B(Star), R(15),
B(Ldar), R(closure),
B(CreateCatchContext), R(15), U8(22), U8(29),
B(Star), R(14),
B(LdaTheHole),
B(SetPendingMessage),
B(Ldar), R(15),
B(PushContext), R(16),
B(Ldar), R(14),
B(PushContext), R(15),
B(LdaImmutableCurrentContextSlot), U8(4),
B(Star), R(18),
B(Mov), R(0), R(17),
B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorReject), R(17), U8(2),
B(PopContext), R(16),
B(Star), R(13),
B(LdaSmi), I8(1),
B(Star), R(17),
B(Mov), R(0), R(16),
B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorReject), R(16), U8(2),
B(PopContext), R(15),
B(Star), R(12),
B(LdaSmi), I8(1),
B(Star), R(11),
B(Jump), U8(14),
B(LdaSmi), I8(-1),
B(Star), R(12),
B(Star), R(11),
B(Jump), U8(8),
B(Star), R(13),
B(LdaSmi), I8(2),
B(Star), R(12),
B(LdaSmi), I8(2),
B(Star), R(11),
B(LdaTheHole),
B(SetPendingMessage),
B(Star), R(14),
B(Star), R(13),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorClose), R(0), U8(1),
B(Ldar), R(14),
B(Ldar), R(13),
B(SetPendingMessage),
B(Ldar), R(12),
B(SwitchOnSmiNoFeedback), U8(46), U8(3), I8(0),
B(Ldar), R(11),
B(SwitchOnSmiNoFeedback), U8(32), U8(3), I8(0),
B(Jump), U8(34),
B(LdaTrue),
B(Star), R(16),
B(Mov), R(0), R(14),
B(Mov), R(12), R(15),
B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorResolve), R(14), U8(3),
B(Star), R(17),
B(Mov), R(0), R(15),
B(Mov), R(13), R(16),
B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorResolve), R(15), U8(3),
B(Star), R(18),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorClose), R(10), U8(1),
B(Ldar), R(18),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorClose), R(9), U8(1),
B(Ldar), R(17),
/* 60 S> */ B(Return),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorClose), R(10), U8(1),
B(Ldar), R(13),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorClose), R(9), U8(1),
B(Ldar), R(12),
/* 60 S> */ B(Return),
B(Ldar), R(13),
B(Ldar), R(12),
B(ReThrow),
B(LdaUndefined),
B(Star), R(12),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorClose), R(10), U8(1),
B(Ldar), R(12),
B(Star), R(11),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorClose), R(9), U8(1),
B(Ldar), R(11),
/* 60 S> */ B(Return),
]
constant pool: [
@ -961,47 +951,33 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["g"],
SYMBOL_TYPE,
SYMBOL_TYPE,
Smi [81],
Smi [187],
Smi [330],
Smi [422],
Smi [525],
Smi [614],
Smi [80],
Smi [180],
Smi [317],
Smi [403],
Smi [500],
Smi [584],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
Smi [15],
Smi [7],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"],
Smi [15],
Smi [7],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["throw"],
ONE_BYTE_INTERNALIZED_STRING_TYPE [""],
Smi [15],
Smi [7],
ONE_BYTE_INTERNALIZED_STRING_TYPE [".catch"],
FIXED_ARRAY_TYPE,
Smi [15],
Smi [7],
Smi [15],
Smi [7],
Smi [533],
Smi [446],
Smi [340],
Smi [503],
Smi [422],
Smi [322],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"],
FIXED_ARRAY_TYPE,
Smi [789],
Smi [615],
Smi [580],
Smi [509],
Smi [366],
Smi [274],
Smi [759],
Smi [556],
Smi [6],
Smi [28],
Smi [35],
]
handlers: [
[52, 875, 881],
[55, 836, 838],
[455, 525, 527],
[52, 845, 851],
[55, 806, 808],
[443, 507, 509],
]

View File

@ -1253,7 +1253,7 @@ snippet: "
"
frame size: 26
parameter count: 2
bytecode array length: 537
bytecode array length: 516
bytecodes: [
B(Mov), R(new_target), R(11),
B(Ldar), R(new_target),
@ -1280,12 +1280,12 @@ bytecodes: [
B(LdaUndefined),
B(Star), R(14),
B(CallJSRuntime), U8(%async_function_promise_create), R(14), U8(1),
B(Star), R(3),
B(Star), R(10),
B(Mov), R(2), R(11),
B(Mov), R(context), R(16),
B(Mov), R(context), R(17),
B(LdaZero),
B(Star), R(7),
B(Star), R(6),
B(Mov), R(context), R(20),
B(Mov), R(context), R(21),
/* 40 S> */ B(LdaImmutableCurrentContextSlot), U8(4),
@ -1295,7 +1295,7 @@ bytecodes: [
B(CallProperty0), R(23), R(22), U8(6),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(5),
B(Star), R(4),
B(Ldar), R(12),
B(SwitchOnSmiNoFeedback), U8(2), U8(1), I8(0),
B(LdaSmi), I8(-2),
@ -1304,31 +1304,29 @@ bytecodes: [
B(LdaSmi), I8(81),
B(Star), R(22),
B(CallRuntime), U16(Runtime::kAbort), R(22), U8(1),
/* 35 S> */ B(LdaNamedProperty), R(5), U8(3), U8(10),
/* 35 S> */ B(LdaNamedProperty), R(4), U8(3), U8(10),
B(Star), R(22),
B(CallProperty0), R(22), R(5), U8(8),
B(Star), R(6),
/* 35 E> */ B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(6), U8(1),
B(CallProperty0), R(22), R(4), U8(8),
B(Star), R(5),
/* 35 E> */ B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(5), U8(1),
B(ToBooleanLogicalNot),
B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(6), U8(1),
B(LdaNamedProperty), R(6), U8(4), U8(12),
B(JumpIfToBooleanTrue), U8(86),
B(LdaNamedProperty), R(6), U8(5), U8(14),
B(Star), R(8),
B(LdaSmi), I8(2),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(5), U8(1),
B(LdaNamedProperty), R(5), U8(4), U8(12),
B(JumpIfToBooleanTrue), U8(77),
B(LdaNamedProperty), R(5), U8(5), U8(14),
B(Star), R(7),
B(Mov), R(8), R(4),
B(LdaSmi), I8(2),
B(Star), R(6),
B(Mov), R(7), R(3),
/* 26 E> */ B(StackCheck),
B(Mov), R(4), R(0),
/* 45 S> */ B(LdaUndefined),
B(Mov), R(3), R(0),
/* 45 S> */ B(Mov), R(11), R(23),
B(Mov), R(0), R(24),
B(Mov), R(10), R(25),
B(CallJSRuntime), U8(%async_function_await_uncaught), R(23), U8(3),
B(Star), R(22),
B(Mov), R(2), R(23),
B(Mov), R(4), R(24),
B(Mov), R(3), R(25),
/* 51 E> */ B(CallJSRuntime), U8(%async_function_await_uncaught), R(22), U8(4),
B(LdaZero),
B(Mov), R(3), R(22),
B(SuspendGenerator), R(11), R(0), U8(22), U8(2),
B(Ldar), R(22),
/* 54 S> */ B(Return),
@ -1336,74 +1334,73 @@ bytecodes: [
B(LdaSmi), I8(-2),
B(Star), R(12),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetInputOrDebugPos), R(11), U8(1),
B(Star), R(22),
B(Star), R(23),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(11), U8(1),
B(SwitchOnSmiNoFeedback), U8(6), U8(2), I8(0),
B(Ldar), R(22),
B(Star), R(24),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(24),
B(JumpIfTrue), U8(5),
B(Ldar), R(23),
/* 45 E> */ B(ReThrow),
B(LdaZero),
B(Star), R(18),
B(Mov), R(22), R(19),
B(Jump), U8(60),
B(LdaZero),
B(Star), R(7),
B(JumpLoop), U8(132), I8(0),
B(Star), R(6),
B(JumpLoop), U8(123), I8(0),
B(Jump), U8(40),
B(Star), R(22),
B(Ldar), R(closure),
B(CreateCatchContext), R(22), U8(8), U8(9),
B(CreateCatchContext), R(22), U8(6), U8(7),
B(Star), R(21),
B(LdaTheHole),
B(SetPendingMessage),
B(Ldar), R(21),
B(PushContext), R(22),
B(LdaSmi), I8(2),
B(TestEqualStrict), R(7), U8(16),
B(TestEqualStrict), R(6), U8(16),
B(JumpIfFalse), U8(6),
B(LdaSmi), I8(1),
B(Star), R(7),
B(Star), R(6),
B(LdaImmutableCurrentContextSlot), U8(4),
B(Star), R(23),
B(CallRuntime), U16(Runtime::kReThrow), R(23), U8(1),
B(PopContext), R(22),
B(LdaSmi), I8(-1),
B(Star), R(18),
B(Jump), U8(8),
B(Jump), U8(7),
B(Star), R(19),
B(LdaSmi), I8(1),
B(LdaZero),
B(Star), R(18),
B(LdaTheHole),
B(SetPendingMessage),
B(Star), R(20),
B(LdaZero),
B(TestEqualStrict), R(7), U8(17),
B(TestEqualStrict), R(6), U8(17),
B(JumpIfTrue), U8(104),
B(LdaNamedProperty), R(5), U8(10), U8(18),
B(Star), R(9),
B(LdaNamedProperty), R(4), U8(8), U8(18),
B(Star), R(8),
B(TestUndetectable),
B(JumpIfFalse), U8(4),
B(Jump), U8(93),
B(LdaSmi), I8(1),
B(TestEqualStrict), R(7), U8(21),
B(TestEqualStrict), R(6), U8(21),
B(JumpIfFalse), U8(61),
B(Ldar), R(9),
B(Ldar), R(8),
B(TestTypeOf), U8(5),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(131),
B(Star), R(21),
B(LdaConstant), U8(11),
B(LdaConstant), U8(9),
B(Star), R(22),
B(CallRuntime), U16(Runtime::kNewTypeError), R(21), U8(2),
B(Throw),
B(Mov), R(context), R(21),
B(Mov), R(9), R(22),
B(Mov), R(5), R(23),
B(Mov), R(8), R(22),
B(Mov), R(4), R(23),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(22), U8(2),
B(Jump), U8(20),
B(Star), R(22),
B(Ldar), R(closure),
B(CreateCatchContext), R(22), U8(8), U8(12),
B(CreateCatchContext), R(22), U8(6), U8(10),
B(Star), R(21),
B(LdaTheHole),
B(SetPendingMessage),
@ -1411,39 +1408,35 @@ bytecodes: [
B(PushContext), R(22),
B(PopContext), R(22),
B(Jump), U8(27),
B(Mov), R(9), R(21),
B(Mov), R(5), R(22),
B(Mov), R(8), R(21),
B(Mov), R(4), R(22),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(21), U8(2),
B(Star), R(10),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(10), U8(1),
B(Star), R(9),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(9), U8(1),
B(JumpIfToBooleanFalse), U8(4),
B(Jump), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(10), U8(1),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(9), U8(1),
B(Ldar), R(20),
B(SetPendingMessage),
B(Ldar), R(18),
B(SwitchOnSmiNoFeedback), U8(13), U8(2), I8(0),
B(Jump), U8(13),
B(LdaZero),
B(Star), R(14),
B(Mov), R(19), R(15),
B(Jump), U8(83),
B(TestEqualStrictNoFeedback), R(18),
B(JumpIfFalse), U8(5),
B(Ldar), R(19),
B(ReThrow),
B(LdaUndefined),
B(Star), R(18),
B(LdaUndefined),
B(Star), R(20),
B(Mov), R(3), R(19),
B(Mov), R(10), R(19),
B(CallJSRuntime), U8(%promise_resolve), R(18), U8(3),
B(LdaZero),
B(Star), R(14),
B(Mov), R(3), R(15),
B(Mov), R(10), R(15),
B(Jump), U8(59),
B(Jump), U8(45),
B(Star), R(18),
B(Ldar), R(closure),
B(CreateCatchContext), R(18), U8(8), U8(15),
B(CreateCatchContext), R(18), U8(6), U8(11),
B(Star), R(17),
B(LdaTheHole),
B(SetPendingMessage),
@ -1455,12 +1448,12 @@ bytecodes: [
B(Star), R(21),
B(LdaFalse),
B(Star), R(22),
B(Mov), R(3), R(20),
B(Mov), R(10), R(20),
B(CallJSRuntime), U8(%promise_internal_reject), R(19), U8(4),
B(PopContext), R(18),
B(LdaZero),
B(Star), R(14),
B(Mov), R(3), R(15),
B(Mov), R(10), R(15),
B(Jump), U8(14),
B(LdaSmi), I8(-1),
B(Star), R(14),
@ -1473,12 +1466,12 @@ bytecodes: [
B(Star), R(16),
B(LdaUndefined),
B(Star), R(17),
B(Mov), R(3), R(18),
B(Mov), R(10), R(18),
B(CallJSRuntime), U8(%async_function_promise_release), R(17), U8(2),
B(Ldar), R(16),
B(SetPendingMessage),
B(Ldar), R(14),
B(SwitchOnSmiNoFeedback), U8(16), U8(2), I8(0),
B(SwitchOnSmiNoFeedback), U8(12), U8(2), I8(0),
B(Jump), U8(8),
B(Ldar), R(15),
/* 54 S> */ B(Return),
@ -1490,28 +1483,24 @@ bytecodes: [
constant pool: [
Smi [88],
SYMBOL_TYPE,
Smi [94],
Smi [90],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"],
Smi [15],
Smi [7],
ONE_BYTE_INTERNALIZED_STRING_TYPE [".catch"],
FIXED_ARRAY_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"],
ONE_BYTE_INTERNALIZED_STRING_TYPE [""],
FIXED_ARRAY_TYPE,
Smi [6],
Smi [14],
FIXED_ARRAY_TYPE,
Smi [6],
Smi [9],
]
handlers: [
[70, 492, 498],
[73, 447, 449],
[79, 280, 286],
[82, 240, 242],
[347, 357, 359],
[70, 471, 477],
[73, 426, 428],
[79, 271, 277],
[82, 231, 233],
[337, 347, 349],
]

View File

@ -535,7 +535,7 @@ snippet: "
"
frame size: 14
parameter count: 1
bytecode array length: 278
bytecode array length: 269
bytecodes: [
B(Mov), R(new_target), R(3),
B(Ldar), R(new_target),
@ -574,16 +574,14 @@ bytecodes: [
B(CallRuntime), U16(Runtime::kAbort), R(9), U8(1),
/* 41 S> */ B(LdaSmi), I8(10),
/* 41 E> */ B(TestLessThan), R(0), U8(4),
B(JumpIfFalse), U8(73),
B(JumpIfFalse), U8(64),
/* 23 E> */ B(StackCheck),
/* 52 S> */ B(LdaUndefined),
B(Star), R(9),
B(Mov), R(1), R(10),
/* 52 S> */ B(Mov), R(3), R(10),
B(Mov), R(0), R(11),
B(Mov), R(2), R(12),
/* 58 E> */ B(CallJSRuntime), U8(%async_function_await_uncaught), R(9), U8(4),
B(CallJSRuntime), U8(%async_function_await_uncaught), R(10), U8(3),
B(Star), R(9),
B(LdaZero),
B(Mov), R(2), R(9),
B(SuspendGenerator), R(3), R(0), U8(9), U8(2),
B(Ldar), R(9),
/* 61 S> */ B(Return),
@ -591,19 +589,18 @@ bytecodes: [
B(LdaSmi), I8(-2),
B(Star), R(4),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetInputOrDebugPos), R(3), U8(1),
B(Star), R(9),
B(Star), R(10),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(3), U8(1),
B(SwitchOnSmiNoFeedback), U8(2), U8(2), I8(0),
B(Ldar), R(9),
/* 52 E> */ B(ReThrow),
B(Star), R(11),
B(LdaZero),
B(Star), R(5),
B(Mov), R(9), R(6),
B(Jump), U8(89),
B(TestEqualStrictNoFeedback), R(11),
B(JumpIfTrue), U8(5),
B(Ldar), R(10),
/* 52 E> */ B(ReThrow),
/* 49 S> */ B(Ldar), R(0),
B(Inc), U8(5),
B(Star), R(0),
B(JumpLoop), U8(96), I8(0),
B(JumpLoop), U8(87), I8(0),
B(LdaUndefined),
B(Star), R(9),
B(LdaUndefined),
@ -617,7 +614,7 @@ bytecodes: [
B(Jump), U8(45),
B(Star), R(9),
B(Ldar), R(closure),
B(CreateCatchContext), R(9), U8(4), U8(5),
B(CreateCatchContext), R(9), U8(2), U8(3),
B(Star), R(8),
B(LdaTheHole),
B(SetPendingMessage),
@ -652,7 +649,7 @@ bytecodes: [
B(Ldar), R(7),
B(SetPendingMessage),
B(Ldar), R(5),
B(SwitchOnSmiNoFeedback), U8(6), U8(2), I8(0),
B(SwitchOnSmiNoFeedback), U8(4), U8(2), I8(0),
B(Jump), U8(8),
B(Ldar), R(6),
/* 61 S> */ B(Return),
@ -663,16 +660,14 @@ bytecodes: [
]
constant pool: [
Smi [51],
Smi [55],
Smi [15],
Smi [7],
Smi [51],
ONE_BYTE_INTERNALIZED_STRING_TYPE [".catch"],
FIXED_ARRAY_TYPE,
Smi [6],
Smi [9],
]
handlers: [
[62, 233, 239],
[65, 188, 190],
[62, 224, 230],
[65, 179, 181],
]

View File

@ -4,7 +4,7 @@ Running test: testBreakLocations
function testFunction() {
async function f1() {
for (let x = |_|0; x |_|< 1; ++|_|x) |_|await |C|x;
for (let x = |_|0; x |_|< 1; ++|_|x) |_|await x;
|_|return await Promise.|C|resolve(2);
|R|}
@ -15,7 +15,7 @@ function testFunction() {
|_|await [1].|C|map(x => Promise.|C|resolve(x)|R|)[0];
|_|await Promise.|C|resolve().|C|then(x => x |_|* 2|R|);
let p = |_|Promise.|C|resolve(42);
|_|await |C|p;
|_|await p;
|_|return r;
|R|}

View File

@ -227,7 +227,7 @@ async function testPromiseAsyncWithCode() {
var resolveNested;
var p = |C|new Promise(resolve => resolveNested |_|= resolve|R|);
|C|setTimeout(resolveNested, 0);
|_|await |C|p;
|_|await p;
|R|}
|C|setTimeout(returnCall, 0);
|_|await |C|foo();