Skip to content

Commit 0d15ec8

Browse files
cristiancavalliofrobots
authored andcommitted
deps: cherry pick 7166503 from upstream v8
Original Commit Message: Previously, any expressions inside destructuring patterns in a catch would be parsed in the surrounding scope, instead of in the catch's scope. This change fixes that by entering not only the catch scope, but also the block scope inside it. [email protected] BUG=v8:5106, v8:5112 Review-Url: https://codereview.chromium.org/2110193002 Cr-Commit-Position: refs/heads/master@{#37415} PR-URL: #9173 Reviewed-By: jasnell - James M Snell <[email protected]> Reviewed-By: ofrobots - Ali Ijaz Sheikh <[email protected]>
1 parent bd7c1e7 commit 0d15ec8

File tree

2 files changed

+51
-20
lines changed

2 files changed

+51
-20
lines changed

deps/v8/src/parsing/parser.cc

+22-20
Original file line numberDiff line numberDiff line change
@@ -2923,40 +2923,40 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
29232923
catch_scope = NewScope(scope_, CATCH_SCOPE);
29242924
catch_scope->set_start_position(scanner()->location().beg_pos);
29252925

2926-
ExpressionClassifier pattern_classifier(this);
2927-
Expression* pattern = ParsePrimaryExpression(&pattern_classifier, CHECK_OK);
2928-
ValidateBindingPattern(&pattern_classifier, CHECK_OK);
2929-
2930-
const AstRawString* name = ast_value_factory()->dot_catch_string();
2931-
bool is_simple = pattern->IsVariableProxy();
2932-
if (is_simple) {
2933-
auto proxy = pattern->AsVariableProxy();
2934-
scope_->RemoveUnresolved(proxy);
2935-
name = proxy->raw_name();
2936-
}
2937-
2938-
catch_variable = catch_scope->DeclareLocal(name, VAR, kCreatedInitialized,
2939-
Variable::NORMAL);
2940-
2941-
Expect(Token::RPAREN, CHECK_OK);
2942-
29432926
{
29442927
CollectExpressionsInTailPositionToListScope
29452928
collect_expressions_in_tail_position_scope(
29462929
function_state_, &expressions_in_tail_position_in_catch_block);
29472930
BlockState block_state(&scope_, catch_scope);
29482931

2949-
// TODO(adamk): Make a version of ParseBlock that takes a scope and
2950-
// a block.
29512932
catch_block =
29522933
factory()->NewBlock(nullptr, 16, false, RelocInfo::kNoPosition);
2953-
Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
29542934

2935+
// Create a block scope to hold any lexical declarations created
2936+
// as part of destructuring the catch parameter.
2937+
Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
29552938
block_scope->set_start_position(scanner()->location().beg_pos);
29562939
{
29572940
BlockState block_state(&scope_, block_scope);
29582941
Target target(&this->target_stack_, catch_block);
29592942

2943+
ExpressionClassifier pattern_classifier(this);
2944+
Expression* pattern =
2945+
ParsePrimaryExpression(&pattern_classifier, CHECK_OK);
2946+
ValidateBindingPattern(&pattern_classifier, CHECK_OK);
2947+
2948+
const AstRawString* name = ast_value_factory()->dot_catch_string();
2949+
bool is_simple = pattern->IsVariableProxy();
2950+
if (is_simple) {
2951+
auto proxy = pattern->AsVariableProxy();
2952+
scope_->RemoveUnresolved(proxy);
2953+
name = proxy->raw_name();
2954+
}
2955+
catch_variable = catch_scope->DeclareLocal(
2956+
name, VAR, kCreatedInitialized, Variable::NORMAL);
2957+
2958+
Expect(Token::RPAREN, CHECK_OK);
2959+
29602960
if (!is_simple) {
29612961
DeclarationDescriptor descriptor;
29622962
descriptor.declaration_kind = DeclarationDescriptor::NORMAL;
@@ -2978,6 +2978,8 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
29782978
catch_block->statements()->Add(init_block, zone());
29792979
}
29802980

2981+
// TODO(adamk): This should call ParseBlock in order to properly
2982+
// add an additional block scope for the catch body.
29812983
Expect(Token::LBRACE, CHECK_OK);
29822984
while (peek() != Token::RBRACE) {
29832985
Statement* stat = ParseStatementListItem(CHECK_OK);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright 2016 the V8 project authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
function* g1() {
6+
try {
7+
throw {};
8+
} catch ({a = class extends (yield) {}}) {
9+
}
10+
}
11+
g1().next(); // crashes without fix
12+
13+
function* g2() {
14+
let x = function(){};
15+
try {
16+
throw {};
17+
} catch ({b = class extends x {}}) {
18+
}
19+
}
20+
g2().next(); // crashes without fix
21+
22+
function* g3() {
23+
let x = 42;
24+
try {
25+
throw {};
26+
} catch ({c = (function() { return x })()}) {
27+
}
28+
}
29+
g3().next(); // throws a ReferenceError without fix

0 commit comments

Comments
 (0)