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

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: Rebase 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
« no previous file with comments | « src/parser.h ('k') | src/runtime/runtime-scopes.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 959 matching lines...) Expand 10 before | Expand all | Expand 10 after
970 *info->context(), scope); 970 *info->context(), scope);
971 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this 971 // 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 972 // means the Parser cannot operate independent of the V8 heap. Tell the
973 // string table to internalize strings and values right after they're 973 // 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. 974 // created. This kind of parsing can only be done in the main thread.
975 DCHECK(parsing_on_main_thread_); 975 DCHECK(parsing_on_main_thread_);
976 ast_value_factory()->Internalize(info->isolate()); 976 ast_value_factory()->Internalize(info->isolate());
977 } 977 }
978 original_scope_ = scope; 978 original_scope_ = scope;
979 if (info->is_eval()) { 979 if (info->is_eval()) {
980 if (!scope->is_script_scope() || is_strict(info->language_mode())) { 980 scope = NewScope(scope, EVAL_SCOPE);
981 scope = NewScope(scope, EVAL_SCOPE);
982 }
983 } else if (info->is_module()) { 981 } else if (info->is_module()) {
984 scope = NewScope(scope, MODULE_SCOPE); 982 scope = NewScope(scope, MODULE_SCOPE);
985 } 983 }
986 984
987 scope->set_start_position(0); 985 scope->set_start_position(0);
988 986
989 // Compute the parsing mode. 987 // Compute the parsing mode.
990 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY; 988 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY;
991 if (allow_natives() || extension_ != NULL || scope->is_eval_scope()) { 989 if (allow_natives() || extension_ != NULL || scope->is_eval_scope()) {
992 mode = PARSE_EAGERLY; 990 mode = PARSE_EAGERLY;
993 } 991 }
994 ParsingModeScope parsing_mode(this, mode); 992 ParsingModeScope parsing_mode(this, mode);
995 993
996 // Enters 'scope'. 994 // 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
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
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 }
1295 } else if (literal->raw_value()->AsString() == 1273 } else if (literal->raw_value()->AsString() ==
1296 ast_value_factory()->use_asm_string() && 1274 ast_value_factory()->use_asm_string() &&
(...skipping 2940 matching lines...) Expand 10 before | Expand all | Expand 10 after
4237 Assignment* assignment = factory()->NewAssignment( 4215 Assignment* assignment = factory()->NewAssignment(
4238 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition); 4216 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition);
4239 VariableProxy* get_proxy = factory()->NewVariableProxy( 4217 VariableProxy* get_proxy = factory()->NewVariableProxy(
4240 function_state_->generator_object_variable()); 4218 function_state_->generator_object_variable());
4241 Yield* yield = factory()->NewYield( 4219 Yield* yield = factory()->NewYield(
4242 get_proxy, assignment, Yield::kInitial, RelocInfo::kNoPosition); 4220 get_proxy, assignment, Yield::kInitial, RelocInfo::kNoPosition);
4243 body->Add(factory()->NewExpressionStatement( 4221 body->Add(factory()->NewExpressionStatement(
4244 yield, RelocInfo::kNoPosition), zone()); 4222 yield, RelocInfo::kNoPosition), zone());
4245 } 4223 }
4246 4224
4247 ParseStatementList(body, Token::RBRACE, false, NULL, CHECK_OK); 4225 ParseStatementList(body, Token::RBRACE, CHECK_OK);
4248 4226
4249 if (IsGeneratorFunction(kind)) { 4227 if (IsGeneratorFunction(kind)) {
4250 VariableProxy* get_proxy = factory()->NewVariableProxy( 4228 VariableProxy* get_proxy = factory()->NewVariableProxy(
4251 function_state_->generator_object_variable()); 4229 function_state_->generator_object_variable());
4252 Expression* undefined = 4230 Expression* undefined =
4253 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition); 4231 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition);
4254 Yield* yield = factory()->NewYield(get_proxy, undefined, Yield::kFinal, 4232 Yield* yield = factory()->NewYield(get_proxy, undefined, Yield::kFinal,
4255 RelocInfo::kNoPosition); 4233 RelocInfo::kNoPosition);
4256 body->Add(factory()->NewExpressionStatement( 4234 body->Add(factory()->NewExpressionStatement(
4257 yield, RelocInfo::kNoPosition), zone()); 4235 yield, RelocInfo::kNoPosition), zone());
(...skipping 1544 matching lines...) Expand 10 before | Expand all | Expand 10 after
5802 5780
5803 Expression* Parser::SpreadCallNew(Expression* function, 5781 Expression* Parser::SpreadCallNew(Expression* function,
5804 ZoneList<v8::internal::Expression*>* args, 5782 ZoneList<v8::internal::Expression*>* args,
5805 int pos) { 5783 int pos) {
5806 args->InsertAt(0, function, zone()); 5784 args->InsertAt(0, function, zone());
5807 5785
5808 return factory()->NewCallRuntime( 5786 return factory()->NewCallRuntime(
5809 ast_value_factory()->reflect_construct_string(), NULL, args, pos); 5787 ast_value_factory()->reflect_construct_string(), NULL, args, pos);
5810 } 5788 }
5811 } } // namespace v8::internal 5789 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/runtime/runtime-scopes.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698