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 943 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
954 } | 954 } |
955 | 955 |
956 | 956 |
957 FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) { | 957 FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) { |
958 // Note that this function can be called from the main thread or from a | 958 // Note that this function can be called from the main thread or from a |
959 // background thread. We should not access anything Isolate / heap dependent | 959 // background thread. We should not access anything Isolate / heap dependent |
960 // via ParseInfo, and also not pass it forward. | 960 // via ParseInfo, and also not pass it forward. |
961 DCHECK(scope_ == NULL); | 961 DCHECK(scope_ == NULL); |
962 DCHECK(target_stack_ == NULL); | 962 DCHECK(target_stack_ == NULL); |
963 | 963 |
| 964 Mode parsing_mode = FLAG_lazy && allow_lazy() ? PARSE_LAZILY : PARSE_EAGERLY; |
| 965 if (allow_natives() || extension_ != NULL) parsing_mode = PARSE_EAGERLY; |
| 966 |
964 FunctionLiteral* result = NULL; | 967 FunctionLiteral* result = NULL; |
965 { | 968 { |
966 Scope* scope = NewScope(scope_, SCRIPT_SCOPE); | 969 Scope* scope = NewScope(scope_, SCRIPT_SCOPE); |
967 info->set_script_scope(scope); | 970 info->set_script_scope(scope); |
968 if (!info->context().is_null() && !info->context()->IsNativeContext()) { | 971 if (!info->context().is_null() && !info->context()->IsNativeContext()) { |
969 scope = Scope::DeserializeScopeChain(info->isolate(), zone(), | 972 scope = Scope::DeserializeScopeChain(info->isolate(), zone(), |
970 *info->context(), scope); | 973 *info->context(), scope); |
971 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this | 974 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this |
972 // means the Parser cannot operate independent of the V8 heap. Tell the | 975 // means the Parser cannot operate independent of the V8 heap. Tell the |
973 // string table to internalize strings and values right after they're | 976 // string table to internalize strings and values right after they're |
974 // created. This kind of parsing can only be done in the main thread. | 977 // created. This kind of parsing can only be done in the main thread. |
975 DCHECK(parsing_on_main_thread_); | 978 DCHECK(parsing_on_main_thread_); |
976 ast_value_factory()->Internalize(info->isolate()); | 979 ast_value_factory()->Internalize(info->isolate()); |
977 } | 980 } |
978 original_scope_ = scope; | 981 original_scope_ = scope; |
979 if (info->is_eval()) { | 982 if (info->is_eval()) { |
980 if (!scope->is_script_scope() || is_strict(info->language_mode())) { | 983 if (!scope->is_script_scope() || is_strict(info->language_mode())) { |
981 scope = NewScope(scope, EVAL_SCOPE); | 984 parsing_mode = PARSE_EAGERLY; |
982 } | 985 } |
| 986 scope = NewScope(scope, EVAL_SCOPE); |
983 } else if (info->is_module()) { | 987 } else if (info->is_module()) { |
984 scope = NewScope(scope, MODULE_SCOPE); | 988 scope = NewScope(scope, MODULE_SCOPE); |
985 } | 989 } |
986 | 990 |
987 scope->set_start_position(0); | 991 scope->set_start_position(0); |
988 | 992 |
989 // Compute the parsing mode. | 993 // Enter 'scope' with the given parsing mode. |
990 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY; | 994 ParsingModeScope parsing_mode_scope(this, parsing_mode); |
991 if (allow_natives() || extension_ != NULL || scope->is_eval_scope()) { | |
992 mode = PARSE_EAGERLY; | |
993 } | |
994 ParsingModeScope parsing_mode(this, mode); | |
995 | |
996 // Enters 'scope'. | |
997 AstNodeFactory function_factory(ast_value_factory()); | 995 AstNodeFactory function_factory(ast_value_factory()); |
998 FunctionState function_state(&function_state_, &scope_, scope, | 996 FunctionState function_state(&function_state_, &scope_, scope, |
999 kNormalFunction, &function_factory); | 997 kNormalFunction, &function_factory); |
1000 | 998 |
1001 scope_->SetLanguageMode(info->language_mode()); | 999 scope_->SetLanguageMode(info->language_mode()); |
1002 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); | 1000 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); |
1003 bool ok = true; | 1001 bool ok = true; |
1004 int beg_pos = scanner()->location().beg_pos; | 1002 int beg_pos = scanner()->location().beg_pos; |
1005 if (info->is_module()) { | 1003 if (info->is_module()) { |
1006 DCHECK(allow_harmony_modules()); | 1004 DCHECK(allow_harmony_modules()); |
1007 ParseModuleItemList(body, &ok); | 1005 ParseModuleItemList(body, &ok); |
1008 } else { | 1006 } else { |
1009 Scope* eval_scope = nullptr; | 1007 ParseStatementList(body, Token::EOS, &ok); |
1010 ParseStatementList(body, Token::EOS, info->is_eval(), &eval_scope, &ok); | |
1011 if (eval_scope != nullptr) | |
1012 eval_scope->set_end_position(scanner()->peek_location().beg_pos); | |
1013 } | 1008 } |
1014 | 1009 |
1015 // The parser will peek but not consume EOS. Our scope logically goes all | 1010 // The parser will peek but not consume EOS. Our scope logically goes all |
1016 // the way to the EOS, though. | 1011 // the way to the EOS, though. |
1017 scope->set_end_position(scanner()->peek_location().beg_pos); | 1012 scope->set_end_position(scanner()->peek_location().beg_pos); |
1018 | 1013 |
1019 if (ok && is_strict(language_mode())) { | 1014 if (ok && is_strict(language_mode())) { |
1020 CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); | 1015 CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); |
1021 CheckConflictingVarDeclarations(scope_, &ok); | 1016 CheckConflictingVarDeclarations(scope_, &ok); |
1022 } | 1017 } |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1188 | 1183 |
1189 if (result != NULL) { | 1184 if (result != NULL) { |
1190 Handle<String> inferred_name(shared_info->inferred_name()); | 1185 Handle<String> inferred_name(shared_info->inferred_name()); |
1191 result->set_inferred_name(inferred_name); | 1186 result->set_inferred_name(inferred_name); |
1192 } | 1187 } |
1193 return result; | 1188 return result; |
1194 } | 1189 } |
1195 | 1190 |
1196 | 1191 |
1197 void* Parser::ParseStatementList(ZoneList<Statement*>* body, int end_token, | 1192 void* Parser::ParseStatementList(ZoneList<Statement*>* body, int end_token, |
1198 bool is_eval, Scope** eval_scope, bool* ok) { | 1193 bool* ok) { |
1199 // StatementList :: | 1194 // StatementList :: |
1200 // (StatementListItem)* <end_token> | 1195 // (StatementListItem)* <end_token> |
1201 | 1196 |
1202 // Allocate a target stack to use for this set of source | 1197 // Allocate a target stack to use for this set of source |
1203 // elements. This way, all scripts and functions get their own | 1198 // elements. This way, all scripts and functions get their own |
1204 // target stack thus avoiding illegal breaks and continues across | 1199 // target stack thus avoiding illegal breaks and continues across |
1205 // functions. | 1200 // functions. |
1206 TargetScope scope(&this->target_stack_); | 1201 TargetScope scope(&this->target_stack_); |
1207 | 1202 |
1208 DCHECK(body != NULL); | 1203 DCHECK(body != NULL); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1260 bool use_strong_found = | 1255 bool use_strong_found = |
1261 allow_strong_mode() && | 1256 allow_strong_mode() && |
1262 literal->raw_value()->AsString() == | 1257 literal->raw_value()->AsString() == |
1263 ast_value_factory()->use_strong_string() && | 1258 ast_value_factory()->use_strong_string() && |
1264 token_loc.end_pos - token_loc.beg_pos == | 1259 token_loc.end_pos - token_loc.beg_pos == |
1265 ast_value_factory()->use_strong_string()->length() + 2; | 1260 ast_value_factory()->use_strong_string()->length() + 2; |
1266 if (use_strict_found || use_strong_found) { | 1261 if (use_strict_found || use_strong_found) { |
1267 // Strong mode implies strict mode. If there are several "use strict" | 1262 // Strong mode implies strict mode. If there are several "use strict" |
1268 // / "use strong" directives, do the strict mode changes only once. | 1263 // / "use strong" directives, do the strict mode changes only once. |
1269 if (is_sloppy(scope_->language_mode())) { | 1264 if (is_sloppy(scope_->language_mode())) { |
1270 // TODO(mstarzinger): Global strict eval calls, need their own scope | |
1271 // as specified in ES5 10.4.2(3). The correct fix would be to always | |
1272 // add this scope in DoParseProgram(), but that requires adaptations | |
1273 // all over the code base, so we go with a quick-fix for now. | |
1274 // In the same manner, we have to patch the parsing mode. | |
1275 if (is_eval && !scope_->is_eval_scope()) { | |
1276 DCHECK(scope_->is_script_scope()); | |
1277 Scope* scope = NewScope(scope_, EVAL_SCOPE); | |
1278 scope->set_start_position(scope_->start_position()); | |
1279 scope->set_end_position(scope_->end_position()); | |
1280 scope_ = scope; | |
1281 if (eval_scope != NULL) { | |
1282 // Caller will correct the positions of the ad hoc eval scope. | |
1283 *eval_scope = scope; | |
1284 } | |
1285 mode_ = PARSE_EAGERLY; | |
1286 } | |
1287 scope_->SetLanguageMode(static_cast<LanguageMode>( | 1265 scope_->SetLanguageMode(static_cast<LanguageMode>( |
1288 scope_->language_mode() | STRICT_BIT)); | 1266 scope_->language_mode() | STRICT_BIT)); |
1289 } | 1267 } |
1290 | 1268 |
1291 if (use_strong_found) { | 1269 if (use_strong_found) { |
1292 scope_->SetLanguageMode(static_cast<LanguageMode>( | 1270 scope_->SetLanguageMode(static_cast<LanguageMode>( |
1293 scope_->language_mode() | STRONG_BIT)); | 1271 scope_->language_mode() | STRONG_BIT)); |
1294 } | 1272 } |
| 1273 // Because declarations in strict eval code don't leak into the scope |
| 1274 // of the eval call, it is likely that functions declared in strict |
| 1275 // eval code will be used within the eval code, so lazy parsing is |
| 1276 // probably not a win. Also, resolution of "var" bindings defined in |
| 1277 // strict eval code from within nested functions is currently broken |
| 1278 // with the pre-parser; lazy parsing of strict eval code causes |
| 1279 // regress/regress-crbug-135066.js to fail. |
| 1280 if (scope_->is_eval_scope()) mode_ = PARSE_EAGERLY; |
1295 } else if (literal->raw_value()->AsString() == | 1281 } else if (literal->raw_value()->AsString() == |
1296 ast_value_factory()->use_asm_string() && | 1282 ast_value_factory()->use_asm_string() && |
1297 token_loc.end_pos - token_loc.beg_pos == | 1283 token_loc.end_pos - token_loc.beg_pos == |
1298 ast_value_factory()->use_asm_string()->length() + 2) { | 1284 ast_value_factory()->use_asm_string()->length() + 2) { |
1299 // Store the usage count; The actual use counter on the isolate is | 1285 // Store the usage count; The actual use counter on the isolate is |
1300 // incremented after parsing is done. | 1286 // incremented after parsing is done. |
1301 ++use_counts_[v8::Isolate::kUseAsm]; | 1287 ++use_counts_[v8::Isolate::kUseAsm]; |
1302 scope_->SetAsmModule(); | 1288 scope_->SetAsmModule(); |
1303 } | 1289 } |
1304 } else { | 1290 } else { |
(...skipping 2959 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4264 Assignment* assignment = factory()->NewAssignment( | 4250 Assignment* assignment = factory()->NewAssignment( |
4265 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition); | 4251 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition); |
4266 VariableProxy* get_proxy = factory()->NewVariableProxy( | 4252 VariableProxy* get_proxy = factory()->NewVariableProxy( |
4267 function_state_->generator_object_variable()); | 4253 function_state_->generator_object_variable()); |
4268 Yield* yield = factory()->NewYield( | 4254 Yield* yield = factory()->NewYield( |
4269 get_proxy, assignment, Yield::kInitial, RelocInfo::kNoPosition); | 4255 get_proxy, assignment, Yield::kInitial, RelocInfo::kNoPosition); |
4270 body->Add(factory()->NewExpressionStatement( | 4256 body->Add(factory()->NewExpressionStatement( |
4271 yield, RelocInfo::kNoPosition), zone()); | 4257 yield, RelocInfo::kNoPosition), zone()); |
4272 } | 4258 } |
4273 | 4259 |
4274 ParseStatementList(body, Token::RBRACE, false, NULL, CHECK_OK); | 4260 ParseStatementList(body, Token::RBRACE, CHECK_OK); |
4275 | 4261 |
4276 if (IsGeneratorFunction(kind)) { | 4262 if (IsGeneratorFunction(kind)) { |
4277 VariableProxy* get_proxy = factory()->NewVariableProxy( | 4263 VariableProxy* get_proxy = factory()->NewVariableProxy( |
4278 function_state_->generator_object_variable()); | 4264 function_state_->generator_object_variable()); |
4279 Expression* undefined = | 4265 Expression* undefined = |
4280 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition); | 4266 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition); |
4281 Yield* yield = factory()->NewYield(get_proxy, undefined, Yield::kFinal, | 4267 Yield* yield = factory()->NewYield(get_proxy, undefined, Yield::kFinal, |
4282 RelocInfo::kNoPosition); | 4268 RelocInfo::kNoPosition); |
4283 body->Add(factory()->NewExpressionStatement( | 4269 body->Add(factory()->NewExpressionStatement( |
4284 yield, RelocInfo::kNoPosition), zone()); | 4270 yield, RelocInfo::kNoPosition), zone()); |
(...skipping 1546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5831 | 5817 |
5832 Expression* Parser::SpreadCallNew(Expression* function, | 5818 Expression* Parser::SpreadCallNew(Expression* function, |
5833 ZoneList<v8::internal::Expression*>* args, | 5819 ZoneList<v8::internal::Expression*>* args, |
5834 int pos) { | 5820 int pos) { |
5835 args->InsertAt(0, function, zone()); | 5821 args->InsertAt(0, function, zone()); |
5836 | 5822 |
5837 return factory()->NewCallRuntime( | 5823 return factory()->NewCallRuntime( |
5838 ast_value_factory()->reflect_construct_string(), NULL, args, pos); | 5824 ast_value_factory()->reflect_construct_string(), NULL, args, pos); |
5839 } | 5825 } |
5840 } } // namespace v8::internal | 5826 } } // namespace v8::internal |
OLD | NEW |