Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(200)

Side by Side Diff: src/parser.cc

Issue 1085263003: Eagerly declare eval scopes, even for sloppy scopes (Closed) Base URL: https://chromium.googlesource.com/v8/v8@master
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 955 matching lines...) Expand 10 before | Expand all | Expand 10 after
966 *info->context(), scope); 966 *info->context(), scope);
967 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this 967 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this
968 // means the Parser cannot operate independent of the V8 heap. Tell the 968 // means the Parser cannot operate independent of the V8 heap. Tell the
969 // string table to internalize strings and values right after they're 969 // string table to internalize strings and values right after they're
970 // created. This kind of parsing can only be done in the main thread. 970 // created. This kind of parsing can only be done in the main thread.
971 DCHECK(parsing_on_main_thread_); 971 DCHECK(parsing_on_main_thread_);
972 ast_value_factory()->Internalize(info->isolate()); 972 ast_value_factory()->Internalize(info->isolate());
973 } 973 }
974 original_scope_ = scope; 974 original_scope_ = scope;
975 if (info->is_eval()) { 975 if (info->is_eval()) {
976 if (!scope->is_script_scope() || is_strict(info->language_mode())) { 976 scope = NewScope(scope, EVAL_SCOPE);
977 scope = NewScope(scope, EVAL_SCOPE);
978 }
979 } else if (info->is_module()) { 977 } else if (info->is_module()) {
980 scope = NewScope(scope, MODULE_SCOPE); 978 scope = NewScope(scope, MODULE_SCOPE);
981 } 979 }
982 980
983 scope->set_start_position(0); 981 scope->set_start_position(0);
984 982
985 // Compute the parsing mode. 983 // Compute the parsing mode.
986 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY; 984 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY;
987 if (allow_natives() || extension_ != NULL || scope->is_eval_scope()) { 985 if (allow_natives() || extension_ != NULL || scope->is_eval_scope()) {
988 mode = PARSE_EAGERLY; 986 mode = PARSE_EAGERLY;
989 } 987 }
990 ParsingModeScope parsing_mode(this, mode); 988 ParsingModeScope parsing_mode(this, mode);
991 989
992 // Enters 'scope'. 990 // Enters 'scope'.
993 AstNodeFactory function_factory(ast_value_factory()); 991 AstNodeFactory function_factory(ast_value_factory());
994 FunctionState function_state(&function_state_, &scope_, scope, 992 FunctionState function_state(&function_state_, &scope_, scope,
995 kNormalFunction, &function_factory); 993 kNormalFunction, &function_factory);
996 994
997 scope_->SetLanguageMode(info->language_mode()); 995 scope_->SetLanguageMode(info->language_mode());
998 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); 996 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone());
999 bool ok = true; 997 bool ok = true;
1000 int beg_pos = scanner()->location().beg_pos; 998 int beg_pos = scanner()->location().beg_pos;
1001 if (info->is_module()) { 999 if (info->is_module()) {
1002 DCHECK(allow_harmony_modules()); 1000 DCHECK(allow_harmony_modules());
1003 ParseModuleItemList(body, &ok); 1001 ParseModuleItemList(body, &ok);
1004 } else { 1002 } else {
1005 Scope* eval_scope = nullptr; 1003 ParseStatementList(body, Token::EOS, &ok);
1006 ParseStatementList(body, Token::EOS, info->is_eval(), &eval_scope, &ok);
1007 if (eval_scope != nullptr)
1008 eval_scope->set_end_position(scanner()->location().end_pos);
1009 } 1004 }
1010 1005
1011 scope->set_end_position(scanner()->location().end_pos); 1006 scope->set_end_position(scanner()->location().end_pos);
1012 1007
1013 if (ok && is_strict(language_mode())) { 1008 if (ok && is_strict(language_mode())) {
1014 CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); 1009 CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok);
1015 CheckConflictingVarDeclarations(scope_, &ok); 1010 CheckConflictingVarDeclarations(scope_, &ok);
1016 } 1011 }
1017 1012
1018 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { 1013 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
1183 1178
1184 if (result != NULL) { 1179 if (result != NULL) {
1185 Handle<String> inferred_name(shared_info->inferred_name()); 1180 Handle<String> inferred_name(shared_info->inferred_name());
1186 result->set_inferred_name(inferred_name); 1181 result->set_inferred_name(inferred_name);
1187 } 1182 }
1188 return result; 1183 return result;
1189 } 1184 }
1190 1185
1191 1186
1192 void* Parser::ParseStatementList(ZoneList<Statement*>* body, int end_token, 1187 void* Parser::ParseStatementList(ZoneList<Statement*>* body, int end_token,
1193 bool is_eval, Scope** eval_scope, bool* ok) { 1188 bool* ok) {
1194 // StatementList :: 1189 // StatementList ::
1195 // (StatementListItem)* <end_token> 1190 // (StatementListItem)* <end_token>
1196 1191
1197 // Allocate a target stack to use for this set of source 1192 // Allocate a target stack to use for this set of source
1198 // elements. This way, all scripts and functions get their own 1193 // elements. This way, all scripts and functions get their own
1199 // target stack thus avoiding illegal breaks and continues across 1194 // target stack thus avoiding illegal breaks and continues across
1200 // functions. 1195 // functions.
1201 TargetScope scope(&this->target_stack_); 1196 TargetScope scope(&this->target_stack_);
1202 1197
1203 DCHECK(body != NULL); 1198 DCHECK(body != NULL);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1252 bool use_strong_found = 1247 bool use_strong_found =
1253 allow_strong_mode() && 1248 allow_strong_mode() &&
1254 literal->raw_value()->AsString() == 1249 literal->raw_value()->AsString() ==
1255 ast_value_factory()->use_strong_string() && 1250 ast_value_factory()->use_strong_string() &&
1256 token_loc.end_pos - token_loc.beg_pos == 1251 token_loc.end_pos - token_loc.beg_pos ==
1257 ast_value_factory()->use_strong_string()->length() + 2; 1252 ast_value_factory()->use_strong_string()->length() + 2;
1258 if (use_strict_found || use_strong_found) { 1253 if (use_strict_found || use_strong_found) {
1259 // Strong mode implies strict mode. If there are several "use strict" 1254 // Strong mode implies strict mode. If there are several "use strict"
1260 // / "use strong" directives, do the strict mode changes only once. 1255 // / "use strong" directives, do the strict mode changes only once.
1261 if (is_sloppy(scope_->language_mode())) { 1256 if (is_sloppy(scope_->language_mode())) {
1262 // TODO(mstarzinger): Global strict eval calls, need their own scope
1263 // as specified in ES5 10.4.2(3). The correct fix would be to always
1264 // add this scope in DoParseProgram(), but that requires adaptations
1265 // all over the code base, so we go with a quick-fix for now.
1266 // In the same manner, we have to patch the parsing mode.
1267 if (is_eval && !scope_->is_eval_scope()) {
1268 DCHECK(scope_->is_script_scope());
1269 Scope* scope = NewScope(scope_, EVAL_SCOPE);
1270 scope->set_start_position(scope_->start_position());
1271 scope->set_end_position(scope_->end_position());
1272 scope_ = scope;
1273 if (eval_scope != NULL) {
1274 // Caller will correct the positions of the ad hoc eval scope.
1275 *eval_scope = scope;
1276 }
1277 mode_ = PARSE_EAGERLY;
1278 }
1279 scope_->SetLanguageMode(static_cast<LanguageMode>( 1257 scope_->SetLanguageMode(static_cast<LanguageMode>(
1280 scope_->language_mode() | STRICT_BIT)); 1258 scope_->language_mode() | STRICT_BIT));
1281 } 1259 }
1282 1260
1283 if (use_strong_found) { 1261 if (use_strong_found) {
1284 scope_->SetLanguageMode(static_cast<LanguageMode>( 1262 scope_->SetLanguageMode(static_cast<LanguageMode>(
1285 scope_->language_mode() | STRONG_BIT)); 1263 scope_->language_mode() | STRONG_BIT));
1286 } 1264 }
1287 } else if (literal->raw_value()->AsString() == 1265 } else if (literal->raw_value()->AsString() ==
1288 ast_value_factory()->use_asm_string() && 1266 ast_value_factory()->use_asm_string() &&
(...skipping 2915 matching lines...) Expand 10 before | Expand all | Expand 10 after
4204 Assignment* assignment = factory()->NewAssignment( 4182 Assignment* assignment = factory()->NewAssignment(
4205 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition); 4183 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition);
4206 VariableProxy* get_proxy = factory()->NewVariableProxy( 4184 VariableProxy* get_proxy = factory()->NewVariableProxy(
4207 function_state_->generator_object_variable()); 4185 function_state_->generator_object_variable());
4208 Yield* yield = factory()->NewYield( 4186 Yield* yield = factory()->NewYield(
4209 get_proxy, assignment, Yield::kInitial, RelocInfo::kNoPosition); 4187 get_proxy, assignment, Yield::kInitial, RelocInfo::kNoPosition);
4210 body->Add(factory()->NewExpressionStatement( 4188 body->Add(factory()->NewExpressionStatement(
4211 yield, RelocInfo::kNoPosition), zone()); 4189 yield, RelocInfo::kNoPosition), zone());
4212 } 4190 }
4213 4191
4214 ParseStatementList(body, Token::RBRACE, false, NULL, CHECK_OK); 4192 ParseStatementList(body, Token::RBRACE, CHECK_OK);
4215 4193
4216 if (IsGeneratorFunction(kind)) { 4194 if (IsGeneratorFunction(kind)) {
4217 VariableProxy* get_proxy = factory()->NewVariableProxy( 4195 VariableProxy* get_proxy = factory()->NewVariableProxy(
4218 function_state_->generator_object_variable()); 4196 function_state_->generator_object_variable());
4219 Expression* undefined = 4197 Expression* undefined =
4220 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition); 4198 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition);
4221 Yield* yield = factory()->NewYield(get_proxy, undefined, Yield::kFinal, 4199 Yield* yield = factory()->NewYield(get_proxy, undefined, Yield::kFinal,
4222 RelocInfo::kNoPosition); 4200 RelocInfo::kNoPosition);
4223 body->Add(factory()->NewExpressionStatement( 4201 body->Add(factory()->NewExpressionStatement(
4224 yield, RelocInfo::kNoPosition), zone()); 4202 yield, RelocInfo::kNoPosition), zone());
(...skipping 1538 matching lines...) Expand 10 before | Expand all | Expand 10 after
5763 5741
5764 Expression* Parser::SpreadCallNew(Expression* function, 5742 Expression* Parser::SpreadCallNew(Expression* function,
5765 ZoneList<v8::internal::Expression*>* args, 5743 ZoneList<v8::internal::Expression*>* args,
5766 int pos) { 5744 int pos) {
5767 args->InsertAt(0, function, zone()); 5745 args->InsertAt(0, function, zone());
5768 5746
5769 return factory()->NewCallRuntime( 5747 return factory()->NewCallRuntime(
5770 ast_value_factory()->reflect_construct_string(), NULL, args, pos); 5748 ast_value_factory()->reflect_construct_string(), NULL, args, pos);
5771 } 5749 }
5772 } } // namespace v8::internal 5750 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/runtime/runtime-scopes.cc » ('j') | src/runtime/runtime-scopes.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698