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