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

Side by Side Diff: src/parser.cc

Issue 713813002: Revert "Fix stepping in for-loops." (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « src/mips64/full-codegen-mips64.cc ('k') | src/x64/full-codegen-x64.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 2921 matching lines...) Expand 10 before | Expand all | Expand 10 after
2932 ast_value_factory()->dot_result_string()); 2932 ast_value_factory()->dot_result_string());
2933 2933
2934 Expression* assign_iterator; 2934 Expression* assign_iterator;
2935 Expression* next_result; 2935 Expression* next_result;
2936 Expression* result_done; 2936 Expression* result_done;
2937 Expression* assign_each; 2937 Expression* assign_each;
2938 2938
2939 // var iterator = subject[Symbol.iterator](); 2939 // var iterator = subject[Symbol.iterator]();
2940 assign_iterator = factory()->NewAssignment( 2940 assign_iterator = factory()->NewAssignment(
2941 Token::ASSIGN, factory()->NewVariableProxy(iterator), 2941 Token::ASSIGN, factory()->NewVariableProxy(iterator),
2942 GetIterator(subject, factory()), subject->position()); 2942 GetIterator(subject, factory()), RelocInfo::kNoPosition);
2943 2943
2944 // var result = iterator.next(); 2944 // var result = iterator.next();
2945 { 2945 {
2946 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); 2946 Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
2947 Expression* next_literal = factory()->NewStringLiteral( 2947 Expression* next_literal = factory()->NewStringLiteral(
2948 ast_value_factory()->next_string(), RelocInfo::kNoPosition); 2948 ast_value_factory()->next_string(), RelocInfo::kNoPosition);
2949 Expression* next_property = factory()->NewProperty( 2949 Expression* next_property = factory()->NewProperty(
2950 iterator_proxy, next_literal, RelocInfo::kNoPosition); 2950 iterator_proxy, next_literal, RelocInfo::kNoPosition);
2951 ZoneList<Expression*>* next_arguments = 2951 ZoneList<Expression*>* next_arguments =
2952 new(zone()) ZoneList<Expression*>(0, zone()); 2952 new(zone()) ZoneList<Expression*>(0, zone());
2953 Expression* next_call = factory()->NewCall(next_property, next_arguments, 2953 Expression* next_call = factory()->NewCall(
2954 subject->position()); 2954 next_property, next_arguments, RelocInfo::kNoPosition);
2955 Expression* result_proxy = factory()->NewVariableProxy(result); 2955 Expression* result_proxy = factory()->NewVariableProxy(result);
2956 next_result = factory()->NewAssignment(Token::ASSIGN, result_proxy, 2956 next_result = factory()->NewAssignment(
2957 next_call, subject->position()); 2957 Token::ASSIGN, result_proxy, next_call, RelocInfo::kNoPosition);
2958 } 2958 }
2959 2959
2960 // result.done 2960 // result.done
2961 { 2961 {
2962 Expression* done_literal = factory()->NewStringLiteral( 2962 Expression* done_literal = factory()->NewStringLiteral(
2963 ast_value_factory()->done_string(), RelocInfo::kNoPosition); 2963 ast_value_factory()->done_string(), RelocInfo::kNoPosition);
2964 Expression* result_proxy = factory()->NewVariableProxy(result); 2964 Expression* result_proxy = factory()->NewVariableProxy(result);
2965 result_done = factory()->NewProperty( 2965 result_done = factory()->NewProperty(
2966 result_proxy, done_literal, RelocInfo::kNoPosition); 2966 result_proxy, done_literal, RelocInfo::kNoPosition);
2967 } 2967 }
2968 2968
2969 // each = result.value 2969 // each = result.value
2970 { 2970 {
2971 Expression* value_literal = factory()->NewStringLiteral( 2971 Expression* value_literal = factory()->NewStringLiteral(
2972 ast_value_factory()->value_string(), RelocInfo::kNoPosition); 2972 ast_value_factory()->value_string(), RelocInfo::kNoPosition);
2973 Expression* result_proxy = factory()->NewVariableProxy(result); 2973 Expression* result_proxy = factory()->NewVariableProxy(result);
2974 Expression* result_value = factory()->NewProperty( 2974 Expression* result_value = factory()->NewProperty(
2975 result_proxy, value_literal, RelocInfo::kNoPosition); 2975 result_proxy, value_literal, RelocInfo::kNoPosition);
2976 assign_each = factory()->NewAssignment(Token::ASSIGN, each, result_value, 2976 assign_each = factory()->NewAssignment(
2977 each->position()); 2977 Token::ASSIGN, each, result_value, RelocInfo::kNoPosition);
2978 } 2978 }
2979 2979
2980 for_of->Initialize(each, subject, body, 2980 for_of->Initialize(each, subject, body,
2981 assign_iterator, 2981 assign_iterator,
2982 next_result, 2982 next_result,
2983 result_done, 2983 result_done,
2984 assign_each); 2984 assign_each);
2985 } else { 2985 } else {
2986 stmt->Initialize(each, subject, body); 2986 stmt->Initialize(each, subject, body);
2987 } 2987 }
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
3145 loop->Initialize(NULL, NULL, NULL, inner_block); 3145 loop->Initialize(NULL, NULL, NULL, inner_block);
3146 return outer_block; 3146 return outer_block;
3147 } 3147 }
3148 3148
3149 3149
3150 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, 3150 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
3151 bool* ok) { 3151 bool* ok) {
3152 // ForStatement :: 3152 // ForStatement ::
3153 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement 3153 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
3154 3154
3155 int stmt_pos = peek_position(); 3155 int pos = peek_position();
3156 Statement* init = NULL; 3156 Statement* init = NULL;
3157 ZoneList<const AstRawString*> let_bindings(1, zone()); 3157 ZoneList<const AstRawString*> let_bindings(1, zone());
3158 3158
3159 // Create an in-between scope for let-bound iteration variables. 3159 // Create an in-between scope for let-bound iteration variables.
3160 Scope* saved_scope = scope_; 3160 Scope* saved_scope = scope_;
3161 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); 3161 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE);
3162 scope_ = for_scope; 3162 scope_ = for_scope;
3163 3163
3164 Expect(Token::FOR, CHECK_OK); 3164 Expect(Token::FOR, CHECK_OK);
3165 Expect(Token::LPAREN, CHECK_OK); 3165 Expect(Token::LPAREN, CHECK_OK);
3166 for_scope->set_start_position(scanner()->location().beg_pos); 3166 for_scope->set_start_position(scanner()->location().beg_pos);
3167 if (peek() != Token::SEMICOLON) { 3167 if (peek() != Token::SEMICOLON) {
3168 if (peek() == Token::VAR || 3168 if (peek() == Token::VAR ||
3169 (peek() == Token::CONST && strict_mode() == SLOPPY)) { 3169 (peek() == Token::CONST && strict_mode() == SLOPPY)) {
3170 bool is_const = peek() == Token::CONST; 3170 bool is_const = peek() == Token::CONST;
3171 const AstRawString* name = NULL; 3171 const AstRawString* name = NULL;
3172 VariableDeclarationProperties decl_props = kHasNoInitializers; 3172 VariableDeclarationProperties decl_props = kHasNoInitializers;
3173 Block* variable_statement = 3173 Block* variable_statement =
3174 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, 3174 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name,
3175 CHECK_OK); 3175 CHECK_OK);
3176 bool accept_OF = decl_props == kHasNoInitializers; 3176 bool accept_OF = decl_props == kHasNoInitializers;
3177 ForEachStatement::VisitMode mode; 3177 ForEachStatement::VisitMode mode;
3178 int each_pos = position();
3179 3178
3180 if (name != NULL && CheckInOrOf(accept_OF, &mode)) { 3179 if (name != NULL && CheckInOrOf(accept_OF, &mode)) {
3181 Interface* interface = 3180 Interface* interface =
3182 is_const ? Interface::NewConst() : Interface::NewValue(); 3181 is_const ? Interface::NewConst() : Interface::NewValue();
3183 ForEachStatement* loop = 3182 ForEachStatement* loop =
3184 factory()->NewForEachStatement(mode, labels, stmt_pos); 3183 factory()->NewForEachStatement(mode, labels, pos);
3185 Target target(&this->target_stack_, loop); 3184 Target target(&this->target_stack_, loop);
3186 3185
3187 Expression* enumerable = ParseExpression(true, CHECK_OK); 3186 Expression* enumerable = ParseExpression(true, CHECK_OK);
3188 Expect(Token::RPAREN, CHECK_OK); 3187 Expect(Token::RPAREN, CHECK_OK);
3189 3188
3190 VariableProxy* each = 3189 VariableProxy* each =
3191 scope_->NewUnresolved(factory(), name, interface, each_pos); 3190 scope_->NewUnresolved(factory(), name, interface);
3192 Statement* body = ParseStatement(NULL, CHECK_OK); 3191 Statement* body = ParseStatement(NULL, CHECK_OK);
3193 InitializeForEachStatement(loop, each, enumerable, body); 3192 InitializeForEachStatement(loop, each, enumerable, body);
3194 Block* result = 3193 Block* result =
3195 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); 3194 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition);
3196 result->AddStatement(variable_statement, zone()); 3195 result->AddStatement(variable_statement, zone());
3197 result->AddStatement(loop, zone()); 3196 result->AddStatement(loop, zone());
3198 scope_ = saved_scope; 3197 scope_ = saved_scope;
3199 for_scope->set_end_position(scanner()->location().end_pos); 3198 for_scope->set_end_position(scanner()->location().end_pos);
3200 for_scope = for_scope->FinalizeBlockScope(); 3199 for_scope = for_scope->FinalizeBlockScope();
3201 DCHECK(for_scope == NULL); 3200 DCHECK(for_scope == NULL);
3202 // Parsed for-in loop w/ variable/const declaration. 3201 // Parsed for-in loop w/ variable/const declaration.
3203 return result; 3202 return result;
3204 } else { 3203 } else {
3205 init = variable_statement; 3204 init = variable_statement;
3206 } 3205 }
3207 } else if ((peek() == Token::LET || peek() == Token::CONST) && 3206 } else if ((peek() == Token::LET || peek() == Token::CONST) &&
3208 strict_mode() == STRICT) { 3207 strict_mode() == STRICT) {
3209 bool is_const = peek() == Token::CONST; 3208 bool is_const = peek() == Token::CONST;
3210 const AstRawString* name = NULL; 3209 const AstRawString* name = NULL;
3211 VariableDeclarationProperties decl_props = kHasNoInitializers; 3210 VariableDeclarationProperties decl_props = kHasNoInitializers;
3212 Block* variable_statement = 3211 Block* variable_statement =
3213 ParseVariableDeclarations(kForStatement, &decl_props, &let_bindings, 3212 ParseVariableDeclarations(kForStatement, &decl_props, &let_bindings,
3214 &name, CHECK_OK); 3213 &name, CHECK_OK);
3215 bool accept_IN = name != NULL && decl_props != kHasInitializers; 3214 bool accept_IN = name != NULL && decl_props != kHasInitializers;
3216 bool accept_OF = decl_props == kHasNoInitializers; 3215 bool accept_OF = decl_props == kHasNoInitializers;
3217 ForEachStatement::VisitMode mode; 3216 ForEachStatement::VisitMode mode;
3218 int each_pos = position();
3219 3217
3220 if (accept_IN && CheckInOrOf(accept_OF, &mode)) { 3218 if (accept_IN && CheckInOrOf(accept_OF, &mode)) {
3221 // Rewrite a for-in statement of the form 3219 // Rewrite a for-in statement of the form
3222 // 3220 //
3223 // for (let/const x in e) b 3221 // for (let/const x in e) b
3224 // 3222 //
3225 // into 3223 // into
3226 // 3224 //
3227 // <let x' be a temporary variable> 3225 // <let x' be a temporary variable>
3228 // for (x' in e) { 3226 // for (x' in e) {
3229 // let/const x; 3227 // let/const x;
3230 // x = x'; 3228 // x = x';
3231 // b; 3229 // b;
3232 // } 3230 // }
3233 3231
3234 // TODO(keuchel): Move the temporary variable to the block scope, after 3232 // TODO(keuchel): Move the temporary variable to the block scope, after
3235 // implementing stack allocated block scoped variables. 3233 // implementing stack allocated block scoped variables.
3236 Variable* temp = scope_->DeclarationScope()->NewTemporary( 3234 Variable* temp = scope_->DeclarationScope()->NewTemporary(
3237 ast_value_factory()->dot_for_string()); 3235 ast_value_factory()->dot_for_string());
3238 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); 3236 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
3239 ForEachStatement* loop = 3237 ForEachStatement* loop =
3240 factory()->NewForEachStatement(mode, labels, stmt_pos); 3238 factory()->NewForEachStatement(mode, labels, pos);
3241 Target target(&this->target_stack_, loop); 3239 Target target(&this->target_stack_, loop);
3242 3240
3243 // The expression does not see the loop variable. 3241 // The expression does not see the loop variable.
3244 scope_ = saved_scope; 3242 scope_ = saved_scope;
3245 Expression* enumerable = ParseExpression(true, CHECK_OK); 3243 Expression* enumerable = ParseExpression(true, CHECK_OK);
3246 scope_ = for_scope; 3244 scope_ = for_scope;
3247 Expect(Token::RPAREN, CHECK_OK); 3245 Expect(Token::RPAREN, CHECK_OK);
3248 3246
3249 VariableProxy* each = scope_->NewUnresolved( 3247 VariableProxy* each = scope_->NewUnresolved(factory(), name);
3250 factory(), name, Interface::NewValue(), each_pos);
3251 Statement* body = ParseStatement(NULL, CHECK_OK); 3248 Statement* body = ParseStatement(NULL, CHECK_OK);
3252 Block* body_block = 3249 Block* body_block =
3253 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition); 3250 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition);
3254 Token::Value init_op = is_const ? Token::INIT_CONST : Token::ASSIGN; 3251 Token::Value init_op = is_const ? Token::INIT_CONST : Token::ASSIGN;
3255 Assignment* assignment = factory()->NewAssignment( 3252 Assignment* assignment = factory()->NewAssignment(
3256 init_op, each, temp_proxy, RelocInfo::kNoPosition); 3253 init_op, each, temp_proxy, RelocInfo::kNoPosition);
3257 Statement* assignment_statement = factory()->NewExpressionStatement( 3254 Statement* assignment_statement = factory()->NewExpressionStatement(
3258 assignment, RelocInfo::kNoPosition); 3255 assignment, RelocInfo::kNoPosition);
3259 body_block->AddStatement(variable_statement, zone()); 3256 body_block->AddStatement(variable_statement, zone());
3260 body_block->AddStatement(assignment_statement, zone()); 3257 body_block->AddStatement(assignment_statement, zone());
(...skipping 13 matching lines...) Expand all
3274 Scanner::Location lhs_location = scanner()->peek_location(); 3271 Scanner::Location lhs_location = scanner()->peek_location();
3275 Expression* expression = ParseExpression(false, CHECK_OK); 3272 Expression* expression = ParseExpression(false, CHECK_OK);
3276 ForEachStatement::VisitMode mode; 3273 ForEachStatement::VisitMode mode;
3277 bool accept_OF = expression->IsVariableProxy(); 3274 bool accept_OF = expression->IsVariableProxy();
3278 3275
3279 if (CheckInOrOf(accept_OF, &mode)) { 3276 if (CheckInOrOf(accept_OF, &mode)) {
3280 expression = this->CheckAndRewriteReferenceExpression( 3277 expression = this->CheckAndRewriteReferenceExpression(
3281 expression, lhs_location, "invalid_lhs_in_for", CHECK_OK); 3278 expression, lhs_location, "invalid_lhs_in_for", CHECK_OK);
3282 3279
3283 ForEachStatement* loop = 3280 ForEachStatement* loop =
3284 factory()->NewForEachStatement(mode, labels, stmt_pos); 3281 factory()->NewForEachStatement(mode, labels, pos);
3285 Target target(&this->target_stack_, loop); 3282 Target target(&this->target_stack_, loop);
3286 3283
3287 Expression* enumerable = ParseExpression(true, CHECK_OK); 3284 Expression* enumerable = ParseExpression(true, CHECK_OK);
3288 Expect(Token::RPAREN, CHECK_OK); 3285 Expect(Token::RPAREN, CHECK_OK);
3289 3286
3290 Statement* body = ParseStatement(NULL, CHECK_OK); 3287 Statement* body = ParseStatement(NULL, CHECK_OK);
3291 InitializeForEachStatement(loop, expression, enumerable, body); 3288 InitializeForEachStatement(loop, expression, enumerable, body);
3292 scope_ = saved_scope; 3289 scope_ = saved_scope;
3293 for_scope->set_end_position(scanner()->location().end_pos); 3290 for_scope->set_end_position(scanner()->location().end_pos);
3294 for_scope = for_scope->FinalizeBlockScope(); 3291 for_scope = for_scope->FinalizeBlockScope();
3295 DCHECK(for_scope == NULL); 3292 DCHECK(for_scope == NULL);
3296 // Parsed for-in loop. 3293 // Parsed for-in loop.
3297 return loop; 3294 return loop;
3298 3295
3299 } else { 3296 } else {
3300 init = factory()->NewExpressionStatement(expression, position()); 3297 init = factory()->NewExpressionStatement(
3298 expression, RelocInfo::kNoPosition);
3301 } 3299 }
3302 } 3300 }
3303 } 3301 }
3304 3302
3305 // Standard 'for' loop 3303 // Standard 'for' loop
3306 ForStatement* loop = factory()->NewForStatement(labels, stmt_pos); 3304 ForStatement* loop = factory()->NewForStatement(labels, pos);
3307 Target target(&this->target_stack_, loop); 3305 Target target(&this->target_stack_, loop);
3308 3306
3309 // Parsed initializer at this point. 3307 // Parsed initializer at this point.
3310 Expect(Token::SEMICOLON, CHECK_OK); 3308 Expect(Token::SEMICOLON, CHECK_OK);
3311 3309
3312 // If there are let bindings, then condition and the next statement of the 3310 // If there are let bindings, then condition and the next statement of the
3313 // for loop must be parsed in a new scope. 3311 // for loop must be parsed in a new scope.
3314 Scope* inner_scope = NULL; 3312 Scope* inner_scope = NULL;
3315 if (let_bindings.length() > 0) { 3313 if (let_bindings.length() > 0) {
3316 inner_scope = NewScope(for_scope, BLOCK_SCOPE); 3314 inner_scope = NewScope(for_scope, BLOCK_SCOPE);
3317 inner_scope->set_start_position(scanner()->location().beg_pos); 3315 inner_scope->set_start_position(scanner()->location().beg_pos);
3318 scope_ = inner_scope; 3316 scope_ = inner_scope;
3319 } 3317 }
3320 3318
3321 Expression* cond = NULL; 3319 Expression* cond = NULL;
3322 if (peek() != Token::SEMICOLON) { 3320 if (peek() != Token::SEMICOLON) {
3323 cond = ParseExpression(true, CHECK_OK); 3321 cond = ParseExpression(true, CHECK_OK);
3324 } 3322 }
3325 Expect(Token::SEMICOLON, CHECK_OK); 3323 Expect(Token::SEMICOLON, CHECK_OK);
3326 3324
3327 Statement* next = NULL; 3325 Statement* next = NULL;
3328 if (peek() != Token::RPAREN) { 3326 if (peek() != Token::RPAREN) {
3329 int next_pos = position();
3330 Expression* exp = ParseExpression(true, CHECK_OK); 3327 Expression* exp = ParseExpression(true, CHECK_OK);
3331 next = factory()->NewExpressionStatement(exp, next_pos); 3328 next = factory()->NewExpressionStatement(exp, RelocInfo::kNoPosition);
3332 } 3329 }
3333 Expect(Token::RPAREN, CHECK_OK); 3330 Expect(Token::RPAREN, CHECK_OK);
3334 3331
3335 Statement* body = ParseStatement(NULL, CHECK_OK); 3332 Statement* body = ParseStatement(NULL, CHECK_OK);
3336 3333
3337 Statement* result = NULL; 3334 Statement* result = NULL;
3338 if (let_bindings.length() > 0) { 3335 if (let_bindings.length() > 0) {
3339 scope_ = for_scope; 3336 scope_ = for_scope;
3340 result = DesugarLetBindingsInForStatement(inner_scope, &let_bindings, loop, 3337 result = DesugarLetBindingsInForStatement(inner_scope, &let_bindings, loop,
3341 init, cond, next, body, CHECK_OK); 3338 init, cond, next, body, CHECK_OK);
(...skipping 1684 matching lines...) Expand 10 before | Expand all | Expand 10 after
5026 5023
5027 // We cannot internalize on a background thread; a foreground task will take 5024 // We cannot internalize on a background thread; a foreground task will take
5028 // care of calling Parser::Internalize just before compilation. 5025 // care of calling Parser::Internalize just before compilation.
5029 5026
5030 if (compile_options() == ScriptCompiler::kProduceParserCache) { 5027 if (compile_options() == ScriptCompiler::kProduceParserCache) {
5031 if (result != NULL) *info_->cached_data() = recorder.GetScriptData(); 5028 if (result != NULL) *info_->cached_data() = recorder.GetScriptData();
5032 log_ = NULL; 5029 log_ = NULL;
5033 } 5030 }
5034 } 5031 }
5035 } } // namespace v8::internal 5032 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/mips64/full-codegen-mips64.cc ('k') | src/x64/full-codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698