Commit b4a3af91 authored by Leszek Swirski's avatar Leszek Swirski Committed by Commit Bot

[ignition] Move for-of desugaring to bytecode

This removes the iteration protocol from the parser entirely, and opens
up future possibilities for more bytecodes implementing the various
functions of the protocol.

Change-Id: I316b8a92434d3b5f47927408a235ddaecd65d5bb
Reviewed-on: https://chromium-review.googlesource.com/c/1403125
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarAdam Klein <adamk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58795}
parent 09576a81
......@@ -244,17 +244,15 @@ template <class Subclass>
void AstTraversalVisitor<Subclass>::VisitForInStatement(ForInStatement* stmt) {
PROCESS_NODE(stmt);
RECURSE(Visit(stmt->each()));
RECURSE(Visit(stmt->enumerable()));
RECURSE(Visit(stmt->subject()));
RECURSE(Visit(stmt->body()));
}
template <class Subclass>
void AstTraversalVisitor<Subclass>::VisitForOfStatement(ForOfStatement* stmt) {
PROCESS_NODE(stmt);
RECURSE(Visit(stmt->assign_iterator()));
RECURSE(Visit(stmt->next_result()));
RECURSE(Visit(stmt->result_done()));
RECURSE(Visit(stmt->assign_each()));
RECURSE(Visit(stmt->each()));
RECURSE(Visit(stmt->subject()));
RECURSE(Visit(stmt->body()));
}
......@@ -532,12 +530,6 @@ void AstTraversalVisitor<Subclass>::VisitEmptyParentheses(
PROCESS_EXPRESSION(expr);
}
template <class Subclass>
void AstTraversalVisitor<Subclass>::VisitGetIterator(GetIterator* expr) {
PROCESS_EXPRESSION(expr);
RECURSE_EXPRESSION(Visit(expr->iterable()));
}
template <class Subclass>
void AstTraversalVisitor<Subclass>::VisitGetTemplateObject(
GetTemplateObject* expr) {
......
......@@ -89,7 +89,6 @@ namespace internal {
V(DoExpression) \
V(EmptyParentheses) \
V(FunctionLiteral) \
V(GetIterator) \
V(GetTemplateObject) \
V(ImportCallExpression) \
V(Literal) \
......@@ -619,7 +618,7 @@ class ForStatement final : public IterationStatement {
Statement* next_;
};
// Shared class for for-in and for-of statements.
class ForEachStatement : public IterationStatement {
public:
enum VisitMode {
......@@ -633,120 +632,55 @@ class ForEachStatement : public IterationStatement {
return mode == ITERATE ? "for-of" : "for-in";
}
protected:
ForEachStatement(ZonePtrList<const AstRawString>* labels,
ZonePtrList<const AstRawString>* own_labels, int pos,
NodeType type)
: IterationStatement(labels, own_labels, pos, type) {}
};
class ForInStatement final : public ForEachStatement {
public:
void Initialize(Expression* each, Expression* subject, Statement* body) {
ForEachStatement::Initialize(body);
IterationStatement::Initialize(body);
each_ = each;
subject_ = subject;
}
Expression* enumerable() const {
return subject();
}
Expression* each() const { return each_; }
Expression* subject() const { return subject_; }
enum ForInType { FAST_FOR_IN, SLOW_FOR_IN };
ForInType for_in_type() const { return ForInTypeField::decode(bit_field_); }
private:
protected:
friend class AstNodeFactory;
ForInStatement(ZonePtrList<const AstRawString>* labels,
ZonePtrList<const AstRawString>* own_labels, int pos)
: ForEachStatement(labels, own_labels, pos, kForInStatement),
ForEachStatement(ZonePtrList<const AstRawString>* labels,
ZonePtrList<const AstRawString>* own_labels, int pos,
NodeType type)
: IterationStatement(labels, own_labels, pos, type),
each_(nullptr),
subject_(nullptr) {
bit_field_ = ForInTypeField::update(bit_field_, SLOW_FOR_IN);
}
subject_(nullptr) {}
Expression* each_;
Expression* subject_;
class ForInTypeField
: public BitField<ForInType, ForEachStatement::kNextBitFieldIndex, 1> {};
};
class ForInStatement final : public ForEachStatement {
private:
friend class AstNodeFactory;
ForInStatement(ZonePtrList<const AstRawString>* labels,
ZonePtrList<const AstRawString>* own_labels, int pos)
: ForEachStatement(labels, own_labels, pos, kForInStatement) {}
};
enum class IteratorType { kNormal, kAsync };
class ForOfStatement final : public ForEachStatement {
public:
void Initialize(Statement* body, Variable* iterator,
Expression* assign_iterator, Expression* assign_next,
Expression* next_result, Expression* result_done,
Expression* assign_each) {
ForEachStatement::Initialize(body);
iterator_ = iterator;
assign_iterator_ = assign_iterator;
assign_next_ = assign_next;
next_result_ = next_result;
result_done_ = result_done;
assign_each_ = assign_each;
}
Variable* iterator() const {
return iterator_;
}
// iterator = subject[Symbol.iterator]()
Expression* assign_iterator() const {
return assign_iterator_;
}
// iteratorRecord.next = iterator.next
Expression* assign_next() const { return assign_next_; }
// result = iterator.next() // with type check
Expression* next_result() const {
return next_result_;
}
// result.done
Expression* result_done() const {
return result_done_;
}
// each = result.value
Expression* assign_each() const {
return assign_each_;
}
void set_assign_iterator(Expression* e) { assign_iterator_ = e; }
void set_assign_next(Expression* e) { assign_next_ = e; }
void set_next_result(Expression* e) { next_result_ = e; }
void set_result_done(Expression* e) { result_done_ = e; }
void set_assign_each(Expression* e) { assign_each_ = e; }
IteratorType type() const { return type_; }
private:
friend class AstNodeFactory;
ForOfStatement(ZonePtrList<const AstRawString>* labels,
ZonePtrList<const AstRawString>* own_labels, int pos)
ZonePtrList<const AstRawString>* own_labels, int pos,
IteratorType type)
: ForEachStatement(labels, own_labels, pos, kForOfStatement),
iterator_(nullptr),
assign_iterator_(nullptr),
next_result_(nullptr),
result_done_(nullptr),
assign_each_(nullptr) {}
type_(type) {}
Variable* iterator_;
Expression* assign_iterator_;
Expression* assign_next_;
Expression* next_result_;
Expression* result_done_;
Expression* assign_each_;
IteratorType type_;
};
class ExpressionStatement final : public Statement {
public:
void set_expression(Expression* e) { expression_ = e; }
......@@ -2719,27 +2653,6 @@ class EmptyParentheses final : public Expression {
}
};
// Represents the spec operation `GetIterator()`
// (defined at https://tc39.github.io/ecma262/#sec-getiterator). Ignition
// desugars this into a LoadIC / JSLoadNamed, CallIC, and a type-check to
// validate return value of the Symbol.iterator() call.
enum class IteratorType { kNormal, kAsync };
class GetIterator final : public Expression {
public:
IteratorType hint() const { return hint_; }
Expression* iterable() const { return iterable_; }
private:
friend class AstNodeFactory;
GetIterator(Expression* iterable, IteratorType hint, int pos)
: Expression(pos, kGetIterator), hint_(hint), iterable_(iterable) {}
IteratorType hint_;
Expression* iterable_;
};
// Represents the spec operation `GetTemplateObject(templateLiteral)`
// (defined at https://tc39.github.io/ecma262/#sec-gettemplateobject).
class GetTemplateObject final : public Expression {
......@@ -2957,7 +2870,8 @@ class AstNodeFactory final {
return new (zone_) ForInStatement(labels, own_labels, pos);
}
case ForEachStatement::ITERATE: {
return new (zone_) ForOfStatement(labels, own_labels, pos);
return new (zone_)
ForOfStatement(labels, own_labels, pos, IteratorType::kNormal);
}
}
UNREACHABLE();
......@@ -2965,8 +2879,8 @@ class AstNodeFactory final {
ForOfStatement* NewForOfStatement(ZonePtrList<const AstRawString>* labels,
ZonePtrList<const AstRawString>* own_labels,
int pos) {
return new (zone_) ForOfStatement(labels, own_labels, pos);
int pos, IteratorType type) {
return new (zone_) ForOfStatement(labels, own_labels, pos, type);
}
ExpressionStatement* NewExpressionStatement(Expression* expression, int pos) {
......@@ -3377,11 +3291,6 @@ class AstNodeFactory final {
return new (zone_) EmptyParentheses(pos);
}
GetIterator* NewGetIterator(Expression* iterable, IteratorType hint,
int pos) {
return new (zone_) GetIterator(iterable, hint, pos);
}
GetTemplateObject* NewGetTemplateObject(
const ZonePtrList<const AstRawString>* cooked_strings,
const ZonePtrList<const AstRawString>* raw_strings, int pos) {
......
......@@ -161,16 +161,30 @@ void CallPrinter::VisitForStatement(ForStatement* node) {
void CallPrinter::VisitForInStatement(ForInStatement* node) {
Find(node->each());
Find(node->enumerable());
Find(node->subject());
Find(node->body());
}
void CallPrinter::VisitForOfStatement(ForOfStatement* node) {
Find(node->assign_iterator());
Find(node->next_result());
Find(node->result_done());
Find(node->assign_each());
Find(node->each());
// Check the subject's position in case there was a GetIterator error.
bool was_found = false;
if (node->subject()->position() == position_) {
is_async_iterator_error_ = node->type() == IteratorType::kAsync;
is_iterator_error_ = !is_async_iterator_error_;
was_found = !found_;
if (was_found) {
found_ = true;
}
}
Find(node->subject(), true);
if (was_found) {
done_ = true;
found_ = false;
}
Find(node->body());
}
......@@ -472,23 +486,6 @@ void CallPrinter::VisitEmptyParentheses(EmptyParentheses* node) {
UNREACHABLE();
}
void CallPrinter::VisitGetIterator(GetIterator* node) {
bool was_found = false;
if (node->position() == position_) {
is_async_iterator_error_ = node->hint() == IteratorType::kAsync;
is_iterator_error_ = !is_async_iterator_error_;
was_found = !found_;
if (was_found) {
found_ = true;
}
}
Find(node->iterable(), true);
if (was_found) {
done_ = true;
found_ = false;
}
}
void CallPrinter::VisitGetTemplateObject(GetTemplateObject* node) {}
void CallPrinter::VisitTemplateLiteral(TemplateLiteral* node) {
......@@ -969,7 +966,7 @@ void AstPrinter::VisitForInStatement(ForInStatement* node) {
PrintLabelsIndented(node->labels());
PrintLabelsIndented(node->own_labels(), "OWN ");
PrintIndentedVisit("FOR", node->each());
PrintIndentedVisit("IN", node->enumerable());
PrintIndentedVisit("IN", node->subject());
PrintIndentedVisit("BODY", node->body());
}
......@@ -978,10 +975,17 @@ void AstPrinter::VisitForOfStatement(ForOfStatement* node) {
IndentedScope indent(this, "FOR OF", node->position());
PrintLabelsIndented(node->labels());
PrintLabelsIndented(node->own_labels(), "OWN ");
PrintIndentedVisit("INIT", node->assign_iterator());
PrintIndentedVisit("NEXT", node->next_result());
PrintIndentedVisit("DONE", node->result_done());
PrintIndentedVisit("EACH", node->assign_each());
const char* for_type;
switch (node->type()) {
case IteratorType::kNormal:
for_type = "FOR";
break;
case IteratorType::kAsync:
for_type = "FOR AWAIT";
break;
}
PrintIndentedVisit(for_type, node->each());
PrintIndentedVisit("OF", node->subject());
PrintIndentedVisit("BODY", node->body());
}
......@@ -1361,11 +1365,6 @@ void AstPrinter::VisitEmptyParentheses(EmptyParentheses* node) {
IndentedScope indent(this, "()", node->position());
}
void AstPrinter::VisitGetIterator(GetIterator* node) {
IndentedScope indent(this, "GET-ITERATOR", node->position());
Visit(node->iterable());
}
void AstPrinter::VisitGetTemplateObject(GetTemplateObject* node) {
IndentedScope indent(this, "GET-TEMPLATE-OBJECT", node->position());
}
......
This diff is collapsed.
......@@ -62,6 +62,7 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
class IteratorRecord;
class NaryCodeCoverageSlots;
class RegisterAllocationScope;
class AccumulatorPreservingScope;
class TestResultScope;
class ValueResultScope;
......@@ -69,6 +70,7 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
enum class TestFallthrough { kThen, kElse, kNone };
enum class TypeHint { kAny, kBoolean, kString };
enum class AccumulatorPreservingMode { kNone, kPreserve };
// An assignment has to evaluate its LHS before its RHS, but has to assign to
// the LHS after both evaluations are done. This class stores the data
......@@ -195,7 +197,9 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
void VisitPropertyLoadForRegister(Register obj, Property* expr,
Register destination);
AssignmentLhsData PrepareAssignmentLhs(Expression* lhs);
AssignmentLhsData PrepareAssignmentLhs(
Expression* lhs, AccumulatorPreservingMode accumulator_preserving_mode =
AccumulatorPreservingMode::kNone);
void BuildAssignment(const AssignmentLhsData& data, Token::Value op,
LookupHoistingMode lookup_hoisting_mode);
......@@ -241,8 +245,9 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
void BuildNewLocalWithContext(Scope* scope);
void BuildGeneratorPrologue();
void BuildSuspendPoint(Expression* suspend_expr);
void BuildSuspendPoint(int position);
void BuildAwait(int position = kNoSourcePosition);
void BuildAwait(Expression* await_expr);
void BuildFinalizeIteration(IteratorRecord iterator, Register done,
......@@ -339,6 +344,12 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
void BuildTest(ToBooleanMode mode, BytecodeLabels* then_labels,
BytecodeLabels* else_labels, TestFallthrough fallthrough);
template <typename TryBodyFunc, typename FinallyBodyFunc>
void BuildTryFinally(TryBodyFunc try_body_func,
FinallyBodyFunc finally_body_func,
HandlerTable::CatchPrediction catch_prediction,
TryFinallyStatement* stmt_for_coverage = nullptr);
// Visitors for obtaining expression result in the accumulator, in a
// register, or just getting the effect. Some visitors return a TypeHint which
// specifies the type of the result of the visited expression.
......
......@@ -5405,14 +5405,13 @@ ParserBase<Impl>::ParseForEachStatementWithDeclarations(
}
}
StatementT final_loop = impl()->InitializeForEachStatement(
loop, each_variable, enumerable, body_block);
loop->Initialize(each_variable, enumerable, body_block);
init_block = impl()->CreateForEachStatementTDZ(init_block, *for_info);
// Parsed for-in loop w/ variable declarations.
if (!impl()->IsNull(init_block)) {
init_block->statements()->Add(final_loop, zone());
init_block->statements()->Add(loop, zone());
if (IsLexicalVariableMode(for_info->parsing_result.descriptor.mode)) {
scope()->set_end_position(end_position());
init_block->set_scope(scope()->FinalizeBlockScope());
......@@ -5420,7 +5419,7 @@ ParserBase<Impl>::ParseForEachStatementWithDeclarations(
return init_block;
}
return final_loop;
return loop;
}
template <typename Impl>
......@@ -5451,7 +5450,8 @@ ParserBase<Impl>::ParseForEachStatementWithoutDeclarations(
}
impl()->RecordIterationStatementSourceRange(loop, body_range);
RETURN_IF_PARSE_ERROR;
return impl()->InitializeForEachStatement(loop, expression, enumerable, body);
loop->Initialize(expression, enumerable, body);
return loop;
}
template <typename Impl>
......@@ -5563,7 +5563,12 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForAwaitStatement(
scope()->set_start_position(scanner()->location().beg_pos);
scope()->set_is_hidden();
auto loop = factory()->NewForOfStatement(labels, own_labels, stmt_pos);
auto loop = factory()->NewForOfStatement(labels, own_labels, stmt_pos,
IteratorType::kAsync);
// Two suspends: one for next() and one for return()
function_state_->AddSuspend();
function_state_->AddSuspend();
TargetT target(this, loop);
ExpressionT each_variable = impl()->NullExpression();
......@@ -5620,7 +5625,6 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForAwaitStatement(
}
ExpectContextualKeyword(ast_value_factory()->of_string());
int each_keyword_pos = scanner()->location().beg_pos;
const bool kAllowIn = true;
ExpressionT iterable = impl()->NullExpression();
......@@ -5658,16 +5662,14 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForAwaitStatement(
USE(block_scope);
}
}
const bool finalize = true;
StatementT final_loop = impl()->InitializeForOfStatement(
loop, each_variable, iterable, body, finalize, IteratorType::kAsync,
each_keyword_pos);
loop->Initialize(each_variable, iterable, body);
if (!has_declarations) {
Scope* for_scope = scope()->FinalizeBlockScope();
DCHECK_NULL(for_scope);
USE(for_scope);
return final_loop;
return loop;
}
BlockT init_block =
......@@ -5677,12 +5679,12 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForAwaitStatement(
Scope* for_scope = scope()->FinalizeBlockScope();
// Parsed for-in loop w/ variable declarations.
if (!impl()->IsNull(init_block)) {
init_block->statements()->Add(final_loop, zone());
init_block->statements()->Add(loop, zone());
init_block->set_scope(for_scope);
return init_block;
}
DCHECK_NULL(for_scope);
return final_loop;
return loop;
}
template <typename Impl>
......
This diff is collapsed.
......@@ -378,26 +378,6 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
const DeclarationParsingResult::Declaration* declaration,
ZonePtrList<const AstRawString>* names);
// [if (IteratorType == kAsync)]
// !%_IsJSReceiver(result = Await(next.[[Call]](iterator, « »)) &&
// %ThrowIteratorResultNotAnObject(result)
// [else]
// !%_IsJSReceiver(result = next.[[Call]](iterator, « »)) &&
// %ThrowIteratorResultNotAnObject(result)
// [endif]
Expression* BuildIteratorNextResult(VariableProxy* iterator,
VariableProxy* next, Variable* result,
IteratorType type, int pos);
// Initialize the components of a for-in / for-of statement.
Statement* InitializeForEachStatement(ForEachStatement* stmt,
Expression* each, Expression* subject,
Statement* body);
Statement* InitializeForOfStatement(ForOfStatement* stmt, Expression* each,
Expression* iterable, Statement* body,
bool finalize, IteratorType type,
int next_result_pos = kNoSourcePosition);
Block* RewriteForVarInLegacy(const ForInfo& for_info);
void DesugarBindingInForEachStatement(ForInfo* for_info, Block** body_block,
Expression** each_variable);
......@@ -555,23 +535,14 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
Expression* BuildInitialYield(int pos, FunctionKind kind);
Assignment* BuildCreateJSGeneratorObject(int pos, FunctionKind kind);
Variable* AsyncGeneratorAwaitVariable();
// Generic AST generator for throwing errors from compiled code.
Expression* NewThrowError(Runtime::FunctionId function_id,
MessageTemplate message, const AstRawString* arg,
int pos);
void FinalizeIteratorUse(Variable* completion, Expression* condition,
Variable* iter, Block* iterator_use, Block* result,
IteratorType type);
Statement* FinalizeForOfStatement(ForOfStatement* loop, Variable* completion,
IteratorType type, int pos);
void BuildIteratorCloseForCompletion(ZonePtrList<Statement>* statements,
Variable* iterator,
Expression* completion,
IteratorType type);
Statement* CheckCallable(Variable* var, Expression* error, int pos);
void RewriteAsyncFunctionBody(ScopedPtrList<Statement>* body, Block* block,
......
......@@ -285,7 +285,6 @@ NOT_A_PATTERN(ForOfStatement)
NOT_A_PATTERN(ForStatement)
NOT_A_PATTERN(FunctionDeclaration)
NOT_A_PATTERN(FunctionLiteral)
NOT_A_PATTERN(GetIterator)
NOT_A_PATTERN(GetTemplateObject)
NOT_A_PATTERN(IfStatement)
NOT_A_PATTERN(ImportCallExpression)
......
......@@ -516,6 +516,9 @@ class PreParserStatement {
void Initialize(PreParserStatement init, const PreParserExpression& cond,
PreParserStatement next, PreParserStatement body,
const SourceRange& body_range = {}) {}
void Initialize(PreParserExpression each, const PreParserExpression& subject,
PreParserStatement body, const SourceRange& body_range = {}) {
}
protected:
enum Type {
......@@ -815,7 +818,7 @@ class PreParserFactory {
PreParserStatement NewForOfStatement(
ZonePtrList<const AstRawString>* labels,
ZonePtrList<const AstRawString>* own_labels, int pos) {
ZonePtrList<const AstRawString>* own_labels, int pos, IteratorType type) {
return PreParserStatement::Default();
}
......@@ -1408,20 +1411,6 @@ class PreParser : public ParserBase<PreParser> {
return PreParserStatement::Default();
}
V8_INLINE PreParserStatement InitializeForEachStatement(
PreParserStatement stmt, const PreParserExpression& each,
const PreParserExpression& subject, PreParserStatement body) {
return stmt;
}
V8_INLINE PreParserStatement InitializeForOfStatement(
PreParserStatement stmt, const PreParserExpression& each,
const PreParserExpression& iterable, PreParserStatement body,
bool finalize, IteratorType type,
int next_result_pos = kNoSourcePosition) {
return stmt;
}
V8_INLINE PreParserBlock RewriteForVarInLegacy(const ForInfo& for_info) {
return PreParserBlock::Null();
}
......
......@@ -167,7 +167,7 @@ bytecodes: [
B(JumpIfUndefined), U8(41),
B(Star), R(6),
B(Ldar), R(6),
/* 67 E> */ B(StaNamedProperty), R(0), U8(2), U8(3),
/* 68 E> */ B(StaNamedProperty), R(0), U8(2), U8(3),
/* 62 E> */ B(StackCheck),
/* 100 S> */ B(LdaNamedProperty), R(0), U8(2), U8(5),
B(Star), R(6),
......@@ -223,7 +223,7 @@ bytecodes: [
B(LdaZero),
B(Star), R(8),
B(Ldar), R(6),
/* 64 E> */ B(StaKeyedProperty), R(0), R(8), U8(3),
/* 65 E> */ B(StaKeyedProperty), R(0), R(8), U8(3),
/* 59 E> */ B(StackCheck),
/* 83 S> */ B(LdaSmi), I8(3),
/* 91 E> */ B(LdaKeyedProperty), R(0), U8(5),
......
......@@ -98,149 +98,121 @@ snippet: "
function* f() { for (let x of [42]) yield x }
f();
"
frame size: 17
frame size: 16
parameter count: 1
bytecode array length: 333
bytecode array length: 261
bytecodes: [
B(SwitchOnGeneratorState), R(2), U8(0), U8(2),
B(Mov), R(closure), R(11),
B(Mov), R(this), R(12),
B(InvokeIntrinsic), U8(Runtime::k_CreateJSGeneratorObject), R(11), U8(2),
B(Mov), R(closure), R(4),
B(Mov), R(this), R(5),
B(InvokeIntrinsic), U8(Runtime::k_CreateJSGeneratorObject), R(4), U8(2),
B(Star), R(2),
/* 11 E> */ B(StackCheck),
/* 11 E> */ B(SuspendGenerator), R(2), R(0), U8(11), U8(0),
B(ResumeGenerator), R(2), R(0), U8(11),
B(Star), R(11),
/* 11 E> */ B(SuspendGenerator), R(2), R(0), U8(4), U8(0),
B(ResumeGenerator), R(2), R(0), U8(4),
B(Star), R(4),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(2), U8(1),
B(SwitchOnSmiNoFeedback), U8(2), U8(2), I8(0),
B(Ldar), R(11),
B(Ldar), R(4),
/* 11 E> */ B(Throw),
B(Ldar), R(11),
B(Ldar), R(4),
/* 44 S> */ B(Return),
B(LdaZero),
B(Star), R(7),
B(Mov), R(context), R(13),
B(Mov), R(context), R(14),
/* 30 S> */ B(CreateArrayLiteral), U8(4), U8(0), U8(37),
B(Star), R(15),
B(LdaNamedProperty), R(15), U8(5), U8(1),
B(Star), R(16),
B(CallProperty0), R(16), R(15), U8(3),
B(Star), R(6),
B(LdaNamedProperty), R(6), U8(5), U8(1),
B(Star), R(7),
B(CallProperty0), R(7), R(6), U8(3),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(4),
/* 30 E> */ B(LdaNamedProperty), R(4), U8(6), U8(5),
B(Star), R(5),
/* 25 S> */ B(CallProperty0), R(5), R(4), U8(7),
B(Star), R(6),
/* 25 E> */ B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(6), U8(1),
B(ToBooleanLogicalNot),
B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(6), U8(1),
B(LdaNamedProperty), R(6), U8(7), U8(9),
B(JumpIfToBooleanTrue), U8(66),
B(LdaNamedProperty), R(6), U8(8), U8(11),
B(LdaNamedProperty), R(5), U8(6), U8(5),
B(Star), R(4),
B(LdaFalse),
B(Star), R(8),
B(LdaSmi), I8(2),
B(Star), R(7),
B(Mov), R(8), R(3),
B(Mov), R(context), R(11),
B(LdaTrue),
B(Star), R(8),
/* 25 S> */ B(CallProperty0), R(4), R(5), U8(7),
B(Star), R(12),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(12), U8(1),
B(LdaNamedProperty), R(12), U8(7), U8(9),
B(JumpIfToBooleanTrue), U8(64),
B(LdaNamedProperty), R(12), U8(8), U8(11),
B(Star), R(12),
B(LdaFalse),
B(Star), R(8),
B(Mov), R(12), R(3),
/* 16 E> */ B(StackCheck),
/* 25 S> */ B(Mov), R(3), R(0),
/* 36 S> */ B(LdaFalse),
B(Star), R(16),
B(Mov), R(0), R(15),
B(InvokeIntrinsic), U8(Runtime::k_CreateIterResultObject), R(15), U8(2),
/* 36 E> */ B(SuspendGenerator), R(2), R(0), U8(15), U8(1),
B(ResumeGenerator), R(2), R(0), U8(15),
B(Star), R(15),
B(Star), R(14),
B(Mov), R(0), R(13),
B(InvokeIntrinsic), U8(Runtime::k_CreateIterResultObject), R(13), U8(2),
/* 36 E> */ B(SuspendGenerator), R(2), R(0), U8(13), U8(1),
B(ResumeGenerator), R(2), R(0), U8(13),
B(Star), R(13),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(2), U8(1),
B(SwitchOnSmiNoFeedback), U8(9), U8(2), I8(0),
B(Ldar), R(15),
B(Ldar), R(13),
/* 36 E> */ B(Throw),
B(LdaSmi), I8(1),
B(Star), R(11),
B(Mov), R(15), R(12),
B(Jump), U8(54),
B(LdaZero),
B(Star), R(7),
B(JumpLoop), U8(85), I8(0),
B(Jump), U8(33),
B(Star), R(15),
B(CreateCatchContext), R(15), U8(11),
B(PushContext), R(15),
B(Star), R(14),
B(LdaSmi), I8(2),
B(TestEqualStrict), R(7), U8(13),
B(JumpIfFalse), U8(6),
B(LdaSmi), I8(1),
B(Star), R(7),
B(LdaImmutableCurrentContextSlot), U8(4),
B(Star), R(16),
B(CallRuntime), U16(Runtime::kReThrow), R(16), U8(1),
B(PopContext), R(15),
B(Star), R(9),
B(Mov), R(13), R(10),
B(Jump), U8(20),
B(Ldar), R(13),
B(JumpLoop), U8(81), I8(0),
B(LdaSmi), I8(-1),
B(Star), R(12),
B(Star), R(11),
B(Star), R(10),
B(Star), R(9),
B(Jump), U8(7),
B(Star), R(12),
B(Star), R(10),
B(LdaZero),
B(Star), R(11),
B(Star), R(9),
B(LdaTheHole),
B(SetPendingMessage),
B(Star), R(11),
B(Ldar), R(8),
B(JumpIfToBooleanTrue), U8(60),
B(LdaNamedProperty), R(5), U8(11), U8(13),
B(Star), R(13),
B(LdaZero),
B(TestEqualStrict), R(7), U8(14),
B(JumpIfTrue), U8(90),
B(LdaNamedProperty), R(4), U8(12), U8(15),
B(Star), R(9),
B(TestUndetectable),
B(JumpIfFalse), U8(4),
B(Jump), U8(79),
B(LdaSmi), I8(1),
B(TestEqualStrict), R(7), U8(17),
B(JumpIfFalse), U8(47),
B(Ldar), R(9),
B(JumpIfUndefined), U8(52),
B(JumpIfNull), U8(50),
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(JumpIfTrue), U8(18),
B(Wide), B(LdaSmi), I16(154),
B(Star), R(14),
B(LdaConstant), U8(13),
B(LdaConstant), U8(12),
B(Star), R(15),
B(CallRuntime), U16(Runtime::kNewTypeError), R(14), U8(2),
B(Throw),
B(Mov), R(context), R(14),
B(Mov), R(9), R(15),
B(Mov), R(4), R(16),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(15), U8(2),
B(Jump), U8(6),
B(LdaTheHole),
B(SetPendingMessage),
B(CallProperty0), R(13), R(5), U8(15),
B(JumpIfJSReceiver), U8(21),
B(Star), R(15),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(15), U8(1),
B(Jump), U8(12),
B(Star), R(14),
B(LdaZero),
B(TestReferenceEqual), R(9),
B(JumpIfTrue), U8(5),
B(Ldar), R(14),
B(Jump), U8(27),
B(Mov), R(9), R(14),
B(Mov), R(4), R(15),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(14), U8(2),
B(Star), R(10),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(10), U8(1),
B(JumpIfToBooleanFalse), U8(4),
B(Jump), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(10), U8(1),
B(Ldar), R(13),
B(SetPendingMessage),
B(ReThrow),
B(Ldar), R(11),
B(SwitchOnSmiNoFeedback), U8(14), U8(2), I8(0),
B(SetPendingMessage),
B(Ldar), R(9),
B(SwitchOnSmiNoFeedback), U8(13), U8(2), I8(0),
B(Jump), U8(8),
B(Ldar), R(12),
B(Ldar), R(10),
B(ReThrow),
B(Ldar), R(12),
B(Ldar), R(10),
/* 44 S> */ B(Return),
B(LdaUndefined),
/* 44 S> */ B(Return),
]
constant pool: [
Smi [22],
Smi [138],
Smi [132],
Smi [10],
Smi [7],
ARRAY_BOILERPLATE_DESCRIPTION_TYPE,
......@@ -250,16 +222,14 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"],
Smi [16],
Smi [7],
SCOPE_INFO_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"],
ONE_BYTE_INTERNALIZED_STRING_TYPE [""],
Smi [6],
Smi [9],
]
handlers: [
[48, 203, 211],
[51, 170, 172],
[271, 281, 283],
[79, 163, 171],
[217, 230, 232],
]
---
......
This diff is collapsed.
......@@ -1752,7 +1752,7 @@ TEST(CodeSerializerLargeCodeObject) {
StaticCharVector("var j=1; if (j == 0) {"),
StaticCharVector(
"for (let i of Object.prototype) for (let k = 0; k < 0; ++k);"),
StaticCharVector("} j=7; j"), 1200);
StaticCharVector("} j=7; j"), 2000);
Handle<String> source_str =
isolate->factory()->NewStringFromOneByte(source).ToHandleChecked();
......
......@@ -4,7 +4,7 @@ Running test: testBasic
Debugger (test.js:10:2)
Basic (test.js:48:4)
-- async function --
Basic (test.js:47:19)
Basic (test.js:47:17)
(anonymous) (testBasic.js:0:0)
......@@ -26,7 +26,7 @@ Running test: testCaughtReject
Debugger (test.js:10:2)
CaughtReject (test.js:76:4)
-- async function --
CaughtReject (test.js:72:21)
CaughtReject (test.js:72:19)
(anonymous) (testCaughtReject.js:0:0)
......@@ -34,7 +34,7 @@ Running test: testCaughtThrow
Debugger (test.js:10:2)
CaughtThrow (test.js:86:4)
-- async function --
CaughtThrow (test.js:82:21)
CaughtThrow (test.js:82:19)
(anonymous) (testCaughtThrow.js:0:0)
......@@ -53,6 +53,6 @@ Running test: testCaughtThrowOnBreak
Debugger (test.js:10:2)
CaughtThrowOnBreak (test.js:124:4)
-- async function --
CaughtThrowOnBreak (test.js:120:21)
CaughtThrowOnBreak (test.js:120:19)
(anonymous) (testCaughtThrowOnBreak.js:0:0)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment