[generators] Perform state dispatch in loop header.
This is necessary to eventually build a turbofan graph. BUG=v8:4907 LOG=n Review URL: https://codereview.chromium.org/1901713003 Cr-Commit-Position: refs/heads/master@{#35820}
This commit is contained in:
parent
25ff296c4c
commit
42c0e2ec7c
@ -569,9 +569,10 @@ BytecodeGenerator::BytecodeGenerator(CompilationInfo* info)
|
||||
execution_result_(nullptr),
|
||||
register_allocator_(nullptr),
|
||||
generator_resume_points_(info->literal()->yield_count(), info->zone()),
|
||||
generator_state_(),
|
||||
generator_yields_seen_(0),
|
||||
try_catch_nesting_level_(0),
|
||||
try_finally_nesting_level_(0),
|
||||
generator_yields_seen_(0) {
|
||||
try_finally_nesting_level_(0) {
|
||||
InitializeAstVisitor(isolate());
|
||||
}
|
||||
|
||||
@ -582,7 +583,10 @@ Handle<BytecodeArray> BytecodeGenerator::MakeBytecode() {
|
||||
// Initialize control scope.
|
||||
ControlScopeForTopLevel control(this);
|
||||
|
||||
RegisterAllocationScope register_scope(this);
|
||||
|
||||
if (IsGeneratorFunction(info()->literal()->kind())) {
|
||||
generator_state_ = register_allocator()->NewRegister();
|
||||
VisitGeneratorPrologue();
|
||||
}
|
||||
|
||||
@ -632,30 +636,71 @@ void BytecodeGenerator::MakeBytecodeBody() {
|
||||
VisitStatements(info()->literal()->body());
|
||||
}
|
||||
|
||||
void BytecodeGenerator::BuildIndexedJump(Register index, size_t start_index,
|
||||
size_t size,
|
||||
ZoneVector<BytecodeLabel>& targets) {
|
||||
// TODO(neis): Optimize this by using a proper jump table.
|
||||
for (size_t i = start_index; i < start_index + size; i++) {
|
||||
DCHECK(0 <= i && i < targets.size());
|
||||
builder()
|
||||
->LoadLiteral(Smi::FromInt(static_cast<int>(i)))
|
||||
.CompareOperation(Token::Value::EQ_STRICT, index)
|
||||
.JumpIfTrue(&(targets[i]));
|
||||
}
|
||||
builder()->Illegal(); // Should never get here.
|
||||
}
|
||||
|
||||
void BytecodeGenerator::VisitIterationHeader(IterationStatement* stmt,
|
||||
LoopBuilder* loop_builder) {
|
||||
// Recall that stmt->yield_count() is always zero inside ordinary
|
||||
// (i.e. non-generator) functions.
|
||||
|
||||
// Collect all labels for generator resume points within the loop (if any) so
|
||||
// that they can be bound to the loop header below. Also create fresh labels
|
||||
// for these resume points, to be used inside the loop.
|
||||
ZoneVector<BytecodeLabel> resume_points_in_loop(zone());
|
||||
for (size_t id = generator_yields_seen_;
|
||||
id < generator_yields_seen_ + stmt->yield_count(); id++) {
|
||||
DCHECK(0 <= id && id < generator_resume_points_.size());
|
||||
auto& label = generator_resume_points_[id];
|
||||
resume_points_in_loop.push_back(label);
|
||||
generator_resume_points_[id] = BytecodeLabel();
|
||||
}
|
||||
|
||||
loop_builder->LoopHeader(&resume_points_in_loop);
|
||||
|
||||
if (stmt->yield_count() > 0) {
|
||||
// If we are not resuming, fall through to loop body.
|
||||
// If we are resuming, perform state dispatch.
|
||||
BytecodeLabel not_resuming;
|
||||
builder()
|
||||
->LoadLiteral(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting))
|
||||
.CompareOperation(Token::Value::EQ, generator_state_)
|
||||
.JumpIfTrue(¬_resuming);
|
||||
BuildIndexedJump(generator_state_, generator_yields_seen_,
|
||||
stmt->yield_count(), generator_resume_points_);
|
||||
builder()->Bind(¬_resuming);
|
||||
}
|
||||
}
|
||||
|
||||
void BytecodeGenerator::VisitGeneratorPrologue() {
|
||||
// The generator resume trampoline abuses the new.target register both to
|
||||
// indicate that this is a resume call and to pass in the generator object.
|
||||
// In ordinary calls, new.target is always undefined because generator
|
||||
// functions are non-constructable.
|
||||
Register generator_object = Register::new_target();
|
||||
BytecodeLabel regular_call;
|
||||
builder()
|
||||
->LoadAccumulatorWithRegister(Register::new_target())
|
||||
->LoadAccumulatorWithRegister(generator_object)
|
||||
.JumpIfUndefined(®ular_call);
|
||||
|
||||
// This is a resume call. Restore registers and perform state dispatch.
|
||||
// (The current context has already been restored by the trampoline.)
|
||||
{
|
||||
RegisterAllocationScope register_scope(this);
|
||||
Register state = register_allocator()->NewRegister();
|
||||
builder()
|
||||
->ResumeGenerator(Register::new_target())
|
||||
.StoreAccumulatorInRegister(state);
|
||||
|
||||
// TODO(neis): Optimize this by using a proper jump table.
|
||||
for (size_t i = 0; i < generator_resume_points_.size(); ++i) {
|
||||
builder()
|
||||
->LoadLiteral(Smi::FromInt(static_cast<int>(i)))
|
||||
.CompareOperation(Token::Value::EQ_STRICT, state)
|
||||
.JumpIfTrue(&(generator_resume_points_[i]));
|
||||
}
|
||||
builder()->Illegal(); // Should never get here.
|
||||
}
|
||||
builder()
|
||||
->ResumeGenerator(generator_object)
|
||||
.StoreAccumulatorInRegister(generator_state_);
|
||||
BuildIndexedJump(generator_state_, 0, generator_resume_points_.size(),
|
||||
generator_resume_points_);
|
||||
|
||||
builder()->Bind(®ular_call);
|
||||
// This is a regular call. Fall through to the ordinary function prologue,
|
||||
@ -989,7 +1034,7 @@ void BytecodeGenerator::VisitIterationBody(IterationStatement* stmt,
|
||||
|
||||
void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
|
||||
LoopBuilder loop_builder(builder());
|
||||
loop_builder.LoopHeader();
|
||||
VisitIterationHeader(stmt, &loop_builder);
|
||||
if (stmt->cond()->ToBooleanIsFalse()) {
|
||||
VisitIterationBody(stmt, &loop_builder);
|
||||
loop_builder.Condition();
|
||||
@ -1014,7 +1059,7 @@ void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
|
||||
}
|
||||
|
||||
LoopBuilder loop_builder(builder());
|
||||
loop_builder.LoopHeader();
|
||||
VisitIterationHeader(stmt, &loop_builder);
|
||||
loop_builder.Condition();
|
||||
if (!stmt->cond()->ToBooleanIsTrue()) {
|
||||
builder()->SetExpressionAsStatementPosition(stmt->cond());
|
||||
@ -1038,7 +1083,7 @@ void BytecodeGenerator::VisitForStatement(ForStatement* stmt) {
|
||||
}
|
||||
|
||||
LoopBuilder loop_builder(builder());
|
||||
loop_builder.LoopHeader();
|
||||
VisitIterationHeader(stmt, &loop_builder);
|
||||
loop_builder.Condition();
|
||||
if (stmt->cond() && !stmt->cond()->ToBooleanIsTrue()) {
|
||||
builder()->SetExpressionAsStatementPosition(stmt->cond());
|
||||
@ -1163,7 +1208,7 @@ void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
||||
builder()->StoreAccumulatorInRegister(index);
|
||||
|
||||
// The loop
|
||||
loop_builder.LoopHeader();
|
||||
VisitIterationHeader(stmt, &loop_builder);
|
||||
builder()->SetExpressionAsStatementPosition(stmt->each());
|
||||
loop_builder.Condition();
|
||||
builder()->ForInDone(index, cache_length);
|
||||
@ -1191,7 +1236,7 @@ void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
|
||||
builder()->SetExpressionAsStatementPosition(stmt->assign_iterator());
|
||||
VisitForEffect(stmt->assign_iterator());
|
||||
|
||||
loop_builder.LoopHeader();
|
||||
VisitIterationHeader(stmt, &loop_builder);
|
||||
loop_builder.Next();
|
||||
builder()->SetExpressionAsStatementPosition(stmt->next_result());
|
||||
VisitForEffect(stmt->next_result());
|
||||
@ -2213,7 +2258,7 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) {
|
||||
}
|
||||
|
||||
void BytecodeGenerator::VisitYield(Yield* expr) {
|
||||
int id = generator_yields_seen_++;
|
||||
size_t id = generator_yields_seen_++;
|
||||
|
||||
builder()->SetExpressionPosition(expr);
|
||||
Register value = VisitForRegisterValue(expr->expression());
|
||||
@ -2222,7 +2267,7 @@ void BytecodeGenerator::VisitYield(Yield* expr) {
|
||||
|
||||
// Save context, registers, and state. Then return.
|
||||
builder()
|
||||
->LoadLiteral(Smi::FromInt(id))
|
||||
->LoadLiteral(Smi::FromInt(static_cast<int>(id)))
|
||||
.SuspendGenerator(generator)
|
||||
.LoadAccumulatorWithRegister(value)
|
||||
.Return(); // Hard return (ignore any finally blocks).
|
||||
@ -2233,6 +2278,12 @@ void BytecodeGenerator::VisitYield(Yield* expr) {
|
||||
{
|
||||
RegisterAllocationScope register_scope(this);
|
||||
|
||||
// Update state to indicate that we have finished resuming. Loop headers
|
||||
// rely on this.
|
||||
builder()
|
||||
->LoadLiteral(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting))
|
||||
.StoreAccumulatorInRegister(generator_state_);
|
||||
|
||||
Register input = register_allocator()->NewRegister();
|
||||
builder()
|
||||
->CallRuntime(Runtime::kGeneratorGetInput, generator, 1)
|
||||
|
@ -109,6 +109,11 @@ class BytecodeGenerator final : public AstVisitor {
|
||||
void BuildHoleCheckForVariableLoad(VariableMode mode, Handle<String> name);
|
||||
void BuildHoleCheckForVariableAssignment(Variable* variable, Token::Value op);
|
||||
|
||||
// Build jump to targets[value], where
|
||||
// start_index <= value < start_index + size.
|
||||
void BuildIndexedJump(Register value, size_t start_index, size_t size,
|
||||
ZoneVector<BytecodeLabel>& targets);
|
||||
|
||||
void VisitGeneratorPrologue();
|
||||
|
||||
void VisitArgumentsObject(Variable* variable);
|
||||
@ -135,7 +140,9 @@ class BytecodeGenerator final : public AstVisitor {
|
||||
Register value_out);
|
||||
void VisitForInAssignment(Expression* expr, FeedbackVectorSlot slot);
|
||||
|
||||
// Visit the body of a loop iteration.
|
||||
// Visit the header/body of a loop iteration.
|
||||
void VisitIterationHeader(IterationStatement* stmt,
|
||||
LoopBuilder* loop_builder);
|
||||
void VisitIterationBody(IterationStatement* stmt, LoopBuilder* loop_builder);
|
||||
|
||||
// Visit a statement and switch scopes, the context is in the accumulator.
|
||||
@ -202,9 +209,10 @@ class BytecodeGenerator final : public AstVisitor {
|
||||
ExpressionResultScope* execution_result_;
|
||||
RegisterAllocationScope* register_allocator_;
|
||||
ZoneVector<BytecodeLabel> generator_resume_points_;
|
||||
Register generator_state_;
|
||||
size_t generator_yields_seen_;
|
||||
int try_catch_nesting_level_;
|
||||
int try_finally_nesting_level_;
|
||||
int generator_yields_seen_;
|
||||
};
|
||||
|
||||
} // namespace interpreter
|
||||
|
@ -90,13 +90,16 @@ void BlockBuilder::EndBlock() {
|
||||
LoopBuilder::~LoopBuilder() { DCHECK(continue_sites_.empty()); }
|
||||
|
||||
|
||||
void LoopBuilder::LoopHeader() {
|
||||
void LoopBuilder::LoopHeader(ZoneVector<BytecodeLabel>* additional_labels) {
|
||||
// Jumps from before the loop header into the loop violate ordering
|
||||
// requirements of bytecode basic blocks. The only entry into a loop
|
||||
// must be the loop header. Surely breaks is okay? Not if nested
|
||||
// and misplaced between the headers.
|
||||
DCHECK(break_sites_.empty() && continue_sites_.empty());
|
||||
builder()->Bind(&loop_header_);
|
||||
for (auto& label : *additional_labels) {
|
||||
builder()->Bind(loop_header_, &label);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -87,7 +87,7 @@ class LoopBuilder final : public BreakableControlFlowBuilder {
|
||||
continue_sites_(builder->zone()) {}
|
||||
~LoopBuilder();
|
||||
|
||||
void LoopHeader();
|
||||
void LoopHeader(ZoneVector<BytecodeLabel>* additional_labels);
|
||||
void Condition() { builder()->Bind(&condition_); }
|
||||
void Next() { builder()->Bind(&next_); }
|
||||
void JumpToHeader() { builder()->Jump(&loop_header_); }
|
||||
|
@ -13,9 +13,9 @@ ignition generators: yes
|
||||
snippet: "
|
||||
function* f() { }
|
||||
"
|
||||
frame size: 10
|
||||
frame size: 11
|
||||
parameter count: 1
|
||||
bytecode array length: 193
|
||||
bytecode array length: 197
|
||||
bytecodes: [
|
||||
B(Ldar), R(new_target),
|
||||
B(JumpIfUndefined), U8(12),
|
||||
@ -30,78 +30,80 @@ bytecodes: [
|
||||
B(Ldar), R(this),
|
||||
B(StaContextSlot), R(context), U8(4),
|
||||
B(StackCheck),
|
||||
B(Mov), R(context), R(3),
|
||||
B(Mov), R(context), R(4),
|
||||
B(Ldar), R(closure),
|
||||
B(Star), R(4),
|
||||
B(Star), R(5),
|
||||
B(LdaContextSlot), R(context), U8(4),
|
||||
B(Star), R(5),
|
||||
B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(4), U8(2),
|
||||
B(StaContextSlot), R(context), U8(5),
|
||||
B(Star), R(4),
|
||||
B(LdaContextSlot), R(context), U8(5),
|
||||
B(Star), R(5),
|
||||
B(LdaZero),
|
||||
B(SuspendGenerator), R(5),
|
||||
B(Ldar), R(4),
|
||||
B(Return),
|
||||
B(CallRuntime), U16(Runtime::kGeneratorGetInput), R(5), U8(1),
|
||||
B(Star), R(6),
|
||||
B(CallRuntime), U16(Runtime::kGeneratorGetResumeMode), R(5), U8(1),
|
||||
B(Star), R(7),
|
||||
B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(5), U8(2),
|
||||
B(StaContextSlot), R(context), U8(5),
|
||||
B(Star), R(5),
|
||||
B(LdaContextSlot), R(context), U8(5),
|
||||
B(Star), R(6),
|
||||
B(LdaZero),
|
||||
B(TestEqualStrict), R(7),
|
||||
B(SuspendGenerator), R(6),
|
||||
B(Ldar), R(5),
|
||||
B(Return),
|
||||
B(LdaSmi), U8(-2),
|
||||
B(Star), R(1),
|
||||
B(CallRuntime), U16(Runtime::kGeneratorGetInput), R(6), U8(1),
|
||||
B(Star), R(7),
|
||||
B(CallRuntime), U16(Runtime::kGeneratorGetResumeMode), R(6), U8(1),
|
||||
B(Star), R(8),
|
||||
B(LdaZero),
|
||||
B(TestEqualStrict), R(8),
|
||||
B(JumpIfTrue), U8(31),
|
||||
B(LdaSmi), U8(2),
|
||||
B(TestEqualStrict), R(7),
|
||||
B(TestEqualStrict), R(8),
|
||||
B(JumpIfTrue), U8(22),
|
||||
B(Jump), U8(2),
|
||||
B(Mov), R(6), R(8),
|
||||
B(Mov), R(7), R(9),
|
||||
B(LdaTrue),
|
||||
B(Star), R(9),
|
||||
B(CallRuntime), U16(Runtime::kCreateIterResultObject), R(8), U8(2),
|
||||
B(Star), R(2),
|
||||
B(Star), R(10),
|
||||
B(CallRuntime), U16(Runtime::kCreateIterResultObject), R(9), U8(2),
|
||||
B(Star), R(3),
|
||||
B(LdaZero),
|
||||
B(Star), R(1),
|
||||
B(Jump), U8(38),
|
||||
B(Ldar), R(6),
|
||||
B(Throw),
|
||||
B(Ldar), R(6),
|
||||
B(LdaUndefined),
|
||||
B(Star), R(4),
|
||||
B(LdaTrue),
|
||||
B(Star), R(5),
|
||||
B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(4), U8(2),
|
||||
B(Star), R(2),
|
||||
B(Jump), U8(38),
|
||||
B(Ldar), R(7),
|
||||
B(Throw),
|
||||
B(Ldar), R(7),
|
||||
B(LdaUndefined),
|
||||
B(Star), R(5),
|
||||
B(LdaTrue),
|
||||
B(Star), R(6),
|
||||
B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(5), U8(2),
|
||||
B(Star), R(3),
|
||||
B(LdaSmi), U8(1),
|
||||
B(Star), R(1),
|
||||
B(Star), R(2),
|
||||
B(Jump), U8(14),
|
||||
B(LdaSmi), U8(-1),
|
||||
B(Star), R(1),
|
||||
B(Jump), U8(8),
|
||||
B(Star), R(2),
|
||||
B(LdaSmi), U8(2),
|
||||
B(Star), R(1),
|
||||
B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
|
||||
B(Jump), U8(8),
|
||||
B(Star), R(3),
|
||||
B(LdaContextSlot), R(context), U8(5),
|
||||
B(LdaSmi), U8(2),
|
||||
B(Star), R(2),
|
||||
B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
|
||||
B(Star), R(4),
|
||||
B(CallRuntime), U16(Runtime::kGeneratorClose), R(4), U8(1),
|
||||
B(CallRuntime), U16(Runtime::kInterpreterSetPendingMessage), R(3), U8(1),
|
||||
B(LdaContextSlot), R(context), U8(5),
|
||||
B(Star), R(5),
|
||||
B(CallRuntime), U16(Runtime::kGeneratorClose), R(5), U8(1),
|
||||
B(CallRuntime), U16(Runtime::kInterpreterSetPendingMessage), R(4), U8(1),
|
||||
B(LdaZero),
|
||||
B(TestEqualStrict), R(1),
|
||||
B(TestEqualStrict), R(2),
|
||||
B(JumpIfTrue), U8(16),
|
||||
B(LdaSmi), U8(1),
|
||||
B(TestEqualStrict), R(1),
|
||||
B(TestEqualStrict), R(2),
|
||||
B(JumpIfTrue), U8(13),
|
||||
B(LdaSmi), U8(2),
|
||||
B(TestEqualStrict), R(1),
|
||||
B(TestEqualStrict), R(2),
|
||||
B(JumpIfTrue), U8(10),
|
||||
B(Jump), U8(11),
|
||||
B(Ldar), R(2),
|
||||
B(Ldar), R(3),
|
||||
B(Return),
|
||||
B(Ldar), R(2),
|
||||
B(Ldar), R(3),
|
||||
B(Return),
|
||||
B(Ldar), R(2),
|
||||
B(Ldar), R(3),
|
||||
B(ReThrow),
|
||||
B(LdaUndefined),
|
||||
B(Return),
|
||||
@ -109,16 +111,16 @@ bytecodes: [
|
||||
constant pool: [
|
||||
]
|
||||
handlers: [
|
||||
[30, 129, 135],
|
||||
[30, 133, 139],
|
||||
]
|
||||
|
||||
---
|
||||
snippet: "
|
||||
function* f() { yield 42 }
|
||||
"
|
||||
frame size: 10
|
||||
frame size: 11
|
||||
parameter count: 1
|
||||
bytecode array length: 285
|
||||
bytecode array length: 293
|
||||
bytecodes: [
|
||||
B(Ldar), R(new_target),
|
||||
B(JumpIfUndefined), U8(18),
|
||||
@ -129,141 +131,146 @@ bytecodes: [
|
||||
B(JumpIfTrue), U8(55),
|
||||
B(LdaSmi), U8(1),
|
||||
B(TestEqualStrict), R(1),
|
||||
B(JumpIfTrue), U8(125),
|
||||
B(JumpIfTrueConstant), U8(0),
|
||||
B(Illegal),
|
||||
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1),
|
||||
B(PushContext), R(0),
|
||||
B(Ldar), R(this),
|
||||
B(StaContextSlot), R(context), U8(4),
|
||||
B(StackCheck),
|
||||
B(Mov), R(context), R(3),
|
||||
B(Mov), R(context), R(4),
|
||||
B(Ldar), R(closure),
|
||||
B(Star), R(4),
|
||||
B(LdaContextSlot), R(context), U8(4),
|
||||
B(Star), R(5),
|
||||
B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(4), U8(2),
|
||||
B(LdaContextSlot), R(context), U8(4),
|
||||
B(Star), R(6),
|
||||
B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(5), U8(2),
|
||||
B(StaContextSlot), R(context), U8(5),
|
||||
B(Star), R(4),
|
||||
B(Star), R(5),
|
||||
B(LdaContextSlot), R(context), U8(5),
|
||||
B(Star), R(6),
|
||||
B(LdaZero),
|
||||
B(SuspendGenerator), R(6),
|
||||
B(Ldar), R(5),
|
||||
B(Return),
|
||||
B(LdaSmi), U8(-2),
|
||||
B(Star), R(1),
|
||||
B(CallRuntime), U16(Runtime::kGeneratorGetInput), R(6), U8(1),
|
||||
B(Star), R(7),
|
||||
B(CallRuntime), U16(Runtime::kGeneratorGetResumeMode), R(6), U8(1),
|
||||
B(Star), R(8),
|
||||
B(LdaZero),
|
||||
B(TestEqualStrict), R(8),
|
||||
B(JumpIfTrue), U8(31),
|
||||
B(LdaSmi), U8(2),
|
||||
B(TestEqualStrict), R(8),
|
||||
B(JumpIfTrue), U8(22),
|
||||
B(Jump), U8(2),
|
||||
B(Mov), R(7), R(9),
|
||||
B(LdaTrue),
|
||||
B(Star), R(10),
|
||||
B(CallRuntime), U16(Runtime::kCreateIterResultObject), R(9), U8(2),
|
||||
B(Star), R(3),
|
||||
B(LdaZero),
|
||||
B(Star), R(2),
|
||||
B(Jump), U8(119),
|
||||
B(Ldar), R(7),
|
||||
B(Throw),
|
||||
B(Ldar), R(7),
|
||||
B(LdaSmi), U8(42),
|
||||
B(Star), R(5),
|
||||
B(LdaFalse),
|
||||
B(Star), R(6),
|
||||
B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(5), U8(2),
|
||||
B(Star), R(7),
|
||||
B(LdaContextSlot), R(context), U8(5),
|
||||
B(Star), R(5),
|
||||
B(LdaZero),
|
||||
B(LdaSmi), U8(1),
|
||||
B(SuspendGenerator), R(5),
|
||||
B(Ldar), R(4),
|
||||
B(Ldar), R(7),
|
||||
B(Return),
|
||||
B(LdaSmi), U8(-2),
|
||||
B(Star), R(1),
|
||||
B(CallRuntime), U16(Runtime::kGeneratorGetInput), R(5), U8(1),
|
||||
B(Star), R(6),
|
||||
B(CallRuntime), U16(Runtime::kGeneratorGetResumeMode), R(5), U8(1),
|
||||
B(Star), R(7),
|
||||
B(Star), R(8),
|
||||
B(LdaZero),
|
||||
B(TestEqualStrict), R(7),
|
||||
B(JumpIfTrue), U8(31),
|
||||
B(LdaSmi), U8(2),
|
||||
B(TestEqualStrict), R(7),
|
||||
B(JumpIfTrue), U8(22),
|
||||
B(Jump), U8(2),
|
||||
B(Mov), R(6), R(8),
|
||||
B(LdaTrue),
|
||||
B(Star), R(9),
|
||||
B(CallRuntime), U16(Runtime::kCreateIterResultObject), R(8), U8(2),
|
||||
B(Star), R(2),
|
||||
B(LdaZero),
|
||||
B(Star), R(1),
|
||||
B(Jump), U8(115),
|
||||
B(Ldar), R(6),
|
||||
B(Throw),
|
||||
B(Ldar), R(6),
|
||||
B(LdaSmi), U8(42),
|
||||
B(Star), R(4),
|
||||
B(LdaFalse),
|
||||
B(Star), R(5),
|
||||
B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(4), U8(2),
|
||||
B(Star), R(6),
|
||||
B(LdaContextSlot), R(context), U8(5),
|
||||
B(Star), R(4),
|
||||
B(LdaSmi), U8(1),
|
||||
B(SuspendGenerator), R(4),
|
||||
B(Ldar), R(6),
|
||||
B(Return),
|
||||
B(CallRuntime), U16(Runtime::kGeneratorGetInput), R(4), U8(1),
|
||||
B(Star), R(5),
|
||||
B(CallRuntime), U16(Runtime::kGeneratorGetResumeMode), R(4), U8(1),
|
||||
B(Star), R(7),
|
||||
B(LdaZero),
|
||||
B(TestEqualStrict), R(7),
|
||||
B(TestEqualStrict), R(8),
|
||||
B(JumpIfTrue), U8(32),
|
||||
B(LdaSmi), U8(2),
|
||||
B(TestEqualStrict), R(7),
|
||||
B(TestEqualStrict), R(8),
|
||||
B(JumpIfTrue), U8(23),
|
||||
B(Jump), U8(2),
|
||||
B(Mov), R(5), R(8),
|
||||
B(Mov), R(6), R(9),
|
||||
B(LdaTrue),
|
||||
B(Star), R(9),
|
||||
B(CallRuntime), U16(Runtime::kCreateIterResultObject), R(8), U8(2),
|
||||
B(Star), R(2),
|
||||
B(Star), R(10),
|
||||
B(CallRuntime), U16(Runtime::kCreateIterResultObject), R(9), U8(2),
|
||||
B(Star), R(3),
|
||||
B(LdaSmi), U8(1),
|
||||
B(Star), R(1),
|
||||
B(Jump), U8(38),
|
||||
B(Ldar), R(5),
|
||||
B(Throw),
|
||||
B(Ldar), R(5),
|
||||
B(LdaUndefined),
|
||||
B(Star), R(4),
|
||||
B(LdaTrue),
|
||||
B(Star), R(5),
|
||||
B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(4), U8(2),
|
||||
B(Star), R(2),
|
||||
B(Jump), U8(38),
|
||||
B(Ldar), R(6),
|
||||
B(Throw),
|
||||
B(Ldar), R(6),
|
||||
B(LdaUndefined),
|
||||
B(Star), R(5),
|
||||
B(LdaTrue),
|
||||
B(Star), R(6),
|
||||
B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(5), U8(2),
|
||||
B(Star), R(3),
|
||||
B(LdaSmi), U8(2),
|
||||
B(Star), R(1),
|
||||
B(Star), R(2),
|
||||
B(Jump), U8(14),
|
||||
B(LdaSmi), U8(-1),
|
||||
B(Star), R(1),
|
||||
B(Jump), U8(8),
|
||||
B(Star), R(2),
|
||||
B(LdaSmi), U8(3),
|
||||
B(Star), R(1),
|
||||
B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
|
||||
B(Jump), U8(8),
|
||||
B(Star), R(3),
|
||||
B(LdaContextSlot), R(context), U8(5),
|
||||
B(LdaSmi), U8(3),
|
||||
B(Star), R(2),
|
||||
B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
|
||||
B(Star), R(4),
|
||||
B(CallRuntime), U16(Runtime::kGeneratorClose), R(4), U8(1),
|
||||
B(CallRuntime), U16(Runtime::kInterpreterSetPendingMessage), R(3), U8(1),
|
||||
B(LdaContextSlot), R(context), U8(5),
|
||||
B(Star), R(5),
|
||||
B(CallRuntime), U16(Runtime::kGeneratorClose), R(5), U8(1),
|
||||
B(CallRuntime), U16(Runtime::kInterpreterSetPendingMessage), R(4), U8(1),
|
||||
B(LdaZero),
|
||||
B(TestEqualStrict), R(1),
|
||||
B(TestEqualStrict), R(2),
|
||||
B(JumpIfTrue), U8(22),
|
||||
B(LdaSmi), U8(1),
|
||||
B(TestEqualStrict), R(1),
|
||||
B(TestEqualStrict), R(2),
|
||||
B(JumpIfTrue), U8(19),
|
||||
B(LdaSmi), U8(2),
|
||||
B(TestEqualStrict), R(1),
|
||||
B(TestEqualStrict), R(2),
|
||||
B(JumpIfTrue), U8(16),
|
||||
B(LdaSmi), U8(3),
|
||||
B(TestEqualStrict), R(1),
|
||||
B(TestEqualStrict), R(2),
|
||||
B(JumpIfTrue), U8(13),
|
||||
B(Jump), U8(14),
|
||||
B(Ldar), R(2),
|
||||
B(Ldar), R(3),
|
||||
B(Return),
|
||||
B(Ldar), R(2),
|
||||
B(Ldar), R(3),
|
||||
B(Return),
|
||||
B(Ldar), R(2),
|
||||
B(Ldar), R(3),
|
||||
B(Return),
|
||||
B(Ldar), R(2),
|
||||
B(Ldar), R(3),
|
||||
B(ReThrow),
|
||||
B(LdaUndefined),
|
||||
B(Return),
|
||||
]
|
||||
constant pool: [
|
||||
kInstanceTypeDontCare,
|
||||
]
|
||||
handlers: [
|
||||
[36, 212, 218],
|
||||
[36, 220, 226],
|
||||
]
|
||||
|
||||
---
|
||||
snippet: "
|
||||
function* f() { for (let x of [42]) yield x }
|
||||
"
|
||||
frame size: 16
|
||||
frame size: 17
|
||||
parameter count: 1
|
||||
bytecode array length: 773
|
||||
bytecode array length: 794
|
||||
bytecodes: [
|
||||
B(Ldar), R(new_target),
|
||||
B(JumpIfUndefined), U8(18),
|
||||
@ -274,54 +281,56 @@ bytecodes: [
|
||||
B(JumpIfTrue), U8(55),
|
||||
B(LdaSmi), U8(1),
|
||||
B(TestEqualStrict), R(3),
|
||||
B(JumpIfTrueConstant), U8(8),
|
||||
B(JumpIfTrueConstant), U8(3),
|
||||
B(Illegal),
|
||||
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1),
|
||||
B(PushContext), R(0),
|
||||
B(Ldar), R(this),
|
||||
B(StaContextSlot), R(context), U8(4),
|
||||
B(StackCheck),
|
||||
B(Mov), R(context), R(5),
|
||||
B(Mov), R(context), R(6),
|
||||
B(Ldar), R(closure),
|
||||
B(Star), R(6),
|
||||
B(Star), R(7),
|
||||
B(LdaContextSlot), R(context), U8(4),
|
||||
B(Star), R(7),
|
||||
B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(6), U8(2),
|
||||
B(StaContextSlot), R(context), U8(5),
|
||||
B(Star), R(6),
|
||||
B(LdaContextSlot), R(context), U8(5),
|
||||
B(Star), R(7),
|
||||
B(LdaZero),
|
||||
B(SuspendGenerator), R(7),
|
||||
B(Ldar), R(6),
|
||||
B(Return),
|
||||
B(CallRuntime), U16(Runtime::kGeneratorGetInput), R(7), U8(1),
|
||||
B(Star), R(8),
|
||||
B(CallRuntime), U16(Runtime::kGeneratorGetResumeMode), R(7), U8(1),
|
||||
B(Star), R(9),
|
||||
B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(7), U8(2),
|
||||
B(StaContextSlot), R(context), U8(5),
|
||||
B(Star), R(7),
|
||||
B(LdaContextSlot), R(context), U8(5),
|
||||
B(Star), R(8),
|
||||
B(LdaZero),
|
||||
B(TestEqualStrict), R(9),
|
||||
B(SuspendGenerator), R(8),
|
||||
B(Ldar), R(7),
|
||||
B(Return),
|
||||
B(LdaSmi), U8(-2),
|
||||
B(Star), R(3),
|
||||
B(CallRuntime), U16(Runtime::kGeneratorGetInput), R(8), U8(1),
|
||||
B(Star), R(9),
|
||||
B(CallRuntime), U16(Runtime::kGeneratorGetResumeMode), R(8), U8(1),
|
||||
B(Star), R(10),
|
||||
B(LdaZero),
|
||||
B(TestEqualStrict), R(10),
|
||||
B(JumpIfTrue), U8(31),
|
||||
B(LdaSmi), U8(2),
|
||||
B(TestEqualStrict), R(9),
|
||||
B(TestEqualStrict), R(10),
|
||||
B(JumpIfTrue), U8(22),
|
||||
B(Jump), U8(2),
|
||||
B(Mov), R(8), R(10),
|
||||
B(Mov), R(9), R(11),
|
||||
B(LdaTrue),
|
||||
B(Star), R(11),
|
||||
B(CallRuntime), U16(Runtime::kCreateIterResultObject), R(10), U8(2),
|
||||
B(Star), R(4),
|
||||
B(Star), R(12),
|
||||
B(CallRuntime), U16(Runtime::kCreateIterResultObject), R(11), U8(2),
|
||||
B(Star), R(5),
|
||||
B(LdaZero),
|
||||
B(Star), R(3),
|
||||
B(JumpConstant), U8(16),
|
||||
B(Ldar), R(8),
|
||||
B(Star), R(4),
|
||||
B(JumpConstant), U8(17),
|
||||
B(Ldar), R(9),
|
||||
B(Throw),
|
||||
B(Ldar), R(8),
|
||||
B(Ldar), R(9),
|
||||
B(LdaConstant), U8(0),
|
||||
B(Star), R(6),
|
||||
B(Ldar), R(closure),
|
||||
B(Star), R(7),
|
||||
B(CallRuntime), U16(Runtime::kPushBlockContext), R(6), U8(2),
|
||||
B(Ldar), R(closure),
|
||||
B(Star), R(8),
|
||||
B(CallRuntime), U16(Runtime::kPushBlockContext), R(7), U8(2),
|
||||
B(PushContext), R(1),
|
||||
B(LdaTheHole),
|
||||
B(StaContextSlot), R(context), U8(4),
|
||||
@ -329,45 +338,52 @@ bytecodes: [
|
||||
B(StaContextSlot), R(1), U8(10),
|
||||
B(LdaZero),
|
||||
B(StaContextSlot), R(1), U8(9),
|
||||
B(Mov), R(context), R(8),
|
||||
B(Mov), R(context), R(9),
|
||||
B(Mov), R(context), R(10),
|
||||
B(CreateArrayLiteral), U8(1), U8(0), U8(3),
|
||||
B(Star), R(11),
|
||||
B(LdaConstant), U8(2),
|
||||
B(KeyedLoadIC), R(11), U8(3),
|
||||
B(Star), R(10),
|
||||
B(Call), R(10), R(11), U8(1), U8(1),
|
||||
B(StaContextSlot), R(1), U8(7),
|
||||
B(LdaContextSlot), R(1), U8(7),
|
||||
B(Star), R(12),
|
||||
B(LoadIC), R(12), U8(3), U8(7),
|
||||
B(LdaConstant), U8(2),
|
||||
B(KeyedLoadIC), R(12), U8(3),
|
||||
B(Star), R(11),
|
||||
B(Call), R(11), R(12), U8(1), U8(5),
|
||||
B(Call), R(11), R(12), U8(1), U8(1),
|
||||
B(StaContextSlot), R(1), U8(7),
|
||||
B(LdaSmi), U8(-2),
|
||||
B(TestEqual), R(3),
|
||||
B(JumpIfTrue), U8(9),
|
||||
B(LdaSmi), U8(1),
|
||||
B(TestEqualStrict), R(3),
|
||||
B(JumpIfTrueConstant), U8(9),
|
||||
B(Illegal),
|
||||
B(LdaContextSlot), R(1), U8(7),
|
||||
B(Star), R(13),
|
||||
B(LoadIC), R(13), U8(4), U8(7),
|
||||
B(Star), R(12),
|
||||
B(Call), R(12), R(13), U8(1), U8(5),
|
||||
B(StaContextSlot), R(1), U8(8),
|
||||
B(Star), R(10),
|
||||
B(InvokeIntrinsic), U16(Runtime::k_IsJSReceiver), R(10), U8(1),
|
||||
B(Star), R(11),
|
||||
B(InvokeIntrinsic), U16(Runtime::k_IsJSReceiver), R(11), U8(1),
|
||||
B(LogicalNot),
|
||||
B(JumpIfFalse), U8(12),
|
||||
B(LdaContextSlot), R(1), U8(8),
|
||||
B(Star), R(10),
|
||||
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(10), U8(1),
|
||||
B(Star), R(11),
|
||||
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(11), U8(1),
|
||||
B(LdaContextSlot), R(1), U8(8),
|
||||
B(Star), R(10),
|
||||
B(LoadIC), R(10), U8(4), U8(9),
|
||||
B(JumpIfToBooleanTrueConstant), U8(9),
|
||||
B(Star), R(11),
|
||||
B(LoadIC), R(11), U8(5), U8(9),
|
||||
B(JumpIfToBooleanTrueConstant), U8(10),
|
||||
B(LdaSmi), U8(2),
|
||||
B(StaContextSlot), R(1), U8(9),
|
||||
B(LdaContextSlot), R(1), U8(8),
|
||||
B(Star), R(10),
|
||||
B(LoadIC), R(10), U8(5), U8(11),
|
||||
B(Star), R(11),
|
||||
B(LoadIC), R(11), U8(6), U8(11),
|
||||
B(StaContextSlot), R(1), U8(6),
|
||||
B(LdaContextSlot), R(1), U8(10),
|
||||
B(StackCheck),
|
||||
B(LdaConstant), U8(6),
|
||||
B(Star), R(10),
|
||||
B(Ldar), R(closure),
|
||||
B(LdaConstant), U8(7),
|
||||
B(Star), R(11),
|
||||
B(CallRuntime), U16(Runtime::kPushBlockContext), R(10), U8(2),
|
||||
B(Ldar), R(closure),
|
||||
B(Star), R(12),
|
||||
B(CallRuntime), U16(Runtime::kPushBlockContext), R(11), U8(2),
|
||||
B(PushContext), R(2),
|
||||
B(LdaTheHole),
|
||||
B(StaContextSlot), R(context), U8(4),
|
||||
@ -375,35 +391,37 @@ bytecodes: [
|
||||
B(StaContextSlot), R(context), U8(4),
|
||||
B(LdaContextSlot), R(context), U8(4),
|
||||
B(JumpIfNotHole), U8(11),
|
||||
B(LdaConstant), U8(7),
|
||||
B(Star), R(11),
|
||||
B(CallRuntime), U16(Runtime::kThrowReferenceError), R(11), U8(1),
|
||||
B(Star), R(10),
|
||||
B(LdaFalse),
|
||||
B(Star), R(11),
|
||||
B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(10), U8(2),
|
||||
B(LdaConstant), U8(8),
|
||||
B(Star), R(12),
|
||||
B(LdaContextSlot), R(1), U8(5),
|
||||
B(Star), R(10),
|
||||
B(LdaSmi), U8(1),
|
||||
B(SuspendGenerator), R(10),
|
||||
B(Ldar), R(12),
|
||||
B(Return),
|
||||
B(CallRuntime), U16(Runtime::kGeneratorGetInput), R(10), U8(1),
|
||||
B(CallRuntime), U16(Runtime::kThrowReferenceError), R(12), U8(1),
|
||||
B(Star), R(11),
|
||||
B(CallRuntime), U16(Runtime::kGeneratorGetResumeMode), R(10), U8(1),
|
||||
B(LdaFalse),
|
||||
B(Star), R(12),
|
||||
B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(11), U8(2),
|
||||
B(Star), R(13),
|
||||
B(LdaContextSlot), R(1), U8(5),
|
||||
B(Star), R(11),
|
||||
B(LdaSmi), U8(1),
|
||||
B(SuspendGenerator), R(11),
|
||||
B(Ldar), R(13),
|
||||
B(Return),
|
||||
B(LdaSmi), U8(-2),
|
||||
B(Star), R(3),
|
||||
B(CallRuntime), U16(Runtime::kGeneratorGetInput), R(11), U8(1),
|
||||
B(Star), R(12),
|
||||
B(CallRuntime), U16(Runtime::kGeneratorGetResumeMode), R(11), U8(1),
|
||||
B(Star), R(14),
|
||||
B(LdaZero),
|
||||
B(TestEqualStrict), R(13),
|
||||
B(TestEqualStrict), R(14),
|
||||
B(JumpIfTrue), U8(45),
|
||||
B(LdaSmi), U8(2),
|
||||
B(TestEqualStrict), R(13),
|
||||
B(TestEqualStrict), R(14),
|
||||
B(JumpIfTrue), U8(36),
|
||||
B(Jump), U8(2),
|
||||
B(Mov), R(11), R(14),
|
||||
B(Mov), R(12), R(15),
|
||||
B(LdaTrue),
|
||||
B(Star), R(15),
|
||||
B(CallRuntime), U16(Runtime::kCreateIterResultObject), R(14), U8(2),
|
||||
B(Star), R(16),
|
||||
B(CallRuntime), U16(Runtime::kCreateIterResultObject), R(15), U8(2),
|
||||
B(PopContext), R(2),
|
||||
B(PopContext), R(2),
|
||||
B(PopContext), R(2),
|
||||
@ -411,186 +429,186 @@ bytecodes: [
|
||||
B(PopContext), R(2),
|
||||
B(PopContext), R(2),
|
||||
B(PopContext), R(2),
|
||||
B(Star), R(7),
|
||||
B(Star), R(8),
|
||||
B(LdaZero),
|
||||
B(Star), R(6),
|
||||
B(Star), R(7),
|
||||
B(Jump), U8(78),
|
||||
B(Ldar), R(11),
|
||||
B(Ldar), R(12),
|
||||
B(Throw),
|
||||
B(Ldar), R(11),
|
||||
B(Ldar), R(12),
|
||||
B(PopContext), R(2),
|
||||
B(LdaZero),
|
||||
B(StaContextSlot), R(1), U8(9),
|
||||
B(Wide), B(Jump), U16(-205),
|
||||
B(Wide), B(Jump), U16(-222),
|
||||
B(Jump), U8(49),
|
||||
B(Star), R(11),
|
||||
B(LdaConstant), U8(10),
|
||||
B(Star), R(10),
|
||||
B(Ldar), R(closure),
|
||||
B(Star), R(12),
|
||||
B(CallRuntime), U16(Runtime::kPushCatchContext), R(10), U8(3),
|
||||
B(Star), R(9),
|
||||
B(LdaConstant), U8(11),
|
||||
B(Star), R(11),
|
||||
B(Ldar), R(closure),
|
||||
B(Star), R(13),
|
||||
B(CallRuntime), U16(Runtime::kPushCatchContext), R(11), U8(3),
|
||||
B(Star), R(10),
|
||||
B(PushContext), R(2),
|
||||
B(LdaContextSlot), R(1), U8(9),
|
||||
B(Star), R(10),
|
||||
B(Star), R(11),
|
||||
B(LdaSmi), U8(2),
|
||||
B(TestEqualStrict), R(10),
|
||||
B(TestEqualStrict), R(11),
|
||||
B(JumpIfFalse), U8(7),
|
||||
B(LdaSmi), U8(1),
|
||||
B(StaContextSlot), R(1), U8(9),
|
||||
B(LdaContextSlot), R(context), U8(4),
|
||||
B(Star), R(10),
|
||||
B(CallRuntime), U16(Runtime::kReThrow), R(10), U8(1),
|
||||
B(Star), R(11),
|
||||
B(CallRuntime), U16(Runtime::kReThrow), R(11), U8(1),
|
||||
B(PopContext), R(2),
|
||||
B(LdaSmi), U8(-1),
|
||||
B(Star), R(6),
|
||||
B(Jump), U8(8),
|
||||
B(Star), R(7),
|
||||
B(LdaSmi), U8(1),
|
||||
B(Star), R(6),
|
||||
B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
|
||||
B(Jump), U8(8),
|
||||
B(Star), R(8),
|
||||
B(LdaContextSlot), R(1), U8(9),
|
||||
B(LdaSmi), U8(1),
|
||||
B(Star), R(7),
|
||||
B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
|
||||
B(Star), R(9),
|
||||
B(LdaContextSlot), R(1), U8(9),
|
||||
B(Star), R(10),
|
||||
B(LdaZero),
|
||||
B(TestEqualStrict), R(9),
|
||||
B(TestEqualStrict), R(10),
|
||||
B(JumpIfTrue), U8(10),
|
||||
B(LdaContextSlot), R(1), U8(7),
|
||||
B(Star), R(9),
|
||||
B(Star), R(10),
|
||||
B(LdaUndefined),
|
||||
B(TestEqualStrict), R(9),
|
||||
B(TestEqualStrict), R(10),
|
||||
B(LogicalNot),
|
||||
B(JumpIfFalseConstant), U8(15),
|
||||
B(JumpIfFalseConstant), U8(16),
|
||||
B(LdaContextSlot), R(1), U8(7),
|
||||
B(Star), R(9),
|
||||
B(LoadIC), R(9), U8(11), U8(13),
|
||||
B(Star), R(10),
|
||||
B(LoadIC), R(10), U8(12), U8(13),
|
||||
B(StaContextSlot), R(1), U8(11),
|
||||
B(LdaContextSlot), R(1), U8(11),
|
||||
B(Star), R(9),
|
||||
B(Star), R(10),
|
||||
B(LdaNull),
|
||||
B(TestEqual), R(9),
|
||||
B(TestEqual), R(10),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(JumpConstant), U8(14),
|
||||
B(JumpConstant), U8(15),
|
||||
B(LdaContextSlot), R(1), U8(9),
|
||||
B(Star), R(9),
|
||||
B(Star), R(10),
|
||||
B(LdaSmi), U8(1),
|
||||
B(TestEqualStrict), R(9),
|
||||
B(TestEqualStrict), R(10),
|
||||
B(JumpIfFalse), U8(82),
|
||||
B(LdaContextSlot), R(1), U8(11),
|
||||
B(TypeOf),
|
||||
B(Star), R(9),
|
||||
B(LdaConstant), U8(12),
|
||||
B(TestEqualStrict), R(9),
|
||||
B(Star), R(10),
|
||||
B(LdaConstant), U8(13),
|
||||
B(TestEqualStrict), R(10),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(18),
|
||||
B(Wide), B(LdaSmi), U16(129),
|
||||
B(Star), R(9),
|
||||
B(LdaConstant), U8(13),
|
||||
B(Star), R(10),
|
||||
B(CallRuntime), U16(Runtime::kNewTypeError), R(9), U8(2),
|
||||
B(LdaConstant), U8(14),
|
||||
B(Star), R(11),
|
||||
B(CallRuntime), U16(Runtime::kNewTypeError), R(10), U8(2),
|
||||
B(Throw),
|
||||
B(Mov), R(context), R(9),
|
||||
B(Mov), R(context), R(10),
|
||||
B(LdaContextSlot), R(1), U8(11),
|
||||
B(Star), R(11),
|
||||
B(LdaContextSlot), R(1), U8(7),
|
||||
B(Star), R(12),
|
||||
B(CallRuntime), U16(Runtime::k_Call), R(11), U8(2),
|
||||
B(Jump), U8(30),
|
||||
B(Star), R(12),
|
||||
B(LdaConstant), U8(11),
|
||||
B(Star), R(11),
|
||||
B(Ldar), R(closure),
|
||||
B(Star), R(13),
|
||||
B(CallRuntime), U16(Runtime::kPushCatchContext), R(11), U8(3),
|
||||
B(Star), R(10),
|
||||
B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
|
||||
B(Ldar), R(10),
|
||||
B(PushContext), R(2),
|
||||
B(PopContext), R(2),
|
||||
B(Jump), U8(44),
|
||||
B(LdaContextSlot), R(1), U8(11),
|
||||
B(Star), R(10),
|
||||
B(LdaContextSlot), R(1), U8(7),
|
||||
B(Star), R(11),
|
||||
B(CallRuntime), U16(Runtime::k_Call), R(10), U8(2),
|
||||
B(Jump), U8(30),
|
||||
B(Star), R(11),
|
||||
B(LdaConstant), U8(10),
|
||||
B(Star), R(10),
|
||||
B(Ldar), R(closure),
|
||||
B(Star), R(12),
|
||||
B(CallRuntime), U16(Runtime::kPushCatchContext), R(10), U8(3),
|
||||
B(Star), R(9),
|
||||
B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
|
||||
B(Ldar), R(9),
|
||||
B(PushContext), R(2),
|
||||
B(PopContext), R(2),
|
||||
B(Jump), U8(44),
|
||||
B(LdaContextSlot), R(1), U8(11),
|
||||
B(Star), R(9),
|
||||
B(LdaContextSlot), R(1), U8(7),
|
||||
B(Star), R(10),
|
||||
B(CallRuntime), U16(Runtime::k_Call), R(9), U8(2),
|
||||
B(StaContextSlot), R(1), U8(12),
|
||||
B(LdaContextSlot), R(1), U8(12),
|
||||
B(Star), R(9),
|
||||
B(InvokeIntrinsic), U16(Runtime::k_IsJSReceiver), R(9), U8(1),
|
||||
B(Star), R(10),
|
||||
B(InvokeIntrinsic), U16(Runtime::k_IsJSReceiver), R(10), U8(1),
|
||||
B(JumpIfToBooleanFalse), U8(4),
|
||||
B(Jump), U8(12),
|
||||
B(LdaContextSlot), R(1), U8(12),
|
||||
B(Star), R(9),
|
||||
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(9), U8(1),
|
||||
B(CallRuntime), U16(Runtime::kInterpreterSetPendingMessage), R(8), U8(1),
|
||||
B(Star), R(10),
|
||||
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(10), U8(1),
|
||||
B(CallRuntime), U16(Runtime::kInterpreterSetPendingMessage), R(9), U8(1),
|
||||
B(LdaZero),
|
||||
B(TestEqualStrict), R(6),
|
||||
B(TestEqualStrict), R(7),
|
||||
B(JumpIfTrue), U8(10),
|
||||
B(LdaSmi), U8(1),
|
||||
B(TestEqualStrict), R(6),
|
||||
B(TestEqualStrict), R(7),
|
||||
B(JumpIfTrue), U8(18),
|
||||
B(Jump), U8(30),
|
||||
B(Ldar), R(7),
|
||||
B(Ldar), R(8),
|
||||
B(PopContext), R(1),
|
||||
B(PopContext), R(1),
|
||||
B(Star), R(4),
|
||||
B(Star), R(5),
|
||||
B(LdaSmi), U8(1),
|
||||
B(Star), R(3),
|
||||
B(Jump), U8(49),
|
||||
B(Ldar), R(7),
|
||||
B(PopContext), R(1),
|
||||
B(PopContext), R(1),
|
||||
B(Star), R(4),
|
||||
B(Jump), U8(49),
|
||||
B(Ldar), R(8),
|
||||
B(PopContext), R(1),
|
||||
B(PopContext), R(1),
|
||||
B(Star), R(5),
|
||||
B(LdaSmi), U8(2),
|
||||
B(Star), R(3),
|
||||
B(Star), R(4),
|
||||
B(Jump), U8(35),
|
||||
B(PopContext), R(1),
|
||||
B(LdaUndefined),
|
||||
B(Star), R(6),
|
||||
B(LdaTrue),
|
||||
B(Star), R(7),
|
||||
B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(6), U8(2),
|
||||
B(Star), R(4),
|
||||
B(LdaTrue),
|
||||
B(Star), R(8),
|
||||
B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(7), U8(2),
|
||||
B(Star), R(5),
|
||||
B(LdaSmi), U8(3),
|
||||
B(Star), R(3),
|
||||
B(Star), R(4),
|
||||
B(Jump), U8(14),
|
||||
B(LdaSmi), U8(-1),
|
||||
B(Star), R(3),
|
||||
B(Jump), U8(8),
|
||||
B(Star), R(4),
|
||||
B(LdaSmi), U8(4),
|
||||
B(Star), R(3),
|
||||
B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
|
||||
B(Jump), U8(8),
|
||||
B(Star), R(5),
|
||||
B(LdaContextSlot), R(context), U8(5),
|
||||
B(LdaSmi), U8(4),
|
||||
B(Star), R(4),
|
||||
B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
|
||||
B(Star), R(6),
|
||||
B(CallRuntime), U16(Runtime::kGeneratorClose), R(6), U8(1),
|
||||
B(CallRuntime), U16(Runtime::kInterpreterSetPendingMessage), R(5), U8(1),
|
||||
B(LdaContextSlot), R(context), U8(5),
|
||||
B(Star), R(7),
|
||||
B(CallRuntime), U16(Runtime::kGeneratorClose), R(7), U8(1),
|
||||
B(CallRuntime), U16(Runtime::kInterpreterSetPendingMessage), R(6), U8(1),
|
||||
B(LdaZero),
|
||||
B(TestEqualStrict), R(3),
|
||||
B(TestEqualStrict), R(4),
|
||||
B(JumpIfTrue), U8(28),
|
||||
B(LdaSmi), U8(1),
|
||||
B(TestEqualStrict), R(3),
|
||||
B(TestEqualStrict), R(4),
|
||||
B(JumpIfTrue), U8(25),
|
||||
B(LdaSmi), U8(2),
|
||||
B(TestEqualStrict), R(3),
|
||||
B(TestEqualStrict), R(4),
|
||||
B(JumpIfTrue), U8(22),
|
||||
B(LdaSmi), U8(3),
|
||||
B(TestEqualStrict), R(3),
|
||||
B(TestEqualStrict), R(4),
|
||||
B(JumpIfTrue), U8(19),
|
||||
B(LdaSmi), U8(4),
|
||||
B(TestEqualStrict), R(3),
|
||||
B(TestEqualStrict), R(4),
|
||||
B(JumpIfTrue), U8(16),
|
||||
B(Jump), U8(17),
|
||||
B(Ldar), R(4),
|
||||
B(Ldar), R(5),
|
||||
B(Return),
|
||||
B(Ldar), R(4),
|
||||
B(Ldar), R(5),
|
||||
B(Return),
|
||||
B(Ldar), R(4),
|
||||
B(Ldar), R(5),
|
||||
B(ReThrow),
|
||||
B(Ldar), R(4),
|
||||
B(Ldar), R(5),
|
||||
B(Return),
|
||||
B(Ldar), R(4),
|
||||
B(Ldar), R(5),
|
||||
B(ReThrow),
|
||||
B(LdaUndefined),
|
||||
B(Return),
|
||||
@ -599,6 +617,7 @@ constant pool: [
|
||||
InstanceType::FIXED_ARRAY_TYPE,
|
||||
InstanceType::FIXED_ARRAY_TYPE,
|
||||
InstanceType::SYMBOL_TYPE,
|
||||
kInstanceTypeDontCare,
|
||||
InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE,
|
||||
InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE,
|
||||
InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE,
|
||||
@ -615,9 +634,9 @@ constant pool: [
|
||||
kInstanceTypeDontCare,
|
||||
]
|
||||
handlers: [
|
||||
[36, 691, 697],
|
||||
[146, 427, 433],
|
||||
[149, 378, 380],
|
||||
[535, 550, 552],
|
||||
[36, 712, 718],
|
||||
[150, 448, 454],
|
||||
[153, 399, 401],
|
||||
[556, 571, 573],
|
||||
]
|
||||
|
||||
|
@ -575,3 +575,26 @@
|
||||
}
|
||||
assertEquals({value: undefined, done: true}, g.next());
|
||||
}
|
||||
|
||||
{
|
||||
function* foo() {
|
||||
for (let i = 0; i < 3; ++i) {
|
||||
let j = 0
|
||||
yield i;
|
||||
do {
|
||||
yield (i + 10);
|
||||
} while (++j < 2);
|
||||
}
|
||||
}
|
||||
g = foo();
|
||||
assertEquals({value: 0, done: false}, g.next());
|
||||
assertEquals({value: 10, done: false}, g.next());
|
||||
assertEquals({value: 10, done: false}, g.next());
|
||||
assertEquals({value: 1, done: false}, g.next());
|
||||
assertEquals({value: 11, done: false}, g.next());
|
||||
assertEquals({value: 11, done: false}, g.next());
|
||||
assertEquals({value: 2, done: false}, g.next());
|
||||
assertEquals({value: 12, done: false}, g.next());
|
||||
assertEquals({value: 12, done: false}, g.next());
|
||||
assertEquals({value: undefined, done: true}, g.next());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user