| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/api.h" | 7 #include "src/api.h" |
| 8 #include "src/ast.h" | 8 #include "src/ast.h" |
| 9 #include "src/bailout-reason.h" | 9 #include "src/bailout-reason.h" |
| 10 #include "src/base/platform/platform.h" | 10 #include "src/base/platform/platform.h" |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 275 | 275 |
| 276 FunctionLiteral* Parser::DefaultConstructor(bool call_super, Scope* scope, | 276 FunctionLiteral* Parser::DefaultConstructor(bool call_super, Scope* scope, |
| 277 int pos, int end_pos) { | 277 int pos, int end_pos) { |
| 278 int materialized_literal_count = -1; | 278 int materialized_literal_count = -1; |
| 279 int expected_property_count = -1; | 279 int expected_property_count = -1; |
| 280 int handler_count = 0; | 280 int handler_count = 0; |
| 281 int parameter_count = 0; | 281 int parameter_count = 0; |
| 282 const AstRawString* name = ast_value_factory()->empty_string(); | 282 const AstRawString* name = ast_value_factory()->empty_string(); |
| 283 | 283 |
| 284 Scope* function_scope = NewScope(scope, FUNCTION_SCOPE); | 284 Scope* function_scope = NewScope(scope, FUNCTION_SCOPE); |
| 285 function_scope->SetStrictMode(STRICT); | 285 function_scope->SetLanguageMode( |
| 286 static_cast<LanguageMode>(scope->language_mode() | STRICT)); |
| 286 // Set start and end position to the same value | 287 // Set start and end position to the same value |
| 287 function_scope->set_start_position(pos); | 288 function_scope->set_start_position(pos); |
| 288 function_scope->set_end_position(pos); | 289 function_scope->set_end_position(pos); |
| 289 ZoneList<Statement*>* body = NULL; | 290 ZoneList<Statement*>* body = NULL; |
| 290 | 291 |
| 291 { | 292 { |
| 292 AstNodeFactory function_factory(ast_value_factory()); | 293 AstNodeFactory function_factory(ast_value_factory()); |
| 293 FunctionState function_state(&function_state_, &scope_, function_scope, | 294 FunctionState function_state(&function_state_, &scope_, function_scope, |
| 294 &function_factory); | 295 &function_factory); |
| 295 | 296 |
| (...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 911 *scope = Scope::DeserializeScopeChain(info->isolate(), zone(), | 912 *scope = Scope::DeserializeScopeChain(info->isolate(), zone(), |
| 912 *info->context(), *scope); | 913 *info->context(), *scope); |
| 913 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this | 914 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this |
| 914 // means the Parser cannot operate independent of the V8 heap. Tell the | 915 // means the Parser cannot operate independent of the V8 heap. Tell the |
| 915 // string table to internalize strings and values right after they're | 916 // string table to internalize strings and values right after they're |
| 916 // created. | 917 // created. |
| 917 ast_value_factory()->Internalize(isolate()); | 918 ast_value_factory()->Internalize(isolate()); |
| 918 } | 919 } |
| 919 original_scope_ = *scope; | 920 original_scope_ = *scope; |
| 920 if (info->is_eval()) { | 921 if (info->is_eval()) { |
| 921 if (!(*scope)->is_script_scope() || info->strict_mode() == STRICT) { | 922 if (!(*scope)->is_script_scope() || is_strict(info->language_mode())) { |
| 922 *scope = NewScope(*scope, EVAL_SCOPE); | 923 *scope = NewScope(*scope, EVAL_SCOPE); |
| 923 } | 924 } |
| 924 } else if (info->is_global()) { | 925 } else if (info->is_global()) { |
| 925 *scope = NewScope(*scope, SCRIPT_SCOPE); | 926 *scope = NewScope(*scope, SCRIPT_SCOPE); |
| 926 } | 927 } |
| 927 (*scope)->set_start_position(0); | 928 (*scope)->set_start_position(0); |
| 928 // End position will be set by the caller. | 929 // End position will be set by the caller. |
| 929 | 930 |
| 930 // Compute the parsing mode. | 931 // Compute the parsing mode. |
| 931 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY; | 932 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY; |
| 932 if (allow_natives() || extension_ != NULL || | 933 if (allow_natives() || extension_ != NULL || |
| 933 (*scope)->is_eval_scope()) { | 934 (*scope)->is_eval_scope()) { |
| 934 mode = PARSE_EAGERLY; | 935 mode = PARSE_EAGERLY; |
| 935 } | 936 } |
| 936 ParsingModeScope parsing_mode(this, mode); | 937 ParsingModeScope parsing_mode(this, mode); |
| 937 | 938 |
| 938 // Enters 'scope'. | 939 // Enters 'scope'. |
| 939 AstNodeFactory function_factory(ast_value_factory()); | 940 AstNodeFactory function_factory(ast_value_factory()); |
| 940 FunctionState function_state(&function_state_, &scope_, *scope, | 941 FunctionState function_state(&function_state_, &scope_, *scope, |
| 941 &function_factory); | 942 &function_factory); |
| 942 | 943 |
| 943 scope_->SetStrictMode(info->strict_mode()); | 944 scope_->SetLanguageMode(info->language_mode()); |
| 944 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); | 945 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); |
| 945 bool ok = true; | 946 bool ok = true; |
| 946 int beg_pos = scanner()->location().beg_pos; | 947 int beg_pos = scanner()->location().beg_pos; |
| 947 if (info->is_module()) { | 948 if (info->is_module()) { |
| 948 DCHECK(allow_harmony_modules()); | 949 DCHECK(allow_harmony_modules()); |
| 949 Module* module = ParseModule(&ok); | 950 Module* module = ParseModule(&ok); |
| 950 if (ok) { | 951 if (ok) { |
| 951 // TODO(adamk): Do something with returned Module | 952 // TODO(adamk): Do something with returned Module |
| 952 CHECK(module); | 953 CHECK(module); |
| 953 body->Add(factory()->NewEmptyStatement(RelocInfo::kNoPosition), zone()); | 954 body->Add(factory()->NewEmptyStatement(RelocInfo::kNoPosition), zone()); |
| 954 } | 955 } |
| 955 } else { | 956 } else { |
| 956 ParseStatementList(body, Token::EOS, info->is_eval(), eval_scope, &ok); | 957 ParseStatementList(body, Token::EOS, info->is_eval(), eval_scope, &ok); |
| 957 } | 958 } |
| 958 | 959 |
| 959 if (ok && strict_mode() == STRICT) { | 960 if (ok && is_strict(language_mode())) { |
| 960 CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); | 961 CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); |
| 961 } | 962 } |
| 962 | 963 |
| 963 if (ok && allow_harmony_scoping() && strict_mode() == STRICT) { | 964 if (ok && allow_harmony_scoping() && is_strict(language_mode())) { |
| 964 CheckConflictingVarDeclarations(scope_, &ok); | 965 CheckConflictingVarDeclarations(scope_, &ok); |
| 965 } | 966 } |
| 966 | 967 |
| 967 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { | 968 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { |
| 968 if (body->length() != 1 || | 969 if (body->length() != 1 || |
| 969 !body->at(0)->IsExpressionStatement() || | 970 !body->at(0)->IsExpressionStatement() || |
| 970 !body->at(0)->AsExpressionStatement()-> | 971 !body->at(0)->AsExpressionStatement()-> |
| 971 expression()->IsFunctionLiteral()) { | 972 expression()->IsFunctionLiteral()) { |
| 972 ReportMessage("single_function_literal"); | 973 ReportMessage("single_function_literal"); |
| 973 ok = false; | 974 ok = false; |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1052 Scope* scope = NewScope(scope_, SCRIPT_SCOPE); | 1053 Scope* scope = NewScope(scope_, SCRIPT_SCOPE); |
| 1053 info()->SetScriptScope(scope); | 1054 info()->SetScriptScope(scope); |
| 1054 if (!info()->closure().is_null()) { | 1055 if (!info()->closure().is_null()) { |
| 1055 scope = Scope::DeserializeScopeChain(isolate(), zone(), | 1056 scope = Scope::DeserializeScopeChain(isolate(), zone(), |
| 1056 info()->closure()->context(), scope); | 1057 info()->closure()->context(), scope); |
| 1057 } | 1058 } |
| 1058 original_scope_ = scope; | 1059 original_scope_ = scope; |
| 1059 AstNodeFactory function_factory(ast_value_factory()); | 1060 AstNodeFactory function_factory(ast_value_factory()); |
| 1060 FunctionState function_state(&function_state_, &scope_, scope, | 1061 FunctionState function_state(&function_state_, &scope_, scope, |
| 1061 &function_factory); | 1062 &function_factory); |
| 1062 DCHECK(scope->strict_mode() == SLOPPY || info()->strict_mode() == STRICT); | 1063 DCHECK(!is_strict(scope->language_mode()) || |
| 1063 DCHECK(info()->strict_mode() == shared_info->strict_mode()); | 1064 is_strict(info()->language_mode())); |
| 1064 scope->SetStrictMode(shared_info->strict_mode()); | 1065 DCHECK(info()->language_mode() == shared_info->language_mode()); |
| 1066 scope->SetLanguageMode(shared_info->language_mode()); |
| 1065 FunctionLiteral::FunctionType function_type = shared_info->is_expression() | 1067 FunctionLiteral::FunctionType function_type = shared_info->is_expression() |
| 1066 ? (shared_info->is_anonymous() | 1068 ? (shared_info->is_anonymous() |
| 1067 ? FunctionLiteral::ANONYMOUS_EXPRESSION | 1069 ? FunctionLiteral::ANONYMOUS_EXPRESSION |
| 1068 : FunctionLiteral::NAMED_EXPRESSION) | 1070 : FunctionLiteral::NAMED_EXPRESSION) |
| 1069 : FunctionLiteral::DECLARATION; | 1071 : FunctionLiteral::DECLARATION; |
| 1070 bool ok = true; | 1072 bool ok = true; |
| 1071 | 1073 |
| 1072 if (shared_info->is_arrow()) { | 1074 if (shared_info->is_arrow()) { |
| 1073 // The first expression being parsed is the parameter list of the arrow | 1075 // The first expression being parsed is the parameter list of the arrow |
| 1074 // function. Setting this avoids prevents ExpressionFromIdentifier() | 1076 // function. Setting this avoids prevents ExpressionFromIdentifier() |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1132 if (directive_prologue) { | 1134 if (directive_prologue) { |
| 1133 // A shot at a directive. | 1135 // A shot at a directive. |
| 1134 ExpressionStatement* e_stat; | 1136 ExpressionStatement* e_stat; |
| 1135 Literal* literal; | 1137 Literal* literal; |
| 1136 // Still processing directive prologue? | 1138 // Still processing directive prologue? |
| 1137 if ((e_stat = stat->AsExpressionStatement()) != NULL && | 1139 if ((e_stat = stat->AsExpressionStatement()) != NULL && |
| 1138 (literal = e_stat->expression()->AsLiteral()) != NULL && | 1140 (literal = e_stat->expression()->AsLiteral()) != NULL && |
| 1139 literal->raw_value()->IsString()) { | 1141 literal->raw_value()->IsString()) { |
| 1140 // Check "use strict" directive (ES5 14.1) and "use asm" directive. Only | 1142 // Check "use strict" directive (ES5 14.1) and "use asm" directive. Only |
| 1141 // one can be present. | 1143 // one can be present. |
| 1142 if (strict_mode() == SLOPPY && | 1144 if (!is_strict(language_mode()) && |
| 1143 literal->raw_value()->AsString() == | 1145 literal->raw_value()->AsString() == |
| 1144 ast_value_factory()->use_strict_string() && | 1146 ast_value_factory()->use_strict_string() && |
| 1145 token_loc.end_pos - token_loc.beg_pos == | 1147 token_loc.end_pos - token_loc.beg_pos == |
| 1146 ast_value_factory()->use_strict_string()->length() + 2) { | 1148 ast_value_factory()->use_strict_string()->length() + 2) { |
| 1147 // TODO(mstarzinger): Global strict eval calls, need their own scope | 1149 // TODO(mstarzinger): Global strict eval calls, need their own scope |
| 1148 // as specified in ES5 10.4.2(3). The correct fix would be to always | 1150 // as specified in ES5 10.4.2(3). The correct fix would be to always |
| 1149 // add this scope in DoParseProgram(), but that requires adaptations | 1151 // add this scope in DoParseProgram(), but that requires adaptations |
| 1150 // all over the code base, so we go with a quick-fix for now. | 1152 // all over the code base, so we go with a quick-fix for now. |
| 1151 // In the same manner, we have to patch the parsing mode. | 1153 // In the same manner, we have to patch the parsing mode. |
| 1152 if (is_eval && !scope_->is_eval_scope()) { | 1154 if (is_eval && !scope_->is_eval_scope()) { |
| 1153 DCHECK(scope_->is_script_scope()); | 1155 DCHECK(scope_->is_script_scope()); |
| 1154 Scope* scope = NewScope(scope_, EVAL_SCOPE); | 1156 Scope* scope = NewScope(scope_, EVAL_SCOPE); |
| 1155 scope->set_start_position(scope_->start_position()); | 1157 scope->set_start_position(scope_->start_position()); |
| 1156 scope->set_end_position(scope_->end_position()); | 1158 scope->set_end_position(scope_->end_position()); |
| 1157 scope_ = scope; | 1159 scope_ = scope; |
| 1158 if (eval_scope != NULL) { | 1160 if (eval_scope != NULL) { |
| 1159 // Caller will correct the positions of the ad hoc eval scope. | 1161 // Caller will correct the positions of the ad hoc eval scope. |
| 1160 *eval_scope = scope; | 1162 *eval_scope = scope; |
| 1161 } | 1163 } |
| 1162 mode_ = PARSE_EAGERLY; | 1164 mode_ = PARSE_EAGERLY; |
| 1163 } | 1165 } |
| 1164 scope_->SetStrictMode(STRICT); | 1166 scope_->SetLanguageMode( |
| 1167 static_cast<LanguageMode>(scope_->language_mode() | STRICT)); |
| 1165 // "use strict" is the only directive for now. | 1168 // "use strict" is the only directive for now. |
| 1166 directive_prologue = false; | 1169 directive_prologue = false; |
| 1167 } else if (literal->raw_value()->AsString() == | 1170 } else if (literal->raw_value()->AsString() == |
| 1168 ast_value_factory()->use_asm_string() && | 1171 ast_value_factory()->use_asm_string() && |
| 1169 token_loc.end_pos - token_loc.beg_pos == | 1172 token_loc.end_pos - token_loc.beg_pos == |
| 1170 ast_value_factory()->use_asm_string()->length() + 2) { | 1173 ast_value_factory()->use_asm_string()->length() + 2) { |
| 1171 // Store the usage count; The actual use counter on the isolate is | 1174 // Store the usage count; The actual use counter on the isolate is |
| 1172 // incremented after parsing is done. | 1175 // incremented after parsing is done. |
| 1173 ++use_counts_[v8::Isolate::kUseAsm]; | 1176 ++use_counts_[v8::Isolate::kUseAsm]; |
| 1174 scope_->SetAsmModule(); | 1177 scope_->SetAsmModule(); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1195 switch (peek()) { | 1198 switch (peek()) { |
| 1196 case Token::FUNCTION: | 1199 case Token::FUNCTION: |
| 1197 return ParseFunctionDeclaration(NULL, ok); | 1200 return ParseFunctionDeclaration(NULL, ok); |
| 1198 case Token::CLASS: | 1201 case Token::CLASS: |
| 1199 return ParseClassDeclaration(NULL, ok); | 1202 return ParseClassDeclaration(NULL, ok); |
| 1200 case Token::CONST: | 1203 case Token::CONST: |
| 1201 case Token::VAR: | 1204 case Token::VAR: |
| 1202 return ParseVariableStatement(kStatementListItem, NULL, ok); | 1205 return ParseVariableStatement(kStatementListItem, NULL, ok); |
| 1203 case Token::LET: | 1206 case Token::LET: |
| 1204 DCHECK(allow_harmony_scoping()); | 1207 DCHECK(allow_harmony_scoping()); |
| 1205 if (strict_mode() == STRICT) { | 1208 if (is_strict(language_mode())) { |
| 1206 return ParseVariableStatement(kStatementListItem, NULL, ok); | 1209 return ParseVariableStatement(kStatementListItem, NULL, ok); |
| 1207 } | 1210 } |
| 1208 // Fall through. | 1211 // Fall through. |
| 1209 default: | 1212 default: |
| 1210 return ParseStatement(NULL, ok); | 1213 return ParseStatement(NULL, ok); |
| 1211 } | 1214 } |
| 1212 } | 1215 } |
| 1213 | 1216 |
| 1214 | 1217 |
| 1215 Statement* Parser::ParseModuleItem(bool* ok) { | 1218 Statement* Parser::ParseModuleItem(bool* ok) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1240 | 1243 |
| 1241 int pos = peek_position(); | 1244 int pos = peek_position(); |
| 1242 // Construct block expecting 16 statements. | 1245 // Construct block expecting 16 statements. |
| 1243 Block* body = factory()->NewBlock(NULL, 16, false, RelocInfo::kNoPosition); | 1246 Block* body = factory()->NewBlock(NULL, 16, false, RelocInfo::kNoPosition); |
| 1244 #ifdef DEBUG | 1247 #ifdef DEBUG |
| 1245 if (FLAG_print_interface_details) PrintF("# Literal "); | 1248 if (FLAG_print_interface_details) PrintF("# Literal "); |
| 1246 #endif | 1249 #endif |
| 1247 Scope* scope = NewScope(scope_, MODULE_SCOPE); | 1250 Scope* scope = NewScope(scope_, MODULE_SCOPE); |
| 1248 | 1251 |
| 1249 scope->set_start_position(scanner()->location().beg_pos); | 1252 scope->set_start_position(scanner()->location().beg_pos); |
| 1250 scope->SetStrictMode(STRICT); | 1253 scope->SetLanguageMode( |
| 1254 static_cast<LanguageMode>(scope->language_mode() | STRICT)); |
| 1251 | 1255 |
| 1252 { | 1256 { |
| 1253 BlockState block_state(&scope_, scope); | 1257 BlockState block_state(&scope_, scope); |
| 1254 Target target(&this->target_stack_, body); | 1258 Target target(&this->target_stack_, body); |
| 1255 | 1259 |
| 1256 while (peek() != Token::EOS) { | 1260 while (peek() != Token::EOS) { |
| 1257 Statement* stat = ParseModuleItem(CHECK_OK); | 1261 Statement* stat = ParseModuleItem(CHECK_OK); |
| 1258 if (stat && !stat->IsEmpty()) { | 1262 if (stat && !stat->IsEmpty()) { |
| 1259 body->AddStatement(stat, zone()); | 1263 body->AddStatement(stat, zone()); |
| 1260 } | 1264 } |
| (...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1721 // (Ecma 262 5th Edition, clause 14): | 1725 // (Ecma 262 5th Edition, clause 14): |
| 1722 // SourceElement: | 1726 // SourceElement: |
| 1723 // Statement | 1727 // Statement |
| 1724 // FunctionDeclaration | 1728 // FunctionDeclaration |
| 1725 // Common language extension is to allow function declaration in place | 1729 // Common language extension is to allow function declaration in place |
| 1726 // of any statement. This language extension is disabled in strict mode. | 1730 // of any statement. This language extension is disabled in strict mode. |
| 1727 // | 1731 // |
| 1728 // In Harmony mode, this case also handles the extension: | 1732 // In Harmony mode, this case also handles the extension: |
| 1729 // Statement: | 1733 // Statement: |
| 1730 // GeneratorDeclaration | 1734 // GeneratorDeclaration |
| 1731 if (strict_mode() == STRICT) { | 1735 if (is_strict(language_mode())) { |
| 1732 ReportMessageAt(scanner()->peek_location(), "strict_function"); | 1736 ReportMessageAt(scanner()->peek_location(), "strict_function"); |
| 1733 *ok = false; | 1737 *ok = false; |
| 1734 return NULL; | 1738 return NULL; |
| 1735 } | 1739 } |
| 1736 return ParseFunctionDeclaration(NULL, ok); | 1740 return ParseFunctionDeclaration(NULL, ok); |
| 1737 } | 1741 } |
| 1738 | 1742 |
| 1739 case Token::DEBUGGER: | 1743 case Token::DEBUGGER: |
| 1740 return ParseDebuggerStatement(ok); | 1744 return ParseDebuggerStatement(ok); |
| 1741 | 1745 |
| 1742 case Token::VAR: | 1746 case Token::VAR: |
| 1743 return ParseVariableStatement(kStatement, NULL, ok); | 1747 return ParseVariableStatement(kStatement, NULL, ok); |
| 1744 | 1748 |
| 1745 case Token::CONST: | 1749 case Token::CONST: |
| 1746 // In ES6 CONST is not allowed as a Statement, only as a | 1750 // In ES6 CONST is not allowed as a Statement, only as a |
| 1747 // LexicalDeclaration, however we continue to allow it in sloppy mode for | 1751 // LexicalDeclaration, however we continue to allow it in sloppy mode for |
| 1748 // backwards compatibility. | 1752 // backwards compatibility. |
| 1749 if (strict_mode() == SLOPPY) { | 1753 if (!is_strict(language_mode())) { |
| 1750 return ParseVariableStatement(kStatement, NULL, ok); | 1754 return ParseVariableStatement(kStatement, NULL, ok); |
| 1751 } | 1755 } |
| 1752 | 1756 |
| 1753 // Fall through. | 1757 // Fall through. |
| 1754 default: | 1758 default: |
| 1755 return ParseExpressionOrLabelledStatement(labels, ok); | 1759 return ParseExpressionOrLabelledStatement(labels, ok); |
| 1756 } | 1760 } |
| 1757 } | 1761 } |
| 1758 | 1762 |
| 1759 | 1763 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1807 // functions. The function CheckConflictingVarDeclarations checks for | 1811 // functions. The function CheckConflictingVarDeclarations checks for |
| 1808 // var and let bindings from different scopes whereas this is a check for | 1812 // var and let bindings from different scopes whereas this is a check for |
| 1809 // conflicting declarations within the same scope. This check also covers | 1813 // conflicting declarations within the same scope. This check also covers |
| 1810 // the special case | 1814 // the special case |
| 1811 // | 1815 // |
| 1812 // function () { let x; { var x; } } | 1816 // function () { let x; { var x; } } |
| 1813 // | 1817 // |
| 1814 // because the var declaration is hoisted to the function scope where 'x' | 1818 // because the var declaration is hoisted to the function scope where 'x' |
| 1815 // is already bound. | 1819 // is already bound. |
| 1816 DCHECK(IsDeclaredVariableMode(var->mode())); | 1820 DCHECK(IsDeclaredVariableMode(var->mode())); |
| 1817 if (allow_harmony_scoping() && strict_mode() == STRICT) { | 1821 if (allow_harmony_scoping() && is_strict(language_mode())) { |
| 1818 // In harmony we treat re-declarations as early errors. See | 1822 // In harmony we treat re-declarations as early errors. See |
| 1819 // ES5 16 for a definition of early errors. | 1823 // ES5 16 for a definition of early errors. |
| 1820 ParserTraits::ReportMessage("var_redeclaration", name); | 1824 ParserTraits::ReportMessage("var_redeclaration", name); |
| 1821 *ok = false; | 1825 *ok = false; |
| 1822 return; | 1826 return; |
| 1823 } | 1827 } |
| 1824 Expression* expression = NewThrowTypeError( | 1828 Expression* expression = NewThrowTypeError( |
| 1825 "var_redeclaration", name, declaration->position()); | 1829 "var_redeclaration", name, declaration->position()); |
| 1826 declaration_scope->SetIllegalRedeclaration(expression); | 1830 declaration_scope->SetIllegalRedeclaration(expression); |
| 1827 } else if (mode == VAR) { | 1831 } else if (mode == VAR) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1848 declaration_scope->AddDeclaration(declaration); | 1852 declaration_scope->AddDeclaration(declaration); |
| 1849 | 1853 |
| 1850 if (mode == CONST_LEGACY && declaration_scope->is_script_scope()) { | 1854 if (mode == CONST_LEGACY && declaration_scope->is_script_scope()) { |
| 1851 // For global const variables we bind the proxy to a variable. | 1855 // For global const variables we bind the proxy to a variable. |
| 1852 DCHECK(resolve); // should be set by all callers | 1856 DCHECK(resolve); // should be set by all callers |
| 1853 Variable::Kind kind = Variable::NORMAL; | 1857 Variable::Kind kind = Variable::NORMAL; |
| 1854 var = new (zone()) | 1858 var = new (zone()) |
| 1855 Variable(declaration_scope, name, mode, true, kind, | 1859 Variable(declaration_scope, name, mode, true, kind, |
| 1856 kNeedsInitialization, kNotAssigned, proxy->interface()); | 1860 kNeedsInitialization, kNotAssigned, proxy->interface()); |
| 1857 } else if (declaration_scope->is_eval_scope() && | 1861 } else if (declaration_scope->is_eval_scope() && |
| 1858 declaration_scope->strict_mode() == SLOPPY) { | 1862 !is_strict(declaration_scope->language_mode())) { |
| 1859 // For variable declarations in a sloppy eval scope the proxy is bound | 1863 // For variable declarations in a sloppy eval scope the proxy is bound |
| 1860 // to a lookup variable to force a dynamic declaration using the | 1864 // to a lookup variable to force a dynamic declaration using the |
| 1861 // DeclareLookupSlot runtime function. | 1865 // DeclareLookupSlot runtime function. |
| 1862 Variable::Kind kind = Variable::NORMAL; | 1866 Variable::Kind kind = Variable::NORMAL; |
| 1863 // TODO(sigurds) figure out if kNotAssigned is OK here | 1867 // TODO(sigurds) figure out if kNotAssigned is OK here |
| 1864 var = new (zone()) Variable(declaration_scope, name, mode, true, kind, | 1868 var = new (zone()) Variable(declaration_scope, name, mode, true, kind, |
| 1865 declaration->initialization(), kNotAssigned, | 1869 declaration->initialization(), kNotAssigned, |
| 1866 proxy->interface()); | 1870 proxy->interface()); |
| 1867 var->AllocateTo(Variable::LOOKUP, -1); | 1871 var->AllocateTo(Variable::LOOKUP, -1); |
| 1868 resolve = true; | 1872 resolve = true; |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1982 is_generator ? FunctionKind::kGeneratorFunction | 1986 is_generator ? FunctionKind::kGeneratorFunction |
| 1983 : FunctionKind::kNormalFunction, | 1987 : FunctionKind::kNormalFunction, |
| 1984 pos, FunctionLiteral::DECLARATION, | 1988 pos, FunctionLiteral::DECLARATION, |
| 1985 FunctionLiteral::NORMAL_ARITY, CHECK_OK); | 1989 FunctionLiteral::NORMAL_ARITY, CHECK_OK); |
| 1986 // Even if we're not at the top-level of the global or a function | 1990 // Even if we're not at the top-level of the global or a function |
| 1987 // scope, we treat it as such and introduce the function with its | 1991 // scope, we treat it as such and introduce the function with its |
| 1988 // initial value upon entering the corresponding scope. | 1992 // initial value upon entering the corresponding scope. |
| 1989 // In ES6, a function behaves as a lexical binding, except in | 1993 // In ES6, a function behaves as a lexical binding, except in |
| 1990 // a script scope, or the initial scope of eval or another function. | 1994 // a script scope, or the initial scope of eval or another function. |
| 1991 VariableMode mode = | 1995 VariableMode mode = |
| 1992 allow_harmony_scoping() && strict_mode() == STRICT && | 1996 allow_harmony_scoping() && is_strict(language_mode()) && |
| 1993 !(scope_->is_script_scope() || scope_->is_eval_scope() || | 1997 !(scope_->is_script_scope() || scope_->is_eval_scope() || |
| 1994 scope_->is_function_scope()) ? LET : VAR; | 1998 scope_->is_function_scope()) |
| 1999 ? LET |
| 2000 : VAR; |
| 1995 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); | 2001 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); |
| 1996 Declaration* declaration = | 2002 Declaration* declaration = |
| 1997 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos); | 2003 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos); |
| 1998 Declare(declaration, true, CHECK_OK); | 2004 Declare(declaration, true, CHECK_OK); |
| 1999 if (names) names->Add(name, zone()); | 2005 if (names) names->Add(name, zone()); |
| 2000 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); | 2006 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
| 2001 } | 2007 } |
| 2002 | 2008 |
| 2003 | 2009 |
| 2004 Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names, | 2010 Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names, |
| 2005 bool* ok) { | 2011 bool* ok) { |
| 2006 // ClassDeclaration :: | 2012 // ClassDeclaration :: |
| 2007 // 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}' | 2013 // 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}' |
| 2008 // | 2014 // |
| 2009 // A ClassDeclaration | 2015 // A ClassDeclaration |
| 2010 // | 2016 // |
| 2011 // class C { ... } | 2017 // class C { ... } |
| 2012 // | 2018 // |
| 2013 // has the same semantics as: | 2019 // has the same semantics as: |
| 2014 // | 2020 // |
| 2015 // let C = class C { ... }; | 2021 // let C = class C { ... }; |
| 2016 // | 2022 // |
| 2017 // so rewrite it as such. | 2023 // so rewrite it as such. |
| 2018 | 2024 |
| 2019 Expect(Token::CLASS, CHECK_OK); | 2025 Expect(Token::CLASS, CHECK_OK); |
| 2020 if (!allow_harmony_sloppy() && strict_mode() == SLOPPY) { | 2026 if (!allow_harmony_sloppy() && !is_strict(language_mode())) { |
| 2021 ReportMessage("sloppy_lexical"); | 2027 ReportMessage("sloppy_lexical"); |
| 2022 *ok = false; | 2028 *ok = false; |
| 2023 return NULL; | 2029 return NULL; |
| 2024 } | 2030 } |
| 2025 | 2031 |
| 2026 int pos = position(); | 2032 int pos = position(); |
| 2027 bool is_strict_reserved = false; | 2033 bool is_strict_reserved = false; |
| 2028 const AstRawString* name = | 2034 const AstRawString* name = |
| 2029 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); | 2035 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); |
| 2030 ClassLiteral* value = ParseClassLiteral(name, scanner()->location(), | 2036 ClassLiteral* value = ParseClassLiteral(name, scanner()->location(), |
| 2031 is_strict_reserved, pos, CHECK_OK); | 2037 is_strict_reserved, pos, CHECK_OK); |
| 2032 | 2038 |
| 2033 VariableProxy* proxy = NewUnresolved(name, LET, Interface::NewValue()); | 2039 VariableProxy* proxy = NewUnresolved(name, LET, Interface::NewValue()); |
| 2034 Declaration* declaration = | 2040 Declaration* declaration = |
| 2035 factory()->NewVariableDeclaration(proxy, LET, scope_, pos); | 2041 factory()->NewVariableDeclaration(proxy, LET, scope_, pos); |
| 2036 Declare(declaration, true, CHECK_OK); | 2042 Declare(declaration, true, CHECK_OK); |
| 2037 proxy->var()->set_initializer_position(pos); | 2043 proxy->var()->set_initializer_position(pos); |
| 2038 | 2044 |
| 2039 Token::Value init_op = Token::INIT_LET; | 2045 Token::Value init_op = Token::INIT_LET; |
| 2040 Assignment* assignment = factory()->NewAssignment(init_op, proxy, value, pos); | 2046 Assignment* assignment = factory()->NewAssignment(init_op, proxy, value, pos); |
| 2041 Statement* assignment_statement = | 2047 Statement* assignment_statement = |
| 2042 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition); | 2048 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition); |
| 2043 if (names) names->Add(name, zone()); | 2049 if (names) names->Add(name, zone()); |
| 2044 return assignment_statement; | 2050 return assignment_statement; |
| 2045 } | 2051 } |
| 2046 | 2052 |
| 2047 | 2053 |
| 2048 Block* Parser::ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok) { | 2054 Block* Parser::ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok) { |
| 2049 if (allow_harmony_scoping() && strict_mode() == STRICT) { | 2055 if (allow_harmony_scoping() && is_strict(language_mode())) { |
| 2050 return ParseScopedBlock(labels, ok); | 2056 return ParseScopedBlock(labels, ok); |
| 2051 } | 2057 } |
| 2052 | 2058 |
| 2053 // Block :: | 2059 // Block :: |
| 2054 // '{' Statement* '}' | 2060 // '{' Statement* '}' |
| 2055 | 2061 |
| 2056 // Note that a Block does not introduce a new execution scope! | 2062 // Note that a Block does not introduce a new execution scope! |
| 2057 // (ECMA-262, 3rd, 12.2) | 2063 // (ECMA-262, 3rd, 12.2) |
| 2058 // | 2064 // |
| 2059 // Construct block expecting 16 statements. | 2065 // Construct block expecting 16 statements. |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2150 // bindings are created uninitialized by their declaration nodes and | 2156 // bindings are created uninitialized by their declaration nodes and |
| 2151 // need initialization. 'var' declared bindings are always initialized | 2157 // need initialization. 'var' declared bindings are always initialized |
| 2152 // immediately by their declaration nodes. | 2158 // immediately by their declaration nodes. |
| 2153 bool needs_init = false; | 2159 bool needs_init = false; |
| 2154 bool is_const = false; | 2160 bool is_const = false; |
| 2155 Token::Value init_op = Token::INIT_VAR; | 2161 Token::Value init_op = Token::INIT_VAR; |
| 2156 if (peek() == Token::VAR) { | 2162 if (peek() == Token::VAR) { |
| 2157 Consume(Token::VAR); | 2163 Consume(Token::VAR); |
| 2158 } else if (peek() == Token::CONST) { | 2164 } else if (peek() == Token::CONST) { |
| 2159 Consume(Token::CONST); | 2165 Consume(Token::CONST); |
| 2160 switch (strict_mode()) { | 2166 if (!is_strict(language_mode())) { |
| 2161 case SLOPPY: | 2167 mode = CONST_LEGACY; |
| 2162 mode = CONST_LEGACY; | 2168 init_op = Token::INIT_CONST_LEGACY; |
| 2163 init_op = Token::INIT_CONST_LEGACY; | 2169 } else { |
| 2164 break; | 2170 DCHECK(var_context != kStatement); |
| 2165 case STRICT: | 2171 // In ES5 const is not allowed in strict mode. |
| 2166 DCHECK(var_context != kStatement); | 2172 if (!allow_harmony_scoping()) { |
| 2167 // In ES5 const is not allowed in strict mode. | 2173 ReportMessage("strict_const"); |
| 2168 if (!allow_harmony_scoping()) { | 2174 *ok = false; |
| 2169 ReportMessage("strict_const"); | 2175 return NULL; |
| 2170 *ok = false; | 2176 } |
| 2171 return NULL; | 2177 mode = CONST; |
| 2172 } | 2178 init_op = Token::INIT_CONST; |
| 2173 mode = CONST; | |
| 2174 init_op = Token::INIT_CONST; | |
| 2175 } | 2179 } |
| 2176 is_const = true; | 2180 is_const = true; |
| 2177 needs_init = true; | 2181 needs_init = true; |
| 2178 } else if (peek() == Token::LET && strict_mode() == STRICT) { | 2182 } else if (peek() == Token::LET && is_strict(language_mode())) { |
| 2179 DCHECK(allow_harmony_scoping()); | 2183 DCHECK(allow_harmony_scoping()); |
| 2180 Consume(Token::LET); | 2184 Consume(Token::LET); |
| 2181 DCHECK(var_context != kStatement); | 2185 DCHECK(var_context != kStatement); |
| 2182 mode = LET; | 2186 mode = LET; |
| 2183 needs_init = true; | 2187 needs_init = true; |
| 2184 init_op = Token::INIT_LET; | 2188 init_op = Token::INIT_LET; |
| 2185 } else { | 2189 } else { |
| 2186 UNREACHABLE(); // by current callers | 2190 UNREACHABLE(); // by current callers |
| 2187 } | 2191 } |
| 2188 | 2192 |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2339 | 2343 |
| 2340 // Construct the call to Runtime_InitializeConstGlobal | 2344 // Construct the call to Runtime_InitializeConstGlobal |
| 2341 // and add it to the initialization statement block. | 2345 // and add it to the initialization statement block. |
| 2342 // Note that the function does different things depending on | 2346 // Note that the function does different things depending on |
| 2343 // the number of arguments (1 or 2). | 2347 // the number of arguments (1 or 2). |
| 2344 initialize = factory()->NewCallRuntime( | 2348 initialize = factory()->NewCallRuntime( |
| 2345 ast_value_factory()->initialize_const_global_string(), | 2349 ast_value_factory()->initialize_const_global_string(), |
| 2346 Runtime::FunctionForId(Runtime::kInitializeConstGlobal), arguments, | 2350 Runtime::FunctionForId(Runtime::kInitializeConstGlobal), arguments, |
| 2347 pos); | 2351 pos); |
| 2348 } else { | 2352 } else { |
| 2349 // Add strict mode. | 2353 // Add language mode. |
| 2350 // We may want to pass singleton to avoid Literal allocations. | 2354 // We may want to pass singleton to avoid Literal allocations. |
| 2351 StrictMode strict_mode = initialization_scope->strict_mode(); | 2355 LanguageMode language_mode = initialization_scope->language_mode(); |
| 2352 arguments->Add(factory()->NewNumberLiteral(strict_mode, pos), zone()); | 2356 arguments->Add(factory()->NewNumberLiteral(language_mode, pos), zone()); |
| 2353 | 2357 |
| 2354 // Be careful not to assign a value to the global variable if | 2358 // Be careful not to assign a value to the global variable if |
| 2355 // we're in a with. The initialization value should not | 2359 // we're in a with. The initialization value should not |
| 2356 // necessarily be stored in the global object in that case, | 2360 // necessarily be stored in the global object in that case, |
| 2357 // which is why we need to generate a separate assignment node. | 2361 // which is why we need to generate a separate assignment node. |
| 2358 if (value != NULL && !inside_with()) { | 2362 if (value != NULL && !inside_with()) { |
| 2359 arguments->Add(value, zone()); | 2363 arguments->Add(value, zone()); |
| 2360 value = NULL; // zap the value to avoid the unnecessary assignment | 2364 value = NULL; // zap the value to avoid the unnecessary assignment |
| 2361 // Construct the call to Runtime_InitializeVarGlobal | 2365 // Construct the call to Runtime_InitializeVarGlobal |
| 2362 // and add it to the initialization statement block. | 2366 // and add it to the initialization statement block. |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2651 | 2655 |
| 2652 | 2656 |
| 2653 Statement* Parser::ParseWithStatement(ZoneList<const AstRawString*>* labels, | 2657 Statement* Parser::ParseWithStatement(ZoneList<const AstRawString*>* labels, |
| 2654 bool* ok) { | 2658 bool* ok) { |
| 2655 // WithStatement :: | 2659 // WithStatement :: |
| 2656 // 'with' '(' Expression ')' Statement | 2660 // 'with' '(' Expression ')' Statement |
| 2657 | 2661 |
| 2658 Expect(Token::WITH, CHECK_OK); | 2662 Expect(Token::WITH, CHECK_OK); |
| 2659 int pos = position(); | 2663 int pos = position(); |
| 2660 | 2664 |
| 2661 if (strict_mode() == STRICT) { | 2665 if (is_strict(language_mode())) { |
| 2662 ReportMessage("strict_mode_with"); | 2666 ReportMessage("strict_mode_with"); |
| 2663 *ok = false; | 2667 *ok = false; |
| 2664 return NULL; | 2668 return NULL; |
| 2665 } | 2669 } |
| 2666 | 2670 |
| 2667 Expect(Token::LPAREN, CHECK_OK); | 2671 Expect(Token::LPAREN, CHECK_OK); |
| 2668 Expression* expr = ParseExpression(true, CHECK_OK); | 2672 Expression* expr = ParseExpression(true, CHECK_OK); |
| 2669 Expect(Token::RPAREN, CHECK_OK); | 2673 Expect(Token::RPAREN, CHECK_OK); |
| 2670 | 2674 |
| 2671 scope_->DeclarationScope()->RecordWithStatement(); | 2675 scope_->DeclarationScope()->RecordWithStatement(); |
| (...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3221 Scope* saved_scope = scope_; | 3225 Scope* saved_scope = scope_; |
| 3222 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); | 3226 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); |
| 3223 scope_ = for_scope; | 3227 scope_ = for_scope; |
| 3224 | 3228 |
| 3225 Expect(Token::FOR, CHECK_OK); | 3229 Expect(Token::FOR, CHECK_OK); |
| 3226 Expect(Token::LPAREN, CHECK_OK); | 3230 Expect(Token::LPAREN, CHECK_OK); |
| 3227 for_scope->set_start_position(scanner()->location().beg_pos); | 3231 for_scope->set_start_position(scanner()->location().beg_pos); |
| 3228 bool is_let_identifier_expression = false; | 3232 bool is_let_identifier_expression = false; |
| 3229 if (peek() != Token::SEMICOLON) { | 3233 if (peek() != Token::SEMICOLON) { |
| 3230 if (peek() == Token::VAR || | 3234 if (peek() == Token::VAR || |
| 3231 (peek() == Token::CONST && strict_mode() == SLOPPY)) { | 3235 (peek() == Token::CONST && !is_strict(language_mode()))) { |
| 3232 bool is_const = peek() == Token::CONST; | 3236 bool is_const = peek() == Token::CONST; |
| 3233 const AstRawString* name = NULL; | 3237 const AstRawString* name = NULL; |
| 3234 VariableDeclarationProperties decl_props = kHasNoInitializers; | 3238 VariableDeclarationProperties decl_props = kHasNoInitializers; |
| 3235 Block* variable_statement = | 3239 Block* variable_statement = |
| 3236 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, | 3240 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, |
| 3237 CHECK_OK); | 3241 CHECK_OK); |
| 3238 bool accept_OF = decl_props == kHasNoInitializers; | 3242 bool accept_OF = decl_props == kHasNoInitializers; |
| 3239 ForEachStatement::VisitMode mode; | 3243 ForEachStatement::VisitMode mode; |
| 3240 int each_pos = position(); | 3244 int each_pos = position(); |
| 3241 | 3245 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 3260 scope_ = saved_scope; | 3264 scope_ = saved_scope; |
| 3261 for_scope->set_end_position(scanner()->location().end_pos); | 3265 for_scope->set_end_position(scanner()->location().end_pos); |
| 3262 for_scope = for_scope->FinalizeBlockScope(); | 3266 for_scope = for_scope->FinalizeBlockScope(); |
| 3263 DCHECK(for_scope == NULL); | 3267 DCHECK(for_scope == NULL); |
| 3264 // Parsed for-in loop w/ variable/const declaration. | 3268 // Parsed for-in loop w/ variable/const declaration. |
| 3265 return result; | 3269 return result; |
| 3266 } else { | 3270 } else { |
| 3267 init = variable_statement; | 3271 init = variable_statement; |
| 3268 } | 3272 } |
| 3269 } else if ((peek() == Token::LET || peek() == Token::CONST) && | 3273 } else if ((peek() == Token::LET || peek() == Token::CONST) && |
| 3270 strict_mode() == STRICT) { | 3274 is_strict(language_mode())) { |
| 3271 bool is_const = peek() == Token::CONST; | 3275 bool is_const = peek() == Token::CONST; |
| 3272 const AstRawString* name = NULL; | 3276 const AstRawString* name = NULL; |
| 3273 VariableDeclarationProperties decl_props = kHasNoInitializers; | 3277 VariableDeclarationProperties decl_props = kHasNoInitializers; |
| 3274 Block* variable_statement = | 3278 Block* variable_statement = |
| 3275 ParseVariableDeclarations(kForStatement, &decl_props, &let_bindings, | 3279 ParseVariableDeclarations(kForStatement, &decl_props, &let_bindings, |
| 3276 &name, CHECK_OK); | 3280 &name, CHECK_OK); |
| 3277 bool accept_IN = name != NULL && decl_props != kHasInitializers; | 3281 bool accept_IN = name != NULL && decl_props != kHasInitializers; |
| 3278 bool accept_OF = decl_props == kHasNoInitializers; | 3282 bool accept_OF = decl_props == kHasNoInitializers; |
| 3279 ForEachStatement::VisitMode mode; | 3283 ForEachStatement::VisitMode mode; |
| 3280 int each_pos = position(); | 3284 int each_pos = position(); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3367 } | 3371 } |
| 3368 } | 3372 } |
| 3369 } | 3373 } |
| 3370 | 3374 |
| 3371 // Standard 'for' loop | 3375 // Standard 'for' loop |
| 3372 ForStatement* loop = factory()->NewForStatement(labels, stmt_pos); | 3376 ForStatement* loop = factory()->NewForStatement(labels, stmt_pos); |
| 3373 Target target(&this->target_stack_, loop); | 3377 Target target(&this->target_stack_, loop); |
| 3374 | 3378 |
| 3375 // Parsed initializer at this point. | 3379 // Parsed initializer at this point. |
| 3376 // Detect attempts at 'let' declarations in sloppy mode. | 3380 // Detect attempts at 'let' declarations in sloppy mode. |
| 3377 if (peek() == Token::IDENTIFIER && strict_mode() == SLOPPY && | 3381 if (peek() == Token::IDENTIFIER && !is_strict(language_mode()) && |
| 3378 is_let_identifier_expression) { | 3382 is_let_identifier_expression) { |
| 3379 ReportMessage("sloppy_lexical", NULL); | 3383 ReportMessage("sloppy_lexical", NULL); |
| 3380 *ok = false; | 3384 *ok = false; |
| 3381 return NULL; | 3385 return NULL; |
| 3382 } | 3386 } |
| 3383 Expect(Token::SEMICOLON, CHECK_OK); | 3387 Expect(Token::SEMICOLON, CHECK_OK); |
| 3384 | 3388 |
| 3385 // If there are let bindings, then condition and the next statement of the | 3389 // If there are let bindings, then condition and the next statement of the |
| 3386 // for loop must be parsed in a new scope. | 3390 // for loop must be parsed in a new scope. |
| 3387 Scope* inner_scope = NULL; | 3391 Scope* inner_scope = NULL; |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3622 // in all normal cases, function declarations are fully hoisted to a | 3626 // in all normal cases, function declarations are fully hoisted to a |
| 3623 // declaration scope and compiled relative to that. | 3627 // declaration scope and compiled relative to that. |
| 3624 // - (2) is the case iff the current declaration scope is still the original | 3628 // - (2) is the case iff the current declaration scope is still the original |
| 3625 // one relative to the deserialized scope chain. Otherwise we must be | 3629 // one relative to the deserialized scope chain. Otherwise we must be |
| 3626 // compiling a function in an inner declaration scope in the eval, e.g. a | 3630 // compiling a function in an inner declaration scope in the eval, e.g. a |
| 3627 // nested function, and hoisting works normally relative to that. | 3631 // nested function, and hoisting works normally relative to that. |
| 3628 Scope* declaration_scope = scope_->DeclarationScope(); | 3632 Scope* declaration_scope = scope_->DeclarationScope(); |
| 3629 Scope* original_declaration_scope = original_scope_->DeclarationScope(); | 3633 Scope* original_declaration_scope = original_scope_->DeclarationScope(); |
| 3630 Scope* scope = | 3634 Scope* scope = |
| 3631 function_type == FunctionLiteral::DECLARATION && | 3635 function_type == FunctionLiteral::DECLARATION && |
| 3632 (!allow_harmony_scoping() || strict_mode() == SLOPPY) && | 3636 (!allow_harmony_scoping() || !is_strict(language_mode())) && |
| 3633 (original_scope_ == original_declaration_scope || | 3637 (original_scope_ == original_declaration_scope || |
| 3634 declaration_scope != original_declaration_scope) | 3638 declaration_scope != original_declaration_scope) |
| 3635 ? NewScope(declaration_scope, FUNCTION_SCOPE) | 3639 ? NewScope(declaration_scope, FUNCTION_SCOPE) |
| 3636 : NewScope(scope_, FUNCTION_SCOPE); | 3640 : NewScope(scope_, FUNCTION_SCOPE); |
| 3637 ZoneList<Statement*>* body = NULL; | 3641 ZoneList<Statement*>* body = NULL; |
| 3638 int materialized_literal_count = -1; | 3642 int materialized_literal_count = -1; |
| 3639 int expected_property_count = -1; | 3643 int expected_property_count = -1; |
| 3640 int handler_count = 0; | 3644 int handler_count = 0; |
| 3641 FunctionLiteral::ParameterFlag duplicate_parameters = | 3645 FunctionLiteral::ParameterFlag duplicate_parameters = |
| 3642 FunctionLiteral::kNoDuplicateParameters; | 3646 FunctionLiteral::kNoDuplicateParameters; |
| 3643 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ | 3647 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ |
| 3644 ? FunctionLiteral::kIsParenthesized | 3648 ? FunctionLiteral::kIsParenthesized |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3696 } | 3700 } |
| 3697 if (!reserved_loc.IsValid() && is_strict_reserved) { | 3701 if (!reserved_loc.IsValid() && is_strict_reserved) { |
| 3698 reserved_loc = scanner()->location(); | 3702 reserved_loc = scanner()->location(); |
| 3699 } | 3703 } |
| 3700 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) { | 3704 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) { |
| 3701 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters; | 3705 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters; |
| 3702 dupe_error_loc = scanner()->location(); | 3706 dupe_error_loc = scanner()->location(); |
| 3703 } | 3707 } |
| 3704 | 3708 |
| 3705 Variable* var = scope_->DeclareParameter(param_name, VAR, is_rest); | 3709 Variable* var = scope_->DeclareParameter(param_name, VAR, is_rest); |
| 3706 if (scope->strict_mode() == SLOPPY) { | 3710 if (!is_strict(scope->language_mode())) { |
| 3707 // TODO(sigurds) Mark every parameter as maybe assigned. This is a | 3711 // TODO(sigurds) Mark every parameter as maybe assigned. This is a |
| 3708 // conservative approximation necessary to account for parameters | 3712 // conservative approximation necessary to account for parameters |
| 3709 // that are assigned via the arguments array. | 3713 // that are assigned via the arguments array. |
| 3710 var->set_maybe_assigned(); | 3714 var->set_maybe_assigned(); |
| 3711 } | 3715 } |
| 3712 | 3716 |
| 3713 num_parameters++; | 3717 num_parameters++; |
| 3714 if (num_parameters > Code::kMaxArguments) { | 3718 if (num_parameters > Code::kMaxArguments) { |
| 3715 ReportMessage("too_many_parameters"); | 3719 ReportMessage("too_many_parameters"); |
| 3716 *ok = false; | 3720 *ok = false; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 3733 | 3737 |
| 3734 // If we have a named function expression, we add a local variable | 3738 // If we have a named function expression, we add a local variable |
| 3735 // declaration to the body of the function with the name of the | 3739 // declaration to the body of the function with the name of the |
| 3736 // function and let it refer to the function itself (closure). | 3740 // function and let it refer to the function itself (closure). |
| 3737 // NOTE: We create a proxy and resolve it here so that in the | 3741 // NOTE: We create a proxy and resolve it here so that in the |
| 3738 // future we can change the AST to only refer to VariableProxies | 3742 // future we can change the AST to only refer to VariableProxies |
| 3739 // instead of Variables and Proxis as is the case now. | 3743 // instead of Variables and Proxis as is the case now. |
| 3740 Variable* fvar = NULL; | 3744 Variable* fvar = NULL; |
| 3741 Token::Value fvar_init_op = Token::INIT_CONST_LEGACY; | 3745 Token::Value fvar_init_op = Token::INIT_CONST_LEGACY; |
| 3742 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { | 3746 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { |
| 3743 if (allow_harmony_scoping() && strict_mode() == STRICT) { | 3747 if (allow_harmony_scoping() && is_strict(language_mode())) { |
| 3744 fvar_init_op = Token::INIT_CONST; | 3748 fvar_init_op = Token::INIT_CONST; |
| 3745 } | 3749 } |
| 3746 VariableMode fvar_mode = | 3750 VariableMode fvar_mode = |
| 3747 allow_harmony_scoping() && strict_mode() == STRICT | 3751 allow_harmony_scoping() && is_strict(language_mode()) ? CONST |
| 3748 ? CONST : CONST_LEGACY; | 3752 : CONST_LEGACY; |
| 3749 DCHECK(function_name != NULL); | 3753 DCHECK(function_name != NULL); |
| 3750 fvar = new (zone()) | 3754 fvar = new (zone()) |
| 3751 Variable(scope_, function_name, fvar_mode, true /* is valid LHS */, | 3755 Variable(scope_, function_name, fvar_mode, true /* is valid LHS */, |
| 3752 Variable::NORMAL, kCreatedInitialized, kNotAssigned, | 3756 Variable::NORMAL, kCreatedInitialized, kNotAssigned, |
| 3753 Interface::NewConst()); | 3757 Interface::NewConst()); |
| 3754 VariableProxy* proxy = factory()->NewVariableProxy(fvar); | 3758 VariableProxy* proxy = factory()->NewVariableProxy(fvar); |
| 3755 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( | 3759 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( |
| 3756 proxy, fvar_mode, scope_, RelocInfo::kNoPosition); | 3760 proxy, fvar_mode, scope_, RelocInfo::kNoPosition); |
| 3757 scope_->DeclareFunctionVar(fvar_declaration); | 3761 scope_->DeclareFunctionVar(fvar_declaration); |
| 3758 } | 3762 } |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3803 is_generator, CHECK_OK); | 3807 is_generator, CHECK_OK); |
| 3804 materialized_literal_count = function_state.materialized_literal_count(); | 3808 materialized_literal_count = function_state.materialized_literal_count(); |
| 3805 expected_property_count = function_state.expected_property_count(); | 3809 expected_property_count = function_state.expected_property_count(); |
| 3806 handler_count = function_state.handler_count(); | 3810 handler_count = function_state.handler_count(); |
| 3807 } | 3811 } |
| 3808 | 3812 |
| 3809 // Validate strict mode. | 3813 // Validate strict mode. |
| 3810 // Concise methods use StrictFormalParameters. | 3814 // Concise methods use StrictFormalParameters. |
| 3811 // Functions for which IsSimpleParameterList() returns false use | 3815 // Functions for which IsSimpleParameterList() returns false use |
| 3812 // StrictFormalParameters. | 3816 // StrictFormalParameters. |
| 3813 if (strict_mode() == STRICT || IsConciseMethod(kind) || is_rest) { | 3817 if (is_strict(language_mode()) || IsConciseMethod(kind) || is_rest) { |
| 3814 CheckStrictFunctionNameAndParameters(function_name, | 3818 CheckStrictFunctionNameAndParameters(function_name, |
| 3815 name_is_strict_reserved, | 3819 name_is_strict_reserved, |
| 3816 function_name_location, | 3820 function_name_location, |
| 3817 eval_args_error_log, | 3821 eval_args_error_log, |
| 3818 dupe_error_loc, | 3822 dupe_error_loc, |
| 3819 reserved_loc, | 3823 reserved_loc, |
| 3820 CHECK_OK); | 3824 CHECK_OK); |
| 3821 } | 3825 } |
| 3822 if (strict_mode() == STRICT) { | 3826 if (is_strict(language_mode())) { |
| 3823 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(), | 3827 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(), |
| 3824 CHECK_OK); | 3828 CHECK_OK); |
| 3825 } | 3829 } |
| 3826 if (allow_harmony_scoping() && strict_mode() == STRICT) { | 3830 if (allow_harmony_scoping() && is_strict(language_mode())) { |
| 3827 CheckConflictingVarDeclarations(scope, CHECK_OK); | 3831 CheckConflictingVarDeclarations(scope, CHECK_OK); |
| 3828 } | 3832 } |
| 3829 } | 3833 } |
| 3830 | 3834 |
| 3831 FunctionLiteral* function_literal = factory()->NewFunctionLiteral( | 3835 FunctionLiteral* function_literal = factory()->NewFunctionLiteral( |
| 3832 function_name, ast_value_factory(), scope, body, | 3836 function_name, ast_value_factory(), scope, body, |
| 3833 materialized_literal_count, expected_property_count, handler_count, | 3837 materialized_literal_count, expected_property_count, handler_count, |
| 3834 num_parameters, duplicate_parameters, function_type, | 3838 num_parameters, duplicate_parameters, function_type, |
| 3835 FunctionLiteral::kIsFunction, parenthesized, kind, pos); | 3839 FunctionLiteral::kIsFunction, parenthesized, kind, pos); |
| 3836 function_literal->set_function_token_position(function_token_pos); | 3840 function_literal->set_function_token_position(function_token_pos); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 3859 scanner()->SeekForward(entry.end_pos() - 1); | 3863 scanner()->SeekForward(entry.end_pos() - 1); |
| 3860 | 3864 |
| 3861 scope_->set_end_position(entry.end_pos()); | 3865 scope_->set_end_position(entry.end_pos()); |
| 3862 Expect(Token::RBRACE, ok); | 3866 Expect(Token::RBRACE, ok); |
| 3863 if (!*ok) { | 3867 if (!*ok) { |
| 3864 return; | 3868 return; |
| 3865 } | 3869 } |
| 3866 total_preparse_skipped_ += scope_->end_position() - function_block_pos; | 3870 total_preparse_skipped_ += scope_->end_position() - function_block_pos; |
| 3867 *materialized_literal_count = entry.literal_count(); | 3871 *materialized_literal_count = entry.literal_count(); |
| 3868 *expected_property_count = entry.property_count(); | 3872 *expected_property_count = entry.property_count(); |
| 3869 scope_->SetStrictMode(entry.strict_mode()); | 3873 scope_->SetLanguageMode(entry.language_mode()); |
| 3870 return; | 3874 return; |
| 3871 } | 3875 } |
| 3872 cached_parse_data_->Reject(); | 3876 cached_parse_data_->Reject(); |
| 3873 } | 3877 } |
| 3874 // With no cached data, we partially parse the function, without building an | 3878 // With no cached data, we partially parse the function, without building an |
| 3875 // AST. This gathers the data needed to build a lazy function. | 3879 // AST. This gathers the data needed to build a lazy function. |
| 3876 SingletonLogger logger; | 3880 SingletonLogger logger; |
| 3877 PreParser::PreParseResult result = | 3881 PreParser::PreParseResult result = |
| 3878 ParseLazyFunctionBodyWithPreParser(&logger); | 3882 ParseLazyFunctionBodyWithPreParser(&logger); |
| 3879 if (result == PreParser::kPreParseStackOverflow) { | 3883 if (result == PreParser::kPreParseStackOverflow) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 3890 return; | 3894 return; |
| 3891 } | 3895 } |
| 3892 scope_->set_end_position(logger.end()); | 3896 scope_->set_end_position(logger.end()); |
| 3893 Expect(Token::RBRACE, ok); | 3897 Expect(Token::RBRACE, ok); |
| 3894 if (!*ok) { | 3898 if (!*ok) { |
| 3895 return; | 3899 return; |
| 3896 } | 3900 } |
| 3897 total_preparse_skipped_ += scope_->end_position() - function_block_pos; | 3901 total_preparse_skipped_ += scope_->end_position() - function_block_pos; |
| 3898 *materialized_literal_count = logger.literals(); | 3902 *materialized_literal_count = logger.literals(); |
| 3899 *expected_property_count = logger.properties(); | 3903 *expected_property_count = logger.properties(); |
| 3900 scope_->SetStrictMode(logger.strict_mode()); | 3904 scope_->SetLanguageMode(logger.language_mode()); |
| 3901 if (produce_cached_parse_data()) { | 3905 if (produce_cached_parse_data()) { |
| 3902 DCHECK(log_); | 3906 DCHECK(log_); |
| 3903 // Position right after terminal '}'. | 3907 // Position right after terminal '}'. |
| 3904 int body_end = scanner()->location().end_pos; | 3908 int body_end = scanner()->location().end_pos; |
| 3905 log_->LogFunction(function_block_pos, body_end, *materialized_literal_count, | 3909 log_->LogFunction(function_block_pos, body_end, *materialized_literal_count, |
| 3906 *expected_property_count, scope_->strict_mode()); | 3910 *expected_property_count, scope_->language_mode()); |
| 3907 } | 3911 } |
| 3908 } | 3912 } |
| 3909 | 3913 |
| 3910 | 3914 |
| 3911 ZoneList<Statement*>* Parser::ParseEagerFunctionBody( | 3915 ZoneList<Statement*>* Parser::ParseEagerFunctionBody( |
| 3912 const AstRawString* function_name, int pos, Variable* fvar, | 3916 const AstRawString* function_name, int pos, Variable* fvar, |
| 3913 Token::Value fvar_init_op, bool is_generator, bool* ok) { | 3917 Token::Value fvar_init_op, bool is_generator, bool* ok) { |
| 3914 // Everything inside an eagerly parsed function will be parsed eagerly | 3918 // Everything inside an eagerly parsed function will be parsed eagerly |
| 3915 // (see comment above). | 3919 // (see comment above). |
| 3916 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 3920 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3991 reusable_preparser_->set_allow_harmony_object_literals( | 3995 reusable_preparser_->set_allow_harmony_object_literals( |
| 3992 allow_harmony_object_literals()); | 3996 allow_harmony_object_literals()); |
| 3993 reusable_preparser_->set_allow_harmony_templates(allow_harmony_templates()); | 3997 reusable_preparser_->set_allow_harmony_templates(allow_harmony_templates()); |
| 3994 reusable_preparser_->set_allow_harmony_sloppy(allow_harmony_sloppy()); | 3998 reusable_preparser_->set_allow_harmony_sloppy(allow_harmony_sloppy()); |
| 3995 reusable_preparser_->set_allow_harmony_unicode(allow_harmony_unicode()); | 3999 reusable_preparser_->set_allow_harmony_unicode(allow_harmony_unicode()); |
| 3996 reusable_preparser_->set_allow_harmony_computed_property_names( | 4000 reusable_preparser_->set_allow_harmony_computed_property_names( |
| 3997 allow_harmony_computed_property_names()); | 4001 allow_harmony_computed_property_names()); |
| 3998 reusable_preparser_->set_allow_harmony_rest_params( | 4002 reusable_preparser_->set_allow_harmony_rest_params( |
| 3999 allow_harmony_rest_params()); | 4003 allow_harmony_rest_params()); |
| 4000 } | 4004 } |
| 4001 PreParser::PreParseResult result = | 4005 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction( |
| 4002 reusable_preparser_->PreParseLazyFunction(strict_mode(), | 4006 language_mode(), is_generator(), logger); |
| 4003 is_generator(), | |
| 4004 logger); | |
| 4005 if (pre_parse_timer_ != NULL) { | 4007 if (pre_parse_timer_ != NULL) { |
| 4006 pre_parse_timer_->Stop(); | 4008 pre_parse_timer_->Stop(); |
| 4007 } | 4009 } |
| 4008 return result; | 4010 return result; |
| 4009 } | 4011 } |
| 4010 | 4012 |
| 4011 | 4013 |
| 4012 ClassLiteral* Parser::ParseClassLiteral(const AstRawString* name, | 4014 ClassLiteral* Parser::ParseClassLiteral(const AstRawString* name, |
| 4013 Scanner::Location class_name_location, | 4015 Scanner::Location class_name_location, |
| 4014 bool name_is_strict_reserved, int pos, | 4016 bool name_is_strict_reserved, int pos, |
| 4015 bool* ok) { | 4017 bool* ok) { |
| 4016 // All parts of a ClassDeclaration and ClassExpression are strict code. | 4018 // All parts of a ClassDeclaration and ClassExpression are strict code. |
| 4017 if (name_is_strict_reserved) { | 4019 if (name_is_strict_reserved) { |
| 4018 ReportMessageAt(class_name_location, "unexpected_strict_reserved"); | 4020 ReportMessageAt(class_name_location, "unexpected_strict_reserved"); |
| 4019 *ok = false; | 4021 *ok = false; |
| 4020 return NULL; | 4022 return NULL; |
| 4021 } | 4023 } |
| 4022 if (IsEvalOrArguments(name)) { | 4024 if (IsEvalOrArguments(name)) { |
| 4023 ReportMessageAt(class_name_location, "strict_eval_arguments"); | 4025 ReportMessageAt(class_name_location, "strict_eval_arguments"); |
| 4024 *ok = false; | 4026 *ok = false; |
| 4025 return NULL; | 4027 return NULL; |
| 4026 } | 4028 } |
| 4027 | 4029 |
| 4028 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); | 4030 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); |
| 4029 BlockState block_state(&scope_, block_scope); | 4031 BlockState block_state(&scope_, block_scope); |
| 4030 scope_->SetStrictMode(STRICT); | 4032 scope_->SetLanguageMode( |
| 4033 static_cast<LanguageMode>(scope_->language_mode() | STRICT)); |
| 4031 scope_->SetScopeName(name); | 4034 scope_->SetScopeName(name); |
| 4032 | 4035 |
| 4033 VariableProxy* proxy = NULL; | 4036 VariableProxy* proxy = NULL; |
| 4034 if (name != NULL) { | 4037 if (name != NULL) { |
| 4035 proxy = NewUnresolved(name, CONST, Interface::NewConst()); | 4038 proxy = NewUnresolved(name, CONST, Interface::NewConst()); |
| 4036 Declaration* declaration = | 4039 Declaration* declaration = |
| 4037 factory()->NewVariableDeclaration(proxy, CONST, block_scope, pos); | 4040 factory()->NewVariableDeclaration(proxy, CONST, block_scope, pos); |
| 4038 Declare(declaration, true, CHECK_OK); | 4041 Declare(declaration, true, CHECK_OK); |
| 4039 } | 4042 } |
| 4040 | 4043 |
| (...skipping 1342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5383 } else { | 5386 } else { |
| 5384 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); | 5387 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); |
| 5385 running_hash = StringHasher::ComputeRunningHash(running_hash, data, | 5388 running_hash = StringHasher::ComputeRunningHash(running_hash, data, |
| 5386 raw_string->length()); | 5389 raw_string->length()); |
| 5387 } | 5390 } |
| 5388 } | 5391 } |
| 5389 | 5392 |
| 5390 return running_hash; | 5393 return running_hash; |
| 5391 } | 5394 } |
| 5392 } } // namespace v8::internal | 5395 } } // namespace v8::internal |
| OLD | NEW |