Commit 82e80605 authored by machenbach's avatar machenbach Committed by Commit bot

Revert of [destructuring] Implement parameter pattern matching. (patchset #7...

Revert of [destructuring] Implement parameter pattern matching. (patchset #7 id:120001 of https://codereview.chromium.org/1189743003/)

Reason for revert:
[Sheriff] Breaks tsan:
http://build.chromium.org/p/client.v8/builders/V8%20Linux64%20TSAN/builds/4392

Original issue's description:
> [destructuring] Implement parameter pattern matching.
>
> Scoping for initializers is yet incorrect. Defaults are not supported.
>
> R=arv@chromium.org,rossberg@chromium.org
> BUG=v8:811
> LOG=N
>
> Committed: https://crrev.com/42f30f4ded2b1ca0c4caa7639e6206e93c78ee70
> Cr-Commit-Position: refs/heads/master@{#29184}

TBR=arv@chromium.org,rossberg@chromium.org,caitpotter88@gmail.com,wingo@igalia.com,dslomov@chromium.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=v8:811

Review URL: https://codereview.chromium.org/1195163007

Cr-Commit-Position: refs/heads/master@{#29188}
parent 86594b7d
...@@ -1182,7 +1182,7 @@ FunctionLiteral* Parser::ParseLazy(Isolate* isolate, ParseInfo* info, ...@@ -1182,7 +1182,7 @@ FunctionLiteral* Parser::ParseLazy(Isolate* isolate, ParseInfo* info,
NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction); NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction);
scope->set_start_position(shared_info->start_position()); scope->set_start_position(shared_info->start_position());
ExpressionClassifier formals_classifier; ExpressionClassifier formals_classifier;
ParserFormalParameterParsingState parsing_state(scope); bool has_rest = false;
{ {
// Parsing patterns as variable reference expression creates // Parsing patterns as variable reference expression creates
// NewUnresolved references in current scope. Entrer arrow function // NewUnresolved references in current scope. Entrer arrow function
...@@ -1190,19 +1190,17 @@ FunctionLiteral* Parser::ParseLazy(Isolate* isolate, ParseInfo* info, ...@@ -1190,19 +1190,17 @@ FunctionLiteral* Parser::ParseLazy(Isolate* isolate, ParseInfo* info,
BlockState block_state(&scope_, scope); BlockState block_state(&scope_, scope);
if (Check(Token::LPAREN)) { if (Check(Token::LPAREN)) {
// '(' StrictFormalParameters ')' // '(' StrictFormalParameters ')'
ParseFormalParameterList(&parsing_state, &formals_classifier, &ok); ParseFormalParameterList(scope, &has_rest, &formals_classifier, &ok);
if (ok) ok = Check(Token::RPAREN); if (ok) ok = Check(Token::RPAREN);
} else { } else {
// BindingIdentifier // BindingIdentifier
const bool is_rest = false; ParseFormalParameter(scope, has_rest, &formals_classifier, &ok);
ParseFormalParameter(is_rest, &parsing_state, &formals_classifier,
&ok);
} }
} }
if (ok) { if (ok) {
Expression* expression = Expression* expression =
ParseArrowFunctionLiteral(parsing_state, formals_classifier, &ok); ParseArrowFunctionLiteral(scope, has_rest, formals_classifier, &ok);
if (ok) { if (ok) {
// Scanning must end at the same position that was recorded // Scanning must end at the same position that was recorded
// previously. If not, parsing has been interrupted due to a stack // previously. If not, parsing has been interrupted due to a stack
...@@ -1549,7 +1547,7 @@ ZoneList<ImportDeclaration*>* Parser::ParseNamedImports(int pos, bool* ok) { ...@@ -1549,7 +1547,7 @@ ZoneList<ImportDeclaration*>* Parser::ParseNamedImports(int pos, bool* ok) {
VariableProxy* proxy = NewUnresolved(local_name, IMPORT); VariableProxy* proxy = NewUnresolved(local_name, IMPORT);
ImportDeclaration* declaration = ImportDeclaration* declaration =
factory()->NewImportDeclaration(proxy, import_name, NULL, scope_, pos); factory()->NewImportDeclaration(proxy, import_name, NULL, scope_, pos);
Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); Declare(declaration, true, CHECK_OK);
result->Add(declaration, zone()); result->Add(declaration, zone());
if (peek() == Token::RBRACE) break; if (peek() == Token::RBRACE) break;
Expect(Token::COMMA, CHECK_OK); Expect(Token::COMMA, CHECK_OK);
...@@ -1597,8 +1595,7 @@ Statement* Parser::ParseImportDeclaration(bool* ok) { ...@@ -1597,8 +1595,7 @@ Statement* Parser::ParseImportDeclaration(bool* ok) {
VariableProxy* proxy = NewUnresolved(local_name, IMPORT); VariableProxy* proxy = NewUnresolved(local_name, IMPORT);
import_default_declaration = factory()->NewImportDeclaration( import_default_declaration = factory()->NewImportDeclaration(
proxy, ast_value_factory()->default_string(), NULL, scope_, pos); proxy, ast_value_factory()->default_string(), NULL, scope_, pos);
Declare(import_default_declaration, DeclarationDescriptor::NORMAL, true, Declare(import_default_declaration, true, CHECK_OK);
CHECK_OK);
} }
const AstRawString* module_instance_binding = NULL; const AstRawString* module_instance_binding = NULL;
...@@ -1985,9 +1982,7 @@ VariableProxy* Parser::NewUnresolved(const AstRawString* name, ...@@ -1985,9 +1982,7 @@ VariableProxy* Parser::NewUnresolved(const AstRawString* name,
} }
Variable* Parser::Declare(Declaration* declaration, Variable* Parser::Declare(Declaration* declaration, bool resolve, bool* ok) {
DeclarationDescriptor::Kind declaration_kind,
bool resolve, bool* ok) {
VariableProxy* proxy = declaration->proxy(); VariableProxy* proxy = declaration->proxy();
DCHECK(proxy->raw_name() != NULL); DCHECK(proxy->raw_name() != NULL);
const AstRawString* name = proxy->raw_name(); const AstRawString* name = proxy->raw_name();
...@@ -2046,15 +2041,11 @@ Variable* Parser::Declare(Declaration* declaration, ...@@ -2046,15 +2041,11 @@ Variable* Parser::Declare(Declaration* declaration,
if (is_strict(language_mode())) { if (is_strict(language_mode())) {
// In harmony we treat re-declarations as early errors. See // In harmony we treat re-declarations as early errors. See
// ES5 16 for a definition of early errors. // ES5 16 for a definition of early errors.
if (declaration_kind == DeclarationDescriptor::NORMAL) {
ParserTraits::ReportMessage(MessageTemplate::kVarRedeclaration, name); ParserTraits::ReportMessage(MessageTemplate::kVarRedeclaration, name);
} else {
ParserTraits::ReportMessage(MessageTemplate::kStrictParamDupe);
}
*ok = false; *ok = false;
return nullptr; return nullptr;
} }
Expression* expression = NewThrowSyntaxError( Expression* expression = NewThrowTypeError(
MessageTemplate::kVarRedeclaration, name, declaration->position()); MessageTemplate::kVarRedeclaration, name, declaration->position());
declaration_scope->SetIllegalRedeclaration(expression); declaration_scope->SetIllegalRedeclaration(expression);
} else if (mode == VAR) { } else if (mode == VAR) {
...@@ -2164,7 +2155,7 @@ Statement* Parser::ParseNativeDeclaration(bool* ok) { ...@@ -2164,7 +2155,7 @@ Statement* Parser::ParseNativeDeclaration(bool* ok) {
VariableProxy* proxy = NewUnresolved(name, VAR); VariableProxy* proxy = NewUnresolved(name, VAR);
Declaration* declaration = Declaration* declaration =
factory()->NewVariableDeclaration(proxy, VAR, scope_, pos); factory()->NewVariableDeclaration(proxy, VAR, scope_, pos);
Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); Declare(declaration, true, CHECK_OK);
NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral( NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral(
name, extension_, RelocInfo::kNoPosition); name, extension_, RelocInfo::kNoPosition);
return factory()->NewExpressionStatement( return factory()->NewExpressionStatement(
...@@ -2209,7 +2200,7 @@ Statement* Parser::ParseFunctionDeclaration( ...@@ -2209,7 +2200,7 @@ Statement* Parser::ParseFunctionDeclaration(
VariableProxy* proxy = NewUnresolved(name, mode); VariableProxy* proxy = NewUnresolved(name, mode);
Declaration* declaration = Declaration* declaration =
factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos); factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos);
Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); Declare(declaration, true, CHECK_OK);
if (names) names->Add(name, zone()); if (names) names->Add(name, zone());
return factory()->NewEmptyStatement(RelocInfo::kNoPosition); return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
} }
...@@ -2250,8 +2241,7 @@ Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names, ...@@ -2250,8 +2241,7 @@ Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names,
Declaration* declaration = factory()->NewVariableDeclaration( Declaration* declaration = factory()->NewVariableDeclaration(
proxy, mode, scope_, pos, is_class_declaration, proxy, mode, scope_, pos, is_class_declaration,
scope_->class_declaration_group_start()); scope_->class_declaration_group_start());
Variable* outer_class_variable = Variable* outer_class_variable = Declare(declaration, true, CHECK_OK);
Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
proxy->var()->set_initializer_position(position()); proxy->var()->set_initializer_position(position());
// This is needed because a class ("class Name { }") creates two bindings (one // This is needed because a class ("class Name { }") creates two bindings (one
// in the outer scope, and one in the class scope). The method is a function // in the outer scope, and one in the class scope). The method is a function
...@@ -2407,7 +2397,6 @@ void Parser::ParseVariableDeclarations(VariableDeclarationContext var_context, ...@@ -2407,7 +2397,6 @@ void Parser::ParseVariableDeclarations(VariableDeclarationContext var_context,
// BindingPattern '=' AssignmentExpression // BindingPattern '=' AssignmentExpression
parsing_result->descriptor.parser = this; parsing_result->descriptor.parser = this;
parsing_result->descriptor.declaration_kind = DeclarationDescriptor::NORMAL;
parsing_result->descriptor.declaration_pos = peek_position(); parsing_result->descriptor.declaration_pos = peek_position();
parsing_result->descriptor.initialization_pos = peek_position(); parsing_result->descriptor.initialization_pos = peek_position();
parsing_result->descriptor.mode = VAR; parsing_result->descriptor.mode = VAR;
...@@ -3339,7 +3328,7 @@ Statement* Parser::DesugarLexicalBindingsInForStatement( ...@@ -3339,7 +3328,7 @@ Statement* Parser::DesugarLexicalBindingsInForStatement(
VariableProxy* proxy = NewUnresolved(names->at(i), mode); VariableProxy* proxy = NewUnresolved(names->at(i), mode);
Declaration* declaration = factory()->NewVariableDeclaration( Declaration* declaration = factory()->NewVariableDeclaration(
proxy, mode, scope_, RelocInfo::kNoPosition); proxy, mode, scope_, RelocInfo::kNoPosition);
Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); Declare(declaration, true, CHECK_OK);
inner_vars.Add(declaration->proxy()->var(), zone()); inner_vars.Add(declaration->proxy()->var(), zone());
VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i)); VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
Assignment* assignment = Assignment* assignment =
...@@ -3795,10 +3784,9 @@ Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) { ...@@ -3795,10 +3784,9 @@ Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) {
void ParserTraits::ParseArrowFunctionFormalParameters( void ParserTraits::ParseArrowFunctionFormalParameters(
ParserFormalParameterParsingState* parsing_state, Expression* expr, Scope* scope, Expression* expr, const Scanner::Location& params_loc,
const Scanner::Location& params_loc, Scanner::Location* duplicate_loc, bool* has_rest, Scanner::Location* duplicate_loc, bool* ok) {
bool* ok) { if (scope->num_parameters() >= Code::kMaxArguments) {
if (parsing_state->scope->num_parameters() >= Code::kMaxArguments) {
ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList); ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList);
*ok = false; *ok = false;
return; return;
...@@ -3824,7 +3812,7 @@ void ParserTraits::ParseArrowFunctionFormalParameters( ...@@ -3824,7 +3812,7 @@ void ParserTraits::ParseArrowFunctionFormalParameters(
DCHECK_EQ(binop->op(), Token::COMMA); DCHECK_EQ(binop->op(), Token::COMMA);
Expression* left = binop->left(); Expression* left = binop->left();
Expression* right = binop->right(); Expression* right = binop->right();
ParseArrowFunctionFormalParameters(parsing_state, left, params_loc, ParseArrowFunctionFormalParameters(scope, left, params_loc, has_rest,
duplicate_loc, ok); duplicate_loc, ok);
if (!*ok) return; if (!*ok) return;
// LHS of comma expression should be unparenthesized. // LHS of comma expression should be unparenthesized.
...@@ -3832,25 +3820,30 @@ void ParserTraits::ParseArrowFunctionFormalParameters( ...@@ -3832,25 +3820,30 @@ void ParserTraits::ParseArrowFunctionFormalParameters(
} }
// Only the right-most expression may be a rest parameter. // Only the right-most expression may be a rest parameter.
DCHECK(!parsing_state->has_rest); DCHECK(!*has_rest);
bool is_rest = false;
if (expr->IsSpread()) { if (expr->IsSpread()) {
is_rest = true; *has_rest = true;
expr = expr->AsSpread()->expression(); expr = expr->AsSpread()->expression();
} }
if (expr->IsVariableProxy()) { if (!expr->IsVariableProxy()) {
// TODO(dslomov): support pattern desugaring
return;
}
DCHECK(!expr->AsVariableProxy()->is_this());
const AstRawString* raw_name = expr->AsVariableProxy()->raw_name();
Scanner::Location param_location(expr->position(),
expr->position() + raw_name->length());
// When the formal parameter was originally seen, it was parsed as a // When the formal parameter was originally seen, it was parsed as a
// VariableProxy and recorded as unresolved in the scope. Here we undo that // VariableProxy and recorded as unresolved in the scope. Here we undo that
// parse-time side-effect for parameters that are single-names (not // parse-time side-effect.
// patterns; for patterns that happens uniformly in
// PatternRewriter::VisitVariableProxy).
parser_->scope_->RemoveUnresolved(expr->AsVariableProxy()); parser_->scope_->RemoveUnresolved(expr->AsVariableProxy());
}
ExpressionClassifier classifier; ExpressionClassifier classifier;
DeclareFormalParameter(parsing_state, expr, &classifier, is_rest); DeclareFormalParameter(scope, expr, &classifier, *has_rest);
if (!duplicate_loc->IsValid()) { if (!duplicate_loc->IsValid()) {
*duplicate_loc = classifier.duplicate_formal_parameter_error().location; *duplicate_loc = classifier.duplicate_formal_parameter_error().location;
} }
...@@ -3925,8 +3918,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral( ...@@ -3925,8 +3918,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
ZoneList<Statement*>* body = NULL; ZoneList<Statement*>* body = NULL;
int materialized_literal_count = -1; int materialized_literal_count = -1;
int expected_property_count = -1; int expected_property_count = -1;
DuplicateFinder duplicate_finder(scanner()->unicode_cache()); ExpressionClassifier formals_classifier;
ExpressionClassifier formals_classifier(&duplicate_finder);
FunctionLiteral::EagerCompileHint eager_compile_hint = FunctionLiteral::EagerCompileHint eager_compile_hint =
parenthesized_function_ ? FunctionLiteral::kShouldEagerCompile parenthesized_function_ ? FunctionLiteral::kShouldEagerCompile
: FunctionLiteral::kShouldLazyCompile; : FunctionLiteral::kShouldLazyCompile;
...@@ -3952,18 +3944,18 @@ FunctionLiteral* Parser::ParseFunctionLiteral( ...@@ -3952,18 +3944,18 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
function_state.set_generator_object_variable(temp); function_state.set_generator_object_variable(temp);
} }
bool has_rest = false;
Expect(Token::LPAREN, CHECK_OK); Expect(Token::LPAREN, CHECK_OK);
int start_position = scanner()->location().beg_pos; int start_position = scanner()->location().beg_pos;
scope_->set_start_position(start_position); scope_->set_start_position(start_position);
ParserFormalParameterParsingState parsing_state(scope); num_parameters = ParseFormalParameterList(scope, &has_rest,
num_parameters = &formals_classifier, CHECK_OK);
ParseFormalParameterList(&parsing_state, &formals_classifier, CHECK_OK);
Expect(Token::RPAREN, CHECK_OK); Expect(Token::RPAREN, CHECK_OK);
int formals_end_position = scanner()->location().end_pos; int formals_end_position = scanner()->location().end_pos;
CheckArityRestrictions(num_parameters, arity_restriction, CheckArityRestrictions(num_parameters, arity_restriction, has_rest,
parsing_state.has_rest, start_position, start_position, formals_end_position, CHECK_OK);
formals_end_position, CHECK_OK);
Expect(Token::LBRACE, CHECK_OK); Expect(Token::LBRACE, CHECK_OK);
// If we have a named function expression, we add a local variable // If we have a named function expression, we add a local variable
...@@ -4058,8 +4050,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral( ...@@ -4058,8 +4050,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
} }
} }
if (!is_lazily_parsed) { if (!is_lazily_parsed) {
body = ParseEagerFunctionBody(function_name, pos, parsing_state, fvar, body = ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op,
fvar_init_op, kind, CHECK_OK); kind, CHECK_OK);
materialized_literal_count = function_state.materialized_literal_count(); materialized_literal_count = function_state.materialized_literal_count();
expected_property_count = function_state.expected_property_count(); expected_property_count = function_state.expected_property_count();
...@@ -4079,8 +4071,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral( ...@@ -4079,8 +4071,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
CheckFunctionName(language_mode(), kind, function_name, CheckFunctionName(language_mode(), kind, function_name,
name_is_strict_reserved, function_name_location, name_is_strict_reserved, function_name_location,
CHECK_OK); CHECK_OK);
const bool use_strict_params = const bool use_strict_params = has_rest || IsConciseMethod(kind);
!parsing_state.is_simple_parameter_list || IsConciseMethod(kind);
const bool allow_duplicate_parameters = const bool allow_duplicate_parameters =
is_sloppy(language_mode()) && !use_strict_params; is_sloppy(language_mode()) && !use_strict_params;
ValidateFormalParameters(&formals_classifier, language_mode(), ValidateFormalParameters(&formals_classifier, language_mode(),
...@@ -4242,40 +4233,8 @@ Statement* Parser::BuildAssertIsCoercible(Variable* var) { ...@@ -4242,40 +4233,8 @@ Statement* Parser::BuildAssertIsCoercible(Variable* var) {
} }
Block* Parser::BuildParameterInitializationBlock(
const ParserFormalParameterParsingState& formal_parameters, bool* ok) {
DCHECK(scope_->is_function_scope());
Block* init_block = nullptr;
for (auto parameter : formal_parameters.params) {
if (parameter.pattern == nullptr) continue;
if (init_block == nullptr) {
init_block = factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition);
}
DeclarationDescriptor descriptor;
descriptor.declaration_kind = DeclarationDescriptor::PARAMETER;
descriptor.parser = this;
descriptor.declaration_scope = scope_;
descriptor.scope = scope_;
descriptor.mode = LET;
descriptor.is_const = false;
descriptor.needs_init = true;
descriptor.declaration_pos = parameter.pattern->position();
descriptor.initialization_pos = parameter.pattern->position();
descriptor.init_op = Token::INIT_LET;
DeclarationParsingResult::Declaration decl(
parameter.pattern, parameter.pattern->position(),
factory()->NewVariableProxy(parameter.var));
PatternRewriter::DeclareAndInitializeVariables(init_block, &descriptor,
&decl, nullptr, CHECK_OK);
}
return init_block;
}
ZoneList<Statement*>* Parser::ParseEagerFunctionBody( ZoneList<Statement*>* Parser::ParseEagerFunctionBody(
const AstRawString* function_name, int pos, const AstRawString* function_name, int pos, Variable* fvar,
const ParserFormalParameterParsingState& formal_parameters, Variable* fvar,
Token::Value fvar_init_op, FunctionKind kind, bool* ok) { Token::Value fvar_init_op, FunctionKind kind, bool* ok) {
// Everything inside an eagerly parsed function will be parsed eagerly // Everything inside an eagerly parsed function will be parsed eagerly
// (see comment above). // (see comment above).
...@@ -4299,12 +4258,6 @@ ZoneList<Statement*>* Parser::ParseEagerFunctionBody( ...@@ -4299,12 +4258,6 @@ ZoneList<Statement*>* Parser::ParseEagerFunctionBody(
AddAssertIsConstruct(body, pos); AddAssertIsConstruct(body, pos);
} }
auto init_block =
BuildParameterInitializationBlock(formal_parameters, CHECK_OK);
if (init_block != nullptr) {
body->Add(init_block, zone());
}
// For generators, allocate and yield an iterator on function entry. // For generators, allocate and yield an iterator on function entry.
if (IsGeneratorFunction(kind)) { if (IsGeneratorFunction(kind)) {
ZoneList<Expression*>* arguments = ZoneList<Expression*>* arguments =
...@@ -4431,7 +4384,7 @@ ClassLiteral* Parser::ParseClassLiteral(const AstRawString* name, ...@@ -4431,7 +4384,7 @@ ClassLiteral* Parser::ParseClassLiteral(const AstRawString* name,
Declaration* declaration = factory()->NewVariableDeclaration( Declaration* declaration = factory()->NewVariableDeclaration(
proxy, CONST, block_scope, pos, is_class_declaration, proxy, CONST, block_scope, pos, is_class_declaration,
scope_->class_declaration_group_start()); scope_->class_declaration_group_start());
Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); Declare(declaration, true, CHECK_OK);
} }
Expression* extends = NULL; Expression* extends = NULL;
......
...@@ -538,27 +538,6 @@ class RegExpParser BASE_EMBEDDED { ...@@ -538,27 +538,6 @@ class RegExpParser BASE_EMBEDDED {
class Parser; class Parser;
class SingletonLogger; class SingletonLogger;
struct ParserFormalParameterParsingState
: public PreParserFormalParameterParsingState {
struct Parameter {
Parameter(Variable* var, Expression* pattern)
: var(var), pattern(pattern) {}
Variable* var;
Expression* pattern;
};
explicit ParserFormalParameterParsingState(Scope* scope)
: PreParserFormalParameterParsingState(scope), params(4, scope->zone()) {}
ZoneList<Parameter> params;
void AddParameter(Variable* var, Expression* pattern) {
params.Add(Parameter(var, pattern), scope->zone());
}
};
class ParserTraits { class ParserTraits {
public: public:
struct Type { struct Type {
...@@ -581,7 +560,7 @@ class ParserTraits { ...@@ -581,7 +560,7 @@ class ParserTraits {
typedef ZoneList<v8::internal::Expression*>* ExpressionList; typedef ZoneList<v8::internal::Expression*>* ExpressionList;
typedef ZoneList<ObjectLiteral::Property*>* PropertyList; typedef ZoneList<ObjectLiteral::Property*>* PropertyList;
typedef const v8::internal::AstRawString* FormalParameter; typedef const v8::internal::AstRawString* FormalParameter;
typedef ParserFormalParameterParsingState FormalParameterParsingState; typedef Scope FormalParameterScope;
typedef ZoneList<v8::internal::Statement*>* StatementList; typedef ZoneList<v8::internal::Statement*>* StatementList;
// For constructing objects returned by the traversing functions. // For constructing objects returned by the traversing functions.
...@@ -772,20 +751,16 @@ class ParserTraits { ...@@ -772,20 +751,16 @@ class ParserTraits {
ZoneList<v8::internal::Statement*>* NewStatementList(int size, Zone* zone) { ZoneList<v8::internal::Statement*>* NewStatementList(int size, Zone* zone) {
return new(zone) ZoneList<v8::internal::Statement*>(size, zone); return new(zone) ZoneList<v8::internal::Statement*>(size, zone);
} }
V8_INLINE void AddParameterInitializationBlock(
const ParserFormalParameterParsingState& formal_parameters,
ZoneList<v8::internal::Statement*>* body, bool* ok);
V8_INLINE Scope* NewScope(Scope* parent_scope, ScopeType scope_type, V8_INLINE Scope* NewScope(Scope* parent_scope, ScopeType scope_type,
FunctionKind kind = kNormalFunction); FunctionKind kind = kNormalFunction);
V8_INLINE void DeclareFormalParameter( V8_INLINE void DeclareFormalParameter(Scope* scope, Expression* name,
ParserFormalParameterParsingState* parsing_state, Expression* name, ExpressionClassifier* classifier,
ExpressionClassifier* classifier, bool is_rest); bool is_rest);
void ParseArrowFunctionFormalParameters( void ParseArrowFunctionFormalParameters(Scope* scope, Expression* params,
ParserFormalParameterParsingState* scope, Expression* params, const Scanner::Location& params_loc,
const Scanner::Location& params_loc, Scanner::Location* duplicate_loc, bool* has_rest,
Scanner::Location* duplicate_loc,
bool* ok); bool* ok);
// Temporary glue; these functions will move to ParserBase. // Temporary glue; these functions will move to ParserBase.
...@@ -799,9 +774,8 @@ class ParserTraits { ...@@ -799,9 +774,8 @@ class ParserTraits {
int* materialized_literal_count, int* expected_property_count, bool* ok, int* materialized_literal_count, int* expected_property_count, bool* ok,
Scanner::BookmarkScope* bookmark = nullptr); Scanner::BookmarkScope* bookmark = nullptr);
V8_INLINE ZoneList<Statement*>* ParseEagerFunctionBody( V8_INLINE ZoneList<Statement*>* ParseEagerFunctionBody(
const AstRawString* name, int pos, const AstRawString* name, int pos, Variable* fvar,
const ParserFormalParameterParsingState& formal_parameters, Token::Value fvar_init_op, FunctionKind kind, bool* ok);
Variable* fvar, Token::Value fvar_init_op, FunctionKind kind, bool* ok);
ClassLiteral* ParseClassLiteral(const AstRawString* name, ClassLiteral* ParseClassLiteral(const AstRawString* name,
Scanner::Location class_name_location, Scanner::Location class_name_location,
...@@ -962,7 +936,6 @@ class Parser : public ParserBase<ParserTraits> { ...@@ -962,7 +936,6 @@ class Parser : public ParserBase<ParserTraits> {
bool* ok); bool* ok);
struct DeclarationDescriptor { struct DeclarationDescriptor {
enum Kind { NORMAL, PARAMETER };
Parser* parser; Parser* parser;
Scope* declaration_scope; Scope* declaration_scope;
Scope* scope; Scope* scope;
...@@ -972,7 +945,6 @@ class Parser : public ParserBase<ParserTraits> { ...@@ -972,7 +945,6 @@ class Parser : public ParserBase<ParserTraits> {
int declaration_pos; int declaration_pos;
int initialization_pos; int initialization_pos;
Token::Value init_op; Token::Value init_op;
Kind declaration_kind;
}; };
struct DeclarationParsingResult { struct DeclarationParsingResult {
...@@ -1123,9 +1095,7 @@ class Parser : public ParserBase<ParserTraits> { ...@@ -1123,9 +1095,7 @@ class Parser : public ParserBase<ParserTraits> {
// Parser support // Parser support
VariableProxy* NewUnresolved(const AstRawString* name, VariableMode mode); VariableProxy* NewUnresolved(const AstRawString* name, VariableMode mode);
Variable* Declare(Declaration* declaration, Variable* Declare(Declaration* declaration, bool resolve, bool* ok);
DeclarationDescriptor::Kind declaration_kind, bool resolve,
bool* ok);
bool TargetStackContainsLabel(const AstRawString* label); bool TargetStackContainsLabel(const AstRawString* label);
BreakableStatement* LookupBreakTarget(const AstRawString* label, bool* ok); BreakableStatement* LookupBreakTarget(const AstRawString* label, bool* ok);
...@@ -1151,14 +1121,10 @@ class Parser : public ParserBase<ParserTraits> { ...@@ -1151,14 +1121,10 @@ class Parser : public ParserBase<ParserTraits> {
PreParser::PreParseResult ParseLazyFunctionBodyWithPreParser( PreParser::PreParseResult ParseLazyFunctionBodyWithPreParser(
SingletonLogger* logger, Scanner::BookmarkScope* bookmark = nullptr); SingletonLogger* logger, Scanner::BookmarkScope* bookmark = nullptr);
Block* BuildParameterInitializationBlock(
const ParserFormalParameterParsingState& formal_parameters, bool* ok);
// Consumes the ending }. // Consumes the ending }.
ZoneList<Statement*>* ParseEagerFunctionBody( ZoneList<Statement*>* ParseEagerFunctionBody(
const AstRawString* function_name, int pos, const AstRawString* function_name, int pos, Variable* fvar,
const ParserFormalParameterParsingState& formal_parameters, Token::Value fvar_init_op, FunctionKind kind, bool* ok);
Variable* fvar, Token::Value fvar_init_op, FunctionKind kind, bool* ok);
void ThrowPendingError(Isolate* isolate, Handle<Script> script); void ThrowPendingError(Isolate* isolate, Handle<Script> script);
...@@ -1222,11 +1188,10 @@ void ParserTraits::SkipLazyFunctionBody(int* materialized_literal_count, ...@@ -1222,11 +1188,10 @@ void ParserTraits::SkipLazyFunctionBody(int* materialized_literal_count,
ZoneList<Statement*>* ParserTraits::ParseEagerFunctionBody( ZoneList<Statement*>* ParserTraits::ParseEagerFunctionBody(
const AstRawString* name, int pos, const AstRawString* name, int pos, Variable* fvar,
const ParserFormalParameterParsingState& formal_parameters, Variable* fvar,
Token::Value fvar_init_op, FunctionKind kind, bool* ok) { Token::Value fvar_init_op, FunctionKind kind, bool* ok) {
return parser_->ParseEagerFunctionBody(name, pos, formal_parameters, fvar, return parser_->ParseEagerFunctionBody(name, pos, fvar, fvar_init_op, kind,
fvar_init_op, kind, ok); ok);
} }
void ParserTraits::CheckConflictingVarDeclarations(v8::internal::Scope* scope, void ParserTraits::CheckConflictingVarDeclarations(v8::internal::Scope* scope,
...@@ -1305,20 +1270,18 @@ Expression* ParserTraits::SpreadCallNew( ...@@ -1305,20 +1270,18 @@ Expression* ParserTraits::SpreadCallNew(
} }
void ParserTraits::DeclareFormalParameter( void ParserTraits::DeclareFormalParameter(Scope* scope, Expression* pattern,
ParserFormalParameterParsingState* parsing_state, Expression* pattern, ExpressionClassifier* classifier,
ExpressionClassifier* classifier, bool is_rest) { bool is_rest) {
bool is_duplicate = false; bool is_duplicate = false;
bool is_simple_name = pattern->IsVariableProxy(); if (!pattern->IsVariableProxy()) {
DCHECK(parser_->allow_harmony_destructuring() || is_simple_name); // TODO(dslomov): implement.
DCHECK(parser_->allow_harmony_destructuring());
const AstRawString* name = is_simple_name return;
? pattern->AsVariableProxy()->raw_name() }
: parser_->ast_value_factory()->empty_string(); auto name = pattern->AsVariableProxy()->raw_name();
Variable* var = Variable* var = scope->DeclareParameter(name, VAR, is_rest, &is_duplicate);
parsing_state->scope->DeclareParameter(name, VAR, is_rest, &is_duplicate); if (is_sloppy(scope->language_mode())) {
parsing_state->AddParameter(var, is_simple_name ? nullptr : pattern);
if (is_sloppy(parsing_state->scope->language_mode())) {
// TODO(sigurds) Mark every parameter as maybe assigned. This is a // TODO(sigurds) Mark every parameter as maybe assigned. This is a
// conservative approximation necessary to account for parameters // conservative approximation necessary to account for parameters
// that are assigned via the arguments array. // that are assigned via the arguments array.
...@@ -1329,18 +1292,6 @@ void ParserTraits::DeclareFormalParameter( ...@@ -1329,18 +1292,6 @@ void ParserTraits::DeclareFormalParameter(
parser_->scanner()->location()); parser_->scanner()->location());
} }
} }
void ParserTraits::AddParameterInitializationBlock(
const ParserFormalParameterParsingState& formal_parameters,
ZoneList<v8::internal::Statement*>* body, bool* ok) {
auto* init_block =
parser_->BuildParameterInitializationBlock(formal_parameters, ok);
if (!*ok) return;
if (init_block != nullptr) {
body->Add(init_block, parser_->zone());
}
}
} } // namespace v8::internal } } // namespace v8::internal
#endif // V8_PARSER_H_ #endif // V8_PARSER_H_
...@@ -53,8 +53,7 @@ void Parser::PatternRewriter::VisitVariableProxy(VariableProxy* pattern) { ...@@ -53,8 +53,7 @@ void Parser::PatternRewriter::VisitVariableProxy(VariableProxy* pattern) {
Declaration* declaration = factory()->NewVariableDeclaration( Declaration* declaration = factory()->NewVariableDeclaration(
proxy, descriptor_->mode, descriptor_->scope, proxy, descriptor_->mode, descriptor_->scope,
descriptor_->declaration_pos); descriptor_->declaration_pos);
Variable* var = parser->Declare(declaration, descriptor_->declaration_kind, Variable* var = parser->Declare(declaration, descriptor_->mode != VAR, ok_);
descriptor_->mode != VAR, ok_);
if (!*ok_) return; if (!*ok_) return;
DCHECK_NOT_NULL(var); DCHECK_NOT_NULL(var);
DCHECK(!proxy->is_resolved() || proxy->var() == var); DCHECK(!proxy->is_resolved() || proxy->var() == var);
......
...@@ -1038,18 +1038,17 @@ PreParser::Expression PreParser::ParseFunctionLiteral( ...@@ -1038,18 +1038,17 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
DuplicateFinder duplicate_finder(scanner()->unicode_cache()); DuplicateFinder duplicate_finder(scanner()->unicode_cache());
ExpressionClassifier formals_classifier(&duplicate_finder); ExpressionClassifier formals_classifier(&duplicate_finder);
bool has_rest = false;
Expect(Token::LPAREN, CHECK_OK); Expect(Token::LPAREN, CHECK_OK);
int start_position = scanner()->location().beg_pos; int start_position = scanner()->location().beg_pos;
function_scope->set_start_position(start_position); function_scope->set_start_position(start_position);
PreParserFormalParameterParsingState parsing_state(nullptr); int num_parameters = ParseFormalParameterList(nullptr, &has_rest,
int num_parameters = &formals_classifier, CHECK_OK);
ParseFormalParameterList(&parsing_state, &formals_classifier, CHECK_OK);
Expect(Token::RPAREN, CHECK_OK); Expect(Token::RPAREN, CHECK_OK);
int formals_end_position = scanner()->location().end_pos; int formals_end_position = scanner()->location().end_pos;
CheckArityRestrictions(num_parameters, arity_restriction, CheckArityRestrictions(num_parameters, arity_restriction, has_rest,
parsing_state.has_rest, start_position, start_position, formals_end_position, CHECK_OK);
formals_end_position, CHECK_OK);
// See Parser::ParseFunctionLiteral for more information about lazy parsing // See Parser::ParseFunctionLiteral for more information about lazy parsing
// and lazy compilation. // and lazy compilation.
...@@ -1069,8 +1068,7 @@ PreParser::Expression PreParser::ParseFunctionLiteral( ...@@ -1069,8 +1068,7 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
// function, since the function can declare itself strict. // function, since the function can declare itself strict.
CheckFunctionName(language_mode(), kind, function_name, CheckFunctionName(language_mode(), kind, function_name,
name_is_strict_reserved, function_name_location, CHECK_OK); name_is_strict_reserved, function_name_location, CHECK_OK);
const bool strict_formal_parameters = const bool strict_formal_parameters = has_rest || IsConciseMethod(kind);
!parsing_state.is_simple_parameter_list || IsConciseMethod(kind);
const bool allow_duplicate_parameters = const bool allow_duplicate_parameters =
is_sloppy(language_mode()) && !strict_formal_parameters; is_sloppy(language_mode()) && !strict_formal_parameters;
ValidateFormalParameters(&formals_classifier, language_mode(), ValidateFormalParameters(&formals_classifier, language_mode(),
......
...@@ -70,8 +70,6 @@ class ParserBase : public Traits { ...@@ -70,8 +70,6 @@ class ParserBase : public Traits {
typedef typename Traits::Type::FunctionLiteral FunctionLiteralT; typedef typename Traits::Type::FunctionLiteral FunctionLiteralT;
typedef typename Traits::Type::Literal LiteralT; typedef typename Traits::Type::Literal LiteralT;
typedef typename Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT; typedef typename Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT;
typedef typename Traits::Type::FormalParameterParsingState
FormalParameterParsingStateT;
ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit, ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit,
v8::Extension* extension, AstValueFactory* ast_value_factory, v8::Extension* extension, AstValueFactory* ast_value_factory,
...@@ -559,7 +557,7 @@ class ParserBase : public Traits { ...@@ -559,7 +557,7 @@ class ParserBase : public Traits {
ExpressionT expr, bool* ok) { ExpressionT expr, bool* ok) {
if (classifier->is_valid_binding_pattern()) { if (classifier->is_valid_binding_pattern()) {
// A simple arrow formal parameter: IDENTIFIER => BODY. // A simple arrow formal parameter: IDENTIFIER => BODY.
if (!this->IsIdentifier(expr)) { if (!allow_harmony_destructuring() && !this->IsIdentifier(expr)) {
Traits::ReportMessageAt(scanner()->location(), Traits::ReportMessageAt(scanner()->location(),
MessageTemplate::kUnexpectedToken, MessageTemplate::kUnexpectedToken,
Token::String(scanner()->current_token())); Token::String(scanner()->current_token()));
...@@ -648,9 +646,9 @@ class ParserBase : public Traits { ...@@ -648,9 +646,9 @@ class ParserBase : public Traits {
ExpressionT ParseMemberExpression(ExpressionClassifier* classifier, bool* ok); ExpressionT ParseMemberExpression(ExpressionClassifier* classifier, bool* ok);
ExpressionT ParseMemberExpressionContinuation( ExpressionT ParseMemberExpressionContinuation(
ExpressionT expression, ExpressionClassifier* classifier, bool* ok); ExpressionT expression, ExpressionClassifier* classifier, bool* ok);
ExpressionT ParseArrowFunctionLiteral( ExpressionT ParseArrowFunctionLiteral(Scope* function_scope, bool has_rest,
const FormalParameterParsingStateT& parsing_state, const ExpressionClassifier& classifier,
const ExpressionClassifier& classifier, bool* ok); bool* ok);
ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, ExpressionT ParseTemplateLiteral(ExpressionT tag, int start,
ExpressionClassifier* classifier, bool* ok); ExpressionClassifier* classifier, bool* ok);
void AddTemplateExpression(ExpressionT); void AddTemplateExpression(ExpressionT);
...@@ -662,10 +660,9 @@ class ParserBase : public Traits { ...@@ -662,10 +660,9 @@ class ParserBase : public Traits {
ExpressionT ParseStrongSuperCallExpression(ExpressionClassifier* classifier, ExpressionT ParseStrongSuperCallExpression(ExpressionClassifier* classifier,
bool* ok); bool* ok);
void ParseFormalParameter(bool is_rest, void ParseFormalParameter(Scope* scope, bool is_rest,
FormalParameterParsingStateT* parsing_result,
ExpressionClassifier* classifier, bool* ok); ExpressionClassifier* classifier, bool* ok);
int ParseFormalParameterList(FormalParameterParsingStateT* parsing_state, int ParseFormalParameterList(Scope* scope, bool* has_rest,
ExpressionClassifier* classifier, bool* ok); ExpressionClassifier* classifier, bool* ok);
void CheckArityRestrictions( void CheckArityRestrictions(
int param_count, FunctionLiteral::ArityRestriction arity_restriction, int param_count, FunctionLiteral::ArityRestriction arity_restriction,
...@@ -1257,15 +1254,6 @@ class PreParserFactory { ...@@ -1257,15 +1254,6 @@ class PreParserFactory {
}; };
struct PreParserFormalParameterParsingState {
explicit PreParserFormalParameterParsingState(Scope* scope)
: scope(scope), has_rest(false), is_simple_parameter_list(true) {}
Scope* scope;
bool has_rest;
bool is_simple_parameter_list;
};
class PreParser; class PreParser;
class PreParserTraits { class PreParserTraits {
...@@ -1292,7 +1280,6 @@ class PreParserTraits { ...@@ -1292,7 +1280,6 @@ class PreParserTraits {
typedef PreParserExpressionList PropertyList; typedef PreParserExpressionList PropertyList;
typedef PreParserIdentifier FormalParameter; typedef PreParserIdentifier FormalParameter;
typedef PreParserStatementList StatementList; typedef PreParserStatementList StatementList;
typedef PreParserFormalParameterParsingState FormalParameterParsingState;
// For constructing objects returned by the traversing functions. // For constructing objects returned by the traversing functions.
typedef PreParserFactory Factory; typedef PreParserFactory Factory;
...@@ -1531,23 +1518,19 @@ class PreParserTraits { ...@@ -1531,23 +1518,19 @@ class PreParserTraits {
return PreParserExpressionList(); return PreParserExpressionList();
} }
static void AddParameterInitializationBlock(
const PreParserFormalParameterParsingState& formal_parameters,
PreParserStatementList list, bool* ok) {}
V8_INLINE void SkipLazyFunctionBody(int* materialized_literal_count, V8_INLINE void SkipLazyFunctionBody(int* materialized_literal_count,
int* expected_property_count, bool* ok) { int* expected_property_count, bool* ok) {
UNREACHABLE(); UNREACHABLE();
} }
V8_INLINE PreParserStatementList ParseEagerFunctionBody( V8_INLINE PreParserStatementList
PreParserIdentifier function_name, int pos, ParseEagerFunctionBody(PreParserIdentifier function_name, int pos,
const PreParserFormalParameterParsingState& formal_parameters, Variable* fvar, Token::Value fvar_init_op,
Variable* fvar, Token::Value fvar_init_op, FunctionKind kind, bool* ok); FunctionKind kind, bool* ok);
V8_INLINE void ParseArrowFunctionFormalParameters( V8_INLINE void ParseArrowFunctionFormalParameters(
PreParserFormalParameterParsingState* parsing_state, Scope* scope, PreParserExpression expression,
PreParserExpression expression, const Scanner::Location& params_loc, const Scanner::Location& params_loc, bool* has_rest,
Scanner::Location* duplicate_loc, bool* ok); Scanner::Location* duplicate_loc, bool* ok);
struct TemplateLiteralState {}; struct TemplateLiteralState {};
...@@ -1574,7 +1557,7 @@ class PreParserTraits { ...@@ -1574,7 +1557,7 @@ class PreParserTraits {
return !tag.IsNoTemplateTag(); return !tag.IsNoTemplateTag();
} }
void DeclareFormalParameter(void* parsing_state, PreParserExpression pattern, void DeclareFormalParameter(Scope* scope, PreParserExpression pattern,
ExpressionClassifier* classifier, bool is_rest) {} ExpressionClassifier* classifier, bool is_rest) {}
void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {} void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {}
...@@ -1725,7 +1708,6 @@ class PreParser : public ParserBase<PreParserTraits> { ...@@ -1725,7 +1708,6 @@ class PreParser : public ParserBase<PreParserTraits> {
int* expected_property_count, bool* ok); int* expected_property_count, bool* ok);
V8_INLINE PreParserStatementList V8_INLINE PreParserStatementList
ParseEagerFunctionBody(PreParserIdentifier function_name, int pos, ParseEagerFunctionBody(PreParserIdentifier function_name, int pos,
const FormalParameterParsingStateT& formal_parameters,
Variable* fvar, Token::Value fvar_init_op, Variable* fvar, Token::Value fvar_init_op,
FunctionKind kind, bool* ok); FunctionKind kind, bool* ok);
...@@ -1771,8 +1753,8 @@ PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function, ...@@ -1771,8 +1753,8 @@ PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function,
void PreParserTraits::ParseArrowFunctionFormalParameters( void PreParserTraits::ParseArrowFunctionFormalParameters(
PreParserFormalParameterParsingState* parsing_state, Scope* scope, PreParserExpression params,
PreParserExpression params, const Scanner::Location& params_loc, const Scanner::Location& params_loc, bool* has_rest,
Scanner::Location* duplicate_loc, bool* ok) { Scanner::Location* duplicate_loc, bool* ok) {
// TODO(wingo): Detect duplicated identifiers in paramlists. Detect parameter // TODO(wingo): Detect duplicated identifiers in paramlists. Detect parameter
// lists that are too long. // lists that are too long.
...@@ -1780,9 +1762,8 @@ void PreParserTraits::ParseArrowFunctionFormalParameters( ...@@ -1780,9 +1762,8 @@ void PreParserTraits::ParseArrowFunctionFormalParameters(
PreParserStatementList PreParser::ParseEagerFunctionBody( PreParserStatementList PreParser::ParseEagerFunctionBody(
PreParserIdentifier function_name, int pos, PreParserIdentifier function_name, int pos, Variable* fvar,
const PreParserFormalParameterParsingState& formal_parameters, Token::Value fvar_init_op, FunctionKind kind, bool* ok) {
Variable* fvar, Token::Value fvar_init_op, FunctionKind kind, bool* ok) {
ParsingModeScope parsing_mode(this, PARSE_EAGERLY); ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
ParseStatementList(Token::RBRACE, ok); ParseStatementList(Token::RBRACE, ok);
...@@ -1794,11 +1775,10 @@ PreParserStatementList PreParser::ParseEagerFunctionBody( ...@@ -1794,11 +1775,10 @@ PreParserStatementList PreParser::ParseEagerFunctionBody(
PreParserStatementList PreParserTraits::ParseEagerFunctionBody( PreParserStatementList PreParserTraits::ParseEagerFunctionBody(
PreParserIdentifier function_name, int pos, PreParserIdentifier function_name, int pos, Variable* fvar,
const PreParserFormalParameterParsingState& formal_parameters, Token::Value fvar_init_op, FunctionKind kind, bool* ok) {
Variable* fvar, Token::Value fvar_init_op, FunctionKind kind, bool* ok) { return pre_parser_->ParseEagerFunctionBody(function_name, pos, fvar,
return pre_parser_->ParseEagerFunctionBody( fvar_init_op, kind, ok);
function_name, pos, formal_parameters, fvar, fvar_init_op, kind, ok);
} }
...@@ -2182,22 +2162,20 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, ...@@ -2182,22 +2162,20 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
} }
Scope* scope = Scope* scope =
this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction); this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction);
FormalParameterParsingStateT parsing_state(scope);
scope->set_start_position(beg_pos); scope->set_start_position(beg_pos);
ExpressionClassifier args_classifier; ExpressionClassifier args_classifier;
result = this->ParseArrowFunctionLiteral(parsing_state, args_classifier, bool has_rest = false;
CHECK_OK); result = this->ParseArrowFunctionLiteral(scope, has_rest,
args_classifier, CHECK_OK);
} else if (allow_harmony_arrow_functions() && } else if (allow_harmony_arrow_functions() &&
allow_harmony_rest_params() && Check(Token::ELLIPSIS)) { allow_harmony_rest_params() && Check(Token::ELLIPSIS)) {
// (...x) => y // (...x) => y
Scope* scope = Scope* scope =
this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction); this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction);
FormalParameterParsingStateT parsing_state(scope);
scope->set_start_position(beg_pos); scope->set_start_position(beg_pos);
ExpressionClassifier args_classifier; ExpressionClassifier args_classifier;
const bool is_rest = true; const bool has_rest = true;
this->ParseFormalParameter(is_rest, &parsing_state, &args_classifier, this->ParseFormalParameter(scope, has_rest, &args_classifier, CHECK_OK);
CHECK_OK);
if (peek() == Token::COMMA) { if (peek() == Token::COMMA) {
ReportMessageAt(scanner()->peek_location(), ReportMessageAt(scanner()->peek_location(),
MessageTemplate::kParamAfterRest); MessageTemplate::kParamAfterRest);
...@@ -2205,8 +2183,8 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, ...@@ -2205,8 +2183,8 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
return this->EmptyExpression(); return this->EmptyExpression();
} }
Expect(Token::RPAREN, CHECK_OK); Expect(Token::RPAREN, CHECK_OK);
result = this->ParseArrowFunctionLiteral(parsing_state, args_classifier, result = this->ParseArrowFunctionLiteral(scope, has_rest,
CHECK_OK); args_classifier, CHECK_OK);
} else { } else {
// Heuristically try to detect immediately called functions before // Heuristically try to detect immediately called functions before
// seeing the call parentheses. // seeing the call parentheses.
...@@ -2546,11 +2524,6 @@ ParserBase<Traits>::ParsePropertyDefinition( ...@@ -2546,11 +2524,6 @@ ParserBase<Traits>::ParsePropertyDefinition(
DCHECK(!*is_computed_name); DCHECK(!*is_computed_name);
DCHECK(!is_static); DCHECK(!is_static);
if (classifier->duplicate_finder() != nullptr &&
scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) {
classifier->RecordDuplicateFormalParameterError(scanner()->location());
}
ExpressionT lhs = this->ExpressionFromIdentifier( ExpressionT lhs = this->ExpressionFromIdentifier(
name, next_beg_pos, next_end_pos, scope_, factory()); name, next_beg_pos, next_end_pos, scope_, factory());
if (peek() == Token::ASSIGN) { if (peek() == Token::ASSIGN) {
...@@ -2734,7 +2707,7 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, ...@@ -2734,7 +2707,7 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
if (fni_ != NULL) fni_->Enter(); if (fni_ != NULL) fni_->Enter();
ParserBase<Traits>::Checkpoint checkpoint(this); ParserBase<Traits>::Checkpoint checkpoint(this);
ExpressionClassifier arrow_formals_classifier(classifier->duplicate_finder()); ExpressionClassifier arrow_formals_classifier;
if (peek() != Token::LPAREN) { if (peek() != Token::LPAREN) {
// The expression we are going to read is not a parenthesized arrow function // The expression we are going to read is not a parenthesized arrow function
// formal parameter list. // formal parameter list.
...@@ -2753,15 +2726,15 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, ...@@ -2753,15 +2726,15 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction); this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction);
scope->set_start_position(lhs_location.beg_pos); scope->set_start_position(lhs_location.beg_pos);
Scanner::Location duplicate_loc = Scanner::Location::invalid(); Scanner::Location duplicate_loc = Scanner::Location::invalid();
FormalParameterParsingStateT parsing_state(scope); bool has_rest = false;
this->ParseArrowFunctionFormalParameters(&parsing_state, expression, loc, this->ParseArrowFunctionFormalParameters(scope, expression, loc, &has_rest,
&duplicate_loc, CHECK_OK); &duplicate_loc, CHECK_OK);
if (duplicate_loc.IsValid()) { if (duplicate_loc.IsValid()) {
arrow_formals_classifier.RecordDuplicateFormalParameterError( arrow_formals_classifier.RecordDuplicateFormalParameterError(
duplicate_loc); duplicate_loc);
} }
expression = this->ParseArrowFunctionLiteral( expression = this->ParseArrowFunctionLiteral(
parsing_state, arrow_formals_classifier, CHECK_OK); scope, has_rest, arrow_formals_classifier, CHECK_OK);
return expression; return expression;
} }
...@@ -3524,9 +3497,9 @@ ParserBase<Traits>::ParseMemberExpressionContinuation( ...@@ -3524,9 +3497,9 @@ ParserBase<Traits>::ParseMemberExpressionContinuation(
template <class Traits> template <class Traits>
void ParserBase<Traits>::ParseFormalParameter( void ParserBase<Traits>::ParseFormalParameter(Scope* scope, bool is_rest,
bool is_rest, FormalParameterParsingStateT* parsing_state, ExpressionClassifier* classifier,
ExpressionClassifier* classifier, bool* ok) { bool* ok) {
// FormalParameter[Yield,GeneratorParameter] : // FormalParameter[Yield,GeneratorParameter] :
// BindingElement[?Yield, ?GeneratorParameter] // BindingElement[?Yield, ?GeneratorParameter]
...@@ -3543,24 +3516,13 @@ void ParserBase<Traits>::ParseFormalParameter( ...@@ -3543,24 +3516,13 @@ void ParserBase<Traits>::ParseFormalParameter(
return; return;
} }
if (parsing_state->is_simple_parameter_list) { Traits::DeclareFormalParameter(scope, pattern, classifier, is_rest);
parsing_state->is_simple_parameter_list =
!is_rest && Traits::IsIdentifier(pattern);
}
parsing_state->has_rest = is_rest;
if (is_rest && !Traits::IsIdentifier(pattern)) {
ReportUnexpectedToken(next);
*ok = false;
return;
}
Traits::DeclareFormalParameter(parsing_state, pattern, classifier, is_rest);
} }
template <class Traits> template <class Traits>
int ParserBase<Traits>::ParseFormalParameterList( int ParserBase<Traits>::ParseFormalParameterList(
FormalParameterParsingStateT* parsing_state, Scope* scope, bool* is_rest, ExpressionClassifier* classifier, bool* ok) {
ExpressionClassifier* classifier, bool* ok) {
// FormalParameters[Yield,GeneratorParameter] : // FormalParameters[Yield,GeneratorParameter] :
// [empty] // [empty]
// FormalParameterList[?Yield, ?GeneratorParameter] // FormalParameterList[?Yield, ?GeneratorParameter]
...@@ -3584,12 +3546,12 @@ int ParserBase<Traits>::ParseFormalParameterList( ...@@ -3584,12 +3546,12 @@ int ParserBase<Traits>::ParseFormalParameterList(
*ok = false; *ok = false;
return -1; return -1;
} }
bool is_rest = allow_harmony_rest_params() && Check(Token::ELLIPSIS); *is_rest = allow_harmony_rest_params() && Check(Token::ELLIPSIS);
ParseFormalParameter(is_rest, parsing_state, classifier, ok); ParseFormalParameter(scope, *is_rest, classifier, ok);
if (!*ok) return -1; if (!*ok) return -1;
} while (!parsing_state->has_rest && Check(Token::COMMA)); } while (!*is_rest && Check(Token::COMMA));
if (parsing_state->has_rest && peek() == Token::COMMA) { if (*is_rest && peek() == Token::COMMA) {
ReportMessageAt(scanner()->peek_location(), ReportMessageAt(scanner()->peek_location(),
MessageTemplate::kParamAfterRest); MessageTemplate::kParamAfterRest);
*ok = false; *ok = false;
...@@ -3634,8 +3596,8 @@ void ParserBase<Traits>::CheckArityRestrictions( ...@@ -3634,8 +3596,8 @@ void ParserBase<Traits>::CheckArityRestrictions(
template <class Traits> template <class Traits>
typename ParserBase<Traits>::ExpressionT typename ParserBase<Traits>::ExpressionT
ParserBase<Traits>::ParseArrowFunctionLiteral( ParserBase<Traits>::ParseArrowFunctionLiteral(
const FormalParameterParsingStateT& formal_parameters, Scope* scope, bool has_rest, const ExpressionClassifier& formals_classifier,
const ExpressionClassifier& formals_classifier, bool* ok) { bool* ok) {
if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) {
// ASI inserts `;` after arrow parameters if a line terminator is found. // ASI inserts `;` after arrow parameters if a line terminator is found.
// `=> ...` is never a valid expression, so report as syntax error. // `=> ...` is never a valid expression, so report as syntax error.
...@@ -3646,16 +3608,15 @@ ParserBase<Traits>::ParseArrowFunctionLiteral( ...@@ -3646,16 +3608,15 @@ ParserBase<Traits>::ParseArrowFunctionLiteral(
} }
typename Traits::Type::StatementList body; typename Traits::Type::StatementList body;
int num_parameters = formal_parameters.scope->num_parameters(); int num_parameters = scope->num_parameters();
int materialized_literal_count = -1; int materialized_literal_count = -1;
int expected_property_count = -1; int expected_property_count = -1;
Scanner::Location super_loc; Scanner::Location super_loc;
{ {
typename Traits::Type::Factory function_factory(ast_value_factory()); typename Traits::Type::Factory function_factory(ast_value_factory());
FunctionState function_state(&function_state_, &scope_, FunctionState function_state(&function_state_, &scope_, scope,
formal_parameters.scope, kArrowFunction, kArrowFunction, &function_factory);
&function_factory);
Expect(Token::ARROW, CHECK_OK); Expect(Token::ARROW, CHECK_OK);
...@@ -3670,8 +3631,8 @@ ParserBase<Traits>::ParseArrowFunctionLiteral( ...@@ -3670,8 +3631,8 @@ ParserBase<Traits>::ParseArrowFunctionLiteral(
&expected_property_count, CHECK_OK); &expected_property_count, CHECK_OK);
} else { } else {
body = this->ParseEagerFunctionBody( body = this->ParseEagerFunctionBody(
this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters, this->EmptyIdentifier(), RelocInfo::kNoPosition, NULL,
NULL, Token::INIT_VAR, kArrowFunction, CHECK_OK); Token::INIT_VAR, kArrowFunction, CHECK_OK);
materialized_literal_count = materialized_literal_count =
function_state.materialized_literal_count(); function_state.materialized_literal_count();
expected_property_count = function_state.expected_property_count(); expected_property_count = function_state.expected_property_count();
...@@ -3685,14 +3646,13 @@ ParserBase<Traits>::ParseArrowFunctionLiteral( ...@@ -3685,14 +3646,13 @@ ParserBase<Traits>::ParseArrowFunctionLiteral(
ParseAssignmentExpression(true, &classifier, CHECK_OK); ParseAssignmentExpression(true, &classifier, CHECK_OK);
ValidateExpression(&classifier, CHECK_OK); ValidateExpression(&classifier, CHECK_OK);
body = this->NewStatementList(1, zone()); body = this->NewStatementList(1, zone());
this->AddParameterInitializationBlock(formal_parameters, body, CHECK_OK);
body->Add(factory()->NewReturnStatement(expression, pos), zone()); body->Add(factory()->NewReturnStatement(expression, pos), zone());
materialized_literal_count = function_state.materialized_literal_count(); materialized_literal_count = function_state.materialized_literal_count();
expected_property_count = function_state.expected_property_count(); expected_property_count = function_state.expected_property_count();
} }
super_loc = function_state.super_location(); super_loc = function_state.super_location();
formal_parameters.scope->set_end_position(scanner()->location().end_pos); scope->set_end_position(scanner()->location().end_pos);
// Arrow function formal parameters are parsed as StrictFormalParameterList, // Arrow function formal parameters are parsed as StrictFormalParameterList,
// which is not the same as "parameters of a strict function"; it only means // which is not the same as "parameters of a strict function"; it only means
...@@ -3704,23 +3664,21 @@ ParserBase<Traits>::ParseArrowFunctionLiteral( ...@@ -3704,23 +3664,21 @@ ParserBase<Traits>::ParseArrowFunctionLiteral(
// Validate strict mode. // Validate strict mode.
if (is_strict(language_mode())) { if (is_strict(language_mode())) {
CheckStrictOctalLiteral(formal_parameters.scope->start_position(), CheckStrictOctalLiteral(scope->start_position(),
scanner()->location().end_pos, CHECK_OK); scanner()->location().end_pos, CHECK_OK);
this->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK); this->CheckConflictingVarDeclarations(scope, CHECK_OK);
} }
} }
FunctionLiteralT function_literal = factory()->NewFunctionLiteral( FunctionLiteralT function_literal = factory()->NewFunctionLiteral(
this->EmptyIdentifierString(), ast_value_factory(), this->EmptyIdentifierString(), ast_value_factory(), scope, body,
formal_parameters.scope, body, materialized_literal_count, materialized_literal_count, expected_property_count, num_parameters,
expected_property_count, num_parameters,
FunctionLiteral::kNoDuplicateParameters, FunctionLiteral::kNoDuplicateParameters,
FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction, FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction,
FunctionLiteral::kShouldLazyCompile, FunctionKind::kArrowFunction, FunctionLiteral::kShouldLazyCompile, FunctionKind::kArrowFunction,
formal_parameters.scope->start_position()); scope->start_position());
function_literal->set_function_token_position( function_literal->set_function_token_position(scope->start_position());
formal_parameters.scope->start_position());
if (super_loc.IsValid()) function_state_->set_super_location(super_loc); if (super_loc.IsValid()) function_state_->set_super_location(super_loc);
if (fni_ != NULL) this->InferFunctionName(fni_, function_literal); if (fni_ != NULL) this->InferFunctionName(fni_, function_literal);
......
...@@ -466,22 +466,15 @@ Variable* Scope::DeclareParameter(const AstRawString* name, VariableMode mode, ...@@ -466,22 +466,15 @@ Variable* Scope::DeclareParameter(const AstRawString* name, VariableMode mode,
bool is_rest, bool* is_duplicate) { bool is_rest, bool* is_duplicate) {
DCHECK(!already_resolved()); DCHECK(!already_resolved());
DCHECK(is_function_scope()); DCHECK(is_function_scope());
Variable* var = variables_.Declare(this, name, mode, Variable::NORMAL,
Variable* var;
if (!name->IsEmpty()) {
var = variables_.Declare(this, name, mode, Variable::NORMAL,
kCreatedInitialized); kCreatedInitialized);
// TODO(wingo): Avoid O(n^2) check.
*is_duplicate = IsDeclaredParameter(name);
} else {
var = new (zone())
Variable(this, name, TEMPORARY, Variable::NORMAL, kCreatedInitialized);
}
if (is_rest) { if (is_rest) {
DCHECK_NULL(rest_parameter_); DCHECK_NULL(rest_parameter_);
rest_parameter_ = var; rest_parameter_ = var;
rest_index_ = num_parameters(); rest_index_ = num_parameters();
} }
// TODO(wingo): Avoid O(n^2) check.
*is_duplicate = IsDeclaredParameter(name);
params_.Add(var, zone()); params_.Add(var, zone());
return var; return var;
} }
......
...@@ -6389,6 +6389,7 @@ TEST(DestructuringPositiveTests) { ...@@ -6389,6 +6389,7 @@ TEST(DestructuringPositiveTests) {
{"function f(", ") {}"}, {"function f(", ") {}"},
{"function f(argument1, ", ") {}"}, {"function f(argument1, ", ") {}"},
{"var f = (", ") => {};"}, {"var f = (", ") => {};"},
{"var f = ", " => {};"},
{"var f = (argument1,", ") => {};"}, {"var f = (argument1,", ") => {};"},
{NULL, NULL}}; {NULL, NULL}};
...@@ -6416,7 +6417,6 @@ TEST(DestructuringPositiveTests) { ...@@ -6416,7 +6417,6 @@ TEST(DestructuringPositiveTests) {
"{42 : x = 42}", "{42 : x = 42}",
"{42e-2 : x}", "{42e-2 : x}",
"{42e-2 : x = 42}", "{42e-2 : x = 42}",
"{x : y, x : z}",
"{'hi' : x}", "{'hi' : x}",
"{'hi' : x = 42}", "{'hi' : x = 42}",
"{var: x}", "{var: x}",
...@@ -6605,115 +6605,6 @@ TEST(DestructuringDisallowPatternsInForVarIn) { ...@@ -6605,115 +6605,6 @@ TEST(DestructuringDisallowPatternsInForVarIn) {
} }
TEST(DestructuringDuplicateParams) {
i::FLAG_harmony_destructuring = true;
i::FLAG_harmony_arrow_functions = true;
i::FLAG_harmony_computed_property_names = true;
static const ParserFlag always_flags[] = {
kAllowHarmonyObjectLiterals, kAllowHarmonyComputedPropertyNames,
kAllowHarmonyArrowFunctions, kAllowHarmonyDestructuring};
const char* context_data[][2] = {{"'use strict';", ""},
{"function outer() { 'use strict';", "}"},
{nullptr, nullptr}};
// clang-format off
const char* error_data[] = {
"function f(x,x){}",
"function f(x, {x : x}){}",
"function f(x, {x}){}",
"function f({x,x}) {}",
"function f([x,x]) {}",
"function f(x, [y,{z:x}]) {}",
"function f([x,{y:x}]) {}",
// non-simple parameter list causes duplicates to be errors in sloppy mode.
"function f(x, x, {a}) {}",
nullptr};
// clang-format on
RunParserSyncTest(context_data, error_data, kError, NULL, 0, always_flags,
arraysize(always_flags));
}
TEST(DestructuringDuplicateParamsSloppy) {
i::FLAG_harmony_destructuring = true;
i::FLAG_harmony_arrow_functions = true;
i::FLAG_harmony_computed_property_names = true;
static const ParserFlag always_flags[] = {
kAllowHarmonyObjectLiterals, kAllowHarmonyComputedPropertyNames,
kAllowHarmonyArrowFunctions, kAllowHarmonyDestructuring};
const char* context_data[][2] = {
{"", ""}, {"function outer() {", "}"}, {nullptr, nullptr}};
// clang-format off
const char* error_data[] = {
// non-simple parameter list causes duplicates to be errors in sloppy mode.
"function f(x, {x : x}){}",
"function f(x, {x}){}",
"function f({x,x}) {}",
"function f(x, x, {a}) {}",
nullptr};
// clang-format on
RunParserSyncTest(context_data, error_data, kError, NULL, 0, always_flags,
arraysize(always_flags));
}
TEST(DestructuringDisallowPatternsInSingleParamArrows) {
i::FLAG_harmony_destructuring = true;
i::FLAG_harmony_arrow_functions = true;
i::FLAG_harmony_computed_property_names = true;
static const ParserFlag always_flags[] = {
kAllowHarmonyObjectLiterals, kAllowHarmonyComputedPropertyNames,
kAllowHarmonyArrowFunctions, kAllowHarmonyDestructuring};
const char* context_data[][2] = {{"'use strict';", ""},
{"function outer() { 'use strict';", "}"},
{"", ""},
{"function outer() { ", "}"},
{nullptr, nullptr}};
// clang-format off
const char* error_data[] = {
"var f = {x} => {};",
"var f = {x,y} => {};",
nullptr};
// clang-format on
RunParserSyncTest(context_data, error_data, kError, NULL, 0, always_flags,
arraysize(always_flags));
}
TEST(DestructuringDisallowPatternsInRestParams) {
i::FLAG_harmony_destructuring = true;
i::FLAG_harmony_arrow_functions = true;
i::FLAG_harmony_rest_parameters = true;
i::FLAG_harmony_computed_property_names = true;
static const ParserFlag always_flags[] = {
kAllowHarmonyObjectLiterals, kAllowHarmonyComputedPropertyNames,
kAllowHarmonyArrowFunctions, kAllowHarmonyRestParameters,
kAllowHarmonyDestructuring};
const char* context_data[][2] = {{"'use strict';", ""},
{"function outer() { 'use strict';", "}"},
{"", ""},
{"function outer() { ", "}"},
{nullptr, nullptr}};
// clang-format off
const char* error_data[] = {
"function(...{}) {}",
"function(...{x}) {}",
"function(...[x]) {}",
"(...{}) => {}",
"(...{x}) => {}",
"(...[x]) => {}",
nullptr};
// clang-format on
RunParserSyncTest(context_data, error_data, kError, NULL, 0, always_flags,
arraysize(always_flags));
}
TEST(SpreadArray) { TEST(SpreadArray) {
i::FLAG_harmony_spread_arrays = true; i::FLAG_harmony_spread_arrays = true;
......
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
// found in the LICENSE file. // found in the LICENSE file.
// //
// Flags: --harmony-destructuring --harmony-computed-property-names // Flags: --harmony-destructuring --harmony-computed-property-names
// Flags: --harmony-arrow-functions
(function TestObjectLiteralPattern() { (function TestObjectLiteralPattern() {
var { x : x, y : y } = { x : 1, y : 2 }; var { x : x, y : y } = { x : 1, y : 2 };
...@@ -687,44 +686,3 @@ ...@@ -687,44 +686,3 @@
assertEquals('ab', sx); assertEquals('ab', sx);
assertEquals('12', sy); assertEquals('12', sy);
}()); }());
(function TestParameters() {
function f({a, b}) { return a - b; }
assertEquals(1, f({a : 6, b : 5}));
function f1(c, {a, b}) { return c + a - b; }
assertEquals(8, f1(7, {a : 6, b : 5}));
function f2({c, d}, {a, b}) { return c - d + a - b; }
assertEquals(7, f2({c : 7, d : 1}, {a : 6, b : 5}));
function f3([{a, b}]) { return a - b; }
assertEquals(1, f3([{a : 6, b : 5}]));
var g = ({a, b}) => { return a - b; };
assertEquals(1, g({a : 6, b : 5}));
var g1 = (c, {a, b}) => { return c + a - b; };
assertEquals(8, g1(7, {a : 6, b : 5}));
var g2 = ({c, d}, {a, b}) => { return c - d + a - b; };
assertEquals(7, g2({c : 7, d : 1}, {a : 6, b : 5}));
var g3 = ([{a, b}]) => { return a - b; };
assertEquals(1, g3([{a : 6, b : 5}]));
}());
(function TestDuplicatesInParameters() {
assertThrows("'use strict';function f(x,x){}", SyntaxError);
assertThrows("'use strict';function f({x,x}){}", SyntaxError);
assertThrows("'use strict';function f(x, {x}){}", SyntaxError);
assertThrows("'use strict';var f = (x,x) => {};", SyntaxError);
assertThrows("'use strict';var f = ({x,x}) => {};", SyntaxError);
assertThrows("'use strict';var f = (x, {x}) => {};", SyntaxError);
function ok(x) { var x; }; ok();
assertThrows("function f({x}) { var x; }; f({});", SyntaxError);
assertThrows("'use strict'; function f({x}) { let x = 0; }; f({});", SyntaxError);
}());
...@@ -35,6 +35,6 @@ try { ...@@ -35,6 +35,6 @@ try {
eval("(function() { const x; var x })")(); eval("(function() { const x; var x })")();
} catch (e) { } catch (e) {
exception = true; exception = true;
assertTrue(e instanceof SyntaxError); assertTrue(e instanceof TypeError);
} }
assertTrue(exception); assertTrue(exception);
...@@ -14,4 +14,4 @@ function g(x) { ...@@ -14,4 +14,4 @@ function g(x) {
} }
%OptimizeFunctionOnNextCall(g); %OptimizeFunctionOnNextCall(g);
assertThrows(function() { g(42); }, SyntaxError); assertThrows(function() { g(42); }, TypeError);
...@@ -157,7 +157,7 @@ PASS access_after_delete_extra_5(1, 2, 3, 4, 5) is 5 ...@@ -157,7 +157,7 @@ PASS access_after_delete_extra_5(1, 2, 3, 4, 5) is 5
PASS argumentsParam(true) is true PASS argumentsParam(true) is true
PASS argumentsFunctionConstructorParam(true) is true PASS argumentsFunctionConstructorParam(true) is true
PASS argumentsVarUndefined() is '[object Arguments]' PASS argumentsVarUndefined() is '[object Arguments]'
FAIL argumentsConstUndefined() should be [object Arguments]. Threw exception SyntaxError: Identifier 'arguments' has already been declared FAIL argumentsConstUndefined() should be [object Arguments]. Threw exception TypeError: Identifier 'arguments' has already been declared
PASS argumentCalleeInException() is argumentCalleeInException PASS argumentCalleeInException() is argumentCalleeInException
PASS shadowedArgumentsApply([true]) is true PASS shadowedArgumentsApply([true]) is true
PASS shadowedArgumentsLength([]) is 0 PASS shadowedArgumentsLength([]) is 0
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment