summaryrefslogtreecommitdiff
path: root/deps/v8/src/parsing/parser.cc
diff options
context:
space:
mode:
authorMichaël Zasso <targos@protonmail.com>2017-10-18 15:03:02 -0700
committerMichaël Zasso <targos@protonmail.com>2017-10-18 17:01:41 -0700
commit3d1b3df9486c0e7708065257f7311902f6b7b366 (patch)
treecb051bdeaead11e06dcd97725783e0f113afb1bf /deps/v8/src/parsing/parser.cc
parente2cddbb8ccdb7b3c4a40c8acc630f68703bc77b5 (diff)
downloadandroid-node-v8-3d1b3df9486c0e7708065257f7311902f6b7b366.tar.gz
android-node-v8-3d1b3df9486c0e7708065257f7311902f6b7b366.tar.bz2
android-node-v8-3d1b3df9486c0e7708065257f7311902f6b7b366.zip
deps: update V8 to 6.2.414.32
PR-URL: https://github.com/nodejs/node/pull/15362 Reviewed-By: Myles Borins <myles.borins@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Diffstat (limited to 'deps/v8/src/parsing/parser.cc')
-rw-r--r--deps/v8/src/parsing/parser.cc895
1 files changed, 146 insertions, 749 deletions
diff --git a/deps/v8/src/parsing/parser.cc b/deps/v8/src/parsing/parser.cc
index 3da659ebed..9915a18881 100644
--- a/deps/v8/src/parsing/parser.cc
+++ b/deps/v8/src/parsing/parser.cc
@@ -19,10 +19,9 @@
#include "src/messages.h"
#include "src/objects-inl.h"
#include "src/parsing/duplicate-finder.h"
-#include "src/parsing/parameter-initializer-rewriter.h"
+#include "src/parsing/expression-scope-reparenter.h"
#include "src/parsing/parse-info.h"
#include "src/parsing/rewriter.h"
-#include "src/parsing/scanner-character-streams.h"
#include "src/runtime/runtime.h"
#include "src/string-stream.h"
#include "src/tracing/trace-event.h"
@@ -478,7 +477,7 @@ Expression* Parser::NewV8Intrinsic(const AstRawString* name,
Parser::Parser(ParseInfo* info)
: ParserBase<Parser>(info->zone(), &scanner_, info->stack_limit(),
- info->extension(), info->ast_value_factory(),
+ info->extension(), info->GetOrCreateAstValueFactory(),
info->runtime_call_stats(), true),
scanner_(info->unicode_cache()),
reusable_preparser_(nullptr),
@@ -495,8 +494,7 @@ Parser::Parser(ParseInfo* info)
// Even though we were passed ParseInfo, we should not store it in
// Parser - this makes sure that Isolate is not accidentally accessed via
// ParseInfo during background parsing.
- DCHECK(!info->script().is_null() || info->source_stream() != nullptr ||
- info->character_stream() != nullptr);
+ DCHECK(info->character_stream() != nullptr);
// Determine if functions can be lazily compiled. This is necessary to
// allow some of our builtin JS files to be lazily compiled. These
// builtins cannot be handled lazily by the parser, since we have to know
@@ -529,14 +527,6 @@ Parser::Parser(ParseInfo* info)
++feature) {
use_counts_[feature] = 0;
}
- if (info->ast_value_factory() == NULL) {
- // info takes ownership of AstValueFactory.
- info->set_ast_value_factory(new AstValueFactory(
- zone(), info->ast_string_constants(), info->hash_seed()));
- info->set_ast_value_factory_owned();
- ast_value_factory_ = info->ast_value_factory();
- ast_node_factory_.set_ast_value_factory(ast_value_factory_);
- }
}
void Parser::DeserializeScopeChain(
@@ -558,6 +548,19 @@ void Parser::DeserializeScopeChain(
original_scope_ = scope;
}
+namespace {
+
+void MaybeResetCharacterStream(ParseInfo* info, FunctionLiteral* literal) {
+ // Don't reset the character stream if there is an asm.js module since it will
+ // be used again by the asm-parser.
+ if (!FLAG_stress_validate_asm &&
+ (literal == nullptr || !literal->scope()->ContainsAsmModule())) {
+ info->ResetCharacterStream();
+ }
+}
+
+} // namespace
+
FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) {
// TODO(bmeurer): We temporarily need to pass allow_nesting = true here,
// see comment for HistogramTimerScope class.
@@ -569,8 +572,6 @@ FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) {
runtime_call_stats_, info->is_eval() ? &RuntimeCallStats::ParseEval
: &RuntimeCallStats::ParseProgram);
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseProgram");
- Handle<String> source(String::cast(info->script()->source()));
- isolate->counters()->total_parse_size()->Increment(source->length());
base::ElapsedTimer timer;
if (FLAG_trace_parse) {
timer.Start();
@@ -592,33 +593,12 @@ FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) {
DeserializeScopeChain(info, info->maybe_outer_scope_info());
- source = String::Flatten(source);
- FunctionLiteral* result;
+ scanner_.Initialize(info->character_stream(), info->is_module());
+ FunctionLiteral* result = DoParseProgram(info);
+ MaybeResetCharacterStream(info, result);
- if (FLAG_use_parse_tasks) {
- source_ = source;
- compiler_dispatcher_ = isolate->compiler_dispatcher();
- main_parse_info_ = info;
- }
-
- {
- std::unique_ptr<Utf16CharacterStream> stream(ScannerStream::For(source));
- scanner_.Initialize(stream.get(), info->is_module());
- result = DoParseProgram(info);
- }
- if (result != NULL) {
- DCHECK_EQ(scanner_.peek_location().beg_pos, source->length());
- }
HandleSourceURLComments(isolate, info->script());
- if (FLAG_use_parse_tasks) {
- compiler_dispatcher_->FinishAllNow();
- StitchAst(info, isolate);
- source_ = Handle<String>();
- compiler_dispatcher_ = nullptr;
- main_parse_info_ = nullptr;
- }
-
if (FLAG_trace_parse && result != nullptr) {
double ms = timer.Elapsed().InMillisecondsF();
if (info->is_eval()) {
@@ -749,20 +729,18 @@ FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) {
return result;
}
-FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info) {
+FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info,
+ Handle<SharedFunctionInfo> shared_info) {
// It's OK to use the Isolate & counters here, since this function is only
// called in the main thread.
DCHECK(parsing_on_main_thread_);
RuntimeCallTimerScope runtime_timer(runtime_call_stats_,
&RuntimeCallStats::ParseFunction);
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseFunction");
- Handle<String> source(String::cast(info->script()->source()));
- isolate->counters()->total_parse_size()->Increment(source->length());
base::ElapsedTimer timer;
if (FLAG_trace_parse) {
timer.Start();
}
- Handle<SharedFunctionInfo> shared_info = info->shared_info();
DeserializeScopeChain(info, info->maybe_outer_scope_info());
if (info->asm_function_scope()) {
original_scope_ = info->asm_function_scope();
@@ -772,19 +750,15 @@ FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info) {
}
// Initialize parser state.
- source = String::Flatten(source);
- FunctionLiteral* result;
- {
- std::unique_ptr<Utf16CharacterStream> stream(ScannerStream::For(
- source, shared_info->start_position(), shared_info->end_position()));
- Handle<String> name(shared_info->name());
- scanner_.Initialize(stream.get(), info->is_module());
- info->set_function_name(ast_value_factory()->GetString(name));
- result = DoParseFunction(info);
- if (result != nullptr) {
- Handle<String> inferred_name(shared_info->inferred_name());
- result->set_inferred_name(inferred_name);
- }
+ Handle<String> name(shared_info->name());
+ info->set_function_name(ast_value_factory()->GetString(name));
+ scanner_.Initialize(info->character_stream(), info->is_module());
+
+ FunctionLiteral* result = DoParseFunction(info, info->function_name());
+ MaybeResetCharacterStream(info, result);
+ if (result != nullptr) {
+ Handle<String> inferred_name(shared_info->inferred_name());
+ result->set_inferred_name(inferred_name);
}
if (FLAG_trace_parse && result != NULL) {
@@ -809,25 +783,8 @@ static FunctionLiteral::FunctionType ComputeFunctionType(ParseInfo* info) {
return FunctionLiteral::kAnonymousExpression;
}
-FunctionLiteral* Parser::DoParseFunction(ParseInfo* info) {
- const AstRawString* raw_name = info->function_name();
- FunctionNameValidity function_name_validity = kSkipFunctionNameCheck;
- if (!raw_name) {
- bool ok = true;
- if (peek() == Token::LPAREN) {
- const AstRawString* variable_name;
- impl()->GetDefaultStrings(&raw_name, &variable_name);
- } else {
- bool is_strict_reserved = true;
- raw_name = ParseIdentifierOrStrictReservedWord(info->function_kind(),
- &is_strict_reserved, &ok);
- if (!ok) return nullptr;
- function_name_validity = is_strict_reserved
- ? kFunctionNameIsStrictReserved
- : kFunctionNameValidityUnknown;
- }
- }
-
+FunctionLiteral* Parser::DoParseFunction(ParseInfo* info,
+ const AstRawString* raw_name) {
DCHECK_NOT_NULL(raw_name);
DCHECK_NULL(scope_);
DCHECK_NULL(target_stack_);
@@ -949,7 +906,7 @@ FunctionLiteral* Parser::DoParseFunction(ParseInfo* info) {
info->start_position(), info->end_position());
} else {
result = ParseFunctionLiteral(
- raw_name, Scanner::Location::invalid(), function_name_validity, kind,
+ raw_name, Scanner::Location::invalid(), kSkipFunctionNameCheck, kind,
kNoSourcePosition, function_type, info->language_mode(), &ok);
}
// Make sure the results agree.
@@ -1432,8 +1389,13 @@ Declaration* Parser::DeclareVariable(const AstRawString* name,
DCHECK_NOT_NULL(name);
VariableProxy* proxy = factory()->NewVariableProxy(
name, NORMAL_VARIABLE, scanner()->location().beg_pos);
- Declaration* declaration =
- factory()->NewVariableDeclaration(proxy, this->scope(), pos);
+ Declaration* declaration;
+ if (mode == VAR && !scope()->is_declaration_scope()) {
+ DCHECK(scope()->is_block_scope() || scope()->is_with_scope());
+ declaration = factory()->NewNestedVariableDeclaration(proxy, scope(), pos);
+ } else {
+ declaration = factory()->NewVariableDeclaration(proxy, pos);
+ }
Declare(declaration, DeclarationDescriptor::NORMAL, mode, init, ok, nullptr,
scanner()->location().end_pos);
if (!*ok) return nullptr;
@@ -1459,11 +1421,11 @@ Variable* Parser::Declare(Declaration* declaration,
var_end_pos != kNoSourcePosition
? var_end_pos
: declaration->proxy()->position() + 1);
- if (declaration_kind == DeclarationDescriptor::NORMAL) {
+ if (declaration_kind == DeclarationDescriptor::PARAMETER) {
+ ReportMessageAt(loc, MessageTemplate::kParamDupe);
+ } else {
ReportMessageAt(loc, MessageTemplate::kVarRedeclaration,
declaration->proxy()->raw_name());
- } else {
- ReportMessageAt(loc, MessageTemplate::kParamDupe);
}
return nullptr;
}
@@ -1476,25 +1438,14 @@ Variable* Parser::Declare(Declaration* declaration,
Block* Parser::BuildInitializationBlock(
DeclarationParsingResult* parsing_result,
ZoneList<const AstRawString*>* names, bool* ok) {
- Block* result = factory()->NewBlock(
- NULL, 1, true, parsing_result->descriptor.declaration_pos);
+ Block* result = factory()->NewBlock(1, true);
for (auto declaration : parsing_result->declarations) {
- PatternRewriter::DeclareAndInitializeVariables(
- this, result, &(parsing_result->descriptor), &declaration, names,
- CHECK_OK);
+ DeclareAndInitializeVariables(result, &(parsing_result->descriptor),
+ &declaration, names, CHECK_OK);
}
return result;
}
-void Parser::DeclareAndInitializeVariables(
- Block* block, const DeclarationDescriptor* declaration_descriptor,
- const DeclarationParsingResult::Declaration* declaration,
- ZoneList<const AstRawString*>* names, bool* ok) {
- DCHECK_NOT_NULL(block);
- PatternRewriter::DeclareAndInitializeVariables(
- this, block, declaration_descriptor, declaration, names, ok);
-}
-
Statement* Parser::DeclareFunction(const AstRawString* variable_name,
FunctionLiteral* function, VariableMode mode,
int pos, bool is_sloppy_block_function,
@@ -1504,7 +1455,7 @@ Statement* Parser::DeclareFunction(const AstRawString* variable_name,
factory()->NewVariableProxy(variable_name, NORMAL_VARIABLE);
Declaration* declaration =
- factory()->NewFunctionDeclaration(proxy, function, scope(), pos);
+ factory()->NewFunctionDeclaration(proxy, function, pos);
Declare(declaration, DeclarationDescriptor::NORMAL, mode, kCreatedInitialized,
CHECK_OK);
if (names) names->Add(variable_name, zone());
@@ -1589,7 +1540,7 @@ bool Parser::ContainsLabel(ZoneList<const AstRawString*>* labels,
}
Block* Parser::IgnoreCompletion(Statement* statement) {
- Block* block = factory()->NewBlock(nullptr, 1, true, kNoSourcePosition);
+ Block* block = factory()->NewBlock(1, true);
block->statements()->Add(statement, zone());
return block;
}
@@ -1647,7 +1598,7 @@ Statement* Parser::RewriteSwitchStatement(Expression* tag,
// }
// }
- Block* switch_block = factory()->NewBlock(NULL, 2, false, kNoSourcePosition);
+ Block* switch_block = factory()->NewBlock(2, false);
Variable* tag_variable =
NewTemporary(ast_value_factory()->dot_switch_tag_string());
@@ -1668,7 +1619,7 @@ Statement* Parser::RewriteSwitchStatement(Expression* tag,
Expression* tag_read = factory()->NewVariableProxy(tag_variable);
switch_statement->Initialize(tag_read, cases);
- Block* cases_block = factory()->NewBlock(NULL, 1, false, kNoSourcePosition);
+ Block* cases_block = factory()->NewBlock(1, false);
cases_block->statements()->Add(switch_statement, zone());
cases_block->set_scope(scope);
DCHECK_IMPLIES(scope != nullptr,
@@ -1701,11 +1652,9 @@ void Parser::RewriteCatchPattern(CatchInfo* catch_info, bool* ok) {
catch_info->pattern, initializer_position,
factory()->NewVariableProxy(catch_variable));
- catch_info->init_block =
- factory()->NewBlock(nullptr, 8, true, kNoSourcePosition);
- PatternRewriter::DeclareAndInitializeVariables(
- this, catch_info->init_block, &descriptor, &decl,
- &catch_info->bound_names, ok);
+ catch_info->init_block = factory()->NewBlock(8, true);
+ DeclareAndInitializeVariables(catch_info->init_block, &descriptor, &decl,
+ &catch_info->bound_names, ok);
} else {
catch_info->bound_names.Add(catch_info->name, zone());
}
@@ -1748,7 +1697,7 @@ Statement* Parser::RewriteTryStatement(Block* try_block, Block* catch_block,
catch_block, kNoSourcePosition);
RecordTryCatchStatementSourceRange(statement, catch_range);
- try_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
+ try_block = factory()->NewBlock(1, false);
try_block->statements()->Add(statement, zone());
catch_block = nullptr; // Clear to indicate it's been handled.
}
@@ -1803,7 +1752,7 @@ void Parser::ParseAndRewriteAsyncGeneratorFunctionBody(
// "done" iterator result object containing a Promise-unwrapped value.
DCHECK(IsAsyncGeneratorFunction(kind));
- Block* try_block = factory()->NewBlock(nullptr, 3, false, kNoSourcePosition);
+ Block* try_block = factory()->NewBlock(3, false);
Expression* initial_yield = BuildInitialYield(pos, kind);
try_block->statements()->Add(
factory()->NewExpressionStatement(initial_yield, kNoSourcePosition),
@@ -1818,7 +1767,7 @@ void Parser::ParseAndRewriteAsyncGeneratorFunctionBody(
try_block->statements()->Add(final_return, zone());
// For AsyncGenerators, a top-level catch block will reject the Promise.
- Scope* catch_scope = NewHiddenCatchScopeWithParent(scope());
+ Scope* catch_scope = NewHiddenCatchScope();
ZoneList<Expression*>* reject_args =
new (zone()) ZoneList<Expression*>(2, zone());
@@ -1836,11 +1785,10 @@ void Parser::ParseAndRewriteAsyncGeneratorFunctionBody(
TryStatement* try_catch = factory()->NewTryCatchStatementForAsyncAwait(
try_block, catch_scope, catch_block, kNoSourcePosition);
- try_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
+ try_block = factory()->NewBlock(1, false);
try_block->statements()->Add(try_catch, zone());
- Block* finally_block =
- factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
+ Block* finally_block = factory()->NewBlock(1, false);
ZoneList<Expression*>* close_args =
new (zone()) ZoneList<Expression*>(1, zone());
VariableProxy* call_proxy = factory()->NewVariableProxy(
@@ -1937,11 +1885,10 @@ Statement* Parser::InitializeForEachStatement(ForEachStatement* stmt,
if (each->IsArrayLiteral() || each->IsObjectLiteral()) {
Variable* temp = NewTemporary(ast_value_factory()->empty_string());
VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
- Expression* assign_each = PatternRewriter::RewriteDestructuringAssignment(
- this, factory()->NewAssignment(Token::ASSIGN, each, temp_proxy,
- kNoSourcePosition),
- scope());
- auto block = factory()->NewBlock(nullptr, 2, false, kNoSourcePosition);
+ Expression* assign_each =
+ RewriteDestructuringAssignment(factory()->NewAssignment(
+ Token::ASSIGN, each, temp_proxy, kNoSourcePosition));
+ auto block = factory()->NewBlock(2, false);
block->statements()->Add(
factory()->NewExpressionStatement(assign_each, kNoSourcePosition),
zone());
@@ -1979,8 +1926,7 @@ Block* Parser::RewriteForVarInLegacy(const ForInfo& for_info) {
++use_counts_[v8::Isolate::kForInInitializer];
const AstRawString* name = decl.pattern->AsVariableProxy()->raw_name();
VariableProxy* single_var = NewUnresolved(name);
- Block* init_block = factory()->NewBlock(
- nullptr, 2, true, for_info.parsing_result.descriptor.declaration_pos);
+ Block* init_block = factory()->NewBlock(2, true);
init_block->statements()->Add(
factory()->NewExpressionStatement(
factory()->NewAssignment(Token::ASSIGN, single_var,
@@ -2014,14 +1960,12 @@ void Parser::DesugarBindingInForEachStatement(ForInfo* for_info,
DeclarationParsingResult::Declaration& decl =
for_info->parsing_result.declarations[0];
Variable* temp = NewTemporary(ast_value_factory()->dot_for_string());
- auto each_initialization_block =
- factory()->NewBlock(nullptr, 1, true, kNoSourcePosition);
+ auto each_initialization_block = factory()->NewBlock(1, true);
{
auto descriptor = for_info->parsing_result.descriptor;
descriptor.declaration_pos = kNoSourcePosition;
descriptor.initialization_pos = kNoSourcePosition;
descriptor.scope = scope();
- descriptor.declaration_kind = DeclarationDescriptor::LEXICAL_FOR_EACH;
decl.initializer = factory()->NewVariableProxy(temp);
bool is_for_var_of =
@@ -2031,8 +1975,8 @@ void Parser::DesugarBindingInForEachStatement(ForInfo* for_info,
IsLexicalVariableMode(for_info->parsing_result.descriptor.mode) ||
is_for_var_of;
- PatternRewriter::DeclareAndInitializeVariables(
- this, each_initialization_block, &descriptor, &decl,
+ DeclareAndInitializeVariables(
+ each_initialization_block, &descriptor, &decl,
collect_names ? &for_info->bound_names : nullptr, CHECK_OK_VOID);
// Annex B.3.5 prohibits the form
@@ -2061,7 +2005,7 @@ void Parser::DesugarBindingInForEachStatement(ForInfo* for_info,
}
}
- *body_block = factory()->NewBlock(nullptr, 3, false, kNoSourcePosition);
+ *body_block = factory()->NewBlock(3, false);
(*body_block)->statements()->Add(each_initialization_block, zone());
*each_variable = factory()->NewVariableProxy(temp, for_info->position);
}
@@ -2072,7 +2016,7 @@ Block* Parser::CreateForEachStatementTDZ(Block* init_block,
if (IsLexicalVariableMode(for_info.parsing_result.descriptor.mode)) {
DCHECK_NULL(init_block);
- init_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
+ init_block = factory()->NewBlock(1, false);
for (int i = 0; i < for_info.bound_names.length(); ++i) {
// TODO(adamk): This needs to be some sort of special
@@ -2143,32 +2087,21 @@ Statement* Parser::InitializeForOfStatement(
result_value = factory()->NewProperty(result_proxy, value_literal, nopos);
}
- // {{completion = kAbruptCompletion;}}
- Statement* set_completion_abrupt;
- if (finalize) {
- Expression* proxy = factory()->NewVariableProxy(completion);
- Expression* assignment = factory()->NewAssignment(
- Token::ASSIGN, proxy,
- factory()->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos);
-
- set_completion_abrupt =
- IgnoreCompletion(factory()->NewExpressionStatement(assignment, nopos));
- }
-
- // do { let tmp = #result_value; #set_completion_abrupt; tmp }
+ // {{tmp = #result_value, completion = kAbruptCompletion, tmp}}
// Expression* result_value (gets overwritten)
if (finalize) {
- Variable* var_tmp = NewTemporary(avfactory->empty_string());
- Expression* tmp = factory()->NewVariableProxy(var_tmp);
- Expression* assignment =
- factory()->NewAssignment(Token::ASSIGN, tmp, result_value, nopos);
+ Variable* tmp = NewTemporary(avfactory->empty_string());
+ Expression* save_result = factory()->NewAssignment(
+ Token::ASSIGN, factory()->NewVariableProxy(tmp), result_value, nopos);
- Block* block = factory()->NewBlock(nullptr, 2, false, nopos);
- block->statements()->Add(
- factory()->NewExpressionStatement(assignment, nopos), zone());
- block->statements()->Add(set_completion_abrupt, zone());
+ Expression* set_completion_abrupt = factory()->NewAssignment(
+ Token::ASSIGN, factory()->NewVariableProxy(completion),
+ factory()->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos);
- result_value = factory()->NewDoExpression(block, var_tmp, nopos);
+ result_value = factory()->NewBinaryOperation(Token::COMMA, save_result,
+ set_completion_abrupt, nopos);
+ result_value = factory()->NewBinaryOperation(
+ Token::COMMA, result_value, factory()->NewVariableProxy(tmp), nopos);
}
// each = #result_value;
@@ -2177,8 +2110,7 @@ Statement* Parser::InitializeForOfStatement(
assign_each =
factory()->NewAssignment(Token::ASSIGN, each, result_value, nopos);
if (each->IsArrayLiteral() || each->IsObjectLiteral()) {
- assign_each = PatternRewriter::RewriteDestructuringAssignment(
- this, assign_each->AsAssignment(), scope());
+ assign_each = RewriteDestructuringAssignment(assign_each->AsAssignment());
}
}
@@ -2197,7 +2129,7 @@ Statement* Parser::InitializeForOfStatement(
// { #loop-body; #set_completion_normal }
// Statement* body (gets overwritten)
if (finalize) {
- Block* block = factory()->NewBlock(nullptr, 2, false, nopos);
+ Block* block = factory()->NewBlock(2, false);
block->statements()->Add(body, zone());
block->statements()->Add(set_completion_normal, zone());
body = block;
@@ -2211,8 +2143,7 @@ Statement* Parser::InitializeForOfStatement(
Statement* Parser::DesugarLexicalBindingsInForStatement(
ForStatement* loop, Statement* init, Expression* cond, Statement* next,
- Statement* body, const SourceRange& body_range, Scope* inner_scope,
- const ForInfo& for_info, bool* ok) {
+ Statement* body, Scope* inner_scope, const ForInfo& for_info, bool* ok) {
// ES6 13.7.4.8 specifies that on each loop iteration the let variables are
// copied into a new environment. Moreover, the "next" statement must be
// evaluated not in the environment of the just completed iteration but in
@@ -2253,8 +2184,8 @@ Statement* Parser::DesugarLexicalBindingsInForStatement(
DCHECK(for_info.bound_names.length() > 0);
ZoneList<Variable*> temps(for_info.bound_names.length(), zone());
- Block* outer_block = factory()->NewBlock(
- nullptr, for_info.bound_names.length() + 4, false, kNoSourcePosition);
+ Block* outer_block =
+ factory()->NewBlock(for_info.bound_names.length() + 4, false);
// Add statement: let/const x = i.
outer_block->statements()->Add(init, zone());
@@ -2304,12 +2235,12 @@ Statement* Parser::DesugarLexicalBindingsInForStatement(
outer_block->statements()->Add(outer_loop, zone());
outer_block->set_scope(scope());
- Block* inner_block = factory()->NewBlock(NULL, 3, false, kNoSourcePosition);
+ Block* inner_block = factory()->NewBlock(3, false);
{
BlockState block_state(&scope_, inner_scope);
- Block* ignore_completion_block = factory()->NewBlock(
- nullptr, for_info.bound_names.length() + 3, true, kNoSourcePosition);
+ Block* ignore_completion_block =
+ factory()->NewBlock(for_info.bound_names.length() + 3, true);
ZoneList<Variable*> inner_vars(for_info.bound_names.length(), zone());
// For each let variable x:
// make statement: let/const x = temp_x.
@@ -2323,8 +2254,9 @@ Statement* Parser::DesugarLexicalBindingsInForStatement(
Token::INIT, decl->proxy(), temp_proxy, kNoSourcePosition);
Statement* assignment_statement =
factory()->NewExpressionStatement(assignment, kNoSourcePosition);
- DCHECK(init->position() != kNoSourcePosition);
- decl->proxy()->var()->set_initializer_position(init->position());
+ int declaration_pos = for_info.parsing_result.descriptor.declaration_pos;
+ DCHECK(declaration_pos != kNoSourcePosition);
+ decl->proxy()->var()->set_initializer_position(declaration_pos);
ignore_completion_block->statements()->Add(assignment_statement, zone());
}
@@ -2443,7 +2375,6 @@ Statement* Parser::DesugarLexicalBindingsInForStatement(
}
outer_loop->Initialize(NULL, NULL, NULL, inner_block);
- RecordIterationStatementSourceRange(outer_loop, body_range);
return outer_block;
}
@@ -2492,8 +2423,13 @@ void Parser::AddArrowFunctionFormalParameters(
Expression* initializer = nullptr;
if (expr->IsAssignment()) {
+ if (expr->IsRewritableExpression()) {
+ // This expression was parsed as a possible destructuring assignment.
+ // Mark it as already-rewritten to avoid an unnecessary visit later.
+ expr->AsRewritableExpression()->set_rewritten();
+ }
Assignment* assignment = expr->AsAssignment();
- DCHECK(!assignment->is_compound());
+ DCHECK(!assignment->IsCompoundAssignment());
initializer = assignment->value();
expr = assignment->target();
}
@@ -2607,16 +2543,12 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
DCHECK_IMPLIES(parse_lazily(), allow_lazy_);
DCHECK_IMPLIES(parse_lazily(), extension_ == nullptr);
- const bool source_is_external =
- !source_.is_null() && (source_->IsExternalTwoByteString() ||
- source_->IsExternalOneByteString());
const bool is_lazy =
eager_compile_hint == FunctionLiteral::kShouldLazyCompile;
const bool is_top_level =
impl()->AllowsLazyParsingWithoutUnresolvedVariables();
const bool is_lazy_top_level_function = is_lazy && is_top_level;
const bool is_lazy_inner_function = is_lazy && !is_top_level;
- const bool is_eager_top_level_function = !is_lazy && is_top_level;
const bool is_expression =
function_type == FunctionLiteral::kAnonymousExpression ||
function_type == FunctionLiteral::kNamedExpression;
@@ -2648,51 +2580,18 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
parse_lazily() && FLAG_lazy_inner_functions && is_lazy_inner_function &&
(!is_expression || FLAG_aggressive_lazy_inner_functions);
- bool should_use_parse_task =
- FLAG_use_parse_tasks && parse_lazily() && compiler_dispatcher_ &&
- is_eager_top_level_function && source_is_external;
-
// This may be modified later to reflect preparsing decision taken
- bool should_preparse = (parse_lazily() && (is_lazy_top_level_function ||
- should_use_parse_task)) ||
- should_preparse_inner;
+ bool should_preparse =
+ (parse_lazily() && is_lazy_top_level_function) || should_preparse_inner;
ZoneList<Statement*>* body = nullptr;
int expected_property_count = -1;
- bool should_be_used_once_hint = false;
int num_parameters = -1;
int function_length = -1;
bool has_duplicate_parameters = false;
int function_literal_id = GetNextFunctionLiteralId();
ProducedPreParsedScopeData* produced_preparsed_scope_data = nullptr;
- Expect(Token::LPAREN, CHECK_OK);
-
- if (should_use_parse_task) {
- int start_pos = scanner()->location().beg_pos;
- if (function_name_location.IsValid()) {
- start_pos = function_name_location.beg_pos;
- }
- // Warning!
- // Only sets fields in compiler_hints that are currently used.
- int compiler_hints = SharedFunctionInfo::FunctionKindBits::encode(kind);
- if (function_type == FunctionLiteral::kDeclaration) {
- compiler_hints |= SharedFunctionInfo::IsDeclarationBit::encode(true);
- }
- should_use_parse_task = compiler_dispatcher_->Enqueue(
- source_, start_pos, source_->length(), language_mode,
- function_literal_id, allow_natives(), parsing_module_,
- function_type == FunctionLiteral::kNamedExpression, compiler_hints,
- main_parse_info_, nullptr);
- if (V8_UNLIKELY(FLAG_trace_parse_tasks)) {
- PrintF("Spining off task for function at %d: %s\n", start_pos,
- should_use_parse_task ? "SUCCESS" : "FAILED");
- }
- if (!should_use_parse_task) {
- should_preparse = false;
- }
- }
-
Zone* outer_zone = zone();
DeclarationScope* scope;
@@ -2717,6 +2616,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
scope->SetScopeName(function_name);
if (should_preparse) scope->set_needs_migration();
#endif
+
+ Expect(Token::LPAREN, CHECK_OK);
scope->set_start_position(scanner()->location().beg_pos);
// Eager or lazy parse? If is_lazy_top_level_function, we'll parse
@@ -2726,8 +2627,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
// try to lazy parse in the first place, we'll have to parse eagerly.
if (should_preparse) {
DCHECK(parse_lazily());
- DCHECK(is_lazy_top_level_function || is_lazy_inner_function ||
- should_use_parse_task);
+ DCHECK(is_lazy_top_level_function || is_lazy_inner_function);
Scanner::BookmarkScope bookmark(scanner());
bookmark.Set();
LazyParsingResult result = SkipFunction(
@@ -2739,15 +2639,12 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
DCHECK(is_lazy_top_level_function);
bookmark.Apply();
// This is probably an initialization function. Inform the compiler it
- // should also eager-compile this function, and that we expect it to be
- // used once.
+ // should also eager-compile this function.
eager_compile_hint = FunctionLiteral::kShouldEagerCompile;
- should_be_used_once_hint = true;
scope->ResetAfterPreparsing(ast_value_factory(), true);
zone_scope.Reset();
// Trigger eager (re-)parsing, just below this block.
should_preparse = false;
- should_use_parse_task = false;
}
}
@@ -2808,12 +2705,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
function_name, scope, body, expected_property_count, num_parameters,
function_length, duplicate_parameters, function_type, eager_compile_hint,
pos, true, function_literal_id, produced_preparsed_scope_data);
- if (should_use_parse_task) {
- literals_to_stitch_.emplace_back(function_literal);
- }
function_literal->set_function_token_position(function_token_pos);
- if (should_be_used_once_hint)
- function_literal->set_should_be_used_once_hint();
if (should_infer_name) {
DCHECK_NOT_NULL(fni_);
@@ -2866,7 +2758,7 @@ Parser::LazyParsingResult Parser::SkipFunction(
// FIXME(marja): There are 3 ways to skip functions now. Unify them.
DCHECK_NOT_NULL(consumed_preparsed_scope_data_);
if (consumed_preparsed_scope_data_->HasData()) {
- DCHECK(FLAG_experimental_preparser_scope_analysis);
+ DCHECK(FLAG_preparser_scope_analysis);
int end_position;
LanguageMode language_mode;
int num_inner_functions;
@@ -2969,11 +2861,8 @@ Statement* Parser::BuildAssertIsCoercible(Variable* var,
class InitializerRewriter final
: public AstTraversalVisitor<InitializerRewriter> {
public:
- InitializerRewriter(uintptr_t stack_limit, Expression* root, Parser* parser,
- Scope* scope)
- : AstTraversalVisitor(stack_limit, root),
- parser_(parser),
- scope_(scope) {}
+ InitializerRewriter(uintptr_t stack_limit, Expression* root, Parser* parser)
+ : AstTraversalVisitor(stack_limit, root), parser_(parser) {}
private:
// This is required so that the overriden Visit* methods can be
@@ -2983,8 +2872,7 @@ class InitializerRewriter final
// Just rewrite destructuring assignments wrapped in RewritableExpressions.
void VisitRewritableExpression(RewritableExpression* to_rewrite) {
if (to_rewrite->is_rewritten()) return;
- Parser::PatternRewriter::RewriteDestructuringAssignment(parser_, to_rewrite,
- scope_);
+ parser_->RewriteDestructuringAssignment(to_rewrite);
AstTraversalVisitor::VisitRewritableExpression(to_rewrite);
}
@@ -2993,12 +2881,10 @@ class InitializerRewriter final
void VisitFunctionLiteral(FunctionLiteral* expr) {}
Parser* parser_;
- Scope* scope_;
};
-
-void Parser::RewriteParameterInitializer(Expression* expr, Scope* scope) {
- InitializerRewriter rewriter(stack_limit_, expr, this, scope);
+void Parser::RewriteParameterInitializer(Expression* expr) {
+ InitializerRewriter rewriter(stack_limit_, expr, this);
rewriter.Run();
}
@@ -3008,7 +2894,7 @@ Block* Parser::BuildParameterInitializationBlock(
DCHECK(!parameters.is_simple);
DCHECK(scope()->is_function_scope());
DCHECK_EQ(scope(), parameters.scope);
- Block* init_block = factory()->NewBlock(NULL, 1, true, kNoSourcePosition);
+ Block* init_block = factory()->NewBlock(1, true);
int index = 0;
for (auto parameter : parameters.params) {
DeclarationDescriptor descriptor;
@@ -3028,7 +2914,7 @@ Block* Parser::BuildParameterInitializationBlock(
// IS_UNDEFINED($param) ? initializer : $param
// Ensure initializer is rewritten
- RewriteParameterInitializer(parameter->initializer, scope());
+ RewriteParameterInitializer(parameter->initializer);
auto condition = factory()->NewCompareOperation(
Token::EQ_STRICT,
@@ -3041,12 +2927,13 @@ Block* Parser::BuildParameterInitializationBlock(
Scope* param_scope = scope();
Block* param_block = init_block;
- if (!parameter->is_simple() && scope()->calls_sloppy_eval()) {
+ if (!parameter->is_simple() &&
+ scope()->AsDeclarationScope()->calls_sloppy_eval()) {
param_scope = NewVarblockScope();
param_scope->set_start_position(descriptor.initialization_pos);
param_scope->set_end_position(parameter->initializer_end_position);
param_scope->RecordEvalCall();
- param_block = factory()->NewBlock(NULL, 8, true, kNoSourcePosition);
+ param_block = factory()->NewBlock(8, true);
param_block->set_scope(param_scope);
// Pass the appropriate scope in so that PatternRewriter can appropriately
// rewrite inner initializers of the pattern to param_scope
@@ -3058,8 +2945,8 @@ Block* Parser::BuildParameterInitializationBlock(
BlockState block_state(&scope_, param_scope);
DeclarationParsingResult::Declaration decl(
parameter->pattern, parameter->initializer_end_position, initial_value);
- PatternRewriter::DeclareAndInitializeVariables(
- this, param_block, &descriptor, &decl, nullptr, CHECK_OK);
+ DeclareAndInitializeVariables(param_block, &descriptor, &decl, nullptr,
+ CHECK_OK);
if (param_block != init_block) {
param_scope = param_scope->FinalizeBlockScope();
@@ -3073,8 +2960,8 @@ Block* Parser::BuildParameterInitializationBlock(
return init_block;
}
-Scope* Parser::NewHiddenCatchScopeWithParent(Scope* parent) {
- Scope* catch_scope = NewScopeWithParent(parent, CATCH_SCOPE);
+Scope* Parser::NewHiddenCatchScope() {
+ Scope* catch_scope = NewScopeWithParent(scope(), CATCH_SCOPE);
catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR);
catch_scope->set_is_hidden();
return catch_scope;
@@ -3090,7 +2977,7 @@ Block* Parser::BuildRejectPromiseOnException(Block* inner_block) {
// } finally {
// %AsyncFunctionPromiseRelease(.promise);
// }
- Block* result = factory()->NewBlock(nullptr, 2, true, kNoSourcePosition);
+ Block* result = factory()->NewBlock(2, true);
// .promise = %AsyncFunctionPromiseCreate();
Statement* set_promise;
@@ -3107,7 +2994,7 @@ Block* Parser::BuildRejectPromiseOnException(Block* inner_block) {
result->statements()->Add(set_promise, zone());
// catch (.catch) { return %RejectPromise(.promise, .catch), .promise }
- Scope* catch_scope = NewHiddenCatchScopeWithParent(scope());
+ Scope* catch_scope = NewHiddenCatchScope();
Expression* promise_reject = BuildRejectPromise(
factory()->NewVariableProxy(catch_scope->catch_variable()),
@@ -3202,8 +3089,6 @@ ZoneList<Statement*>* Parser::ParseFunction(
DuplicateFinder duplicate_finder;
ExpressionClassifier formals_classifier(this, &duplicate_finder);
- if (IsResumableFunction(kind)) PrepareGeneratorVariables();
-
int expected_parameters_end_pos = parameters_end_pos_;
if (expected_parameters_end_pos != kNoSourcePosition) {
// This is the first function encountered in a CreateDynamicFunction eval.
@@ -3271,8 +3156,8 @@ void Parser::DeclareClassVariable(const AstRawString* name,
if (name != nullptr) {
class_info->proxy = factory()->NewVariableProxy(name, NORMAL_VARIABLE);
- Declaration* declaration = factory()->NewVariableDeclaration(
- class_info->proxy, scope(), class_token_pos);
+ Declaration* declaration =
+ factory()->NewVariableDeclaration(class_info->proxy, class_token_pos);
Declare(declaration, DeclarationDescriptor::NORMAL, CONST,
Variable::DefaultInitializationFlag(CONST), ok);
}
@@ -3289,7 +3174,7 @@ void Parser::DeclareClassProperty(const AstRawString* class_name,
ClassInfo* class_info, bool* ok) {
if (is_constructor) {
DCHECK(!class_info->constructor);
- class_info->constructor = GetPropertyValue(property)->AsFunctionLiteral();
+ class_info->constructor = property->value()->AsFunctionLiteral();
DCHECK_NOT_NULL(class_info->constructor);
class_info->constructor->set_raw_name(
class_name != nullptr ? ast_value_factory()->NewConsString(class_name)
@@ -3496,19 +3381,7 @@ void Parser::ParseOnBackground(ParseInfo* info) {
}
}
- std::unique_ptr<Utf16CharacterStream> stream;
- Utf16CharacterStream* stream_ptr;
- if (info->character_stream()) {
- DCHECK(info->source_stream() == nullptr);
- stream_ptr = info->character_stream();
- } else {
- DCHECK(info->character_stream() == nullptr);
- stream.reset(ScannerStream::For(info->source_stream(),
- info->source_stream_encoding(),
- runtime_call_stats_));
- stream_ptr = stream.get();
- }
- scanner_.Initialize(stream_ptr, info->is_module());
+ scanner_.Initialize(info->character_stream(), info->is_module());
DCHECK(info->maybe_outer_scope_info().is_null());
DCHECK(original_scope_);
@@ -3523,8 +3396,9 @@ void Parser::ParseOnBackground(ParseInfo* info) {
fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
result = DoParseProgram(info);
} else {
- result = DoParseFunction(info);
+ result = DoParseFunction(info, info->function_name());
}
+ MaybeResetCharacterStream(info, result);
info->set_literal(result);
@@ -3828,17 +3702,6 @@ Expression* Parser::ExpressionListToExpression(ZoneList<Expression*>* args) {
return expr;
}
-// This method intoduces the line initializing the generator object
-// when desugaring the body of async_function.
-void Parser::PrepareAsyncFunctionBody(ZoneList<Statement*>* body,
- FunctionKind kind, int pos) {
- // When parsing an async arrow function, we get here without having called
- // PrepareGeneratorVariables yet, so do it now.
- if (function_state_->scope()->generator_object_var() == nullptr) {
- PrepareGeneratorVariables();
- }
-}
-
// This method completes the desugaring of the body of async_function.
void Parser::RewriteAsyncFunctionBody(ZoneList<Statement*>* body, Block* block,
Expression* return_value, bool* ok) {
@@ -3926,7 +3789,8 @@ void Parser::RewriteDestructuringAssignments() {
// pair.scope may already have been removed by FinalizeBlockScope in the
// meantime.
Scope* scope = pair.scope->GetUnremovedScope();
- PatternRewriter::RewriteDestructuringAssignment(this, to_rewrite, scope);
+ BlockState block_state(&scope_, scope);
+ RewriteDestructuringAssignment(to_rewrite);
}
}
}
@@ -4004,7 +3868,7 @@ Expression* Parser::RewriteSpreads(ArrayLiteral* lit) {
// $R = lit
Expression* init_result = factory()->NewAssignment(
Token::INIT, factory()->NewVariableProxy(result), lit, kNoSourcePosition);
- Block* do_block = factory()->NewBlock(nullptr, 16, false, kNoSourcePosition);
+ Block* do_block = factory()->NewBlock(16, false);
do_block->statements()->Add(
factory()->NewExpressionStatement(init_result, kNoSourcePosition),
zone());
@@ -4151,430 +4015,6 @@ void Parser::SetFunctionName(Expression* value, const AstRawString* name,
}
}
-// Desugaring of yield*
-// ====================
-//
-// With the help of do-expressions and function.sent, we desugar yield* into a
-// loop containing a "raw" yield (a yield that doesn't wrap an iterator result
-// object around its argument). Concretely, "yield* iterable" turns into
-// roughly the following code:
-//
-// do {
-// const kNext = 0;
-// const kReturn = 1;
-// const kThrow = 2;
-//
-// let input = undefined;
-// let mode = kNext;
-// let output = undefined;
-//
-// let iterator = GetIterator(iterable);
-//
-// while (true) {
-// // From the generator to the iterator:
-// // Forward input according to resume mode and obtain output.
-// switch (mode) {
-// case kNext:
-// output = iterator.next(input);
-// if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
-// break;
-// case kReturn:
-// IteratorClose(iterator, input, output); // See below.
-// break;
-// case kThrow:
-// let iteratorThrow = iterator.throw;
-// if (IS_NULL_OR_UNDEFINED(iteratorThrow)) {
-// IteratorClose(iterator); // See below.
-// throw MakeTypeError(kThrowMethodMissing);
-// }
-// output = %_Call(iteratorThrow, iterator, input);
-// if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
-// break;
-// }
-// if (output.done) break;
-//
-// // From the generator to its user:
-// // Forward output, receive new input, and determine resume mode.
-// RawYield(output); // See explanation above.
-// mode = %GeneratorGetResumeMode();
-// input = function.sent;
-// }
-// }
-//
-// if (mode === kReturn) {
-// return {value: output.value, done: true};
-// }
-// output.value
-// }
-//
-// IteratorClose(iterator) expands to the following:
-//
-// let iteratorReturn = iterator.return;
-// if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) {
-// let output = %_Call(iteratorReturn, iterator);
-// if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
-// }
-//
-// IteratorClose(iterator, input, output) expands to the following:
-//
-// let iteratorReturn = iterator.return;
-// if (IS_NULL_OR_UNDEFINED(iteratorReturn)) return input;
-// output = %_Call(iteratorReturn, iterator, input);
-// if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
-
-Expression* Parser::RewriteYieldStar(Expression* iterable, int pos) {
- const int nopos = kNoSourcePosition;
- IteratorType type =
- is_async_generator() ? IteratorType::kAsync : IteratorType::kNormal;
-
- if (type == IteratorType::kNormal) {
- return factory()->NewYieldStar(iterable, pos);
- }
-
- // Forward definition for break/continue statements.
- WhileStatement* loop = factory()->NewWhileStatement(nullptr, nopos);
-
- // let input = undefined;
- Variable* var_input = NewTemporary(ast_value_factory()->empty_string());
- Statement* initialize_input;
- {
- Expression* input_proxy = factory()->NewVariableProxy(var_input);
- Expression* assignment =
- factory()->NewAssignment(Token::ASSIGN, input_proxy,
- factory()->NewUndefinedLiteral(nopos), nopos);
- initialize_input = factory()->NewExpressionStatement(assignment, nopos);
- }
-
- // let mode = kNext;
- Variable* var_mode = NewTemporary(ast_value_factory()->empty_string());
- Statement* initialize_mode;
- {
- Expression* mode_proxy = factory()->NewVariableProxy(var_mode);
- Expression* knext =
- factory()->NewSmiLiteral(JSGeneratorObject::kNext, nopos);
- Expression* assignment =
- factory()->NewAssignment(Token::ASSIGN, mode_proxy, knext, nopos);
- initialize_mode = factory()->NewExpressionStatement(assignment, nopos);
- }
-
- // let output = undefined;
- Variable* var_output = NewTemporary(ast_value_factory()->empty_string());
- Statement* initialize_output;
- {
- Expression* output_proxy = factory()->NewVariableProxy(var_output);
- Expression* assignment =
- factory()->NewAssignment(Token::ASSIGN, output_proxy,
- factory()->NewUndefinedLiteral(nopos), nopos);
- initialize_output = factory()->NewExpressionStatement(assignment, nopos);
- }
-
- // let iterator = GetIterator(iterable);
- Variable* var_iterator = NewTemporary(ast_value_factory()->empty_string());
- Statement* get_iterator;
- {
- Expression* iterator = factory()->NewGetIterator(iterable, type, nopos);
- Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator);
- Expression* assignment = factory()->NewAssignment(
- Token::ASSIGN, iterator_proxy, iterator, nopos);
- get_iterator = factory()->NewExpressionStatement(assignment, nopos);
- }
-
- // output = iterator.next(input);
- Statement* call_next;
- {
- Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator);
- Expression* literal =
- factory()->NewStringLiteral(ast_value_factory()->next_string(), nopos);
- Expression* next_property =
- factory()->NewProperty(iterator_proxy, literal, nopos);
- Expression* input_proxy = factory()->NewVariableProxy(var_input);
- auto args = new (zone()) ZoneList<Expression*>(1, zone());
- args->Add(input_proxy, zone());
- Expression* call = factory()->NewCall(next_property, args, nopos);
- if (type == IteratorType::kAsync) {
- call = factory()->NewAwait(call, nopos);
- }
- Expression* output_proxy = factory()->NewVariableProxy(var_output);
- Expression* assignment =
- factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos);
- call_next = factory()->NewExpressionStatement(assignment, nopos);
- }
-
- // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
- Statement* validate_next_output;
- {
- Expression* is_receiver_call;
- {
- auto args = new (zone()) ZoneList<Expression*>(1, zone());
- args->Add(factory()->NewVariableProxy(var_output), zone());
- is_receiver_call =
- factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
- }
-
- Statement* throw_call;
- {
- auto args = new (zone()) ZoneList<Expression*>(1, zone());
- args->Add(factory()->NewVariableProxy(var_output), zone());
- Expression* call = factory()->NewCallRuntime(
- Runtime::kThrowIteratorResultNotAnObject, args, nopos);
- throw_call = factory()->NewExpressionStatement(call, nopos);
- }
-
- validate_next_output = factory()->NewIfStatement(
- is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call,
- nopos);
- }
-
- // let iteratorThrow = iterator.throw;
- Variable* var_throw = NewTemporary(ast_value_factory()->empty_string());
- Statement* get_throw;
- {
- Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator);
- Expression* literal =
- factory()->NewStringLiteral(ast_value_factory()->throw_string(), nopos);
- Expression* property =
- factory()->NewProperty(iterator_proxy, literal, nopos);
- Expression* throw_proxy = factory()->NewVariableProxy(var_throw);
- Expression* assignment =
- factory()->NewAssignment(Token::ASSIGN, throw_proxy, property, nopos);
- get_throw = factory()->NewExpressionStatement(assignment, nopos);
- }
-
- // if (IS_NULL_OR_UNDEFINED(iteratorThrow) {
- // IteratorClose(iterator);
- // throw MakeTypeError(kThrowMethodMissing);
- // }
- Statement* check_throw;
- {
- Expression* condition = factory()->NewCompareOperation(
- Token::EQ, factory()->NewVariableProxy(var_throw),
- factory()->NewNullLiteral(nopos), nopos);
- Expression* call =
- NewThrowTypeError(MessageTemplate::kThrowMethodMissing,
- ast_value_factory()->empty_string(), nopos);
- Statement* throw_call = factory()->NewExpressionStatement(call, nopos);
-
- Block* then = factory()->NewBlock(nullptr, 4 + 1, false, nopos);
- BuildIteratorCloseForCompletion(
- scope(), then->statements(), var_iterator,
- factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), type);
- then->statements()->Add(throw_call, zone());
- check_throw = factory()->NewIfStatement(
- condition, then, factory()->NewEmptyStatement(nopos), nopos);
- }
-
- // output = %_Call(iteratorThrow, iterator, input);
- Statement* call_throw;
- {
- auto args = new (zone()) ZoneList<Expression*>(3, zone());
- args->Add(factory()->NewVariableProxy(var_throw), zone());
- args->Add(factory()->NewVariableProxy(var_iterator), zone());
- args->Add(factory()->NewVariableProxy(var_input), zone());
- Expression* call =
- factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
- if (type == IteratorType::kAsync) {
- call = factory()->NewAwait(call, nopos);
- }
- Expression* assignment = factory()->NewAssignment(
- Token::ASSIGN, factory()->NewVariableProxy(var_output), call, nopos);
- call_throw = factory()->NewExpressionStatement(assignment, nopos);
- }
-
- // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
- Statement* validate_throw_output;
- {
- Expression* is_receiver_call;
- {
- auto args = new (zone()) ZoneList<Expression*>(1, zone());
- args->Add(factory()->NewVariableProxy(var_output), zone());
- is_receiver_call =
- factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
- }
-
- Statement* throw_call;
- {
- auto args = new (zone()) ZoneList<Expression*>(1, zone());
- args->Add(factory()->NewVariableProxy(var_output), zone());
- Expression* call = factory()->NewCallRuntime(
- Runtime::kThrowIteratorResultNotAnObject, args, nopos);
- throw_call = factory()->NewExpressionStatement(call, nopos);
- }
-
- validate_throw_output = factory()->NewIfStatement(
- is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call,
- nopos);
- }
-
- // if (output.done) break;
- Statement* if_done;
- {
- Expression* output_proxy = factory()->NewVariableProxy(var_output);
- Expression* literal =
- factory()->NewStringLiteral(ast_value_factory()->done_string(), nopos);
- Expression* property = factory()->NewProperty(output_proxy, literal, nopos);
- BreakStatement* break_loop = factory()->NewBreakStatement(loop, nopos);
- if_done = factory()->NewIfStatement(
- property, break_loop, factory()->NewEmptyStatement(nopos), nopos);
- }
-
- // Yield(output);
- Statement* yield_output;
- {
- Expression* output_proxy = factory()->NewVariableProxy(var_output);
- Suspend* yield =
- factory()->NewYield(output_proxy, nopos, Suspend::kNoControl);
- yield_output = factory()->NewExpressionStatement(yield, nopos);
- }
-
- // mode = %GeneratorGetResumeMode();
- Statement* get_mode;
- {
- Expression* mode_proxy = factory()->NewVariableProxy(var_mode);
-
- ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone());
- VariableProxy* generator = factory()->NewVariableProxy(
- function_state_->scope()->generator_object_var());
- args->Add(generator, zone());
- Expression* mode = factory()->NewCallRuntime(
- Runtime::kInlineGeneratorGetResumeMode, args, pos);
-
- Expression* assignment =
- factory()->NewAssignment(Token::ASSIGN, mode_proxy, mode, nopos);
- get_mode = factory()->NewExpressionStatement(assignment, nopos);
- }
-
- // input = function.sent;
- Statement* get_input;
- {
- Expression* function_sent = FunctionSentExpression(nopos);
- Expression* input_proxy = factory()->NewVariableProxy(var_input);
- Expression* assignment = factory()->NewAssignment(
- Token::ASSIGN, input_proxy, function_sent, nopos);
- get_input = factory()->NewExpressionStatement(assignment, nopos);
- }
-
- // if (mode === kReturn) {
- // return {value: output.value, done: true};
- // }
- Statement* maybe_return_value;
- {
- Expression* mode_proxy = factory()->NewVariableProxy(var_mode);
- Expression* kreturn =
- factory()->NewSmiLiteral(JSGeneratorObject::kReturn, nopos);
- Expression* condition = factory()->NewCompareOperation(
- Token::EQ_STRICT, mode_proxy, kreturn, nopos);
-
- Expression* output_proxy = factory()->NewVariableProxy(var_output);
- Expression* literal =
- factory()->NewStringLiteral(ast_value_factory()->value_string(), nopos);
- Expression* property = factory()->NewProperty(output_proxy, literal, nopos);
- Statement* return_value = BuildReturnStatement(property, nopos);
-
- maybe_return_value = factory()->NewIfStatement(
- condition, return_value, factory()->NewEmptyStatement(nopos), nopos);
- }
-
- // output.value
- Statement* get_value;
- {
- Expression* output_proxy = factory()->NewVariableProxy(var_output);
- Expression* literal =
- factory()->NewStringLiteral(ast_value_factory()->value_string(), nopos);
- Expression* property = factory()->NewProperty(output_proxy, literal, nopos);
- get_value = factory()->NewExpressionStatement(property, nopos);
- }
-
- // Now put things together.
-
- // switch (mode) { ... }
- SwitchStatement* switch_mode = factory()->NewSwitchStatement(nullptr, nopos);
- {
- auto case_next = new (zone()) ZoneList<Statement*>(3, zone());
- case_next->Add(call_next, zone());
- case_next->Add(validate_next_output, zone());
- case_next->Add(factory()->NewBreakStatement(switch_mode, nopos), zone());
-
- auto case_return = new (zone()) ZoneList<Statement*>(5, zone());
- BuildIteratorClose(case_return, var_iterator, var_input, var_output, type);
- case_return->Add(factory()->NewBreakStatement(switch_mode, nopos), zone());
-
- auto case_throw = new (zone()) ZoneList<Statement*>(5, zone());
- case_throw->Add(get_throw, zone());
- case_throw->Add(check_throw, zone());
- case_throw->Add(call_throw, zone());
- case_throw->Add(validate_throw_output, zone());
- case_throw->Add(factory()->NewBreakStatement(switch_mode, nopos), zone());
-
- auto cases = new (zone()) ZoneList<CaseClause*>(3, zone());
- Expression* knext =
- factory()->NewSmiLiteral(JSGeneratorObject::kNext, nopos);
- Expression* kreturn =
- factory()->NewSmiLiteral(JSGeneratorObject::kReturn, nopos);
- Expression* kthrow =
- factory()->NewSmiLiteral(JSGeneratorObject::kThrow, nopos);
- cases->Add(factory()->NewCaseClause(knext, case_next, nopos), zone());
- cases->Add(factory()->NewCaseClause(kreturn, case_return, nopos), zone());
- cases->Add(factory()->NewCaseClause(kthrow, case_throw, nopos), zone());
-
- switch_mode->Initialize(factory()->NewVariableProxy(var_mode), cases);
- }
-
- // while (true) { ... }
- // Already defined earlier: WhileStatement* loop = ...
- {
- Block* loop_body = factory()->NewBlock(nullptr, 5, false, nopos);
- loop_body->statements()->Add(switch_mode, zone());
- loop_body->statements()->Add(if_done, zone());
-
- if (is_async_generator()) {
- // AsyncGeneratorYield does not yield the original iterator result,
- // unlike sync generators. Do `output = output.value`
- VariableProxy* output_proxy = factory()->NewVariableProxy(var_output);
- Expression* literal = factory()->NewStringLiteral(
- ast_value_factory()->value_string(), nopos);
- Assignment* assign = factory()->NewAssignment(
- Token::ASSIGN, output_proxy,
- factory()->NewProperty(factory()->NewVariableProxy(var_output),
- literal, nopos),
- nopos);
- loop_body->statements()->Add(
- factory()->NewExpressionStatement(assign, nopos), zone());
- }
-
- loop_body->statements()->Add(yield_output, zone());
- loop_body->statements()->Add(get_input, zone());
- loop_body->statements()->Add(get_mode, zone());
-
- loop->Initialize(factory()->NewBooleanLiteral(true, nopos), loop_body);
- }
-
- // do { ... }
- DoExpression* yield_star;
- {
- // The rewriter needs to process the get_value statement only, hence we
- // put the preceding statements into an init block.
-
- Block* do_block_ = factory()->NewBlock(nullptr, 6, true, nopos);
- do_block_->statements()->Add(initialize_input, zone());
- do_block_->statements()->Add(initialize_mode, zone());
- do_block_->statements()->Add(initialize_output, zone());
- do_block_->statements()->Add(get_iterator, zone());
- do_block_->statements()->Add(loop, zone());
- do_block_->statements()->Add(maybe_return_value, zone());
-
- Block* do_block = factory()->NewBlock(nullptr, 2, false, nopos);
- do_block->statements()->Add(do_block_, zone());
- do_block->statements()->Add(get_value, zone());
-
- Variable* dot_result =
- NewTemporary(ast_value_factory()->dot_result_string());
- yield_star = factory()->NewDoExpression(do_block, dot_result, nopos);
- Rewriter::Rewrite(this, GetClosureScope(), yield_star, ast_value_factory());
- }
-
- return yield_star;
-}
-
Statement* Parser::CheckCallable(Variable* var, Expression* error, int pos) {
const int nopos = kNoSourcePosition;
Statement* validate_var;
@@ -4693,10 +4133,9 @@ void Parser::BuildIteratorClose(ZoneList<Statement*>* statements,
statements->Add(validate_output, zone());
}
-void Parser::FinalizeIteratorUse(Scope* use_scope, Variable* completion,
- Expression* condition, Variable* iter,
- Block* iterator_use, Block* target,
- IteratorType type) {
+void Parser::FinalizeIteratorUse(Variable* completion, Expression* condition,
+ Variable* iter, Block* iterator_use,
+ Block* target, IteratorType type) {
//
// This function adds two statements to [target], corresponding to the
// following code:
@@ -4750,10 +4189,9 @@ void Parser::FinalizeIteratorUse(Scope* use_scope, Variable* completion,
// }
Block* maybe_close;
{
- Block* block = factory()->NewBlock(nullptr, 2, true, nopos);
+ Block* block = factory()->NewBlock(2, true);
Expression* proxy = factory()->NewVariableProxy(completion);
- BuildIteratorCloseForCompletion(use_scope, block->statements(), iter, proxy,
- type);
+ BuildIteratorCloseForCompletion(block->statements(), iter, proxy, type);
DCHECK(block->statements()->length() == 2);
maybe_close = IgnoreCompletion(factory()->NewIfStatement(
@@ -4767,7 +4205,7 @@ void Parser::FinalizeIteratorUse(Scope* use_scope, Variable* completion,
// }
Statement* try_catch;
{
- Scope* catch_scope = NewHiddenCatchScopeWithParent(use_scope);
+ Scope* catch_scope = NewHiddenCatchScope();
Statement* rethrow;
// We use %ReThrow rather than the ordinary throw because we want to
@@ -4782,7 +4220,7 @@ void Parser::FinalizeIteratorUse(Scope* use_scope, Variable* completion,
factory()->NewCallRuntime(Runtime::kReThrow, args, nopos), nopos);
}
- Block* catch_block = factory()->NewBlock(nullptr, 2, false, nopos);
+ Block* catch_block = factory()->NewBlock(2, false);
catch_block->statements()->Add(set_completion_throw, zone());
catch_block->statements()->Add(rethrow, zone());
@@ -4793,7 +4231,7 @@ void Parser::FinalizeIteratorUse(Scope* use_scope, Variable* completion,
// try { #try_catch } finally { #maybe_close }
Statement* try_finally;
{
- Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos);
+ Block* try_block = factory()->NewBlock(1, false);
try_block->statements()->Add(try_catch, zone());
try_finally =
@@ -4804,8 +4242,7 @@ void Parser::FinalizeIteratorUse(Scope* use_scope, Variable* completion,
target->statements()->Add(try_finally, zone());
}
-void Parser::BuildIteratorCloseForCompletion(Scope* scope,
- ZoneList<Statement*>* statements,
+void Parser::BuildIteratorCloseForCompletion(ZoneList<Statement*>* statements,
Variable* iterator,
Expression* completion,
IteratorType type) {
@@ -4878,12 +4315,12 @@ void Parser::BuildIteratorCloseForCompletion(Scope* scope,
call = factory()->NewAwait(call, nopos);
}
- Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos);
+ Block* try_block = factory()->NewBlock(1, false);
try_block->statements()->Add(factory()->NewExpressionStatement(call, nopos),
zone());
- Block* catch_block = factory()->NewBlock(nullptr, 0, false, nopos);
- Scope* catch_scope = NewHiddenCatchScopeWithParent(scope);
+ Block* catch_block = factory()->NewBlock(0, false);
+ Scope* catch_scope = NewHiddenCatchScope();
try_call_return = factory()->NewTryCatchStatement(try_block, catch_scope,
catch_block, nopos);
}
@@ -4933,7 +4370,7 @@ void Parser::BuildIteratorCloseForCompletion(Scope* scope,
is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call,
nopos);
- validate_return = factory()->NewBlock(nullptr, 2, false, nopos);
+ validate_return = factory()->NewBlock(2, false);
validate_return->statements()->Add(call_return, zone());
validate_return->statements()->Add(check_return, zone());
}
@@ -4950,7 +4387,7 @@ void Parser::BuildIteratorCloseForCompletion(Scope* scope,
Token::EQ_STRICT, completion,
factory()->NewSmiLiteral(Parser::kThrowCompletion, nopos), nopos);
- Block* then_block = factory()->NewBlock(nullptr, 2, false, nopos);
+ Block* then_block = factory()->NewBlock(2, false);
then_block->statements()->Add(check_return_callable, zone());
then_block->statements()->Add(try_call_return, zone());
@@ -5009,58 +4446,18 @@ Statement* Parser::FinalizeForOfStatement(ForOfStatement* loop,
closing_condition = factory()->NewUnaryOperation(Token::NOT, cmp, nopos);
}
- Block* final_loop = factory()->NewBlock(nullptr, 2, false, nopos);
+ Block* final_loop = factory()->NewBlock(2, false);
{
- Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos);
+ Block* try_block = factory()->NewBlock(1, false);
try_block->statements()->Add(loop, zone());
- // The scope in which the parser creates this loop.
- Scope* loop_scope = scope()->outer_scope();
- DCHECK_EQ(loop_scope->scope_type(), BLOCK_SCOPE);
- DCHECK_EQ(scope()->scope_type(), BLOCK_SCOPE);
-
- FinalizeIteratorUse(loop_scope, var_completion, closing_condition,
- loop->iterator(), try_block, final_loop, type);
+ FinalizeIteratorUse(var_completion, closing_condition, loop->iterator(),
+ try_block, final_loop, type);
}
return final_loop;
}
-void Parser::StitchAst(ParseInfo* top_level_parse_info, Isolate* isolate) {
- if (literals_to_stitch_.empty()) return;
- std::map<int, ParseInfo*> child_infos = top_level_parse_info->child_infos();
- DCHECK(std::is_sorted(literals_to_stitch_.begin(), literals_to_stitch_.end(),
- [](FunctionLiteral* a, FunctionLiteral* b) {
- return a->start_position() < b->start_position();
- }));
- auto it = literals_to_stitch_.begin();
- for (auto& child_info : child_infos) {
- ParseInfo* result = child_info.second;
- // If the parse task failed the function will be treated as lazy function
- // and reparsed before it gets called
- if (!result) continue;
- result->UpdateStatisticsAfterBackgroundParse(isolate);
- if (!result->literal()) continue;
- while ((*it)->start_position() != child_info.first) {
- if (++it == literals_to_stitch_.end()) {
- return;
- }
- }
- FunctionLiteral* literal = *it;
- // FIXME(wiktorg) better handling of default params for arrow functions
- Scope* outer_scope = literal->scope()->outer_scope();
- if (outer_scope->is_declaration_scope() &&
- outer_scope->AsDeclarationScope()->was_lazily_parsed()) {
- continue;
- }
- // TODO(wiktorg) in the future internalize somewhere else (stitching may be
- // done on streamer thread)
- result->ast_value_factory()->Internalize(isolate);
- literal->ReplaceBodyAndScope(result->literal());
- literal->SetShouldEagerCompile();
- }
-}
-
#undef CHECK_OK
#undef CHECK_OK_VOID
#undef CHECK_FAILED