summaryrefslogtreecommitdiff
path: root/deps/v8/src/parsing
diff options
context:
space:
mode:
authorMichaël Zasso <targos@protonmail.com>2018-03-07 08:54:53 +0100
committerMichaël Zasso <targos@protonmail.com>2018-03-07 16:48:52 +0100
commit88786fecff336342a56e6f2e7ff3b286be716e47 (patch)
tree92e6ba5b8ac8dae1a058988d20c9d27bfa654390 /deps/v8/src/parsing
parent4e86f9b5ab83cbabf43839385bf383e6a7ef7d19 (diff)
downloadnode-new-88786fecff336342a56e6f2e7ff3b286be716e47.tar.gz
deps: update V8 to 6.5.254.31
PR-URL: https://github.com/nodejs/node/pull/18453 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Yang Guo <yangguo@chromium.org> Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Diffstat (limited to 'deps/v8/src/parsing')
-rw-r--r--deps/v8/src/parsing/background-parsing-task.cc3
-rw-r--r--deps/v8/src/parsing/expression-classifier.h25
-rw-r--r--deps/v8/src/parsing/expression-scope-reparenter.cc8
-rw-r--r--deps/v8/src/parsing/parse-info.cc14
-rw-r--r--deps/v8/src/parsing/parse-info.h10
-rw-r--r--deps/v8/src/parsing/parser-base.h387
-rw-r--r--deps/v8/src/parsing/parser.cc350
-rw-r--r--deps/v8/src/parsing/parser.h54
-rw-r--r--deps/v8/src/parsing/pattern-rewriter.cc10
-rw-r--r--deps/v8/src/parsing/preparsed-scope-data.cc6
-rw-r--r--deps/v8/src/parsing/preparser.cc20
-rw-r--r--deps/v8/src/parsing/preparser.h25
-rw-r--r--deps/v8/src/parsing/rewriter.cc4
-rw-r--r--deps/v8/src/parsing/scanner-character-streams.cc57
-rw-r--r--deps/v8/src/parsing/scanner.cc117
-rw-r--r--deps/v8/src/parsing/scanner.h17
-rw-r--r--deps/v8/src/parsing/token.h1
17 files changed, 581 insertions, 527 deletions
diff --git a/deps/v8/src/parsing/background-parsing-task.cc b/deps/v8/src/parsing/background-parsing-task.cc
index 387cd3a1c6..cb811566df 100644
--- a/deps/v8/src/parsing/background-parsing-task.cc
+++ b/deps/v8/src/parsing/background-parsing-task.cc
@@ -31,7 +31,8 @@ BackgroundParsingTask::BackgroundParsingTask(
DCHECK(options == ScriptCompiler::kProduceParserCache ||
options == ScriptCompiler::kProduceCodeCache ||
options == ScriptCompiler::kProduceFullCodeCache ||
- options == ScriptCompiler::kNoCompileOptions);
+ options == ScriptCompiler::kNoCompileOptions ||
+ options == ScriptCompiler::kEagerCompile);
VMState<PARSER> state(isolate);
diff --git a/deps/v8/src/parsing/expression-classifier.h b/deps/v8/src/parsing/expression-classifier.h
index 6c6c813b3e..709d5736b5 100644
--- a/deps/v8/src/parsing/expression-classifier.h
+++ b/deps/v8/src/parsing/expression-classifier.h
@@ -97,14 +97,12 @@ class ExpressionClassifier {
: base_(base),
previous_(base->classifier_),
zone_(base->impl()->zone()),
- non_patterns_to_rewrite_(base->impl()->GetNonPatternList()),
reported_errors_(base->impl()->GetReportedErrorList()),
duplicate_finder_(duplicate_finder),
invalid_productions_(0),
function_properties_(0) {
base->classifier_ = this;
reported_errors_begin_ = reported_errors_end_ = reported_errors_->length();
- non_pattern_begin_ = non_patterns_to_rewrite_->length();
}
V8_INLINE ~ExpressionClassifier() {
@@ -291,19 +289,10 @@ class ExpressionClassifier {
Add(Error(loc, message, kLetPatternProduction, arg));
}
- void Accumulate(ExpressionClassifier* inner, unsigned productions,
- bool merge_non_patterns = true) {
+ void Accumulate(ExpressionClassifier* inner, unsigned productions) {
DCHECK_EQ(inner->reported_errors_, reported_errors_);
DCHECK_EQ(inner->reported_errors_begin_, reported_errors_end_);
DCHECK_EQ(inner->reported_errors_end_, reported_errors_->length());
- DCHECK_EQ(inner->non_patterns_to_rewrite_, non_patterns_to_rewrite_);
- DCHECK_LE(non_pattern_begin_, inner->non_pattern_begin_);
- DCHECK_LE(inner->non_pattern_begin_, non_patterns_to_rewrite_->length());
- // Merge non-patterns from the inner classifier, or discard them.
- if (merge_non_patterns)
- inner->non_pattern_begin_ = non_patterns_to_rewrite_->length();
- else
- non_patterns_to_rewrite_->Rewind(inner->non_pattern_begin_);
// Propagate errors from inner, but don't overwrite already recorded
// errors.
unsigned non_arrow_inner_invalid_productions =
@@ -368,16 +357,12 @@ class ExpressionClassifier {
reported_errors_end_;
}
- V8_INLINE int GetNonPatternBegin() const { return non_pattern_begin_; }
-
V8_INLINE void Discard() {
if (reported_errors_end_ == reported_errors_->length()) {
reported_errors_->Rewind(reported_errors_begin_);
reported_errors_end_ = reported_errors_begin_;
}
DCHECK_EQ(reported_errors_begin_, reported_errors_end_);
- DCHECK_LE(non_pattern_begin_, non_patterns_to_rewrite_->length());
- non_patterns_to_rewrite_->Rewind(non_pattern_begin_);
}
ExpressionClassifier* previous() const { return previous_; }
@@ -424,16 +409,8 @@ class ExpressionClassifier {
typename Types::Base* base_;
ExpressionClassifier* previous_;
Zone* zone_;
- ZoneList<typename Types::RewritableExpression>* non_patterns_to_rewrite_;
ZoneList<Error>* reported_errors_;
DuplicateFinder* duplicate_finder_;
- // The uint16_t for non_pattern_begin_ will not be enough in the case,
- // e.g., of an array literal containing more than 64K inner array
- // literals with spreads, as in:
- // var N=65536; eval("var x=[];" + "[" + "[...x],".repeat(N) + "].length");
- // An implementation limit error in ParserBase::AddNonPatternForRewriting
- // will be triggered in this case.
- uint16_t non_pattern_begin_;
unsigned invalid_productions_ : 14;
unsigned function_properties_ : 2;
// The uint16_t for reported_errors_begin_ and reported_errors_end_ will
diff --git a/deps/v8/src/parsing/expression-scope-reparenter.cc b/deps/v8/src/parsing/expression-scope-reparenter.cc
index 18c52add11..bdb0aeadd6 100644
--- a/deps/v8/src/parsing/expression-scope-reparenter.cc
+++ b/deps/v8/src/parsing/expression-scope-reparenter.cc
@@ -85,7 +85,7 @@ void Reparenter::VisitRewritableExpression(RewritableExpression* expr) {
}
void Reparenter::VisitBlock(Block* stmt) {
- if (stmt->scope() != nullptr)
+ if (stmt->scope())
stmt->scope()->ReplaceOuterScope(scope_);
else
VisitStatements(stmt->statements());
@@ -93,7 +93,11 @@ void Reparenter::VisitBlock(Block* stmt) {
void Reparenter::VisitTryCatchStatement(TryCatchStatement* stmt) {
Visit(stmt->try_block());
- stmt->scope()->ReplaceOuterScope(scope_);
+ if (stmt->scope()) {
+ stmt->scope()->ReplaceOuterScope(scope_);
+ } else {
+ Visit(stmt->catch_block());
+ }
}
void Reparenter::VisitWithStatement(WithStatement* stmt) {
diff --git a/deps/v8/src/parsing/parse-info.cc b/deps/v8/src/parsing/parse-info.cc
index 1c9d648a1e..b8f191dd5a 100644
--- a/deps/v8/src/parsing/parse-info.cc
+++ b/deps/v8/src/parsing/parse-info.cc
@@ -45,7 +45,13 @@ ParseInfo::ParseInfo(Handle<SharedFunctionInfo> shared)
Isolate* isolate = shared->GetIsolate();
InitFromIsolate(isolate);
+ // Do not support re-parsing top-level function of a wrapped script.
+ // TODO(yangguo): consider whether we need a top-level function in a
+ // wrapped script at all.
+ DCHECK_IMPLIES(is_toplevel(), !Script::cast(shared->script())->is_wrapped());
+
set_toplevel(shared->is_toplevel());
+ set_wrapped_as_function(shared->is_wrapped());
set_allow_lazy_parsing(FLAG_lazy_inner_functions);
set_is_named_expression(shared->is_named_expression());
set_compiler_hints(shared->compiler_hints());
@@ -54,8 +60,6 @@ ParseInfo::ParseInfo(Handle<SharedFunctionInfo> shared)
function_literal_id_ = shared->function_literal_id();
set_language_mode(shared->language_mode());
set_asm_wasm_broken(shared->is_asm_wasm_broken());
- set_requires_instance_fields_initializer(
- shared->requires_instance_fields_initializer());
Handle<Script> script(Script::cast(shared->script()));
set_script(script);
@@ -90,6 +94,7 @@ ParseInfo::ParseInfo(Handle<Script> script)
set_allow_lazy_parsing();
set_toplevel();
set_script(script);
+ set_wrapped_as_function(script->is_wrapped());
set_native(script->type() == Script::TYPE_NATIVE);
set_eval(script->compilation_type() == Script::COMPILATION_TYPE_EVAL);
@@ -151,6 +156,11 @@ FunctionKind ParseInfo::function_kind() const {
return SharedFunctionInfo::FunctionKindBits::decode(compiler_hints_);
}
+bool ParseInfo::requires_instance_fields_initializer() const {
+ return SharedFunctionInfo::RequiresInstanceFieldsInitializer::decode(
+ compiler_hints_);
+}
+
void ParseInfo::InitFromIsolate(Isolate* isolate) {
DCHECK_NOT_NULL(isolate);
set_hash_seed(isolate->heap()->HashSeed());
diff --git a/deps/v8/src/parsing/parse-info.h b/deps/v8/src/parsing/parse-info.h
index 9deea1ecac..e93c7137ca 100644
--- a/deps/v8/src/parsing/parse-info.h
+++ b/deps/v8/src/parsing/parse-info.h
@@ -79,13 +79,12 @@ class V8_EXPORT_PRIVATE ParseInfo {
FLAG_ACCESSOR(kCollectTypeProfile, collect_type_profile,
set_collect_type_profile)
FLAG_ACCESSOR(kIsAsmWasmBroken, is_asm_wasm_broken, set_asm_wasm_broken)
- FLAG_ACCESSOR(kRequiresInstanceFieldsInitializer,
- requires_instance_fields_initializer,
- set_requires_instance_fields_initializer)
FLAG_ACCESSOR(kBlockCoverageEnabled, block_coverage_enabled,
set_block_coverage_enabled)
FLAG_ACCESSOR(kOnBackgroundThread, on_background_thread,
set_on_background_thread)
+ FLAG_ACCESSOR(kWrappedAsFunction, is_wrapped_as_function,
+ set_wrapped_as_function)
#undef FLAG_ACCESSOR
void set_parse_restriction(ParseRestriction restriction) {
@@ -208,6 +207,7 @@ class V8_EXPORT_PRIVATE ParseInfo {
// Getters for individual compiler hints.
bool is_declaration() const;
FunctionKind function_kind() const;
+ bool requires_instance_fields_initializer() const;
//--------------------------------------------------------------------------
// TODO(titzer): these should not be part of ParseInfo.
@@ -261,8 +261,8 @@ class V8_EXPORT_PRIVATE ParseInfo {
kCollectTypeProfile = 1 << 10,
kBlockCoverageEnabled = 1 << 11,
kIsAsmWasmBroken = 1 << 12,
- kRequiresInstanceFieldsInitializer = 1 << 13,
- kOnBackgroundThread = 1 << 14,
+ kOnBackgroundThread = 1 << 13,
+ kWrappedAsFunction = 1 << 14, // Implicitly wrapped as function.
};
//------------- Inputs to parsing and scope analysis -----------------------
diff --git a/deps/v8/src/parsing/parser-base.h b/deps/v8/src/parsing/parser-base.h
index c393bc5ec2..faefe44011 100644
--- a/deps/v8/src/parsing/parser-base.h
+++ b/deps/v8/src/parsing/parser-base.h
@@ -279,9 +279,11 @@ class ParserBase {
allow_harmony_do_expressions_(false),
allow_harmony_function_sent_(false),
allow_harmony_public_fields_(false),
+ allow_harmony_static_fields_(false),
allow_harmony_dynamic_import_(false),
allow_harmony_import_meta_(false),
- allow_harmony_async_iteration_(false) {}
+ allow_harmony_optional_catch_binding_(false),
+ allow_harmony_private_fields_(false) {}
#define ALLOW_ACCESSORS(name) \
bool allow_##name() const { return allow_##name##_; } \
@@ -291,9 +293,10 @@ class ParserBase {
ALLOW_ACCESSORS(harmony_do_expressions);
ALLOW_ACCESSORS(harmony_function_sent);
ALLOW_ACCESSORS(harmony_public_fields);
+ ALLOW_ACCESSORS(harmony_static_fields);
ALLOW_ACCESSORS(harmony_dynamic_import);
ALLOW_ACCESSORS(harmony_import_meta);
- ALLOW_ACCESSORS(harmony_async_iteration);
+ ALLOW_ACCESSORS(harmony_optional_catch_binding);
#undef ALLOW_ACCESSORS
@@ -304,6 +307,13 @@ class ParserBase {
scanner()->set_allow_harmony_bigint(allow);
}
+ bool allow_harmony_private_fields() const {
+ return scanner()->allow_harmony_private_fields();
+ }
+ void set_allow_harmony_private_fields(bool allow) {
+ scanner()->set_allow_harmony_private_fields(allow);
+ }
+
uintptr_t stack_limit() const { return stack_limit_; }
void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; }
@@ -383,18 +393,27 @@ class ParserBase {
void AddProperty() { expected_property_count_++; }
int expected_property_count() { return expected_property_count_; }
+ void DisableOptimization(BailoutReason reason) {
+ dont_optimize_reason_ = reason;
+ }
+ BailoutReason dont_optimize_reason() { return dont_optimize_reason_; }
+
FunctionKind kind() const { return scope()->function_kind(); }
- FunctionState* outer() const { return outer_function_state_; }
void RewindDestructuringAssignments(int pos) {
destructuring_assignments_to_rewrite_.Rewind(pos);
}
- void SetDestructuringAssignmentsScope(int pos, Scope* scope) {
- for (int i = pos; i < destructuring_assignments_to_rewrite_.length();
- ++i) {
- destructuring_assignments_to_rewrite_[i]->set_scope(scope);
+ void AdoptDestructuringAssignmentsFromParentState(int pos) {
+ const auto& outer_assignments =
+ outer_function_state_->destructuring_assignments_to_rewrite_;
+ DCHECK_GE(outer_assignments.length(), pos);
+ for (int i = pos; i < outer_assignments.length(); ++i) {
+ auto expr = outer_assignments[i];
+ expr->set_scope(scope_);
+ destructuring_assignments_to_rewrite_.Add(expr, scope_->zone());
}
+ outer_function_state_->RewindDestructuringAssignments(pos);
}
const ZoneList<RewritableExpressionT>&
@@ -451,14 +470,6 @@ class ParserBase {
destructuring_assignments_to_rewrite_.Add(expr, scope_->zone());
}
- void AddNonPatternForRewriting(RewritableExpressionT expr, bool* ok) {
- non_patterns_to_rewrite_.Add(expr, scope_->zone());
- if (non_patterns_to_rewrite_.length() >=
- std::numeric_limits<uint16_t>::max()) {
- *ok = false;
- }
- }
-
// Properties count estimation.
int expected_property_count_;
@@ -471,6 +482,9 @@ class ParserBase {
ZoneList<typename ExpressionClassifier::Error> reported_errors_;
+ // A reason, if any, why this function should not be optimized.
+ BailoutReason dont_optimize_reason_;
+
// Record whether the next (=== immediately following) function literal is
// preceded by a parenthesis / exclamation mark. Also record the previous
// state.
@@ -1078,10 +1092,8 @@ class ParserBase {
return ParsePrimaryExpression(&is_async, ok);
}
- // This method wraps the parsing of the expression inside a new expression
- // classifier and calls RewriteNonPattern if parsing is successful.
- // It should be used whenever we're parsing an expression that is known
- // to not be a pattern or part of a pattern.
+ // Use when parsing an expression that is known to not be a pattern or part
+ // of a pattern.
V8_INLINE ExpressionT ParseExpression(bool accept_IN, bool* ok);
// This method does not wrap the parsing of the expression inside a
@@ -1201,14 +1213,15 @@ class ParserBase {
// by value. The method is expected to add the parsed statements to the
// list. This works because in the case of the parser, StatementListT is
// a pointer whereas the preparser does not really modify the body.
- V8_INLINE void ParseStatementList(StatementListT body, int end_token,
+ V8_INLINE void ParseStatementList(StatementListT body, Token::Value end_token,
bool* ok) {
LazyParsingResult result = ParseStatementList(body, end_token, false, ok);
USE(result);
DCHECK_EQ(result, kLazyParsingComplete);
}
- LazyParsingResult ParseStatementList(StatementListT body, int end_token,
- bool may_abort, bool* ok);
+ LazyParsingResult ParseStatementList(StatementListT body,
+ Token::Value end_token, bool may_abort,
+ bool* ok);
StatementT ParseStatementListItem(bool* ok);
StatementT ParseStatement(ZoneList<const AstRawString*>* labels, bool* ok) {
return ParseStatement(labels, kDisallowLabelledFunctionStatement, ok);
@@ -1463,21 +1476,18 @@ class ParserBase {
// Accumulates the classifier that is on top of the stack (inner) to
// the one that is right below (outer) and pops the inner.
- V8_INLINE void Accumulate(unsigned productions,
- bool merge_non_patterns = true) {
+ V8_INLINE void Accumulate(unsigned productions) {
DCHECK_NOT_NULL(classifier_);
ExpressionClassifier* previous = classifier_->previous();
DCHECK_NOT_NULL(previous);
- previous->Accumulate(classifier_, productions, merge_non_patterns);
+ previous->Accumulate(classifier_, productions);
classifier_ = previous;
}
V8_INLINE void AccumulateNonBindingPatternErrors() {
- static const bool kMergeNonPatterns = true;
this->Accumulate(ExpressionClassifier::AllProductions &
- ~(ExpressionClassifier::BindingPatternProduction |
- ExpressionClassifier::LetPatternProduction),
- kMergeNonPatterns);
+ ~(ExpressionClassifier::BindingPatternProduction |
+ ExpressionClassifier::LetPatternProduction));
}
// Pops and discards the classifier that is on top of the stack
@@ -1534,9 +1544,11 @@ class ParserBase {
bool allow_harmony_do_expressions_;
bool allow_harmony_function_sent_;
bool allow_harmony_public_fields_;
+ bool allow_harmony_static_fields_;
bool allow_harmony_dynamic_import_;
bool allow_harmony_import_meta_;
- bool allow_harmony_async_iteration_;
+ bool allow_harmony_optional_catch_binding_;
+ bool allow_harmony_private_fields_;
friend class DiscardableZoneScope;
};
@@ -1553,6 +1565,7 @@ ParserBase<Impl>::FunctionState::FunctionState(
destructuring_assignments_to_rewrite_(16, scope->zone()),
non_patterns_to_rewrite_(0, scope->zone()),
reported_errors_(16, scope->zone()),
+ dont_optimize_reason_(BailoutReason::kNoReason),
next_function_is_likely_called_(false),
previous_function_was_likely_called_(false),
contains_function_or_eval_(false) {
@@ -1587,6 +1600,7 @@ void ParserBase<Impl>::GetUnexpectedTokenMessage(
case Token::STRING:
*message = MessageTemplate::kUnexpectedTokenString;
break;
+ case Token::PRIVATE_NAME:
case Token::IDENTIFIER:
*message = MessageTemplate::kUnexpectedTokenIdentifier;
break;
@@ -1664,6 +1678,13 @@ ParserBase<Impl>::ParseAndClassifyIdentifier(bool* ok) {
if (next == Token::IDENTIFIER || next == Token::ASYNC ||
(next == Token::AWAIT && !parsing_module_ && !is_async_function())) {
IdentifierT name = impl()->GetSymbol();
+
+ if (impl()->IsArguments(name) && scope()->ShouldBanArguments()) {
+ ReportMessage(MessageTemplate::kArgumentsDisallowedInInitializer);
+ *ok = false;
+ return impl()->NullIdentifier();
+ }
+
// When this function is used to read a formal parameter, we don't always
// know whether the function is going to be strict or sloppy. Indeed for
// arrow functions we don't always know that the identifier we are reading
@@ -1942,7 +1963,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseExpression(
bool accept_IN, bool* ok) {
ExpressionClassifier classifier(this);
ExpressionT result = ParseExpressionCoverGrammar(accept_IN, CHECK_OK);
- impl()->RewriteNonPattern(CHECK_OK);
+ ValidateExpression(CHECK_OK);
return result;
}
@@ -2068,22 +2089,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseArrayLiteral(
}
Expect(Token::RBRACK, CHECK_OK);
- ExpressionT result =
- factory()->NewArrayLiteral(values, first_spread_index, pos);
- if (first_spread_index >= 0) {
- auto rewritable = factory()->NewRewritableExpression(result, scope());
- impl()->QueueNonPatternForRewriting(rewritable, ok);
- if (!*ok) {
- // If the non-pattern rewriting mechanism is used in the future for
- // rewriting other things than spreads, this error message will have
- // to change. Also, this error message will never appear while pre-
- // parsing (this is OK, as it is an implementation limitation).
- ReportMessage(MessageTemplate::kTooManySpreads);
- return impl()->NullExpression();
- }
- result = rewritable;
- }
- return result;
+ return factory()->NewArrayLiteral(values, first_spread_index, pos);
}
template <class Impl>
@@ -2108,6 +2114,9 @@ bool ParserBase<Impl>::SetPropertyKindFromToken(Token::Value token,
case Token::SEMICOLON:
*kind = PropertyKind::kClassField;
return true;
+ case Token::PRIVATE_NAME:
+ *kind = PropertyKind::kClassField;
+ return true;
default:
break;
}
@@ -2137,8 +2146,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePropertyName(
!scanner()->HasAnyLineTerminatorAfterNext()) {
Consume(Token::ASYNC);
token = peek();
- if (token == Token::MUL && allow_harmony_async_iteration() &&
- !scanner()->HasAnyLineTerminatorBeforeNext()) {
+ if (token == Token::MUL && !scanner()->HasAnyLineTerminatorBeforeNext()) {
Consume(Token::MUL);
token = peek();
*is_generator = true;
@@ -2198,7 +2206,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePropertyName(
Consume(Token::LBRACK);
ExpressionClassifier computed_name_classifier(this);
expression = ParseAssignmentExpression(true, CHECK_OK);
- impl()->RewriteNonPattern(CHECK_OK);
+ ValidateExpression(CHECK_OK);
AccumulateFormalParameterContainmentErrors();
Expect(Token::RBRACK, CHECK_OK);
break;
@@ -2270,6 +2278,8 @@ ParserBase<Impl>::ParseClassPropertyDefinition(
PropertyKind kind = PropertyKind::kNotSet;
Token::Value name_token = peek();
+ DCHECK_IMPLIES(name_token == Token::PRIVATE_NAME,
+ allow_harmony_private_fields());
int name_token_position = scanner()->peek_location().beg_pos;
IdentifierT name = impl()->NullIdentifier();
@@ -2285,12 +2295,22 @@ ParserBase<Impl>::ParseClassPropertyDefinition(
peek() == Token::RBRACE) {
name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'static'
name_expression = factory()->NewStringLiteral(name, position());
+ } else if (peek() == Token::PRIVATE_NAME) {
+ DCHECK(allow_harmony_private_fields());
+ // TODO(gsathya): Make a better error message for this.
+ ReportUnexpectedToken(Next());
+ *ok = false;
+ return impl()->NullLiteralProperty();
} else {
*is_static = true;
name_expression = ParsePropertyName(&name, &kind, &is_generator, &is_get,
&is_set, &is_async, is_computed_name,
CHECK_OK_CUSTOM(NullLiteralProperty));
}
+ } else if (name_token == Token::PRIVATE_NAME) {
+ Consume(Token::PRIVATE_NAME);
+ name = impl()->GetSymbol();
+ name_expression = factory()->NewStringLiteral(name, position());
} else {
name_expression = ParsePropertyName(&name, &kind, &is_generator, &is_get,
&is_set, &is_async, is_computed_name,
@@ -2312,9 +2332,14 @@ ParserBase<Impl>::ParseClassPropertyDefinition(
// as an uninitialized field.
case PropertyKind::kShorthandProperty:
case PropertyKind::kValueProperty:
- if (allow_harmony_public_fields()) {
+ if (allow_harmony_public_fields() || allow_harmony_private_fields()) {
*property_kind = ClassLiteralProperty::FIELD;
- if (!*is_computed_name) {
+ if (*is_static && !allow_harmony_static_fields()) {
+ ReportUnexpectedToken(Next());
+ *ok = false;
+ return impl()->NullLiteralProperty();
+ }
+ if (!*is_computed_name && name_token != Token::PRIVATE_NAME) {
checker->CheckClassFieldName(*is_static,
CHECK_OK_CUSTOM(NullLiteralProperty));
}
@@ -2362,7 +2387,7 @@ ParserBase<Impl>::ParseClassPropertyDefinition(
name, scanner()->location(), kSkipFunctionNameCheck, kind,
FLAG_harmony_function_tostring ? name_token_position
: kNoSourcePosition,
- FunctionLiteral::kAccessorOrMethod, language_mode(),
+ FunctionLiteral::kAccessorOrMethod, language_mode(), nullptr,
CHECK_OK_CUSTOM(NullLiteralProperty));
*property_kind = ClassLiteralProperty::METHOD;
@@ -2394,7 +2419,7 @@ ParserBase<Impl>::ParseClassPropertyDefinition(
name, scanner()->location(), kSkipFunctionNameCheck, kind,
FLAG_harmony_function_tostring ? name_token_position
: kNoSourcePosition,
- FunctionLiteral::kAccessorOrMethod, language_mode(),
+ FunctionLiteral::kAccessorOrMethod, language_mode(), nullptr,
CHECK_OK_CUSTOM(NullLiteralProperty));
*property_kind =
@@ -2427,7 +2452,8 @@ ParserBase<Impl>::ParseClassFieldInitializer(ClassInfo* class_info,
: class_info->instance_fields_scope;
if (initializer_scope == nullptr) {
- initializer_scope = NewFunctionScope(FunctionKind::kConciseMethod);
+ initializer_scope =
+ NewFunctionScope(FunctionKind::kClassFieldsInitializerFunction);
// TODO(gsathya): Make scopes be non contiguous.
initializer_scope->set_start_position(scanner()->location().end_pos);
initializer_scope->SetLanguageMode(LanguageMode::kStrict);
@@ -2441,7 +2467,7 @@ ParserBase<Impl>::ParseClassFieldInitializer(ClassInfo* class_info,
initializer =
ParseAssignmentExpression(true, CHECK_OK_CUSTOM(NullExpression));
- impl()->RewriteNonPattern(CHECK_OK_CUSTOM(NullExpression));
+ ValidateExpression(CHECK_OK_CUSTOM(NullExpression));
} else {
initializer = factory()->NewUndefinedLiteral(kNoSourcePosition);
}
@@ -2560,7 +2586,7 @@ ParserBase<Impl>::ParseObjectPropertyDefinition(ObjectLiteralChecker* checker,
ExpressionClassifier rhs_classifier(this);
ExpressionT rhs = ParseAssignmentExpression(
true, CHECK_OK_CUSTOM(NullLiteralProperty));
- impl()->RewriteNonPattern(CHECK_OK_CUSTOM(NullLiteralProperty));
+ ValidateExpression(CHECK_OK_CUSTOM(NullLiteralProperty));
AccumulateFormalParameterContainmentErrors();
value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs,
kNoSourcePosition);
@@ -2595,7 +2621,7 @@ ParserBase<Impl>::ParseObjectPropertyDefinition(ObjectLiteralChecker* checker,
ExpressionT value = impl()->ParseFunctionLiteral(
name, scanner()->location(), kSkipFunctionNameCheck, kind,
FLAG_harmony_function_tostring ? next_beg_pos : kNoSourcePosition,
- FunctionLiteral::kAccessorOrMethod, language_mode(),
+ FunctionLiteral::kAccessorOrMethod, language_mode(), nullptr,
CHECK_OK_CUSTOM(NullLiteralProperty));
ObjectLiteralPropertyT result = factory()->NewObjectLiteralProperty(
@@ -2627,7 +2653,7 @@ ParserBase<Impl>::ParseObjectPropertyDefinition(ObjectLiteralChecker* checker,
FunctionLiteralT value = impl()->ParseFunctionLiteral(
name, scanner()->location(), kSkipFunctionNameCheck, kind,
FLAG_harmony_function_tostring ? next_beg_pos : kNoSourcePosition,
- FunctionLiteral::kAccessorOrMethod, language_mode(),
+ FunctionLiteral::kAccessorOrMethod, language_mode(), nullptr,
CHECK_OK_CUSTOM(NullLiteralProperty));
ObjectLiteralPropertyT result = factory()->NewObjectLiteralProperty(
@@ -2711,8 +2737,8 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral(
MessageTemplate::kTooManyArguments);
}
- return factory()->NewObjectLiteral(
- properties, number_of_boilerplate_properties, pos, has_rest_property);
+ return impl()->InitializeObjectLiteral(factory()->NewObjectLiteral(
+ properties, number_of_boilerplate_properties, pos, has_rest_property));
}
template <typename Impl>
@@ -2738,7 +2764,7 @@ typename ParserBase<Impl>::ExpressionListT ParserBase<Impl>::ParseArguments(
*is_simple_parameter_list = false;
}
if (!maybe_arrow) {
- impl()->RewriteNonPattern(CHECK_OK_CUSTOM(NullExpressionList));
+ ValidateExpression(CHECK_OK_CUSTOM(NullExpressionList));
}
if (is_spread) {
if (is_simple_parameter_list != nullptr) {
@@ -2784,7 +2810,7 @@ typename ParserBase<Impl>::ExpressionListT ParserBase<Impl>::ParseArguments(
if (!maybe_arrow || peek() != Token::ARROW) {
if (maybe_arrow) {
- impl()->RewriteNonPattern(CHECK_OK_CUSTOM(NullExpressionList));
+ ValidateExpression(CHECK_OK_CUSTOM(NullExpressionList));
}
}
@@ -2864,7 +2890,6 @@ ParserBase<Impl>::ParseAssignmentExpression(bool accept_IN, bool* ok) {
// Because the arrow's parameters were parsed in the outer scope,
// we need to fix up the scope chain appropriately.
scope_snapshot.Reparent(scope);
- function_state_->SetDestructuringAssignmentsScope(rewritable_length, scope);
FormalParametersT parameters(scope);
if (!classifier()->is_simple_parameter_list()) {
@@ -2914,15 +2939,8 @@ ParserBase<Impl>::ParseAssignmentExpression(bool accept_IN, bool* ok) {
productions &= ~ExpressionClassifier::ExpressionProduction;
}
- if (!Token::IsAssignmentOp(peek())) {
- // Parsed conditional expression only (no assignment).
- // Pending non-pattern expressions must be merged.
- Accumulate(productions);
- return expression;
- } else {
- // Pending non-pattern expressions must be discarded.
- Accumulate(productions, false);
- }
+ Accumulate(productions);
+ if (!Token::IsAssignmentOp(peek())) return expression;
if (is_destructuring_assignment) {
ValidateAssignmentPattern(CHECK_OK);
@@ -2945,7 +2963,7 @@ ParserBase<Impl>::ParseAssignmentExpression(bool accept_IN, bool* ok) {
ExpressionClassifier rhs_classifier(this);
ExpressionT right = ParseAssignmentExpression(accept_IN, CHECK_OK);
- impl()->RewriteNonPattern(CHECK_OK);
+ ValidateExpression(CHECK_OK);
AccumulateFormalParameterContainmentErrors();
// We try to estimate the set of properties set by constructors. We define a
@@ -3019,7 +3037,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseYieldExpression(
// Delegating yields require an RHS; fall through.
default:
expression = ParseAssignmentExpression(accept_IN, CHECK_OK);
- impl()->RewriteNonPattern(CHECK_OK);
+ ValidateExpression(CHECK_OK);
break;
}
}
@@ -3052,7 +3070,7 @@ ParserBase<Impl>::ParseConditionalExpression(bool accept_IN,
// We start using the binary expression parser for prec >= 4 only!
ExpressionT expression = ParseBinaryExpression(4, accept_IN, CHECK_OK);
if (peek() != Token::CONDITIONAL) return expression;
- impl()->RewriteNonPattern(CHECK_OK);
+ ValidateExpression(CHECK_OK);
BindingPatternUnexpectedToken();
ArrowFormalParametersUnexpectedToken();
@@ -3067,7 +3085,7 @@ ParserBase<Impl>::ParseConditionalExpression(bool accept_IN,
left = ParseAssignmentExpression(true, CHECK_OK);
AccumulateNonBindingPatternErrors();
}
- impl()->RewriteNonPattern(CHECK_OK);
+ ValidateExpression(CHECK_OK);
ExpressionT right;
{
SourceRangeScope range_scope(scanner(), &else_range);
@@ -3076,7 +3094,7 @@ ParserBase<Impl>::ParseConditionalExpression(bool accept_IN,
right = ParseAssignmentExpression(accept_IN, CHECK_OK);
AccumulateNonBindingPatternErrors();
}
- impl()->RewriteNonPattern(CHECK_OK);
+ ValidateExpression(CHECK_OK);
ExpressionT expr = factory()->NewConditional(expression, left, right, pos);
impl()->RecordConditionalSourceRange(expr, then_range, else_range);
return expr;
@@ -3093,7 +3111,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseBinaryExpression(
for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
// prec1 >= 4
while (Precedence(peek(), accept_IN) == prec1) {
- impl()->RewriteNonPattern(CHECK_OK);
+ ValidateExpression(CHECK_OK);
BindingPatternUnexpectedToken();
ArrowFormalParametersUnexpectedToken();
@@ -3105,7 +3123,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseBinaryExpression(
const int next_prec = is_right_associative ? prec1 : prec1 + 1;
ExpressionT y = ParseBinaryExpression(next_prec, accept_IN, CHECK_OK);
right_range_scope.Finalize();
- impl()->RewriteNonPattern(CHECK_OK);
+ ValidateExpression(CHECK_OK);
if (impl()->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos)) {
continue;
@@ -3171,7 +3189,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseUnaryExpression(
}
ExpressionT expression = ParseUnaryExpression(CHECK_OK);
- impl()->RewriteNonPattern(CHECK_OK);
+ ValidateExpression(CHECK_OK);
if (op == Token::DELETE && is_strict(language_mode())) {
if (impl()->IsIdentifier(expression)) {
@@ -3200,7 +3218,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseUnaryExpression(
expression, beg_pos, scanner()->location().end_pos,
MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK);
impl()->MarkExpressionAsAssigned(expression);
- impl()->RewriteNonPattern(CHECK_OK);
+ ValidateExpression(CHECK_OK);
return factory()->NewCountOperation(op,
true /* prefix */,
@@ -3211,12 +3229,15 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseUnaryExpression(
classifier()->RecordFormalParameterInitializerError(
scanner()->peek_location(),
MessageTemplate::kAwaitExpressionFormalParameter);
-
int await_pos = peek_position();
Consume(Token::AWAIT);
ExpressionT value = ParseUnaryExpression(CHECK_OK);
+ classifier()->RecordBindingPatternError(
+ Scanner::Location(await_pos, scanner()->location().end_pos),
+ MessageTemplate::kInvalidDestructuringTarget);
+
ExpressionT expr = factory()->NewAwait(value, await_pos);
impl()->RecordSuspendSourceRange(expr, PositionAfterSemicolon());
return expr;
@@ -3242,7 +3263,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePostfixExpression(
expression, lhs_beg_pos, scanner()->location().end_pos,
MessageTemplate::kInvalidLhsInPostfixOp, CHECK_OK);
impl()->MarkExpressionAsAssigned(expression);
- impl()->RewriteNonPattern(CHECK_OK);
+ ValidateExpression(CHECK_OK);
Token::Value next = Next();
expression =
@@ -3267,13 +3288,13 @@ ParserBase<Impl>::ParseLeftHandSideExpression(bool* ok) {
while (true) {
switch (peek()) {
case Token::LBRACK: {
- impl()->RewriteNonPattern(CHECK_OK);
+ ValidateExpression(CHECK_OK);
BindingPatternUnexpectedToken();
ArrowFormalParametersUnexpectedToken();
Consume(Token::LBRACK);
int pos = position();
ExpressionT index = ParseExpressionCoverGrammar(true, CHECK_OK);
- impl()->RewriteNonPattern(CHECK_OK);
+ ValidateExpression(CHECK_OK);
result = factory()->NewProperty(result, index, pos);
Expect(Token::RBRACK, CHECK_OK);
break;
@@ -3281,7 +3302,7 @@ ParserBase<Impl>::ParseLeftHandSideExpression(bool* ok) {
case Token::LPAREN: {
int pos;
- impl()->RewriteNonPattern(CHECK_OK);
+ ValidateExpression(CHECK_OK);
BindingPatternUnexpectedToken();
if (scanner()->current_token() == Token::IDENTIFIER ||
scanner()->current_token() == Token::SUPER ||
@@ -3373,7 +3394,7 @@ ParserBase<Impl>::ParseLeftHandSideExpression(bool* ok) {
}
case Token::PERIOD: {
- impl()->RewriteNonPattern(CHECK_OK);
+ ValidateExpression(CHECK_OK);
BindingPatternUnexpectedToken();
ArrowFormalParametersUnexpectedToken();
Consume(Token::PERIOD);
@@ -3387,7 +3408,7 @@ ParserBase<Impl>::ParseLeftHandSideExpression(bool* ok) {
case Token::TEMPLATE_SPAN:
case Token::TEMPLATE_TAIL: {
- impl()->RewriteNonPattern(CHECK_OK);
+ ValidateExpression(CHECK_OK);
BindingPatternUnexpectedToken();
ArrowFormalParametersUnexpectedToken();
result = ParseTemplateLiteral(result, position(), true, CHECK_OK);
@@ -3446,7 +3467,7 @@ ParserBase<Impl>::ParseMemberWithNewPrefixesExpression(bool* is_async,
} else {
result = ParseMemberWithNewPrefixesExpression(is_async, CHECK_OK);
}
- impl()->RewriteNonPattern(CHECK_OK);
+ ValidateExpression(CHECK_OK);
if (peek() == Token::LPAREN) {
// NewExpression with arguments.
Scanner::Location spread_pos;
@@ -3537,7 +3558,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseMemberExpression(
is_strict_reserved_name ? kFunctionNameIsStrictReserved
: kFunctionNameValidityUnknown,
function_kind, function_token_position, function_type, language_mode(),
- CHECK_OK);
+ nullptr, CHECK_OK);
} else if (peek() == Token::SUPER) {
const bool is_new = false;
result = ParseSuperExpression(is_new, CHECK_OK);
@@ -3657,14 +3678,14 @@ ParserBase<Impl>::ParseMemberExpressionContinuation(ExpressionT expression,
switch (peek()) {
case Token::LBRACK: {
*is_async = false;
- impl()->RewriteNonPattern(CHECK_OK);
+ ValidateExpression(CHECK_OK);
BindingPatternUnexpectedToken();
ArrowFormalParametersUnexpectedToken();
Consume(Token::LBRACK);
int pos = position();
ExpressionT index = ParseExpressionCoverGrammar(true, CHECK_OK);
- impl()->RewriteNonPattern(CHECK_OK);
+ ValidateExpression(CHECK_OK);
expression = factory()->NewProperty(expression, index, pos);
impl()->PushPropertyName(index);
Expect(Token::RBRACK, CHECK_OK);
@@ -3672,13 +3693,19 @@ ParserBase<Impl>::ParseMemberExpressionContinuation(ExpressionT expression,
}
case Token::PERIOD: {
*is_async = false;
- impl()->RewriteNonPattern(CHECK_OK);
+ ValidateExpression(CHECK_OK);
BindingPatternUnexpectedToken();
ArrowFormalParametersUnexpectedToken();
Consume(Token::PERIOD);
int pos = peek_position();
- IdentifierT name = ParseIdentifierName(CHECK_OK);
+ IdentifierT name;
+ if (allow_harmony_private_fields() && peek() == Token::PRIVATE_NAME) {
+ Consume(Token::PRIVATE_NAME);
+ name = impl()->GetSymbol();
+ } else {
+ name = ParseIdentifierName(CHECK_OK);
+ }
expression = factory()->NewProperty(
expression, factory()->NewStringLiteral(name, pos), pos);
impl()->PushLiteralName(name);
@@ -3687,7 +3714,7 @@ ParserBase<Impl>::ParseMemberExpressionContinuation(ExpressionT expression,
case Token::TEMPLATE_SPAN:
case Token::TEMPLATE_TAIL: {
*is_async = false;
- impl()->RewriteNonPattern(CHECK_OK);
+ ValidateExpression(CHECK_OK);
BindingPatternUnexpectedToken();
ArrowFormalParametersUnexpectedToken();
int pos;
@@ -3743,7 +3770,7 @@ void ParserBase<Impl>::ParseFormalParameter(FormalParametersT* parameters,
}
ExpressionClassifier init_classifier(this);
initializer = ParseAssignmentExpression(true, CHECK_OK_CUSTOM(Void));
- impl()->RewriteNonPattern(CHECK_OK_CUSTOM(Void));
+ ValidateExpression(CHECK_OK_CUSTOM(Void));
ValidateFormalParameterInitializer(CHECK_OK_CUSTOM(Void));
parameters->is_simple = false;
DiscardExpressionClassifier();
@@ -3882,7 +3909,7 @@ typename ParserBase<Impl>::BlockT ParserBase<Impl>::ParseVariableDeclarations(
ExpressionClassifier classifier(this);
value = ParseAssignmentExpression(var_context != kForStatement,
CHECK_OK_CUSTOM(NullStatement));
- impl()->RewriteNonPattern(CHECK_OK_CUSTOM(NullStatement));
+ ValidateExpression(CHECK_OK_CUSTOM(NullStatement));
variable_loc.end_pos = scanner()->location().end_pos;
if (!parsing_result->first_initializer_loc.IsValid()) {
@@ -3997,7 +4024,7 @@ ParserBase<Impl>::ParseHoistableDeclaration(
const bool is_async = flags & ParseFunctionFlags::kIsAsync;
DCHECK(!is_generator || !is_async);
- if (allow_harmony_async_iteration() && is_async && Check(Token::MUL)) {
+ if (is_async && Check(Token::MUL)) {
// Async generator
is_generator = true;
}
@@ -4025,7 +4052,7 @@ ParserBase<Impl>::ParseHoistableDeclaration(
FunctionLiteralT function = impl()->ParseFunctionLiteral(
name, scanner()->location(), name_validity, kind, pos,
- FunctionLiteral::kDeclaration, language_mode(),
+ FunctionLiteral::kDeclaration, language_mode(), nullptr,
CHECK_OK_CUSTOM(NullStatement));
// In ES6, a function behaves as a lexical binding, except in
@@ -4096,6 +4123,8 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseClassDeclaration(
template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseNativeDeclaration(
bool* ok) {
+ function_state_->DisableOptimization(BailoutReason::kNativeFunctionLiteral);
+
int pos = peek_position();
Expect(Token::FUNCTION, CHECK_OK_CUSTOM(NullStatement));
// Allow "eval" or "arguments" for backward compatibility.
@@ -4150,6 +4179,11 @@ void ParserBase<Impl>::ParseFunctionBody(
body = inner_block->statements();
}
+ // If we are parsing the source as if it is wrapped in a function, the source
+ // ends without a closing brace.
+ Token::Value closing_token =
+ function_type == FunctionLiteral::kWrapped ? Token::EOS : Token::RBRACE;
+
{
BlockState block_state(&scope_, inner_scope);
@@ -4162,7 +4196,7 @@ void ParserBase<Impl>::ParseFunctionBody(
} else if (IsAsyncFunction(kind)) {
ParseAsyncFunctionBody(inner_scope, body, CHECK_OK_VOID);
} else {
- ParseStatementList(body, Token::RBRACE, CHECK_OK_VOID);
+ ParseStatementList(body, closing_token, CHECK_OK_VOID);
}
if (IsDerivedConstructor(kind)) {
@@ -4172,7 +4206,7 @@ void ParserBase<Impl>::ParseFunctionBody(
}
}
- Expect(Token::RBRACE, CHECK_OK_VOID);
+ Expect(closing_token, CHECK_OK_VOID);
scope()->set_end_position(scanner()->location().end_pos);
if (!parameters.is_simple) {
@@ -4298,11 +4332,11 @@ typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseArrowFunctionLiteral(
bool accept_IN, const FormalParametersT& formal_parameters,
int rewritable_length, bool* ok) {
- const RuntimeCallStats::CounterId counters[2][2] = {
- {&RuntimeCallStats::ParseBackgroundArrowFunctionLiteral,
- &RuntimeCallStats::ParseArrowFunctionLiteral},
- {&RuntimeCallStats::PreParseBackgroundArrowFunctionLiteral,
- &RuntimeCallStats::PreParseArrowFunctionLiteral}};
+ const RuntimeCallCounterId counters[2][2] = {
+ {RuntimeCallCounterId::kParseBackgroundArrowFunctionLiteral,
+ RuntimeCallCounterId::kParseArrowFunctionLiteral},
+ {RuntimeCallCounterId::kPreParseBackgroundArrowFunctionLiteral,
+ RuntimeCallCounterId::kPreParseArrowFunctionLiteral}};
RuntimeCallTimerScope runtime_timer(
runtime_call_stats_,
counters[Impl::IsPreParser()][parsing_on_main_thread_]);
@@ -4337,6 +4371,11 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
FunctionState function_state(&function_state_, &scope_,
formal_parameters.scope);
+ // Move any queued destructuring assignments which appeared
+ // in this function's parameter list into its own function_state.
+ function_state.AdoptDestructuringAssignmentsFromParentState(
+ rewritable_length);
+
Expect(Token::ARROW, CHECK_OK);
if (peek() == Token::LBRACE) {
@@ -4360,14 +4399,10 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
USE(result);
formal_parameters.scope->ResetAfterPreparsing(ast_value_factory_,
false);
-
// Discard any queued destructuring assignments which appeared
- // in this function's parameter list.
- FunctionState* parent_state = function_state.outer();
- DCHECK_NOT_NULL(parent_state);
- DCHECK_GE(parent_state->destructuring_assignments_to_rewrite().length(),
- rewritable_length);
- parent_state->RewindDestructuringAssignments(rewritable_length);
+ // in this function's parameter list, and which were adopted
+ // into this function state, above.
+ function_state.RewindDestructuringAssignments(0);
} else {
Consume(Token::LBRACE);
body = impl()->NewStatementList(8);
@@ -4467,9 +4502,10 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseClassLiteral(
scope()->set_start_position(scanner()->location().end_pos);
if (Check(Token::EXTENDS)) {
+ FuncNameInferrer::State fni_state(fni_);
ExpressionClassifier extends_classifier(this);
class_info.extends = ParseLeftHandSideExpression(CHECK_OK);
- impl()->RewriteNonPattern(CHECK_OK);
+ ValidateExpression(CHECK_OK);
AccumulateFormalParameterContainmentErrors();
}
@@ -4501,7 +4537,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseClassLiteral(
class_info.computed_field_count++;
}
is_constructor &= class_info.has_seen_constructor;
- impl()->RewriteNonPattern(CHECK_OK);
+ ValidateExpression(CHECK_OK);
AccumulateFormalParameterContainmentErrors();
impl()->DeclareClassProperty(name, property, property_kind, is_static,
@@ -4526,7 +4562,7 @@ void ParserBase<Impl>::ParseSingleExpressionFunctionBody(StatementListT body,
ExpressionClassifier classifier(this);
ExpressionT expression = ParseAssignmentExpression(accept_IN, CHECK_OK_VOID);
- impl()->RewriteNonPattern(CHECK_OK_VOID);
+ ValidateExpression(CHECK_OK_VOID);
if (is_async) {
BlockT block = factory()->NewBlock(1, true);
@@ -4564,7 +4600,7 @@ ParserBase<Impl>::ParseAsyncFunctionLiteral(bool* ok) {
IdentifierT name = impl()->NullIdentifier();
FunctionLiteral::FunctionType type = FunctionLiteral::kAnonymousExpression;
- bool is_generator = allow_harmony_async_iteration() && Check(Token::MUL);
+ bool is_generator = Check(Token::MUL);
const bool kIsAsync = true;
const FunctionKind kind = FunctionKindFor(is_generator, kIsAsync);
@@ -4590,7 +4626,7 @@ ParserBase<Impl>::ParseAsyncFunctionLiteral(bool* ok) {
name, scanner()->location(),
is_strict_reserved ? kFunctionNameIsStrictReserved
: kFunctionNameValidityUnknown,
- kind, pos, type, language_mode(), CHECK_OK);
+ kind, pos, type, language_mode(), nullptr, CHECK_OK);
}
template <typename Impl>
@@ -4650,7 +4686,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseTemplateLiteral(
int expr_pos = peek_position();
ExpressionT expression = ParseExpressionCoverGrammar(true, CHECK_OK);
- impl()->RewriteNonPattern(CHECK_OK);
+ ValidateExpression(CHECK_OK);
impl()->AddTemplateExpression(&ts, expression);
if (peek() != Token::RBRACE) {
@@ -4781,8 +4817,9 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseDoExpression(
template <typename Impl>
typename ParserBase<Impl>::LazyParsingResult
-ParserBase<Impl>::ParseStatementList(StatementListT body, int end_token,
- bool may_abort, bool* ok) {
+ParserBase<Impl>::ParseStatementList(StatementListT body,
+ Token::Value end_token, bool may_abort,
+ bool* ok) {
// StatementList ::
// (StatementListItem)* <end_token>
@@ -4953,8 +4990,7 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseStatement(
case Token::WHILE:
return ParseWhileStatement(labels, ok);
case Token::FOR:
- if (V8_UNLIKELY(allow_harmony_async_iteration() && is_async_function() &&
- PeekAhead() == Token::AWAIT)) {
+ if (V8_UNLIKELY(is_async_function() && PeekAhead() == Token::AWAIT)) {
return ParseForAwaitStatement(labels, ok);
}
return ParseForStatement(labels, ok);
@@ -5175,11 +5211,6 @@ ParserBase<Impl>::ParseExpressionOrLabelledStatement(
// Parsed expression statement, followed by semicolon.
ExpectSemicolon(CHECK_OK);
- if (labels != nullptr) {
- // TODO(adamk): Also measure in the PreParser by passing something
- // non-null as |labels|.
- impl()->CountUsage(v8::Isolate::kLabeledExpressionStatement);
- }
return factory()->NewExpressionStatement(expr, pos);
}
@@ -5204,8 +5235,9 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseIfStatement(
StatementT else_statement = impl()->NullStatement();
if (Check(Token::ELSE)) {
- SourceRangeScope range_scope(scanner(), &else_range);
+ else_range = SourceRange::ContinuationOf(then_range);
else_statement = ParseScopedStatement(labels, CHECK_OK);
+ else_range.end = scanner_->location().end_pos;
} else {
else_statement = factory()->NewEmptyStatement(kNoSourcePosition);
}
@@ -5547,50 +5579,60 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseTryStatement(
{
SourceRangeScope catch_range_scope(scanner(), &catch_range);
if (Check(Token::CATCH)) {
- Expect(Token::LPAREN, CHECK_OK);
- catch_info.scope = NewScope(CATCH_SCOPE);
- catch_info.scope->set_start_position(scanner()->location().beg_pos);
-
- {
- BlockState catch_block_state(&scope_, catch_info.scope);
+ bool has_binding;
+ if (allow_harmony_optional_catch_binding()) {
+ has_binding = Check(Token::LPAREN);
+ } else {
+ has_binding = true;
+ Expect(Token::LPAREN, CHECK_OK);
+ }
- catch_block = factory()->NewBlock(16, false);
+ if (has_binding) {
+ catch_info.scope = NewScope(CATCH_SCOPE);
+ catch_info.scope->set_start_position(scanner()->location().beg_pos);
- // Create a block scope to hold any lexical declarations created
- // as part of destructuring the catch parameter.
{
- BlockState catch_variable_block_state(zone(), &scope_);
- scope()->set_start_position(scanner()->location().beg_pos);
- typename Types::Target target(this, catch_block);
-
- // This does not simply call ParsePrimaryExpression to avoid
- // ExpressionFromIdentifier from being called in the first
- // branch, which would introduce an unresolved symbol and mess
- // with arrow function names.
- if (peek_any_identifier()) {
- catch_info.name =
- ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK);
- } else {
- ExpressionClassifier pattern_classifier(this);
- catch_info.pattern = ParsePrimaryExpression(CHECK_OK);
- ValidateBindingPattern(CHECK_OK);
- }
+ BlockState catch_block_state(&scope_, catch_info.scope);
+
+ catch_block = factory()->NewBlock(16, false);
+
+ // Create a block scope to hold any lexical declarations created
+ // as part of destructuring the catch parameter.
+ {
+ BlockState catch_variable_block_state(zone(), &scope_);
+ scope()->set_start_position(scanner()->location().beg_pos);
+
+ // This does not simply call ParsePrimaryExpression to avoid
+ // ExpressionFromIdentifier from being called in the first
+ // branch, which would introduce an unresolved symbol and mess
+ // with arrow function names.
+ if (peek_any_identifier()) {
+ catch_info.name =
+ ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK);
+ } else {
+ ExpressionClassifier pattern_classifier(this);
+ catch_info.pattern = ParsePrimaryExpression(CHECK_OK);
+ ValidateBindingPattern(CHECK_OK);
+ }
- Expect(Token::RPAREN, CHECK_OK);
- impl()->RewriteCatchPattern(&catch_info, CHECK_OK);
- if (!impl()->IsNull(catch_info.init_block)) {
- catch_block->statements()->Add(catch_info.init_block, zone());
- }
+ Expect(Token::RPAREN, CHECK_OK);
+ impl()->RewriteCatchPattern(&catch_info, CHECK_OK);
+ if (!impl()->IsNull(catch_info.init_block)) {
+ catch_block->statements()->Add(catch_info.init_block, zone());
+ }
- catch_info.inner_block = ParseBlock(nullptr, CHECK_OK);
- catch_block->statements()->Add(catch_info.inner_block, zone());
- impl()->ValidateCatchBlock(catch_info, CHECK_OK);
- scope()->set_end_position(scanner()->location().end_pos);
- catch_block->set_scope(scope()->FinalizeBlockScope());
+ catch_info.inner_block = ParseBlock(nullptr, CHECK_OK);
+ catch_block->statements()->Add(catch_info.inner_block, zone());
+ impl()->ValidateCatchBlock(catch_info, CHECK_OK);
+ scope()->set_end_position(scanner()->location().end_pos);
+ catch_block->set_scope(scope()->FinalizeBlockScope());
+ }
}
- }
- catch_info.scope->set_end_position(scanner()->location().end_pos);
+ catch_info.scope->set_end_position(scanner()->location().end_pos);
+ } else {
+ catch_block = ParseBlock(nullptr, CHECK_OK);
+ }
}
}
@@ -5687,7 +5729,7 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForStatement(
if (is_destructuring) {
ValidateAssignmentPattern(CHECK_OK);
} else {
- impl()->RewriteNonPattern(CHECK_OK);
+ ValidateExpression(CHECK_OK);
}
if (is_for_each) {
@@ -5750,7 +5792,7 @@ ParserBase<Impl>::ParseForEachStatementWithDeclarations(
if (for_info->mode == ForEachStatement::ITERATE) {
ExpressionClassifier classifier(this);
enumerable = ParseAssignmentExpression(true, CHECK_OK);
- impl()->RewriteNonPattern(CHECK_OK);
+ ValidateExpression(CHECK_OK);
} else {
enumerable = ParseExpression(true, CHECK_OK);
}
@@ -5826,7 +5868,7 @@ ParserBase<Impl>::ParseForEachStatementWithoutDeclarations(
if (for_info->mode == ForEachStatement::ITERATE) {
ExpressionClassifier classifier(this);
enumerable = ParseAssignmentExpression(true, CHECK_OK);
- impl()->RewriteNonPattern(CHECK_OK);
+ ValidateExpression(CHECK_OK);
} else {
enumerable = ParseExpression(true, CHECK_OK);
}
@@ -5945,7 +5987,6 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForAwaitStatement(
ZoneList<const AstRawString*>* labels, bool* ok) {
// for await '(' ForDeclaration of AssignmentExpression ')'
DCHECK(is_async_function());
- DCHECK(allow_harmony_async_iteration());
int stmt_pos = peek_position();
@@ -6014,7 +6055,7 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForAwaitStatement(
if (lhs->IsArrayLiteral() || lhs->IsObjectLiteral()) {
ValidateAssignmentPattern(CHECK_OK);
} else {
- impl()->RewriteNonPattern(CHECK_OK);
+ ValidateExpression(CHECK_OK);
each_variable = CheckAndRewriteReferenceExpression(
lhs, lhs_beg_pos, lhs_end_pos, MessageTemplate::kInvalidLhsInFor,
kSyntaxError, CHECK_OK);
@@ -6030,7 +6071,7 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForAwaitStatement(
{
ExpressionClassifier classifier(this);
iterable = ParseAssignmentExpression(kAllowIn, CHECK_OK);
- impl()->RewriteNonPattern(CHECK_OK);
+ ValidateExpression(CHECK_OK);
}
Expect(Token::RPAREN, CHECK_OK);
diff --git a/deps/v8/src/parsing/parser.cc b/deps/v8/src/parsing/parser.cc
index 4d291a741e..0497958c82 100644
--- a/deps/v8/src/parsing/parser.cc
+++ b/deps/v8/src/parsing/parser.cc
@@ -276,18 +276,18 @@ bool Parser::ShortcutNumericLiteralBinaryExpression(Expression** x,
return true;
}
case Token::SHL: {
- int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f);
+ int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1F);
*x = factory()->NewNumberLiteral(value, pos);
return true;
}
case Token::SHR: {
- uint32_t shift = DoubleToInt32(y_val) & 0x1f;
+ uint32_t shift = DoubleToInt32(y_val) & 0x1F;
uint32_t value = DoubleToUint32(x_val) >> shift;
*x = factory()->NewNumberLiteral(value, pos);
return true;
}
case Token::SAR: {
- uint32_t shift = DoubleToInt32(y_val) & 0x1f;
+ uint32_t shift = DoubleToInt32(y_val) & 0x1F;
int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
*x = factory()->NewNumberLiteral(value, pos);
return true;
@@ -506,7 +506,7 @@ Parser::Parser(ParseInfo* info)
info->runtime_call_stats(), info->logger(),
info->script().is_null() ? -1 : info->script()->id(),
info->is_module(), true),
- scanner_(info->unicode_cache(), use_counts_),
+ scanner_(info->unicode_cache()),
reusable_preparser_(nullptr),
mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly.
source_range_map_(info->source_range_map()),
@@ -543,10 +543,12 @@ Parser::Parser(ParseInfo* info)
set_allow_harmony_do_expressions(FLAG_harmony_do_expressions);
set_allow_harmony_function_sent(FLAG_harmony_function_sent);
set_allow_harmony_public_fields(FLAG_harmony_public_fields);
+ set_allow_harmony_static_fields(FLAG_harmony_static_fields);
set_allow_harmony_dynamic_import(FLAG_harmony_dynamic_import);
set_allow_harmony_import_meta(FLAG_harmony_import_meta);
- set_allow_harmony_async_iteration(FLAG_harmony_async_iteration);
set_allow_harmony_bigint(FLAG_harmony_bigint);
+ set_allow_harmony_optional_catch_binding(FLAG_harmony_optional_catch_binding);
+ set_allow_harmony_private_fields(FLAG_harmony_private_fields);
for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
++feature) {
use_counts_[feature] = 0;
@@ -592,8 +594,9 @@ FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) {
// called in the main thread.
DCHECK(parsing_on_main_thread_);
RuntimeCallTimerScope runtime_timer(
- runtime_call_stats_, info->is_eval() ? &RuntimeCallStats::ParseEval
- : &RuntimeCallStats::ParseProgram);
+ runtime_call_stats_, info->is_eval()
+ ? RuntimeCallCounterId::kParseEval
+ : RuntimeCallCounterId::kParseProgram);
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseProgram");
base::ElapsedTimer timer;
if (V8_UNLIKELY(FLAG_log_function_events)) timer.Start();
@@ -667,11 +670,9 @@ FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) {
}
DeclarationScope* scope = outer->AsDeclarationScope();
-
scope->set_start_position(0);
FunctionState function_state(&function_state_, &scope_, scope);
-
ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone());
bool ok = true;
int beg_pos = scanner()->location().beg_pos;
@@ -689,7 +690,6 @@ FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) {
var->AllocateTo(VariableLocation::PARAMETER, 0);
PrepareGeneratorVariables();
- scope->ForceContextAllocation();
Expression* initial_yield =
BuildInitialYield(kNoSourcePosition, kGeneratorFunction);
body->Add(
@@ -699,6 +699,8 @@ FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) {
ParseModuleItemList(body, &ok);
ok = ok && module()->Validate(this->scope()->AsModuleScope(),
pending_error_handler(), zone());
+ } else if (info->is_wrapped_as_function()) {
+ ParseWrapped(info, body, scope, zone(), &ok);
} else {
// Don't count the mode in the use counters--give the program a chance
// to enable script-wide strict mode below.
@@ -751,13 +753,53 @@ FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) {
return result;
}
+ZoneList<const AstRawString*>* Parser::PrepareWrappedArguments(ParseInfo* info,
+ Zone* zone) {
+ DCHECK(parsing_on_main_thread_);
+ Handle<FixedArray> arguments(info->script()->wrapped_arguments());
+ int arguments_length = arguments->length();
+ ZoneList<const AstRawString*>* arguments_for_wrapped_function =
+ new (zone) ZoneList<const AstRawString*>(arguments_length, zone);
+ for (int i = 0; i < arguments_length; i++) {
+ const AstRawString* argument_string = ast_value_factory()->GetString(
+ Handle<String>(String::cast(arguments->get(i))));
+ arguments_for_wrapped_function->Add(argument_string, zone);
+ }
+ return arguments_for_wrapped_function;
+}
+
+void Parser::ParseWrapped(ParseInfo* info, ZoneList<Statement*>* body,
+ DeclarationScope* outer_scope, Zone* zone, bool* ok) {
+ DCHECK(info->is_wrapped_as_function());
+ ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
+
+ // Set function and block state for the outer eval scope.
+ DCHECK(outer_scope->is_eval_scope());
+ FunctionState function_state(&function_state_, &scope_, outer_scope);
+
+ const AstRawString* function_name = nullptr;
+ Scanner::Location location(0, 0);
+
+ ZoneList<const AstRawString*>* arguments_for_wrapped_function =
+ PrepareWrappedArguments(info, zone);
+
+ FunctionLiteral* function_literal = ParseFunctionLiteral(
+ function_name, location, kSkipFunctionNameCheck, kNormalFunction,
+ kNoSourcePosition, FunctionLiteral::kWrapped, LanguageMode::kSloppy,
+ arguments_for_wrapped_function, CHECK_OK_VOID);
+
+ Statement* return_statement = factory()->NewReturnStatement(
+ function_literal, kNoSourcePosition, kNoSourcePosition);
+ body->Add(return_statement, zone);
+}
+
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);
+ RuntimeCallCounterId::kParseFunction);
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseFunction");
base::ElapsedTimer timer;
if (V8_UNLIKELY(FLAG_log_function_events)) timer.Start();
@@ -794,7 +836,9 @@ FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info,
}
static FunctionLiteral::FunctionType ComputeFunctionType(ParseInfo* info) {
- if (info->is_declaration()) {
+ if (info->is_wrapped_as_function()) {
+ return FunctionLiteral::kWrapped;
+ } else if (info->is_declaration()) {
return FunctionLiteral::kDeclaration;
} else if (info->is_named_expression()) {
return FunctionLiteral::kNamedExpression;
@@ -927,9 +971,13 @@ FunctionLiteral* Parser::DoParseFunction(ParseInfo* info,
result = DefaultConstructor(raw_name, IsDerivedConstructor(kind),
info->start_position(), info->end_position());
} else {
+ ZoneList<const AstRawString*>* arguments_for_wrapped_function =
+ info->is_wrapped_as_function() ? PrepareWrappedArguments(info, zone())
+ : nullptr;
result = ParseFunctionLiteral(
raw_name, Scanner::Location::invalid(), kSkipFunctionNameCheck, kind,
- kNoSourcePosition, function_type, info->language_mode(), &ok);
+ kNoSourcePosition, function_type, info->language_mode(),
+ arguments_for_wrapped_function, &ok);
}
if (ok) {
@@ -1251,7 +1299,7 @@ Statement* Parser::ParseExportDefault(bool* ok) {
int pos = position();
ExpressionClassifier classifier(this);
Expression* value = ParseAssignmentExpression(true, CHECK_OK);
- RewriteNonPattern(CHECK_OK);
+ ValidateExpression(CHECK_OK);
SetFunctionName(value, ast_value_factory()->default_string());
const AstRawString* local_name =
@@ -1714,7 +1762,6 @@ Statement* Parser::RewriteTryStatement(Block* try_block, Block* catch_block,
if (catch_block != nullptr && finally_block != nullptr) {
// If we have both, create an inner try/catch.
- DCHECK_NOT_NULL(catch_info.scope);
TryCatchStatement* statement;
statement = factory()->NewTryCatchStatement(try_block, catch_info.scope,
catch_block, kNoSourcePosition);
@@ -1727,7 +1774,6 @@ Statement* Parser::RewriteTryStatement(Block* try_block, Block* catch_block,
if (catch_block != nullptr) {
DCHECK_NULL(finally_block);
- DCHECK_NOT_NULL(catch_info.scope);
TryCatchStatement* stmt = factory()->NewTryCatchStatement(
try_block, catch_info.scope, catch_block, pos);
RecordTryCatchStatementSourceRange(stmt, catch_range);
@@ -1844,13 +1890,11 @@ void Parser::DeclareFunctionNameVar(const AstRawString* function_name,
// !%_IsJSReceiver(result = Await(iterator.next())) &&
// %ThrowIteratorResultNotAnObject(result)
// [endif]
-Expression* Parser::BuildIteratorNextResult(Expression* iterator,
+Expression* Parser::BuildIteratorNextResult(VariableProxy* iterator,
+ VariableProxy* next,
Variable* result, IteratorType type,
int pos) {
- Expression* next_literal = factory()->NewStringLiteral(
- ast_value_factory()->next_string(), kNoSourcePosition);
- Expression* next_property =
- factory()->NewProperty(iterator, next_literal, kNoSourcePosition);
+ Expression* next_property = factory()->NewResolvedProperty(iterator, next);
ZoneList<Expression*>* next_arguments =
new (zone()) ZoneList<Expression*>(0, zone());
Expression* next_call =
@@ -2053,6 +2097,7 @@ Statement* Parser::InitializeForOfStatement(
auto avfactory = ast_value_factory();
Variable* iterator = NewTemporary(avfactory->dot_iterator_string());
+ Variable* next = NewTemporary(avfactory->empty_string());
Variable* result = NewTemporary(avfactory->dot_result_string());
Variable* completion = NewTemporary(avfactory->empty_string());
@@ -2065,6 +2110,17 @@ Statement* Parser::InitializeForOfStatement(
iterable->position());
}
+ Expression* assign_next;
+ {
+ assign_next = factory()->NewAssignment(
+ Token::ASSIGN, factory()->NewVariableProxy(next),
+ factory()->NewProperty(factory()->NewVariableProxy(iterator),
+ factory()->NewStringLiteral(
+ avfactory->next_string(), kNoSourcePosition),
+ kNoSourcePosition),
+ kNoSourcePosition);
+ }
+
// [if (IteratorType == kNormal)]
// !%_IsJSReceiver(result = iterator.next()) &&
// %ThrowIteratorResultNotAnObject(result)
@@ -2074,9 +2130,10 @@ Statement* Parser::InitializeForOfStatement(
// [endif]
Expression* next_result;
{
- Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
- next_result =
- BuildIteratorNextResult(iterator_proxy, result, type, next_result_pos);
+ VariableProxy* iterator_proxy = factory()->NewVariableProxy(iterator);
+ VariableProxy* next_proxy = factory()->NewVariableProxy(next);
+ next_result = BuildIteratorNextResult(iterator_proxy, next_proxy, result,
+ type, next_result_pos);
}
// result.done
@@ -2146,8 +2203,8 @@ Statement* Parser::InitializeForOfStatement(
body = block;
}
- for_of->Initialize(body, iterator, assign_iterator, next_result, result_done,
- assign_each);
+ for_of->Initialize(body, iterator, assign_iterator, assign_next, next_result,
+ result_done, assign_each);
return finalize ? FinalizeForOfStatement(for_of, completion, type, nopos)
: for_of;
}
@@ -2510,7 +2567,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
const AstRawString* function_name, Scanner::Location function_name_location,
FunctionNameValidity function_name_validity, FunctionKind kind,
int function_token_pos, FunctionLiteral::FunctionType function_type,
- LanguageMode language_mode, bool* ok) {
+ LanguageMode language_mode,
+ ZoneList<const AstRawString*>* arguments_for_wrapped_function, bool* ok) {
// Function ::
// '(' FormalParameterList? ')' '{' FunctionBody '}'
//
@@ -2520,8 +2578,12 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
// Setter ::
// '(' PropertySetParameterList ')' '{' FunctionBody '}'
+ bool is_wrapped = function_type == FunctionLiteral::kWrapped;
+ DCHECK_EQ(is_wrapped, arguments_for_wrapped_function != nullptr);
+
int pos = function_token_pos == kNoSourcePosition ? peek_position()
: function_token_pos;
+ DCHECK_NE(kNoSourcePosition, pos);
// Anonymous functions were passed either the empty symbol or a null
// handle as the function name. Remember if we were passed a non-empty
@@ -2535,7 +2597,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
}
FunctionLiteral::EagerCompileHint eager_compile_hint =
- function_state_->next_function_is_likely_called()
+ function_state_->next_function_is_likely_called() || is_wrapped
? FunctionLiteral::kShouldEagerCompile
: default_eager_compile_hint();
@@ -2587,8 +2649,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
RuntimeCallTimerScope runtime_timer(
runtime_call_stats_,
parsing_on_main_thread_
- ? &RuntimeCallStats::ParseFunctionLiteral
- : &RuntimeCallStats::ParseBackgroundFunctionLiteral);
+ ? RuntimeCallCounterId::kParseFunctionLiteral
+ : RuntimeCallCounterId::kParseBackgroundFunctionLiteral);
base::ElapsedTimer timer;
if (V8_UNLIKELY(FLAG_log_function_events)) timer.Start();
@@ -2650,7 +2712,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
if (should_preparse) scope->set_needs_migration();
#endif
- Expect(Token::LPAREN, CHECK_OK);
+ if (!is_wrapped) 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
@@ -2661,6 +2723,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
if (should_preparse) {
DCHECK(parse_lazily());
DCHECK(is_lazy_top_level_function || is_lazy_inner_function);
+ DCHECK(!is_wrapped);
Scanner::BookmarkScope bookmark(scanner());
bookmark.Set();
LazyParsingResult result = SkipFunction(
@@ -2687,7 +2750,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
body = ParseFunction(function_name, pos, kind, function_type, scope,
&num_parameters, &function_length,
&has_duplicate_parameters, &expected_property_count,
- CHECK_OK);
+ arguments_for_wrapped_function, CHECK_OK);
}
DCHECK_EQ(should_preparse, temp_zoned_);
@@ -2705,18 +2768,20 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
}
if (V8_UNLIKELY(FLAG_runtime_stats)) {
if (should_preparse) {
- RuntimeCallStats::CounterId counter_id =
+ RuntimeCallCounterId counter_id =
parsing_on_main_thread_
- ? &RuntimeCallStats::PreParseWithVariableResolution
- : &RuntimeCallStats::PreParseBackgroundWithVariableResolution;
+ ? RuntimeCallCounterId::kPreParseWithVariableResolution
+ : RuntimeCallCounterId::
+ kPreParseBackgroundWithVariableResolution;
if (is_top_level) {
- counter_id =
- parsing_on_main_thread_
- ? &RuntimeCallStats::PreParseNoVariableResolution
- : &RuntimeCallStats::PreParseBackgroundNoVariableResolution;
+ counter_id = parsing_on_main_thread_
+ ? RuntimeCallCounterId::kPreParseNoVariableResolution
+ : RuntimeCallCounterId::
+ kPreParseBackgroundNoVariableResolution;
+ }
+ if (runtime_call_stats_) {
+ runtime_call_stats_->CorrectCurrentCounterId(counter_id);
}
- RuntimeCallStats::CorrectCurrentCounterId(runtime_call_stats_,
- counter_id);
}
}
@@ -3118,11 +3183,14 @@ ZoneList<Statement*>* Parser::ParseFunction(
const AstRawString* function_name, int pos, FunctionKind kind,
FunctionLiteral::FunctionType function_type,
DeclarationScope* function_scope, int* num_parameters, int* function_length,
- bool* has_duplicate_parameters, int* expected_property_count, bool* ok) {
+ bool* has_duplicate_parameters, int* expected_property_count,
+ ZoneList<const AstRawString*>* arguments_for_wrapped_function, bool* ok) {
ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);
FunctionState function_state(&function_state_, &scope_, function_scope);
+ bool is_wrapped = function_type == FunctionLiteral::kWrapped;
+
DuplicateFinder duplicate_finder;
ExpressionClassifier formals_classifier(this, &duplicate_finder);
@@ -3136,34 +3204,53 @@ ZoneList<Statement*>* Parser::ParseFunction(
}
ParserFormalParameters formals(function_scope);
- ParseFormalParameterList(&formals, CHECK_OK);
- if (expected_parameters_end_pos != kNoSourcePosition) {
- // Check for '(' or ')' shenanigans in the parameter string for dynamic
- // functions.
- int position = peek_position();
- if (position < expected_parameters_end_pos) {
- ReportMessageAt(Scanner::Location(position, position + 1),
- MessageTemplate::kArgStringTerminatesParametersEarly);
- *ok = false;
- return nullptr;
- } else if (position > expected_parameters_end_pos) {
- ReportMessageAt(Scanner::Location(expected_parameters_end_pos - 2,
- expected_parameters_end_pos),
- MessageTemplate::kUnexpectedEndOfArgString);
- *ok = false;
- return nullptr;
+
+ if (is_wrapped) {
+ // For a function implicitly wrapped in function header and footer, the
+ // function arguments are provided separately to the source, and are
+ // declared directly here.
+ int arguments_length = arguments_for_wrapped_function->length();
+ for (int i = 0; i < arguments_length; i++) {
+ const bool is_rest = false;
+ Expression* argument = ExpressionFromIdentifier(
+ arguments_for_wrapped_function->at(i), kNoSourcePosition);
+ AddFormalParameter(&formals, argument, NullExpression(),
+ kNoSourcePosition, is_rest);
+ }
+ DCHECK_EQ(arguments_length, formals.num_parameters());
+ DeclareFormalParameters(formals.scope, formals.params, formals.is_simple);
+ } else {
+ // For a regular function, the function arguments are parsed from source.
+ DCHECK_NULL(arguments_for_wrapped_function);
+ ParseFormalParameterList(&formals, CHECK_OK);
+ if (expected_parameters_end_pos != kNoSourcePosition) {
+ // Check for '(' or ')' shenanigans in the parameter string for dynamic
+ // functions.
+ int position = peek_position();
+ if (position < expected_parameters_end_pos) {
+ ReportMessageAt(Scanner::Location(position, position + 1),
+ MessageTemplate::kArgStringTerminatesParametersEarly);
+ *ok = false;
+ return nullptr;
+ } else if (position > expected_parameters_end_pos) {
+ ReportMessageAt(Scanner::Location(expected_parameters_end_pos - 2,
+ expected_parameters_end_pos),
+ MessageTemplate::kUnexpectedEndOfArgString);
+ *ok = false;
+ return nullptr;
+ }
}
+ Expect(Token::RPAREN, CHECK_OK);
+ int formals_end_position = scanner()->location().end_pos;
+
+ CheckArityRestrictions(formals.arity, kind, formals.has_rest,
+ function_scope->start_position(),
+ formals_end_position, CHECK_OK);
+ Expect(Token::LBRACE, CHECK_OK);
}
- Expect(Token::RPAREN, CHECK_OK);
- int formals_end_position = scanner()->location().end_pos;
*num_parameters = formals.num_parameters();
*function_length = formals.function_length;
- CheckArityRestrictions(formals.arity, kind, formals.has_rest,
- function_scope->start_position(), formals_end_position,
- CHECK_OK);
- Expect(Token::LBRACE, CHECK_OK);
-
ZoneList<Statement*>* body = new (zone()) ZoneList<Statement*>(8, zone());
ParseFunctionBody(body, function_name, pos, formals, kind, function_type, ok);
@@ -3240,9 +3327,10 @@ void Parser::DeclareClassProperty(const AstRawString* class_name,
return;
}
- DCHECK(allow_harmony_public_fields());
+ DCHECK(allow_harmony_public_fields() || allow_harmony_private_fields());
if (is_static) {
+ DCHECK(allow_harmony_static_fields());
class_info->static_fields->Add(property, zone());
} else {
class_info->instance_fields->Add(property, zone());
@@ -3262,6 +3350,8 @@ void Parser::DeclareClassProperty(const AstRawString* class_name,
FunctionLiteral* Parser::CreateInitializerFunction(
DeclarationScope* scope, ZoneList<ClassLiteral::Property*>* fields) {
+ DCHECK_EQ(scope->function_kind(),
+ FunctionKind::kClassFieldsInitializerFunction);
// function() { .. class fields initializer .. }
ZoneList<Statement*>* statements = NewStatementList(1);
InitializeClassFieldsStatement* static_fields =
@@ -3450,8 +3540,8 @@ void Parser::UpdateStatistics(Isolate* isolate, Handle<Script> script) {
}
void Parser::ParseOnBackground(ParseInfo* info) {
- RuntimeCallTimerScope runtimeTimer(runtime_call_stats_,
- &RuntimeCallStats::ParseBackgroundProgram);
+ RuntimeCallTimerScope runtimeTimer(
+ runtime_call_stats_, RuntimeCallCounterId::kParseBackgroundProgram);
parsing_on_main_thread_ = false;
if (!info->script().is_null()) {
set_script_id(info->script()->id());
@@ -3581,11 +3671,11 @@ namespace {
// http://burtleburtle.net/bob/hash/integer.html
uint32_t HalfAvalance(uint32_t a) {
- a = (a + 0x479ab41d) + (a << 8);
- a = (a ^ 0xe4aa10ce) ^ (a >> 5);
- a = (a + 0x9942f0a6) - (a << 14);
- a = (a ^ 0x5aedd67d) ^ (a >> 3);
- a = (a + 0x17bea992) + (a << 7);
+ a = (a + 0x479AB41D) + (a << 8);
+ a = (a ^ 0xE4AA10CE) ^ (a >> 5);
+ a = (a + 0x9942F0A6) - (a << 14);
+ a = (a ^ 0x5AEDD67D) ^ (a >> 3);
+ a = (a + 0x17BEA992) + (a << 7);
return a;
}
@@ -3808,24 +3898,6 @@ void Parser::RewriteAsyncFunctionBody(ZoneList<Statement*>* body, Block* block,
body->Add(block, zone());
}
-void Parser::RewriteNonPattern(bool* ok) {
- ValidateExpression(CHECK_OK_VOID);
- auto non_patterns_to_rewrite = function_state_->non_patterns_to_rewrite();
- int begin = classifier()->GetNonPatternBegin();
- int end = non_patterns_to_rewrite->length();
- if (begin < end) {
- for (int i = begin; i < end; i++) {
- RewritableExpression* expr = non_patterns_to_rewrite->at(i);
- // TODO(adamk): Make this more typesafe.
- DCHECK(expr->expression()->IsArrayLiteral());
- ArrayLiteral* lit = expr->expression()->AsArrayLiteral();
- expr->Rewrite(RewriteSpreads(lit));
- }
- non_patterns_to_rewrite->Rewind(begin);
- }
-}
-
-
void Parser::RewriteDestructuringAssignments() {
const auto& assignments =
function_state_->destructuring_assignments_to_rewrite();
@@ -3845,102 +3917,11 @@ void Parser::RewriteDestructuringAssignments() {
}
}
-Expression* Parser::RewriteSpreads(ArrayLiteral* lit) {
- // Array literals containing spreads are rewritten using do expressions, e.g.
- // [1, 2, 3, ...x, 4, ...y, 5]
- // is roughly rewritten as:
- // do {
- // $R = [1, 2, 3];
- // for ($i of x) %AppendElement($R, $i);
- // %AppendElement($R, 4);
- // for ($j of y) %AppendElement($R, $j);
- // %AppendElement($R, 5);
- // $R
- // }
- // where $R, $i and $j are fresh temporary variables.
- ZoneList<Expression*>::iterator s = lit->FirstSpread();
- if (s == lit->EndValue()) return nullptr; // no spread, no rewriting...
- Variable* result = NewTemporary(ast_value_factory()->dot_result_string());
- // NOTE: The value assigned to R is the whole original array literal,
- // spreads included. This will be fixed before the rewritten AST is returned.
- // $R = lit
- Expression* init_result = factory()->NewAssignment(
- Token::INIT, factory()->NewVariableProxy(result), lit, kNoSourcePosition);
- Block* do_block = factory()->NewBlock(16, false);
- do_block->statements()->Add(
- factory()->NewExpressionStatement(init_result, kNoSourcePosition),
- zone());
- // Traverse the array literal starting from the first spread.
- while (s != lit->EndValue()) {
- Expression* value = *s++;
- Spread* spread = value->AsSpread();
- if (spread == nullptr) {
- // If the element is not a spread, we're adding a single:
- // %AppendElement($R, value)
- // or, in case of a hole,
- // ++($R.length)
- if (!value->IsTheHoleLiteral()) {
- ZoneList<Expression*>* append_element_args = NewExpressionList(2);
- append_element_args->Add(factory()->NewVariableProxy(result), zone());
- append_element_args->Add(value, zone());
- do_block->statements()->Add(
- factory()->NewExpressionStatement(
- factory()->NewCallRuntime(Runtime::kAppendElement,
- append_element_args,
- kNoSourcePosition),
- kNoSourcePosition),
- zone());
- } else {
- Property* length_property = factory()->NewProperty(
- factory()->NewVariableProxy(result),
- factory()->NewStringLiteral(ast_value_factory()->length_string(),
- kNoSourcePosition),
- kNoSourcePosition);
- CountOperation* count_op = factory()->NewCountOperation(
- Token::INC, true /* prefix */, length_property, kNoSourcePosition);
- do_block->statements()->Add(
- factory()->NewExpressionStatement(count_op, kNoSourcePosition),
- zone());
- }
- } else {
- // If it's a spread, we're adding a for/of loop iterating through it.
- Variable* each = NewTemporary(ast_value_factory()->dot_for_string());
- Expression* subject = spread->expression();
- // %AppendElement($R, each)
- Statement* append_body;
- {
- ZoneList<Expression*>* append_element_args = NewExpressionList(2);
- append_element_args->Add(factory()->NewVariableProxy(result), zone());
- append_element_args->Add(factory()->NewVariableProxy(each), zone());
- append_body = factory()->NewExpressionStatement(
- factory()->NewCallRuntime(Runtime::kAppendElement,
- append_element_args, kNoSourcePosition),
- kNoSourcePosition);
- }
- // for (each of spread) %AppendElement($R, each)
- ForOfStatement* loop =
- factory()->NewForOfStatement(nullptr, kNoSourcePosition);
- const bool finalize = false;
- InitializeForOfStatement(loop, factory()->NewVariableProxy(each), subject,
- append_body, finalize, IteratorType::kNormal);
- do_block->statements()->Add(loop, zone());
- }
- }
- // Now, rewind the original array literal to truncate everything from the
- // first spread (included) until the end. This fixes $R's initialization.
- lit->RewindSpreads();
- return factory()->NewDoExpression(do_block, result, lit->position());
-}
-
void Parser::QueueDestructuringAssignmentForRewriting(
RewritableExpression* expr) {
function_state_->AddDestructuringAssignment(expr);
}
-void Parser::QueueNonPatternForRewriting(RewritableExpression* expr, bool* ok) {
- function_state_->AddNonPatternForRewriting(expr, ok);
-}
-
void Parser::SetFunctionNameFromPropertyName(LiteralProperty* property,
const AstRawString* name,
const AstRawString* prefix) {
@@ -4315,9 +4296,8 @@ void Parser::BuildIteratorCloseForCompletion(ZoneList<Statement*>* statements,
zone());
Block* catch_block = factory()->NewBlock(0, false);
- Scope* catch_scope = NewHiddenCatchScope();
- try_call_return = factory()->NewTryCatchStatement(try_block, catch_scope,
- catch_block, nopos);
+ try_call_return =
+ factory()->NewTryCatchStatement(try_block, nullptr, catch_block, nopos);
}
// let output = %_Call(iteratorReturn, iterator);
diff --git a/deps/v8/src/parsing/parser.h b/deps/v8/src/parsing/parser.h
index aa800dafc5..f92eddcd9d 100644
--- a/deps/v8/src/parsing/parser.h
+++ b/deps/v8/src/parsing/parser.h
@@ -267,6 +267,15 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
// Called by ParseProgram after setting up the scanner.
FunctionLiteral* DoParseProgram(ParseInfo* info);
+ // Parse with the script as if the source is implicitly wrapped in a function.
+ // We manually construct the AST and scopes for a top-level function and the
+ // function wrapper.
+ void ParseWrapped(ParseInfo* info, ZoneList<Statement*>* body,
+ DeclarationScope* scope, Zone* zone, bool* ok);
+
+ ZoneList<const AstRawString*>* PrepareWrappedArguments(ParseInfo* info,
+ Zone* zone);
+
void SetCachedData(ParseInfo* info);
void StitchAst(ParseInfo* top_level_parse_info, Isolate* isolate);
@@ -292,10 +301,12 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
SET_ALLOW(harmony_do_expressions);
SET_ALLOW(harmony_function_sent);
SET_ALLOW(harmony_public_fields);
+ SET_ALLOW(harmony_static_fields);
SET_ALLOW(harmony_dynamic_import);
SET_ALLOW(harmony_import_meta);
- SET_ALLOW(harmony_async_iteration);
SET_ALLOW(harmony_bigint);
+ SET_ALLOW(harmony_optional_catch_binding);
+ SET_ALLOW(harmony_private_fields);
#undef SET_ALLOW
}
return reusable_preparser_;
@@ -391,13 +402,14 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
Expression* RewriteDestructuringAssignment(Assignment* assignment);
// [if (IteratorType == kAsync)]
- // !%_IsJSReceiver(result = Await(iterator.next()) &&
+ // !%_IsJSReceiver(result = Await(next.[[Call]](iterator, « »)) &&
// %ThrowIteratorResultNotAnObject(result)
// [else]
- // !%_IsJSReceiver(result = iterator.next()) &&
+ // !%_IsJSReceiver(result = next.[[Call]](iterator, « »)) &&
// %ThrowIteratorResultNotAnObject(result)
// [endif]
- Expression* BuildIteratorNextResult(Expression* iterator, Variable* result,
+ Expression* BuildIteratorNextResult(VariableProxy* iterator,
+ VariableProxy* next, Variable* result,
IteratorType type, int pos);
// Initialize the components of a for-in / for-of statement.
@@ -425,7 +437,13 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
const AstRawString* name, Scanner::Location function_name_location,
FunctionNameValidity function_name_validity, FunctionKind kind,
int function_token_position, FunctionLiteral::FunctionType type,
- LanguageMode language_mode, bool* ok);
+ LanguageMode language_mode,
+ ZoneList<const AstRawString*>* arguments_for_wrapped_function, bool* ok);
+
+ ObjectLiteral* InitializeObjectLiteral(ObjectLiteral* object_literal) {
+ object_literal->CalculateEmitStore(main_zone());
+ return object_literal;
+ }
// Check if the scope has conflicting var/let declarations from different
// scopes. This covers for example
@@ -488,7 +506,8 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
FunctionLiteral::FunctionType function_type,
DeclarationScope* function_scope, int* num_parameters,
int* function_length, bool* has_duplicate_parameters,
- int* expected_property_count, bool* ok);
+ int* expected_property_count,
+ ZoneList<const AstRawString*>* arguments_for_wrapped_function, bool* ok);
void ThrowPendingError(Isolate* isolate, Handle<Script> script);
@@ -553,13 +572,8 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
Expression* RewriteSpreads(ArrayLiteral* lit);
- // Rewrite expressions that are not used as patterns
- V8_INLINE void RewriteNonPattern(bool* ok);
-
V8_INLINE void QueueDestructuringAssignmentForRewriting(
RewritableExpression* assignment);
- V8_INLINE void QueueNonPatternForRewriting(RewritableExpression* expr,
- bool* ok);
friend class InitializerRewriter;
void RewriteParameterInitializer(Expression* expr);
@@ -760,17 +774,11 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
bool CollapseNaryExpression(Expression** x, Expression* y, Token::Value op,
int pos, const SourceRange& range);
- // Rewrites the following types of unary expressions:
- // not <literal> -> true / false
- // + <numeric literal> -> <numeric literal>
- // - <numeric literal> -> <numeric literal with value negated>
+ // Returns a UnaryExpression or, in one of the following cases, a Literal.
// ! <literal> -> true / false
- // The following rewriting rules enable the collection of type feedback
- // without any special stub and the multiplication is removed later in
- // Crankshaft's canonicalization pass.
- // + foo -> foo * 1
- // - foo -> foo * (-1)
- // ~ foo -> foo ^(~0)
+ // + <Number literal> -> <Number literal>
+ // - <Number literal> -> <Number literal with value negated>
+ // ~ <literal> -> true / false
Expression* BuildUnaryExpression(Expression* expression, Token::Value op,
int pos);
@@ -990,10 +998,6 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
return function_state_->GetReportedErrorList();
}
- V8_INLINE ZoneList<RewritableExpression*>* GetNonPatternList() const {
- return function_state_->non_patterns_to_rewrite();
- }
-
V8_INLINE void CountUsage(v8::Isolate::UseCounterFeature feature) {
++use_counts_[feature];
}
diff --git a/deps/v8/src/parsing/pattern-rewriter.cc b/deps/v8/src/parsing/pattern-rewriter.cc
index faecb5bb0c..daa126d443 100644
--- a/deps/v8/src/parsing/pattern-rewriter.cc
+++ b/deps/v8/src/parsing/pattern-rewriter.cc
@@ -445,6 +445,11 @@ void PatternRewriter::VisitArrayLiteral(ArrayLiteral* node,
auto iterator = CreateTempVar(factory()->NewGetIterator(
factory()->NewVariableProxy(temp), current_value_, IteratorType::kNormal,
current_value_->position()));
+ auto next = CreateTempVar(factory()->NewProperty(
+ factory()->NewVariableProxy(iterator),
+ factory()->NewStringLiteral(ast_value_factory()->next_string(),
+ kNoSourcePosition),
+ kNoSourcePosition));
auto done =
CreateTempVar(factory()->NewBooleanLiteral(false, kNoSourcePosition));
auto result = CreateTempVar();
@@ -525,7 +530,8 @@ void PatternRewriter::VisitArrayLiteral(ArrayLiteral* node,
next_block->statements()->Add(
factory()->NewExpressionStatement(
parser_->BuildIteratorNextResult(
- factory()->NewVariableProxy(iterator), result,
+ factory()->NewVariableProxy(iterator),
+ factory()->NewVariableProxy(next), result,
IteratorType::kNormal, kNoSourcePosition),
kNoSourcePosition),
zone());
@@ -599,6 +605,7 @@ void PatternRewriter::VisitArrayLiteral(ArrayLiteral* node,
// result = IteratorNext(iterator);
Statement* get_next = factory()->NewExpressionStatement(
parser_->BuildIteratorNextResult(factory()->NewVariableProxy(iterator),
+ factory()->NewVariableProxy(next),
result, IteratorType::kNormal, nopos),
nopos);
@@ -756,6 +763,7 @@ NOT_A_PATTERN(ImportCallExpression)
NOT_A_PATTERN(Literal)
NOT_A_PATTERN(NativeFunctionLiteral)
NOT_A_PATTERN(RegExpLiteral)
+NOT_A_PATTERN(ResolvedProperty)
NOT_A_PATTERN(ReturnStatement)
NOT_A_PATTERN(SloppyBlockFunctionStatement)
NOT_A_PATTERN(Spread)
diff --git a/deps/v8/src/parsing/preparsed-scope-data.cc b/deps/v8/src/parsing/preparsed-scope-data.cc
index 7191639cf8..786be3f0e5 100644
--- a/deps/v8/src/parsing/preparsed-scope-data.cc
+++ b/deps/v8/src/parsing/preparsed-scope-data.cc
@@ -24,7 +24,7 @@ class VariableMaybeAssignedField : public BitField8<bool, 0, 1> {};
class VariableContextAllocatedField
: public BitField8<bool, VariableMaybeAssignedField::kNext, 1> {};
-const int kMagicValue = 0xc0de0de;
+const int kMagicValue = 0xC0DE0DE;
#ifdef DEBUG
const size_t kUint32Size = 5;
@@ -571,8 +571,8 @@ void ConsumedPreParsedScopeData::RestoreData(Scope* scope) {
if (scope_data_->RemainingBytes() < kUint8Size) {
// Temporary debugging code for detecting inconsistent data. Write debug
// information on the stack, then crash.
- data_->GetIsolate()->PushStackTraceAndDie(0xc0defee, nullptr, nullptr,
- 0xc0defee);
+ data_->GetIsolate()->PushStackTraceAndDie(0xC0DEFEE, nullptr, nullptr,
+ 0xC0DEFEE);
}
// scope_type is stored only in debug mode.
diff --git a/deps/v8/src/parsing/preparser.cc b/deps/v8/src/parsing/preparser.cc
index 16879e518c..b28eab2e75 100644
--- a/deps/v8/src/parsing/preparser.cc
+++ b/deps/v8/src/parsing/preparser.cc
@@ -207,12 +207,12 @@ PreParser::PreParseResult PreParser::PreParseFunction(
if (!IsArrowFunction(kind) && track_unresolved_variables_ &&
result == kLazyParsingComplete) {
- DeclareFunctionNameVar(function_name, function_type, function_scope);
-
// Declare arguments after parsing the function since lexical 'arguments'
// masks the arguments object. Declare arguments before declaring the
// function var since the arguments object masks 'function arguments'.
function_scope->DeclareArguments(ast_value_factory());
+
+ DeclareFunctionNameVar(function_name, function_type, function_scope);
}
use_counts_ = nullptr;
@@ -266,14 +266,18 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
Identifier function_name, Scanner::Location function_name_location,
FunctionNameValidity function_name_validity, FunctionKind kind,
int function_token_pos, FunctionLiteral::FunctionType function_type,
- LanguageMode language_mode, bool* ok) {
+ LanguageMode language_mode,
+ ZoneList<const AstRawString*>* arguments_for_wrapped_function, bool* ok) {
+ // Wrapped functions are not parsed in the preparser.
+ DCHECK_NULL(arguments_for_wrapped_function);
+ DCHECK_NE(FunctionLiteral::kWrapped, function_type);
// Function ::
// '(' FormalParameterList? ')' '{' FunctionBody '}'
- const RuntimeCallStats::CounterId counters[2][2] = {
- {&RuntimeCallStats::PreParseBackgroundNoVariableResolution,
- &RuntimeCallStats::PreParseNoVariableResolution},
- {&RuntimeCallStats::PreParseBackgroundWithVariableResolution,
- &RuntimeCallStats::PreParseWithVariableResolution}};
+ const RuntimeCallCounterId counters[2][2] = {
+ {RuntimeCallCounterId::kPreParseBackgroundNoVariableResolution,
+ RuntimeCallCounterId::kPreParseNoVariableResolution},
+ {RuntimeCallCounterId::kPreParseBackgroundWithVariableResolution,
+ RuntimeCallCounterId::kPreParseWithVariableResolution}};
RuntimeCallTimerScope runtime_timer(
runtime_call_stats_,
counters[track_unresolved_variables_][parsing_on_main_thread_]);
diff --git a/deps/v8/src/parsing/preparser.h b/deps/v8/src/parsing/preparser.h
index 8c1d183fd6..705cd011ee 100644
--- a/deps/v8/src/parsing/preparser.h
+++ b/deps/v8/src/parsing/preparser.h
@@ -956,12 +956,18 @@ class PreParser : public ParserBase<PreParser> {
bool is_inner_function, bool may_abort, bool* ok) {
UNREACHABLE();
}
- Expression ParseFunctionLiteral(Identifier name,
- Scanner::Location function_name_location,
- FunctionNameValidity function_name_validity,
- FunctionKind kind, int function_token_pos,
- FunctionLiteral::FunctionType function_type,
- LanguageMode language_mode, bool* ok);
+
+ Expression ParseFunctionLiteral(
+ Identifier name, Scanner::Location function_name_location,
+ FunctionNameValidity function_name_validity, FunctionKind kind,
+ int function_token_pos, FunctionLiteral::FunctionType function_type,
+ LanguageMode language_mode,
+ ZoneList<const AstRawString*>* arguments_for_wrapped_function, bool* ok);
+
+ PreParserExpression InitializeObjectLiteral(PreParserExpression literal) {
+ return literal;
+ }
+
LazyParsingResult ParseStatementListAndLogFunction(
PreParserFormalParameters* formals, bool maybe_abort, bool* ok);
@@ -999,7 +1005,6 @@ class PreParser : public ParserBase<PreParser> {
V8_INLINE void RewriteAsyncFunctionBody(
PreParserStatementList body, PreParserStatement block,
const PreParserExpression& return_value, bool* ok) {}
- V8_INLINE void RewriteNonPattern(bool* ok) { ValidateExpression(ok); }
void DeclareAndInitializeVariables(
PreParserStatement block,
@@ -1186,8 +1191,6 @@ class PreParser : public ParserBase<PreParser> {
V8_INLINE void QueueDestructuringAssignmentForRewriting(
PreParserExpression assignment) {}
- V8_INLINE void QueueNonPatternForRewriting(const PreParserExpression& expr,
- bool* ok) {}
// Helper functions for recursive descent.
V8_INLINE bool IsEval(const PreParserIdentifier& identifier) const {
@@ -1665,10 +1668,6 @@ class PreParser : public ParserBase<PreParser> {
return function_state_->GetReportedErrorList();
}
- V8_INLINE ZoneList<PreParserExpression>* GetNonPatternList() const {
- return function_state_->non_patterns_to_rewrite();
- }
-
V8_INLINE void CountUsage(v8::Isolate::UseCounterFeature feature) {
if (use_counts_ != nullptr) ++use_counts_[feature];
}
diff --git a/deps/v8/src/parsing/rewriter.cc b/deps/v8/src/parsing/rewriter.cc
index c31d0ea21d..102efad292 100644
--- a/deps/v8/src/parsing/rewriter.cc
+++ b/deps/v8/src/parsing/rewriter.cc
@@ -367,8 +367,8 @@ bool Rewriter::Rewrite(ParseInfo* info) {
RuntimeCallTimerScope runtimeTimer(
info->runtime_call_stats(),
info->on_background_thread()
- ? &RuntimeCallStats::CompileBackgroundRewriteReturnResult
- : &RuntimeCallStats::CompileRewriteReturnResult);
+ ? RuntimeCallCounterId::kCompileBackgroundRewriteReturnResult
+ : RuntimeCallCounterId::kCompileRewriteReturnResult);
FunctionLiteral* function = info->literal();
DCHECK_NOT_NULL(function);
diff --git a/deps/v8/src/parsing/scanner-character-streams.cc b/deps/v8/src/parsing/scanner-character-streams.cc
index c5175c4de7..20aa5c9f8e 100644
--- a/deps/v8/src/parsing/scanner-character-streams.cc
+++ b/deps/v8/src/parsing/scanner-character-streams.cc
@@ -16,7 +16,7 @@ namespace v8 {
namespace internal {
namespace {
-const unibrow::uchar kUtf8Bom = 0xfeff;
+const unibrow::uchar kUtf8Bom = 0xFEFF;
} // namespace
// ----------------------------------------------------------------------------
@@ -203,7 +203,7 @@ class Utf8ExternalStreamingStream : public BufferedUtf16CharacterStream {
Utf8ExternalStreamingStream(
ScriptCompiler::ExternalSourceStream* source_stream,
RuntimeCallStats* stats)
- : current_({0, {0, 0, unibrow::Utf8::Utf8IncrementalBuffer(0)}}),
+ : current_({0, {0, 0, 0, unibrow::Utf8::State::kAccept}}),
source_stream_(source_stream),
stats_(stats) {}
~Utf8ExternalStreamingStream() override {
@@ -223,7 +223,8 @@ class Utf8ExternalStreamingStream : public BufferedUtf16CharacterStream {
struct StreamPosition {
size_t bytes;
size_t chars;
- unibrow::Utf8::Utf8IncrementalBuffer incomplete_char;
+ uint32_t incomplete_char;
+ unibrow::Utf8::State state;
};
// Position contains a StreamPosition and the index of the chunk the position
@@ -268,25 +269,25 @@ bool Utf8ExternalStreamingStream::SkipToPosition(size_t position) {
const Chunk& chunk = chunks_[current_.chunk_no];
DCHECK(current_.pos.bytes >= chunk.start.bytes);
- unibrow::Utf8::Utf8IncrementalBuffer incomplete_char =
- chunk.start.incomplete_char;
+ unibrow::Utf8::State state = chunk.start.state;
+ uint32_t incomplete_char = chunk.start.incomplete_char;
size_t it = current_.pos.bytes - chunk.start.bytes;
size_t chars = chunk.start.chars;
while (it < chunk.length && chars < position) {
- unibrow::uchar t =
- unibrow::Utf8::ValueOfIncremental(chunk.data[it], &incomplete_char);
+ unibrow::uchar t = unibrow::Utf8::ValueOfIncremental(
+ chunk.data[it], &it, &state, &incomplete_char);
if (t == kUtf8Bom && current_.pos.chars == 0) {
// BOM detected at beginning of the stream. Don't copy it.
} else if (t != unibrow::Utf8::kIncomplete) {
chars++;
if (t > unibrow::Utf16::kMaxNonSurrogateCharCode) chars++;
}
- it++;
}
current_.pos.bytes += it;
current_.pos.chars = chars;
current_.pos.incomplete_char = incomplete_char;
+ current_.pos.state = state;
current_.chunk_no += (it == chunk.length);
return current_.pos.chars == position;
@@ -304,31 +305,33 @@ void Utf8ExternalStreamingStream::FillBufferFromCurrentChunk() {
uint16_t* cursor = buffer_ + (buffer_end_ - buffer_start_);
DCHECK_EQ(cursor, buffer_end_);
+ unibrow::Utf8::State state = current_.pos.state;
+ uint32_t incomplete_char = current_.pos.incomplete_char;
+
// If the current chunk is the last (empty) chunk we'll have to process
// any left-over, partial characters.
if (chunk.length == 0) {
- unibrow::uchar t =
- unibrow::Utf8::ValueOfIncrementalFinish(&current_.pos.incomplete_char);
+ unibrow::uchar t = unibrow::Utf8::ValueOfIncrementalFinish(&state);
if (t != unibrow::Utf8::kBufferEmpty) {
- DCHECK_LT(t, unibrow::Utf16::kMaxNonSurrogateCharCode);
+ DCHECK_EQ(t, unibrow::Utf8::kBadChar);
*cursor = static_cast<uc16>(t);
buffer_end_++;
current_.pos.chars++;
+ current_.pos.incomplete_char = 0;
+ current_.pos.state = state;
}
return;
}
- unibrow::Utf8::Utf8IncrementalBuffer incomplete_char =
- current_.pos.incomplete_char;
- size_t it;
- for (it = current_.pos.bytes - chunk.start.bytes;
- it < chunk.length && cursor + 1 < buffer_start_ + kBufferSize; it++) {
- unibrow::uchar t =
- unibrow::Utf8::ValueOfIncremental(chunk.data[it], &incomplete_char);
- if (t == unibrow::Utf8::kIncomplete) continue;
+ size_t it = current_.pos.bytes - chunk.start.bytes;
+ while (it < chunk.length && cursor + 1 < buffer_start_ + kBufferSize) {
+ unibrow::uchar t = unibrow::Utf8::ValueOfIncremental(
+ chunk.data[it], &it, &state, &incomplete_char);
if (V8_LIKELY(t < kUtf8Bom)) {
*(cursor++) = static_cast<uc16>(t); // The by most frequent case.
- } else if (t == kUtf8Bom && current_.pos.bytes + it == 2) {
+ } else if (t == unibrow::Utf8::kIncomplete) {
+ continue;
+ } else if (t == kUtf8Bom && current_.pos.bytes + it == 3) {
// BOM detected at beginning of the stream. Don't copy it.
} else if (t <= unibrow::Utf16::kMaxNonSurrogateCharCode) {
*(cursor++) = static_cast<uc16>(t);
@@ -341,13 +344,15 @@ void Utf8ExternalStreamingStream::FillBufferFromCurrentChunk() {
current_.pos.bytes = chunk.start.bytes + it;
current_.pos.chars += (cursor - buffer_end_);
current_.pos.incomplete_char = incomplete_char;
+ current_.pos.state = state;
current_.chunk_no += (it == chunk.length);
buffer_end_ = cursor;
}
bool Utf8ExternalStreamingStream::FetchChunk() {
- RuntimeCallTimerScope scope(stats_, &RuntimeCallStats::GetMoreDataCallback);
+ RuntimeCallTimerScope scope(stats_,
+ RuntimeCallCounterId::kGetMoreDataCallback);
DCHECK_EQ(current_.chunk_no, chunks_.size());
DCHECK(chunks_.empty() || chunks_.back().length != 0);
@@ -395,16 +400,15 @@ void Utf8ExternalStreamingStream::SearchPosition(size_t position) {
// checking whether the # bytes in a chunk are equal to the # chars, and if
// so avoid the expensive SkipToPosition.)
bool ascii_only_chunk =
- chunks_[chunk_no].start.incomplete_char ==
- unibrow::Utf8::Utf8IncrementalBuffer(0) &&
+ chunks_[chunk_no].start.incomplete_char == 0 &&
(chunks_[chunk_no + 1].start.bytes - chunks_[chunk_no].start.bytes) ==
(chunks_[chunk_no + 1].start.chars - chunks_[chunk_no].start.chars);
if (ascii_only_chunk) {
size_t skip = position - chunks_[chunk_no].start.chars;
current_ = {chunk_no,
{chunks_[chunk_no].start.bytes + skip,
- chunks_[chunk_no].start.chars + skip,
- unibrow::Utf8::Utf8IncrementalBuffer(0)}};
+ chunks_[chunk_no].start.chars + skip, 0,
+ unibrow::Utf8::State::kAccept}};
} else {
current_ = {chunk_no, chunks_[chunk_no].start};
SkipToPosition(position);
@@ -491,7 +495,8 @@ size_t FindChunk(Chunks& chunks, ScriptCompiler::ExternalSourceStream* source,
// Get more data if needed. We usually won't enter the loop body.
bool out_of_data = !chunks.empty() && chunks.back().byte_length == 0;
{
- RuntimeCallTimerScope scope(stats, &RuntimeCallStats::GetMoreDataCallback);
+ RuntimeCallTimerScope scope(stats,
+ RuntimeCallCounterId::kGetMoreDataCallback);
while (!out_of_data && end_pos <= position + 1) {
const uint8_t* chunk = nullptr;
size_t len = source->GetMoreData(&chunk);
diff --git a/deps/v8/src/parsing/scanner.cc b/deps/v8/src/parsing/scanner.cc
index 8030b93889..3152ab184e 100644
--- a/deps/v8/src/parsing/scanner.cc
+++ b/deps/v8/src/parsing/scanner.cc
@@ -174,31 +174,15 @@ bool Scanner::BookmarkScope::HasBeenApplied() {
return bookmark_ == kBookmarkWasApplied;
}
-// LineTerminator: 'JS_Line_Terminator' in point.properties
-// ES#sec-line-terminators lists exactly 4 code points:
-// LF (U+000A), CR (U+000D), LS(U+2028), PS(U+2029)
-bool Scanner::IsLineTerminator(uc32 c) {
- if (c == 0x000A || c == 0x000D) {
- return true;
- }
- if (c == 0x2028 || c == 0x2029) {
- ++use_counts_[v8::Isolate::UseCounterFeature::
- kLineOrParagraphSeparatorAsLineTerminator];
- return true;
- }
- return false;
-}
-
// ----------------------------------------------------------------------------
// Scanner
-Scanner::Scanner(UnicodeCache* unicode_cache, int* use_counts)
+Scanner::Scanner(UnicodeCache* unicode_cache)
: unicode_cache_(unicode_cache),
octal_pos_(Location::invalid()),
octal_message_(MessageTemplate::kNone),
found_html_comment_(false),
- allow_harmony_bigint_(false),
- use_counts_(use_counts) {}
+ allow_harmony_bigint_(false) {}
void Scanner::Initialize(Utf16CharacterStream* source, bool is_module) {
DCHECK_NOT_NULL(source);
@@ -257,7 +241,8 @@ uc32 Scanner::ScanUnlimitedLengthHexNumber(int max_value, int beg_pos) {
// Ensure that tokens can be stored in a byte.
STATIC_ASSERT(Token::NUM_TOKENS <= 0x100);
-// Table of one-character tokens, by character (0x00..0x7f only).
+// Table of one-character tokens, by character (0x00..0x7F only).
+// clang-format off
static const byte one_char_tokens[] = {
Token::ILLEGAL,
Token::ILLEGAL,
@@ -303,7 +288,7 @@ static const byte one_char_tokens[] = {
Token::RPAREN, // 0x29
Token::ILLEGAL,
Token::ILLEGAL,
- Token::COMMA, // 0x2c
+ Token::COMMA, // 0x2C
Token::ILLEGAL,
Token::ILLEGAL,
Token::ILLEGAL,
@@ -317,12 +302,12 @@ static const byte one_char_tokens[] = {
Token::ILLEGAL,
Token::ILLEGAL,
Token::ILLEGAL,
- Token::COLON, // 0x3a
- Token::SEMICOLON, // 0x3b
+ Token::COLON, // 0x3A
+ Token::SEMICOLON, // 0x3B
Token::ILLEGAL,
Token::ILLEGAL,
Token::ILLEGAL,
- Token::CONDITIONAL, // 0x3f
+ Token::CONDITIONAL, // 0x3F
Token::ILLEGAL,
Token::ILLEGAL,
Token::ILLEGAL,
@@ -350,9 +335,9 @@ static const byte one_char_tokens[] = {
Token::ILLEGAL,
Token::ILLEGAL,
Token::ILLEGAL,
- Token::LBRACK, // 0x5b
+ Token::LBRACK, // 0x5B
Token::ILLEGAL,
- Token::RBRACK, // 0x5d
+ Token::RBRACK, // 0x5D
Token::ILLEGAL,
Token::ILLEGAL,
Token::ILLEGAL,
@@ -382,13 +367,13 @@ static const byte one_char_tokens[] = {
Token::ILLEGAL,
Token::ILLEGAL,
Token::ILLEGAL,
- Token::LBRACE, // 0x7b
+ Token::LBRACE, // 0x7B
Token::ILLEGAL,
- Token::RBRACE, // 0x7d
- Token::BIT_NOT, // 0x7e
+ Token::RBRACE, // 0x7D
+ Token::BIT_NOT, // 0x7E
Token::ILLEGAL
};
-
+// clang-format on
Token::Value Scanner::Next() {
if (next_.token == Token::EOS) {
@@ -405,7 +390,7 @@ Token::Value Scanner::Next() {
}
has_line_terminator_before_next_ = false;
has_multiline_comment_before_next_ = false;
- if (static_cast<unsigned>(c0_) <= 0x7f) {
+ if (static_cast<unsigned>(c0_) <= 0x7F) {
Token::Value token = static_cast<Token::Value>(one_char_tokens[c0_]);
if (token != Token::ILLEGAL) {
int pos = source_pos();
@@ -457,7 +442,7 @@ Token::Value Scanner::SkipWhiteSpace() {
// Advance as long as character is a WhiteSpace or LineTerminator.
// Remember if the latter is the case.
- if (IsLineTerminator(c0_)) {
+ if (unibrow::IsLineTerminator(c0_)) {
has_line_terminator_before_next_ = true;
} else if (!unicode_cache_->IsWhiteSpace(c0_)) {
break;
@@ -514,7 +499,7 @@ Token::Value Scanner::SkipSingleLineComment() {
// separately by the lexical grammar and becomes part of the
// stream of input elements for the syntactic grammar (see
// ECMA-262, section 7.4).
- while (c0_ != kEndOfInput && !IsLineTerminator(c0_)) {
+ while (c0_ != kEndOfInput && !unibrow::IsLineTerminator(c0_)) {
Advance();
}
@@ -524,7 +509,7 @@ Token::Value Scanner::SkipSingleLineComment() {
Token::Value Scanner::SkipSourceURLComment() {
TryToParseSourceURLComment();
- while (c0_ != kEndOfInput && !IsLineTerminator(c0_)) {
+ while (c0_ != kEndOfInput && !unibrow::IsLineTerminator(c0_)) {
Advance();
}
@@ -560,7 +545,7 @@ void Scanner::TryToParseSourceURLComment() {
while (c0_ != kEndOfInput && unicode_cache_->IsWhiteSpace(c0_)) {
Advance();
}
- while (c0_ != kEndOfInput && !IsLineTerminator(c0_)) {
+ while (c0_ != kEndOfInput && !unibrow::IsLineTerminator(c0_)) {
// Disallowed characters.
if (c0_ == '"' || c0_ == '\'') {
value->Reset();
@@ -573,7 +558,7 @@ void Scanner::TryToParseSourceURLComment() {
Advance();
}
// Allow whitespace at the end.
- while (c0_ != kEndOfInput && !IsLineTerminator(c0_)) {
+ while (c0_ != kEndOfInput && !unibrow::IsLineTerminator(c0_)) {
if (!unicode_cache_->IsWhiteSpace(c0_)) {
value->Reset();
break;
@@ -590,7 +575,7 @@ Token::Value Scanner::SkipMultiLineComment() {
while (c0_ != kEndOfInput) {
uc32 ch = c0_;
Advance();
- if (c0_ != kEndOfInput && IsLineTerminator(ch)) {
+ if (c0_ != kEndOfInput && unibrow::IsLineTerminator(ch)) {
// Following ECMA-262, section 7.4, a comment containing
// a newline will make the comment count as a line-terminator.
has_multiline_comment_before_next_ = true;
@@ -875,6 +860,10 @@ void Scanner::Scan() {
token = ScanTemplateStart();
break;
+ case '#':
+ token = ScanPrivateName();
+ break;
+
default:
if (c0_ == kEndOfInput) {
token = Token::EOS;
@@ -940,6 +929,7 @@ void Scanner::SanityCheckTokenDesc(const TokenDesc& token) const {
case Token::REGEXP_LITERAL:
case Token::SMI:
case Token::STRING:
+ case Token::PRIVATE_NAME:
DCHECK_NOT_NULL(token.literal_chars);
DCHECK_NULL(token.raw_literal_chars);
DCHECK_EQ(token.invalid_template_escape_message, MessageTemplate::kNone);
@@ -987,7 +977,8 @@ bool Scanner::ScanEscape() {
Advance<capture_raw>();
// Skip escaped newlines.
- if (!in_template_literal && c0_ != kEndOfInput && IsLineTerminator(c)) {
+ if (!in_template_literal && c0_ != kEndOfInput &&
+ unibrow::IsLineTerminator(c)) {
// Allow escaped CR+LF newlines in multiline string literals.
if (IsCarriageReturn(c) && IsLineFeed(c0_)) Advance<capture_raw>();
return true;
@@ -1080,7 +1071,8 @@ Token::Value Scanner::ScanString() {
AddLiteralChar(c);
}
- while (c0_ != quote && c0_ != kEndOfInput && !IsLineTerminator(c0_)) {
+ while (c0_ != quote && c0_ != kEndOfInput &&
+ !unibrow::IsLineTerminator(c0_)) {
uc32 c = c0_;
Advance();
if (c == '\\') {
@@ -1098,6 +1090,26 @@ Token::Value Scanner::ScanString() {
return Token::STRING;
}
+Token::Value Scanner::ScanPrivateName() {
+ if (!allow_harmony_private_fields()) {
+ ReportScannerError(source_pos(),
+ MessageTemplate::kInvalidOrUnexpectedToken);
+ return Token::ILLEGAL;
+ }
+
+ LiteralScope literal(this);
+ DCHECK_EQ(c0_, '#');
+ AddLiteralCharAdvance();
+ if (c0_ == kEndOfInput || !unicode_cache_->IsIdentifierStart(c0_)) {
+ PushBack(c0_);
+ ReportScannerError(source_pos(),
+ MessageTemplate::kInvalidOrUnexpectedToken);
+ return Token::ILLEGAL;
+ }
+
+ Token::Value token = ScanIdentifierOrKeywordInner(&literal);
+ return token == Token::ILLEGAL ? Token::ILLEGAL : Token::PRIVATE_NAME;
+}
Token::Value Scanner::ScanTemplateSpan() {
// When scanning a TemplateSpan, we are looking for the following construct:
@@ -1136,7 +1148,7 @@ Token::Value Scanner::ScanTemplateSpan() {
ReduceRawLiteralLength(2);
break;
} else if (c == '\\') {
- if (c0_ != kEndOfInput && IsLineTerminator(c0_)) {
+ if (c0_ != kEndOfInput && unibrow::IsLineTerminator(c0_)) {
// The TV of LineContinuation :: \ LineTerminatorSequence is the empty
// code unit sequence.
uc32 lastChar = c0_;
@@ -1397,7 +1409,7 @@ uc32 Scanner::ScanUnicodeEscape() {
if (c0_ == '{') {
int begin = source_pos() - 2;
Advance<capture_raw>();
- uc32 cp = ScanUnlimitedLengthHexNumber<capture_raw>(0x10ffff, begin);
+ uc32 cp = ScanUnlimitedLengthHexNumber<capture_raw>(0x10FFFF, begin);
if (cp < 0 || c0_ != '}') {
ReportScannerError(source_pos(),
MessageTemplate::kInvalidUnicodeEscapeSequence);
@@ -1541,10 +1553,13 @@ static Token::Value KeywordOrIdentifierToken(const uint8_t* input,
return Token::IDENTIFIER;
}
-
Token::Value Scanner::ScanIdentifierOrKeyword() {
- DCHECK(unicode_cache_->IsIdentifierStart(c0_));
LiteralScope literal(this);
+ return ScanIdentifierOrKeywordInner(&literal);
+}
+
+Token::Value Scanner::ScanIdentifierOrKeywordInner(LiteralScope* literal) {
+ DCHECK(unicode_cache_->IsIdentifierStart(c0_));
if (IsInRange(c0_, 'a', 'z') || c0_ == '_') {
do {
char first_char = static_cast<char>(c0_);
@@ -1564,7 +1579,7 @@ Token::Value Scanner::ScanIdentifierOrKeyword() {
AddLiteralChar(first_char);
}
if (c0_ <= kMaxAscii && c0_ != '\\') {
- literal.Complete();
+ literal->Complete();
return Token::IDENTIFIER;
}
} else if (c0_ <= kMaxAscii && c0_ != '\\') {
@@ -1575,7 +1590,7 @@ Token::Value Scanner::ScanIdentifierOrKeyword() {
if (token == Token::IDENTIFIER ||
token == Token::FUTURE_STRICT_RESERVED_WORD ||
Token::IsContextualKeyword(token))
- literal.Complete();
+ literal->Complete();
return token;
}
@@ -1588,7 +1603,7 @@ Token::Value Scanner::ScanIdentifierOrKeyword() {
} while (IsAsciiIdentifier(c0_));
if (c0_ <= kMaxAscii && c0_ != '\\') {
- literal.Complete();
+ literal->Complete();
return Token::IDENTIFIER;
}
@@ -1603,7 +1618,7 @@ Token::Value Scanner::ScanIdentifierOrKeyword() {
return Token::ILLEGAL;
}
AddLiteralChar(c);
- return ScanIdentifierSuffix(&literal, true);
+ return ScanIdentifierSuffix(literal, true);
} else {
uc32 first_char = c0_;
Advance();
@@ -1619,7 +1634,7 @@ Token::Value Scanner::ScanIdentifierOrKeyword() {
continue;
}
// Fallthrough if no longer able to complete keyword.
- return ScanIdentifierSuffix(&literal, false);
+ return ScanIdentifierSuffix(literal, false);
}
if (next_.literal_chars->is_one_byte()) {
@@ -1629,10 +1644,10 @@ Token::Value Scanner::ScanIdentifierOrKeyword() {
if (token == Token::IDENTIFIER ||
token == Token::FUTURE_STRICT_RESERVED_WORD ||
Token::IsContextualKeyword(token))
- literal.Complete();
+ literal->Complete();
return token;
}
- literal.Complete();
+ literal->Complete();
return Token::IDENTIFIER;
}
@@ -1697,12 +1712,12 @@ bool Scanner::ScanRegExpPattern() {
}
while (c0_ != '/' || in_character_class) {
- if (c0_ == kEndOfInput || IsLineTerminator(c0_)) {
+ if (c0_ == kEndOfInput || unibrow::IsLineTerminator(c0_)) {
return false;
}
if (c0_ == '\\') { // Escape sequence.
AddLiteralCharAdvance();
- if (c0_ == kEndOfInput || IsLineTerminator(c0_)) {
+ if (c0_ == kEndOfInput || unibrow::IsLineTerminator(c0_)) {
return false;
}
AddLiteralCharAdvance();
diff --git a/deps/v8/src/parsing/scanner.h b/deps/v8/src/parsing/scanner.h
index 08d77c686b..f5106990ff 100644
--- a/deps/v8/src/parsing/scanner.h
+++ b/deps/v8/src/parsing/scanner.h
@@ -207,7 +207,7 @@ class Scanner {
static const int kNoOctalLocation = -1;
static const uc32 kEndOfInput = Utf16CharacterStream::kEndOfInput;
- explicit Scanner(UnicodeCache* scanner_contants, int* use_counts_);
+ explicit Scanner(UnicodeCache* scanner_contants);
void Initialize(Utf16CharacterStream* source, bool is_module);
@@ -360,6 +360,12 @@ class Scanner {
bool allow_harmony_bigint() const { return allow_harmony_bigint_; }
void set_allow_harmony_bigint(bool allow) { allow_harmony_bigint_ = allow; }
+ bool allow_harmony_private_fields() const {
+ return allow_harmony_private_fields_;
+ }
+ void set_allow_harmony_private_fields(bool allow) {
+ allow_harmony_private_fields_ = allow;
+ }
private:
// Scoped helper for saving & restoring scanner error state.
@@ -717,9 +723,11 @@ class Scanner {
void ScanDecimalDigits();
Token::Value ScanNumber(bool seen_period);
Token::Value ScanIdentifierOrKeyword();
+ Token::Value ScanIdentifierOrKeywordInner(LiteralScope* literal);
Token::Value ScanIdentifierSuffix(LiteralScope* literal, bool escaped);
Token::Value ScanString();
+ Token::Value ScanPrivateName();
// Scans an escape-sequence which is part of a string and adds the
// decoded character to the current literal. Returns true if a pattern
@@ -736,8 +744,6 @@ class Scanner {
bool is_module_;
- bool IsLineTerminator(uc32 c);
-
Token::Value ScanTemplateSpan();
// Return the current source position.
@@ -802,10 +808,9 @@ class Scanner {
// Whether this scanner encountered an HTML comment.
bool found_html_comment_;
- // Whether to recognize BIGINT tokens.
+ // Harmony flags to allow ESNext features.
bool allow_harmony_bigint_;
-
- int* use_counts_;
+ bool allow_harmony_private_fields_;
MessageTemplate::Template scanner_error_;
Location scanner_error_location_;
diff --git a/deps/v8/src/parsing/token.h b/deps/v8/src/parsing/token.h
index e4a4a5e587..07974edf41 100644
--- a/deps/v8/src/parsing/token.h
+++ b/deps/v8/src/parsing/token.h
@@ -151,6 +151,7 @@ namespace internal {
\
/* Identifiers (not keywords or future reserved words). */ \
T(IDENTIFIER, nullptr, 0) \
+ T(PRIVATE_NAME, nullptr, 0) \
\
/* Future reserved words (ECMA-262, section 7.6.1.2). */ \
T(FUTURE_STRICT_RESERVED_WORD, nullptr, 0) \