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

Side by Side Diff: src/interpreter/bytecode-generator.cc

Issue 2035813002: [Interpreter] Move jump processing to bytecode array writer. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@int_fix_bytecode
Patch Set: Address comments Created 4 years, 6 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/interpreter/bytecode-generator.h ('k') | src/interpreter/bytecode-label.h » ('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 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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/interpreter/bytecode-generator.h" 5 #include "src/interpreter/bytecode-generator.h"
6 6
7 #include "src/ast/scopes.h" 7 #include "src/ast/scopes.h"
8 #include "src/code-stubs.h" 8 #include "src/code-stubs.h"
9 #include "src/compiler.h" 9 #include "src/compiler.h"
10 #include "src/interpreter/bytecode-register-allocator.h" 10 #include "src/interpreter/bytecode-register-allocator.h"
11 #include "src/interpreter/control-flow-builders.h" 11 #include "src/interpreter/control-flow-builders.h"
12 #include "src/objects.h" 12 #include "src/objects.h"
13 #include "src/parsing/parser.h" 13 #include "src/parsing/parser.h"
14 #include "src/parsing/token.h" 14 #include "src/parsing/token.h"
15 15
16 namespace v8 { 16 namespace v8 {
17 namespace internal { 17 namespace internal {
18 namespace interpreter { 18 namespace interpreter {
19 19
20
21 // Scoped class tracking context objects created by the visitor. Represents 20 // Scoped class tracking context objects created by the visitor. Represents
22 // mutations of the context chain within the function body, allowing pushing and 21 // mutations of the context chain within the function body, allowing pushing and
23 // popping of the current {context_register} during visitation. 22 // popping of the current {context_register} during visitation.
24 class BytecodeGenerator::ContextScope BASE_EMBEDDED { 23 class BytecodeGenerator::ContextScope BASE_EMBEDDED {
25 public: 24 public:
26 ContextScope(BytecodeGenerator* generator, Scope* scope, 25 ContextScope(BytecodeGenerator* generator, Scope* scope,
27 bool should_pop_context = true) 26 bool should_pop_context = true)
28 : generator_(generator), 27 : generator_(generator),
29 scope_(scope), 28 scope_(scope),
30 outer_(generator_->execution_context()), 29 outer_(generator_->execution_context()),
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 void set_register(Register reg) { register_ = reg; } 80 void set_register(Register reg) { register_ = reg; }
82 81
83 BytecodeGenerator* generator_; 82 BytecodeGenerator* generator_;
84 Scope* scope_; 83 Scope* scope_;
85 ContextScope* outer_; 84 ContextScope* outer_;
86 Register register_; 85 Register register_;
87 int depth_; 86 int depth_;
88 bool should_pop_context_; 87 bool should_pop_context_;
89 }; 88 };
90 89
91
92 // Scoped class for tracking control statements entered by the 90 // Scoped class for tracking control statements entered by the
93 // visitor. The pattern derives AstGraphBuilder::ControlScope. 91 // visitor. The pattern derives AstGraphBuilder::ControlScope.
94 class BytecodeGenerator::ControlScope BASE_EMBEDDED { 92 class BytecodeGenerator::ControlScope BASE_EMBEDDED {
95 public: 93 public:
96 explicit ControlScope(BytecodeGenerator* generator) 94 explicit ControlScope(BytecodeGenerator* generator)
97 : generator_(generator), outer_(generator->execution_control()), 95 : generator_(generator), outer_(generator->execution_control()),
98 context_(generator->execution_context()) { 96 context_(generator->execution_context()) {
99 generator_->set_execution_control(this); 97 generator_->set_execution_control(this);
100 } 98 }
101 virtual ~ControlScope() { generator_->set_execution_control(outer()); } 99 virtual ~ControlScope() { generator_->set_execution_control(outer()); }
(...skipping 15 matching lines...) Expand all
117 ContextScope* context() const { return context_; } 115 ContextScope* context() const { return context_; }
118 116
119 private: 117 private:
120 BytecodeGenerator* generator_; 118 BytecodeGenerator* generator_;
121 ControlScope* outer_; 119 ControlScope* outer_;
122 ContextScope* context_; 120 ContextScope* context_;
123 121
124 DISALLOW_COPY_AND_ASSIGN(ControlScope); 122 DISALLOW_COPY_AND_ASSIGN(ControlScope);
125 }; 123 };
126 124
127
128 // Helper class for a try-finally control scope. It can record intercepted 125 // Helper class for a try-finally control scope. It can record intercepted
129 // control-flow commands that cause entry into a finally-block, and re-apply 126 // control-flow commands that cause entry into a finally-block, and re-apply
130 // them after again leaving that block. Special tokens are used to identify 127 // them after again leaving that block. Special tokens are used to identify
131 // paths going through the finally-block to dispatch after leaving the block. 128 // paths going through the finally-block to dispatch after leaving the block.
132 class BytecodeGenerator::ControlScope::DeferredCommands final { 129 class BytecodeGenerator::ControlScope::DeferredCommands final {
133 public: 130 public:
134 DeferredCommands(BytecodeGenerator* generator, Register token_register, 131 DeferredCommands(BytecodeGenerator* generator, Register token_register,
135 Register result_register) 132 Register result_register)
136 : generator_(generator), 133 : generator_(generator),
137 deferred_(generator->zone()), 134 deferred_(generator->zone()),
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 BytecodeArrayBuilder* builder() { return generator_->builder(); } 193 BytecodeArrayBuilder* builder() { return generator_->builder(); }
197 ControlScope* execution_control() { return generator_->execution_control(); } 194 ControlScope* execution_control() { return generator_->execution_control(); }
198 195
199 private: 196 private:
200 BytecodeGenerator* generator_; 197 BytecodeGenerator* generator_;
201 ZoneVector<Entry> deferred_; 198 ZoneVector<Entry> deferred_;
202 Register token_register_; 199 Register token_register_;
203 Register result_register_; 200 Register result_register_;
204 }; 201 };
205 202
206
207 // Scoped class for dealing with control flow reaching the function level. 203 // Scoped class for dealing with control flow reaching the function level.
208 class BytecodeGenerator::ControlScopeForTopLevel final 204 class BytecodeGenerator::ControlScopeForTopLevel final
209 : public BytecodeGenerator::ControlScope { 205 : public BytecodeGenerator::ControlScope {
210 public: 206 public:
211 explicit ControlScopeForTopLevel(BytecodeGenerator* generator) 207 explicit ControlScopeForTopLevel(BytecodeGenerator* generator)
212 : ControlScope(generator) {} 208 : ControlScope(generator) {}
213 209
214 protected: 210 protected:
215 bool Execute(Command command, Statement* statement) override { 211 bool Execute(Command command, Statement* statement) override {
216 switch (command) { 212 switch (command) {
217 case CMD_BREAK: // We should never see break/continue in top-level. 213 case CMD_BREAK: // We should never see break/continue in top-level.
218 case CMD_CONTINUE: 214 case CMD_CONTINUE:
219 UNREACHABLE(); 215 UNREACHABLE();
220 case CMD_RETURN: 216 case CMD_RETURN:
221 generator()->builder()->SetReturnPosition(); 217 generator()->builder()->SetReturnPosition();
222 generator()->builder()->Return(); 218 generator()->builder()->Return();
223 return true; 219 return true;
224 case CMD_RETHROW: 220 case CMD_RETHROW:
225 generator()->builder()->ReThrow(); 221 generator()->builder()->ReThrow();
226 return true; 222 return true;
227 } 223 }
228 return false; 224 return false;
229 } 225 }
230 }; 226 };
231 227
232
233 // Scoped class for enabling break inside blocks and switch blocks. 228 // Scoped class for enabling break inside blocks and switch blocks.
234 class BytecodeGenerator::ControlScopeForBreakable final 229 class BytecodeGenerator::ControlScopeForBreakable final
235 : public BytecodeGenerator::ControlScope { 230 : public BytecodeGenerator::ControlScope {
236 public: 231 public:
237 ControlScopeForBreakable(BytecodeGenerator* generator, 232 ControlScopeForBreakable(BytecodeGenerator* generator,
238 BreakableStatement* statement, 233 BreakableStatement* statement,
239 BreakableControlFlowBuilder* control_builder) 234 BreakableControlFlowBuilder* control_builder)
240 : ControlScope(generator), 235 : ControlScope(generator),
241 statement_(statement), 236 statement_(statement),
242 control_builder_(control_builder) {} 237 control_builder_(control_builder) {}
(...skipping 11 matching lines...) Expand all
254 break; 249 break;
255 } 250 }
256 return false; 251 return false;
257 } 252 }
258 253
259 private: 254 private:
260 Statement* statement_; 255 Statement* statement_;
261 BreakableControlFlowBuilder* control_builder_; 256 BreakableControlFlowBuilder* control_builder_;
262 }; 257 };
263 258
264
265 // Scoped class for enabling 'break' and 'continue' in iteration 259 // Scoped class for enabling 'break' and 'continue' in iteration
266 // constructs, e.g. do...while, while..., for... 260 // constructs, e.g. do...while, while..., for...
267 class BytecodeGenerator::ControlScopeForIteration final 261 class BytecodeGenerator::ControlScopeForIteration final
268 : public BytecodeGenerator::ControlScope { 262 : public BytecodeGenerator::ControlScope {
269 public: 263 public:
270 ControlScopeForIteration(BytecodeGenerator* generator, 264 ControlScopeForIteration(BytecodeGenerator* generator,
271 IterationStatement* statement, 265 IterationStatement* statement,
272 LoopBuilder* loop_builder) 266 LoopBuilder* loop_builder)
273 : ControlScope(generator), 267 : ControlScope(generator),
274 statement_(statement), 268 statement_(statement),
(...skipping 14 matching lines...) Expand all
289 break; 283 break;
290 } 284 }
291 return false; 285 return false;
292 } 286 }
293 287
294 private: 288 private:
295 Statement* statement_; 289 Statement* statement_;
296 LoopBuilder* loop_builder_; 290 LoopBuilder* loop_builder_;
297 }; 291 };
298 292
299
300 // Scoped class for enabling 'throw' in try-catch constructs. 293 // Scoped class for enabling 'throw' in try-catch constructs.
301 class BytecodeGenerator::ControlScopeForTryCatch final 294 class BytecodeGenerator::ControlScopeForTryCatch final
302 : public BytecodeGenerator::ControlScope { 295 : public BytecodeGenerator::ControlScope {
303 public: 296 public:
304 ControlScopeForTryCatch(BytecodeGenerator* generator, 297 ControlScopeForTryCatch(BytecodeGenerator* generator,
305 TryCatchBuilder* try_catch_builder) 298 TryCatchBuilder* try_catch_builder)
306 : ControlScope(generator) { 299 : ControlScope(generator) {
307 generator->try_catch_nesting_level_++; 300 generator->try_catch_nesting_level_++;
308 } 301 }
309 virtual ~ControlScopeForTryCatch() { 302 virtual ~ControlScopeForTryCatch() {
310 generator()->try_catch_nesting_level_--; 303 generator()->try_catch_nesting_level_--;
311 } 304 }
312 305
313 protected: 306 protected:
314 bool Execute(Command command, Statement* statement) override { 307 bool Execute(Command command, Statement* statement) override {
315 switch (command) { 308 switch (command) {
316 case CMD_BREAK: 309 case CMD_BREAK:
317 case CMD_CONTINUE: 310 case CMD_CONTINUE:
318 case CMD_RETURN: 311 case CMD_RETURN:
319 break; 312 break;
320 case CMD_RETHROW: 313 case CMD_RETHROW:
321 generator()->builder()->ReThrow(); 314 generator()->builder()->ReThrow();
322 return true; 315 return true;
323 } 316 }
324 return false; 317 return false;
325 } 318 }
326 }; 319 };
327 320
328
329 // Scoped class for enabling control flow through try-finally constructs. 321 // Scoped class for enabling control flow through try-finally constructs.
330 class BytecodeGenerator::ControlScopeForTryFinally final 322 class BytecodeGenerator::ControlScopeForTryFinally final
331 : public BytecodeGenerator::ControlScope { 323 : public BytecodeGenerator::ControlScope {
332 public: 324 public:
333 ControlScopeForTryFinally(BytecodeGenerator* generator, 325 ControlScopeForTryFinally(BytecodeGenerator* generator,
334 TryFinallyBuilder* try_finally_builder, 326 TryFinallyBuilder* try_finally_builder,
335 DeferredCommands* commands) 327 DeferredCommands* commands)
336 : ControlScope(generator), 328 : ControlScope(generator),
337 try_finally_builder_(try_finally_builder), 329 try_finally_builder_(try_finally_builder),
338 commands_(commands) { 330 commands_(commands) {
(...skipping 15 matching lines...) Expand all
354 return true; 346 return true;
355 } 347 }
356 return false; 348 return false;
357 } 349 }
358 350
359 private: 351 private:
360 TryFinallyBuilder* try_finally_builder_; 352 TryFinallyBuilder* try_finally_builder_;
361 DeferredCommands* commands_; 353 DeferredCommands* commands_;
362 }; 354 };
363 355
364
365 void BytecodeGenerator::ControlScope::PerformCommand(Command command, 356 void BytecodeGenerator::ControlScope::PerformCommand(Command command,
366 Statement* statement) { 357 Statement* statement) {
367 ControlScope* current = this; 358 ControlScope* current = this;
368 ContextScope* context = generator()->execution_context(); 359 ContextScope* context = generator()->execution_context();
369 // Pop context to the expected depth but do not pop the outermost context. 360 // Pop context to the expected depth but do not pop the outermost context.
370 if (context != current->context() && context->ShouldPopContext()) { 361 if (context != current->context() && context->ShouldPopContext()) {
371 generator()->builder()->PopContext(current->context()->reg()); 362 generator()->builder()->PopContext(current->context()->reg());
372 } 363 }
373 do { 364 do {
374 if (current->Execute(command, statement)) { 365 if (current->Execute(command, statement)) {
375 return; 366 return;
376 } 367 }
377 current = current->outer(); 368 current = current->outer();
378 if (current->context() != context) { 369 if (current->context() != context) {
379 // Pop context to the expected depth. 370 // Pop context to the expected depth.
380 // TODO(rmcilroy): Only emit a single context pop. 371 // TODO(rmcilroy): Only emit a single context pop.
381 generator()->builder()->PopContext(current->context()->reg()); 372 generator()->builder()->PopContext(current->context()->reg());
382 } 373 }
383 } while (current != nullptr); 374 } while (current != nullptr);
384 UNREACHABLE(); 375 UNREACHABLE();
385 } 376 }
386 377
387
388 class BytecodeGenerator::RegisterAllocationScope { 378 class BytecodeGenerator::RegisterAllocationScope {
389 public: 379 public:
390 explicit RegisterAllocationScope(BytecodeGenerator* generator) 380 explicit RegisterAllocationScope(BytecodeGenerator* generator)
391 : generator_(generator), 381 : generator_(generator),
392 outer_(generator->register_allocator()), 382 outer_(generator->register_allocator()),
393 allocator_(builder()->zone(), 383 allocator_(builder()->zone(),
394 builder()->temporary_register_allocator()) { 384 builder()->temporary_register_allocator()) {
395 generator_->set_register_allocator(this); 385 generator_->set_register_allocator(this);
396 } 386 }
397 387
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
435 BytecodeGenerator* generator() const { return generator_; } 425 BytecodeGenerator* generator() const { return generator_; }
436 BytecodeArrayBuilder* builder() const { return generator_->builder(); } 426 BytecodeArrayBuilder* builder() const { return generator_->builder(); }
437 427
438 BytecodeGenerator* generator_; 428 BytecodeGenerator* generator_;
439 RegisterAllocationScope* outer_; 429 RegisterAllocationScope* outer_;
440 BytecodeRegisterAllocator allocator_; 430 BytecodeRegisterAllocator allocator_;
441 431
442 DISALLOW_COPY_AND_ASSIGN(RegisterAllocationScope); 432 DISALLOW_COPY_AND_ASSIGN(RegisterAllocationScope);
443 }; 433 };
444 434
445
446 // Scoped base class for determining where the result of an expression 435 // Scoped base class for determining where the result of an expression
447 // is stored. 436 // is stored.
448 class BytecodeGenerator::ExpressionResultScope { 437 class BytecodeGenerator::ExpressionResultScope {
449 public: 438 public:
450 ExpressionResultScope(BytecodeGenerator* generator, Expression::Context kind) 439 ExpressionResultScope(BytecodeGenerator* generator, Expression::Context kind)
451 : generator_(generator), 440 : generator_(generator),
452 kind_(kind), 441 kind_(kind),
453 outer_(generator->execution_result()), 442 outer_(generator->execution_result()),
454 allocator_(generator), 443 allocator_(generator),
455 result_identified_(false) { 444 result_identified_(false) {
(...skipping 27 matching lines...) Expand all
483 private: 472 private:
484 BytecodeGenerator* generator_; 473 BytecodeGenerator* generator_;
485 Expression::Context kind_; 474 Expression::Context kind_;
486 ExpressionResultScope* outer_; 475 ExpressionResultScope* outer_;
487 RegisterAllocationScope allocator_; 476 RegisterAllocationScope allocator_;
488 bool result_identified_; 477 bool result_identified_;
489 478
490 DISALLOW_COPY_AND_ASSIGN(ExpressionResultScope); 479 DISALLOW_COPY_AND_ASSIGN(ExpressionResultScope);
491 }; 480 };
492 481
493
494 // Scoped class used when the result of the current expression is not 482 // Scoped class used when the result of the current expression is not
495 // expected to produce a result. 483 // expected to produce a result.
496 class BytecodeGenerator::EffectResultScope final 484 class BytecodeGenerator::EffectResultScope final
497 : public ExpressionResultScope { 485 : public ExpressionResultScope {
498 public: 486 public:
499 explicit EffectResultScope(BytecodeGenerator* generator) 487 explicit EffectResultScope(BytecodeGenerator* generator)
500 : ExpressionResultScope(generator, Expression::kEffect) { 488 : ExpressionResultScope(generator, Expression::kEffect) {
501 set_result_identified(); 489 set_result_identified();
502 } 490 }
503 491
504 virtual void SetResultInAccumulator() {} 492 virtual void SetResultInAccumulator() {}
505 virtual void SetResultInRegister(Register reg) {} 493 virtual void SetResultInRegister(Register reg) {}
506 }; 494 };
507 495
508
509 // Scoped class used when the result of the current expression to be 496 // Scoped class used when the result of the current expression to be
510 // evaluated should go into the interpreter's accumulator register. 497 // evaluated should go into the interpreter's accumulator register.
511 class BytecodeGenerator::AccumulatorResultScope final 498 class BytecodeGenerator::AccumulatorResultScope final
512 : public ExpressionResultScope { 499 : public ExpressionResultScope {
513 public: 500 public:
514 explicit AccumulatorResultScope(BytecodeGenerator* generator) 501 explicit AccumulatorResultScope(BytecodeGenerator* generator)
515 : ExpressionResultScope(generator, Expression::kValue) {} 502 : ExpressionResultScope(generator, Expression::kValue) {}
516 503
517 virtual void SetResultInAccumulator() { set_result_identified(); } 504 virtual void SetResultInAccumulator() { set_result_identified(); }
518 505
519 virtual void SetResultInRegister(Register reg) { 506 virtual void SetResultInRegister(Register reg) {
520 builder()->LoadAccumulatorWithRegister(reg); 507 builder()->LoadAccumulatorWithRegister(reg);
521 set_result_identified(); 508 set_result_identified();
522 } 509 }
523 }; 510 };
524 511
525
526 // Scoped class used when the result of the current expression to be 512 // Scoped class used when the result of the current expression to be
527 // evaluated should go into an interpreter register. 513 // evaluated should go into an interpreter register.
528 class BytecodeGenerator::RegisterResultScope final 514 class BytecodeGenerator::RegisterResultScope final
529 : public ExpressionResultScope { 515 : public ExpressionResultScope {
530 public: 516 public:
531 explicit RegisterResultScope(BytecodeGenerator* generator) 517 explicit RegisterResultScope(BytecodeGenerator* generator)
532 : ExpressionResultScope(generator, Expression::kValue) {} 518 : ExpressionResultScope(generator, Expression::kValue) {}
533 519
534 virtual void SetResultInAccumulator() { 520 virtual void SetResultInAccumulator() {
535 result_register_ = allocator()->outer()->NewRegister(); 521 result_register_ = allocator()->outer()->NewRegister();
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
607 // contain jumps to unbound labels (resume points that will never be used). 593 // contain jumps to unbound labels (resume points that will never be used).
608 // We bind these now. 594 // We bind these now.
609 for (auto& label : generator_resume_points_) { 595 for (auto& label : generator_resume_points_) {
610 if (!label.is_bound()) builder()->Bind(&label); 596 if (!label.is_bound()) builder()->Bind(&label);
611 } 597 }
612 598
613 builder()->EnsureReturn(); 599 builder()->EnsureReturn();
614 return builder()->ToBytecodeArray(); 600 return builder()->ToBytecodeArray();
615 } 601 }
616 602
617
618 void BytecodeGenerator::MakeBytecodeBody() { 603 void BytecodeGenerator::MakeBytecodeBody() {
619 // Build the arguments object if it is used. 604 // Build the arguments object if it is used.
620 VisitArgumentsObject(scope()->arguments()); 605 VisitArgumentsObject(scope()->arguments());
621 606
622 // Build rest arguments array if it is used. 607 // Build rest arguments array if it is used.
623 int rest_index; 608 int rest_index;
624 Variable* rest_parameter = scope()->rest_parameter(&rest_index); 609 Variable* rest_parameter = scope()->rest_parameter(&rest_index);
625 VisitRestArgumentsArray(rest_parameter); 610 VisitRestArgumentsArray(rest_parameter);
626 611
627 // Build assignment to {.this_function} variable if it is used. 612 // Build assignment to {.this_function} variable if it is used.
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
722 // Visit declarations and statements. 707 // Visit declarations and statements.
723 if (stmt->scope() != nullptr && stmt->scope()->NeedsContext()) { 708 if (stmt->scope() != nullptr && stmt->scope()->NeedsContext()) {
724 VisitNewLocalBlockContext(stmt->scope()); 709 VisitNewLocalBlockContext(stmt->scope());
725 ContextScope scope(this, stmt->scope()); 710 ContextScope scope(this, stmt->scope());
726 VisitBlockDeclarationsAndStatements(stmt); 711 VisitBlockDeclarationsAndStatements(stmt);
727 } else { 712 } else {
728 VisitBlockDeclarationsAndStatements(stmt); 713 VisitBlockDeclarationsAndStatements(stmt);
729 } 714 }
730 } 715 }
731 716
732
733 void BytecodeGenerator::VisitBlockDeclarationsAndStatements(Block* stmt) { 717 void BytecodeGenerator::VisitBlockDeclarationsAndStatements(Block* stmt) {
734 BlockBuilder block_builder(builder()); 718 BlockBuilder block_builder(builder());
735 ControlScopeForBreakable execution_control(this, stmt, &block_builder); 719 ControlScopeForBreakable execution_control(this, stmt, &block_builder);
736 if (stmt->scope() != nullptr) { 720 if (stmt->scope() != nullptr) {
737 VisitDeclarations(stmt->scope()->declarations()); 721 VisitDeclarations(stmt->scope()->declarations());
738 } 722 }
739 VisitStatements(stmt->statements()); 723 VisitStatements(stmt->statements());
740 if (stmt->labels() != nullptr) block_builder.EndBlock(); 724 if (stmt->labels() != nullptr) block_builder.EndBlock();
741 } 725 }
742 726
743
744 void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) { 727 void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) {
745 Variable* variable = decl->proxy()->var(); 728 Variable* variable = decl->proxy()->var();
746 VariableMode mode = decl->mode(); 729 VariableMode mode = decl->mode();
747 // Const and let variables are initialized with the hole so that we can 730 // Const and let variables are initialized with the hole so that we can
748 // check that they are only assigned once. 731 // check that they are only assigned once.
749 bool hole_init = mode == CONST || mode == LET; 732 bool hole_init = mode == CONST || mode == LET;
750 switch (variable->location()) { 733 switch (variable->location()) {
751 case VariableLocation::GLOBAL: 734 case VariableLocation::GLOBAL:
752 case VariableLocation::UNALLOCATED: 735 case VariableLocation::UNALLOCATED:
753 DCHECK(!variable->binding_needs_init()); 736 DCHECK(!variable->binding_needs_init());
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
795 } 778 }
796 builder() 779 builder()
797 ->LoadLiteral(Smi::FromInt(variable->DeclarationPropertyAttributes())) 780 ->LoadLiteral(Smi::FromInt(variable->DeclarationPropertyAttributes()))
798 .StoreAccumulatorInRegister(attributes) 781 .StoreAccumulatorInRegister(attributes)
799 .CallRuntime(Runtime::kDeclareLookupSlot, name, 3); 782 .CallRuntime(Runtime::kDeclareLookupSlot, name, 3);
800 break; 783 break;
801 } 784 }
802 } 785 }
803 } 786 }
804 787
805
806 void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) { 788 void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) {
807 Variable* variable = decl->proxy()->var(); 789 Variable* variable = decl->proxy()->var();
808 switch (variable->location()) { 790 switch (variable->location()) {
809 case VariableLocation::GLOBAL: 791 case VariableLocation::GLOBAL:
810 case VariableLocation::UNALLOCATED: { 792 case VariableLocation::UNALLOCATED: {
811 Handle<SharedFunctionInfo> function = Compiler::GetSharedFunctionInfo( 793 Handle<SharedFunctionInfo> function = Compiler::GetSharedFunctionInfo(
812 decl->fun(), info()->script(), info()); 794 decl->fun(), info()->script(), info());
813 // Check for stack-overflow exception. 795 // Check for stack-overflow exception.
814 if (function.is_null()) return SetStackOverflow(); 796 if (function.is_null()) return SetStackOverflow();
815 globals()->push_back(variable->name()); 797 globals()->push_back(variable->name());
(...skipping 26 matching lines...) Expand all
842 VisitForAccumulatorValue(decl->fun()); 824 VisitForAccumulatorValue(decl->fun());
843 builder() 825 builder()
844 ->StoreAccumulatorInRegister(literal) 826 ->StoreAccumulatorInRegister(literal)
845 .LoadLiteral(Smi::FromInt(variable->DeclarationPropertyAttributes())) 827 .LoadLiteral(Smi::FromInt(variable->DeclarationPropertyAttributes()))
846 .StoreAccumulatorInRegister(attributes) 828 .StoreAccumulatorInRegister(attributes)
847 .CallRuntime(Runtime::kDeclareLookupSlot, name, 3); 829 .CallRuntime(Runtime::kDeclareLookupSlot, name, 3);
848 } 830 }
849 } 831 }
850 } 832 }
851 833
852
853 void BytecodeGenerator::VisitImportDeclaration(ImportDeclaration* decl) { 834 void BytecodeGenerator::VisitImportDeclaration(ImportDeclaration* decl) {
854 UNIMPLEMENTED(); 835 UNIMPLEMENTED();
855 } 836 }
856 837
857
858 void BytecodeGenerator::VisitExportDeclaration(ExportDeclaration* decl) { 838 void BytecodeGenerator::VisitExportDeclaration(ExportDeclaration* decl) {
859 UNIMPLEMENTED(); 839 UNIMPLEMENTED();
860 } 840 }
861 841
862
863 void BytecodeGenerator::VisitDeclarations( 842 void BytecodeGenerator::VisitDeclarations(
864 ZoneList<Declaration*>* declarations) { 843 ZoneList<Declaration*>* declarations) {
865 RegisterAllocationScope register_scope(this); 844 RegisterAllocationScope register_scope(this);
866 DCHECK(globals()->empty()); 845 DCHECK(globals()->empty());
867 for (int i = 0; i < declarations->length(); i++) { 846 for (int i = 0; i < declarations->length(); i++) {
868 RegisterAllocationScope register_scope(this); 847 RegisterAllocationScope register_scope(this);
869 Visit(declarations->at(i)); 848 Visit(declarations->at(i));
870 } 849 }
871 if (globals()->empty()) return; 850 if (globals()->empty()) return;
872 int array_index = 0; 851 int array_index = 0;
873 Handle<FixedArray> data = isolate()->factory()->NewFixedArray( 852 Handle<FixedArray> data = isolate()->factory()->NewFixedArray(
874 static_cast<int>(globals()->size()), TENURED); 853 static_cast<int>(globals()->size()), TENURED);
875 for (Handle<Object> obj : *globals()) data->set(array_index++, *obj); 854 for (Handle<Object> obj : *globals()) data->set(array_index++, *obj);
876 int encoded_flags = info()->GetDeclareGlobalsFlags(); 855 int encoded_flags = info()->GetDeclareGlobalsFlags();
877 856
878 Register pairs = register_allocator()->NewRegister(); 857 Register pairs = register_allocator()->NewRegister();
879 builder()->LoadLiteral(data); 858 builder()->LoadLiteral(data);
880 builder()->StoreAccumulatorInRegister(pairs); 859 builder()->StoreAccumulatorInRegister(pairs);
881 860
882 Register flags = register_allocator()->NewRegister(); 861 Register flags = register_allocator()->NewRegister();
883 builder()->LoadLiteral(Smi::FromInt(encoded_flags)); 862 builder()->LoadLiteral(Smi::FromInt(encoded_flags));
884 builder()->StoreAccumulatorInRegister(flags); 863 builder()->StoreAccumulatorInRegister(flags);
885 DCHECK(flags.index() == pairs.index() + 1); 864 DCHECK(flags.index() == pairs.index() + 1);
886 865
887 builder()->CallRuntime(Runtime::kDeclareGlobals, pairs, 2); 866 builder()->CallRuntime(Runtime::kDeclareGlobals, pairs, 2);
888 globals()->clear(); 867 globals()->clear();
889 } 868 }
890 869
891
892 void BytecodeGenerator::VisitStatements(ZoneList<Statement*>* statements) { 870 void BytecodeGenerator::VisitStatements(ZoneList<Statement*>* statements) {
893 for (int i = 0; i < statements->length(); i++) { 871 for (int i = 0; i < statements->length(); i++) {
894 // Allocate an outer register allocations scope for the statement. 872 // Allocate an outer register allocations scope for the statement.
895 RegisterAllocationScope allocation_scope(this); 873 RegisterAllocationScope allocation_scope(this);
896 Statement* stmt = statements->at(i); 874 Statement* stmt = statements->at(i);
897 Visit(stmt); 875 Visit(stmt);
898 if (stmt->IsJump()) break; 876 if (stmt->IsJump()) break;
899 } 877 }
900 } 878 }
901 879
902
903 void BytecodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { 880 void BytecodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
904 builder()->SetStatementPosition(stmt); 881 builder()->SetStatementPosition(stmt);
905 VisitForEffect(stmt->expression()); 882 VisitForEffect(stmt->expression());
906 } 883 }
907 884
908
909 void BytecodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) { 885 void BytecodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) {
910 } 886 }
911 887
912
913 void BytecodeGenerator::VisitIfStatement(IfStatement* stmt) { 888 void BytecodeGenerator::VisitIfStatement(IfStatement* stmt) {
914 builder()->SetStatementPosition(stmt); 889 builder()->SetStatementPosition(stmt);
915 BytecodeLabel else_label, end_label; 890 BytecodeLabel else_label, end_label;
916 if (stmt->condition()->ToBooleanIsTrue()) { 891 if (stmt->condition()->ToBooleanIsTrue()) {
917 // Generate then block unconditionally as always true. 892 // Generate then block unconditionally as always true.
918 Visit(stmt->then_statement()); 893 Visit(stmt->then_statement());
919 } else if (stmt->condition()->ToBooleanIsFalse()) { 894 } else if (stmt->condition()->ToBooleanIsFalse()) {
920 // Generate else block unconditionally if it exists. 895 // Generate else block unconditionally if it exists.
921 if (stmt->HasElseStatement()) { 896 if (stmt->HasElseStatement()) {
922 Visit(stmt->else_statement()); 897 Visit(stmt->else_statement());
923 } 898 }
924 } else { 899 } else {
925 // TODO(oth): If then statement is BreakStatement or 900 // TODO(oth): If then statement is BreakStatement or
926 // ContinueStatement we can reduce number of generated 901 // ContinueStatement we can reduce number of generated
927 // jump/jump_ifs here. See BasicLoops test. 902 // jump/jump_ifs here. See BasicLoops test.
928 VisitForAccumulatorValue(stmt->condition()); 903 VisitForAccumulatorValue(stmt->condition());
929 builder()->JumpIfFalse(&else_label); 904 builder()->JumpIfFalse(&else_label);
930 Visit(stmt->then_statement()); 905 Visit(stmt->then_statement());
931 if (stmt->HasElseStatement()) { 906 if (stmt->HasElseStatement()) {
932 builder()->Jump(&end_label); 907 builder()->Jump(&end_label);
933 builder()->Bind(&else_label); 908 builder()->Bind(&else_label);
934 Visit(stmt->else_statement()); 909 Visit(stmt->else_statement());
935 } else { 910 } else {
936 builder()->Bind(&else_label); 911 builder()->Bind(&else_label);
937 } 912 }
938 builder()->Bind(&end_label); 913 builder()->Bind(&end_label);
939 } 914 }
940 } 915 }
941 916
942
943 void BytecodeGenerator::VisitSloppyBlockFunctionStatement( 917 void BytecodeGenerator::VisitSloppyBlockFunctionStatement(
944 SloppyBlockFunctionStatement* stmt) { 918 SloppyBlockFunctionStatement* stmt) {
945 Visit(stmt->statement()); 919 Visit(stmt->statement());
946 } 920 }
947 921
948
949 void BytecodeGenerator::VisitContinueStatement(ContinueStatement* stmt) { 922 void BytecodeGenerator::VisitContinueStatement(ContinueStatement* stmt) {
950 builder()->SetStatementPosition(stmt); 923 builder()->SetStatementPosition(stmt);
951 execution_control()->Continue(stmt->target()); 924 execution_control()->Continue(stmt->target());
952 } 925 }
953 926
954
955 void BytecodeGenerator::VisitBreakStatement(BreakStatement* stmt) { 927 void BytecodeGenerator::VisitBreakStatement(BreakStatement* stmt) {
956 builder()->SetStatementPosition(stmt); 928 builder()->SetStatementPosition(stmt);
957 execution_control()->Break(stmt->target()); 929 execution_control()->Break(stmt->target());
958 } 930 }
959 931
960
961 void BytecodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { 932 void BytecodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
962 builder()->SetStatementPosition(stmt); 933 builder()->SetStatementPosition(stmt);
963 VisitForAccumulatorValue(stmt->expression()); 934 VisitForAccumulatorValue(stmt->expression());
964 execution_control()->ReturnAccumulator(); 935 execution_control()->ReturnAccumulator();
965 } 936 }
966 937
967
968 void BytecodeGenerator::VisitWithStatement(WithStatement* stmt) { 938 void BytecodeGenerator::VisitWithStatement(WithStatement* stmt) {
969 builder()->SetStatementPosition(stmt); 939 builder()->SetStatementPosition(stmt);
970 VisitForAccumulatorValue(stmt->expression()); 940 VisitForAccumulatorValue(stmt->expression());
971 builder()->CastAccumulatorToJSObject(); 941 builder()->CastAccumulatorToJSObject();
972 VisitNewLocalWithContext(); 942 VisitNewLocalWithContext();
973 VisitInScope(stmt->statement(), stmt->scope()); 943 VisitInScope(stmt->statement(), stmt->scope());
974 } 944 }
975 945
976
977 void BytecodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { 946 void BytecodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
978 // We need this scope because we visit for register values. We have to 947 // We need this scope because we visit for register values. We have to
979 // maintain a execution result scope where registers can be allocated. 948 // maintain a execution result scope where registers can be allocated.
980 ZoneList<CaseClause*>* clauses = stmt->cases(); 949 ZoneList<CaseClause*>* clauses = stmt->cases();
981 SwitchBuilder switch_builder(builder(), clauses->length()); 950 SwitchBuilder switch_builder(builder(), clauses->length());
982 ControlScopeForBreakable scope(this, stmt, &switch_builder); 951 ControlScopeForBreakable scope(this, stmt, &switch_builder);
983 int default_index = -1; 952 int default_index = -1;
984 953
985 builder()->SetStatementPosition(stmt); 954 builder()->SetStatementPosition(stmt);
986 955
(...skipping 30 matching lines...) Expand all
1017 for (int i = 0; i < clauses->length(); i++) { 986 for (int i = 0; i < clauses->length(); i++) {
1018 CaseClause* clause = clauses->at(i); 987 CaseClause* clause = clauses->at(i);
1019 switch_builder.SetCaseTarget(i); 988 switch_builder.SetCaseTarget(i);
1020 VisitStatements(clause->statements()); 989 VisitStatements(clause->statements());
1021 } 990 }
1022 builder()->Bind(&done_label); 991 builder()->Bind(&done_label);
1023 992
1024 switch_builder.SetBreakTarget(done_label); 993 switch_builder.SetBreakTarget(done_label);
1025 } 994 }
1026 995
1027
1028 void BytecodeGenerator::VisitCaseClause(CaseClause* clause) { 996 void BytecodeGenerator::VisitCaseClause(CaseClause* clause) {
1029 // Handled entirely in VisitSwitchStatement. 997 // Handled entirely in VisitSwitchStatement.
1030 UNREACHABLE(); 998 UNREACHABLE();
1031 } 999 }
1032 1000
1033 void BytecodeGenerator::VisitIterationBody(IterationStatement* stmt, 1001 void BytecodeGenerator::VisitIterationBody(IterationStatement* stmt,
1034 LoopBuilder* loop_builder) { 1002 LoopBuilder* loop_builder) {
1035 ControlScopeForIteration execution_control(this, stmt, loop_builder); 1003 ControlScopeForIteration execution_control(this, stmt, loop_builder);
1036 builder()->StackCheck(stmt->position()); 1004 builder()->StackCheck(stmt->position());
1037 Visit(stmt->body()); 1005 Visit(stmt->body());
(...skipping 28 matching lines...) Expand all
1066 if (!stmt->cond()->ToBooleanIsTrue()) { 1034 if (!stmt->cond()->ToBooleanIsTrue()) {
1067 builder()->SetExpressionAsStatementPosition(stmt->cond()); 1035 builder()->SetExpressionAsStatementPosition(stmt->cond());
1068 VisitForAccumulatorValue(stmt->cond()); 1036 VisitForAccumulatorValue(stmt->cond());
1069 loop_builder.BreakIfFalse(); 1037 loop_builder.BreakIfFalse();
1070 } 1038 }
1071 VisitIterationBody(stmt, &loop_builder); 1039 VisitIterationBody(stmt, &loop_builder);
1072 loop_builder.JumpToHeader(); 1040 loop_builder.JumpToHeader();
1073 loop_builder.EndLoop(); 1041 loop_builder.EndLoop();
1074 } 1042 }
1075 1043
1076
1077 void BytecodeGenerator::VisitForStatement(ForStatement* stmt) { 1044 void BytecodeGenerator::VisitForStatement(ForStatement* stmt) {
1078 if (stmt->init() != nullptr) { 1045 if (stmt->init() != nullptr) {
1079 Visit(stmt->init()); 1046 Visit(stmt->init());
1080 } 1047 }
1081 if (stmt->cond() && stmt->cond()->ToBooleanIsFalse()) { 1048 if (stmt->cond() && stmt->cond()->ToBooleanIsFalse()) {
1082 // If the condition is known to be false there is no need to generate 1049 // If the condition is known to be false there is no need to generate
1083 // body, next or condition blocks. Init block should be generated. 1050 // body, next or condition blocks. Init block should be generated.
1084 return; 1051 return;
1085 } 1052 }
1086 1053
1087 LoopBuilder loop_builder(builder()); 1054 LoopBuilder loop_builder(builder());
1088 VisitIterationHeader(stmt, &loop_builder); 1055 VisitIterationHeader(stmt, &loop_builder);
1089 if (stmt->cond() && !stmt->cond()->ToBooleanIsTrue()) { 1056 if (stmt->cond() && !stmt->cond()->ToBooleanIsTrue()) {
1090 builder()->SetExpressionAsStatementPosition(stmt->cond()); 1057 builder()->SetExpressionAsStatementPosition(stmt->cond());
1091 VisitForAccumulatorValue(stmt->cond()); 1058 VisitForAccumulatorValue(stmt->cond());
1092 loop_builder.BreakIfFalse(); 1059 loop_builder.BreakIfFalse();
1093 } 1060 }
1094 VisitIterationBody(stmt, &loop_builder); 1061 VisitIterationBody(stmt, &loop_builder);
1095 if (stmt->next() != nullptr) { 1062 if (stmt->next() != nullptr) {
1096 builder()->SetStatementPosition(stmt->next()); 1063 builder()->SetStatementPosition(stmt->next());
1097 Visit(stmt->next()); 1064 Visit(stmt->next());
1098 } 1065 }
1099 loop_builder.JumpToHeader(); 1066 loop_builder.JumpToHeader();
1100 loop_builder.EndLoop(); 1067 loop_builder.EndLoop();
1101 } 1068 }
1102 1069
1103
1104 void BytecodeGenerator::VisitForInAssignment(Expression* expr, 1070 void BytecodeGenerator::VisitForInAssignment(Expression* expr,
1105 FeedbackVectorSlot slot) { 1071 FeedbackVectorSlot slot) {
1106 DCHECK(expr->IsValidReferenceExpression()); 1072 DCHECK(expr->IsValidReferenceExpression());
1107 1073
1108 // Evaluate assignment starting with the value to be stored in the 1074 // Evaluate assignment starting with the value to be stored in the
1109 // accumulator. 1075 // accumulator.
1110 Property* property = expr->AsProperty(); 1076 Property* property = expr->AsProperty();
1111 LhsKind assign_type = Property::GetAssignType(property); 1077 LhsKind assign_type = Property::GetAssignType(property);
1112 switch (assign_type) { 1078 switch (assign_type) {
1113 case VARIABLE: { 1079 case VARIABLE: {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1167 property->obj()->AsSuperPropertyReference(); 1133 property->obj()->AsSuperPropertyReference();
1168 VisitForRegisterValue(super_property->this_var(), receiver); 1134 VisitForRegisterValue(super_property->this_var(), receiver);
1169 VisitForRegisterValue(super_property->home_object(), home_object); 1135 VisitForRegisterValue(super_property->home_object(), home_object);
1170 VisitForRegisterValue(property->key(), key); 1136 VisitForRegisterValue(property->key(), key);
1171 BuildKeyedSuperPropertyStore(receiver, home_object, key, value); 1137 BuildKeyedSuperPropertyStore(receiver, home_object, key, value);
1172 break; 1138 break;
1173 } 1139 }
1174 } 1140 }
1175 } 1141 }
1176 1142
1177
1178 void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) { 1143 void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) {
1179 if (stmt->subject()->IsNullLiteral() || 1144 if (stmt->subject()->IsNullLiteral() ||
1180 stmt->subject()->IsUndefinedLiteral()) { 1145 stmt->subject()->IsUndefinedLiteral()) {
1181 // ForIn generates lots of code, skip if it wouldn't produce any effects. 1146 // ForIn generates lots of code, skip if it wouldn't produce any effects.
1182 return; 1147 return;
1183 } 1148 }
1184 1149
1185 LoopBuilder loop_builder(builder()); 1150 LoopBuilder loop_builder(builder());
1186 BytecodeLabel subject_null_label, subject_undefined_label; 1151 BytecodeLabel subject_null_label, subject_undefined_label;
1187 1152
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1219 VisitForInAssignment(stmt->each(), stmt->EachFeedbackSlot()); 1184 VisitForInAssignment(stmt->each(), stmt->EachFeedbackSlot());
1220 VisitIterationBody(stmt, &loop_builder); 1185 VisitIterationBody(stmt, &loop_builder);
1221 builder()->ForInStep(index); 1186 builder()->ForInStep(index);
1222 builder()->StoreAccumulatorInRegister(index); 1187 builder()->StoreAccumulatorInRegister(index);
1223 loop_builder.JumpToHeader(); 1188 loop_builder.JumpToHeader();
1224 loop_builder.EndLoop(); 1189 loop_builder.EndLoop();
1225 builder()->Bind(&subject_null_label); 1190 builder()->Bind(&subject_null_label);
1226 builder()->Bind(&subject_undefined_label); 1191 builder()->Bind(&subject_undefined_label);
1227 } 1192 }
1228 1193
1229
1230 void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) { 1194 void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
1231 LoopBuilder loop_builder(builder()); 1195 LoopBuilder loop_builder(builder());
1232 ControlScopeForIteration control_scope(this, stmt, &loop_builder); 1196 ControlScopeForIteration control_scope(this, stmt, &loop_builder);
1233 1197
1234 builder()->SetExpressionAsStatementPosition(stmt->assign_iterator()); 1198 builder()->SetExpressionAsStatementPosition(stmt->assign_iterator());
1235 VisitForEffect(stmt->assign_iterator()); 1199 VisitForEffect(stmt->assign_iterator());
1236 1200
1237 VisitIterationHeader(stmt, &loop_builder); 1201 VisitIterationHeader(stmt, &loop_builder);
1238 builder()->SetExpressionAsStatementPosition(stmt->next_result()); 1202 builder()->SetExpressionAsStatementPosition(stmt->next_result());
1239 VisitForEffect(stmt->next_result()); 1203 VisitForEffect(stmt->next_result());
1240 VisitForAccumulatorValue(stmt->result_done()); 1204 VisitForAccumulatorValue(stmt->result_done());
1241 loop_builder.BreakIfTrue(); 1205 loop_builder.BreakIfTrue();
1242 1206
1243 VisitForEffect(stmt->assign_each()); 1207 VisitForEffect(stmt->assign_each());
1244 VisitIterationBody(stmt, &loop_builder); 1208 VisitIterationBody(stmt, &loop_builder);
1245 loop_builder.JumpToHeader(); 1209 loop_builder.JumpToHeader();
1246 loop_builder.EndLoop(); 1210 loop_builder.EndLoop();
1247 } 1211 }
1248 1212
1249
1250 void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { 1213 void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
1251 TryCatchBuilder try_control_builder(builder()); 1214 TryCatchBuilder try_control_builder(builder());
1252 Register no_reg; 1215 Register no_reg;
1253 1216
1254 // Preserve the context in a dedicated register, so that it can be restored 1217 // Preserve the context in a dedicated register, so that it can be restored
1255 // when the handler is entered by the stack-unwinding machinery. 1218 // when the handler is entered by the stack-unwinding machinery.
1256 // TODO(mstarzinger): Be smarter about register allocation. 1219 // TODO(mstarzinger): Be smarter about register allocation.
1257 Register context = register_allocator()->NewRegister(); 1220 Register context = register_allocator()->NewRegister();
1258 builder()->MoveRegister(Register::current_context(), context); 1221 builder()->MoveRegister(Register::current_context(), context);
1259 1222
(...skipping 16 matching lines...) Expand all
1276 } 1239 }
1277 1240
1278 // Load the catch context into the accumulator. 1241 // Load the catch context into the accumulator.
1279 builder()->LoadAccumulatorWithRegister(context); 1242 builder()->LoadAccumulatorWithRegister(context);
1280 1243
1281 // Evaluate the catch-block. 1244 // Evaluate the catch-block.
1282 VisitInScope(stmt->catch_block(), stmt->scope()); 1245 VisitInScope(stmt->catch_block(), stmt->scope());
1283 try_control_builder.EndCatch(); 1246 try_control_builder.EndCatch();
1284 } 1247 }
1285 1248
1286
1287 void BytecodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) { 1249 void BytecodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
1288 TryFinallyBuilder try_control_builder(builder(), IsInsideTryCatch()); 1250 TryFinallyBuilder try_control_builder(builder(), IsInsideTryCatch());
1289 Register no_reg; 1251 Register no_reg;
1290 1252
1291 // We keep a record of all paths that enter the finally-block to be able to 1253 // We keep a record of all paths that enter the finally-block to be able to
1292 // dispatch to the correct continuation point after the statements in the 1254 // dispatch to the correct continuation point after the statements in the
1293 // finally-block have been evaluated. 1255 // finally-block have been evaluated.
1294 // 1256 //
1295 // The try-finally construct can enter the finally-block in three ways: 1257 // The try-finally construct can enter the finally-block in three ways:
1296 // 1. By exiting the try-block normally, falling through at the end. 1258 // 1. By exiting the try-block normally, falling through at the end.
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1341 Visit(stmt->finally_block()); 1303 Visit(stmt->finally_block());
1342 try_control_builder.EndFinally(); 1304 try_control_builder.EndFinally();
1343 1305
1344 // Pending message object is restored on exit. 1306 // Pending message object is restored on exit.
1345 builder()->CallRuntime(Runtime::kInterpreterSetPendingMessage, message, 1); 1307 builder()->CallRuntime(Runtime::kInterpreterSetPendingMessage, message, 1);
1346 1308
1347 // Dynamic dispatch after the finally-block. 1309 // Dynamic dispatch after the finally-block.
1348 commands.ApplyDeferredCommands(); 1310 commands.ApplyDeferredCommands();
1349 } 1311 }
1350 1312
1351
1352 void BytecodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) { 1313 void BytecodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) {
1353 builder()->SetStatementPosition(stmt); 1314 builder()->SetStatementPosition(stmt);
1354 builder()->Debugger(); 1315 builder()->Debugger();
1355 } 1316 }
1356 1317
1357
1358 void BytecodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) { 1318 void BytecodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
1359 // Find or build a shared function info. 1319 // Find or build a shared function info.
1360 Handle<SharedFunctionInfo> shared_info = 1320 Handle<SharedFunctionInfo> shared_info =
1361 Compiler::GetSharedFunctionInfo(expr, info()->script(), info()); 1321 Compiler::GetSharedFunctionInfo(expr, info()->script(), info());
1362 if (shared_info.is_null()) { 1322 if (shared_info.is_null()) {
1363 return SetStackOverflow(); 1323 return SetStackOverflow();
1364 } 1324 }
1365 builder()->CreateClosure(shared_info, 1325 builder()->CreateClosure(shared_info,
1366 expr->pretenure() ? TENURED : NOT_TENURED); 1326 expr->pretenure() ? TENURED : NOT_TENURED);
1367 execution_result()->SetResultInAccumulator(); 1327 execution_result()->SetResultInAccumulator();
1368 } 1328 }
1369 1329
1370
1371 void BytecodeGenerator::VisitClassLiteral(ClassLiteral* expr) { 1330 void BytecodeGenerator::VisitClassLiteral(ClassLiteral* expr) {
1372 if (expr->scope()->ContextLocalCount() > 0) { 1331 if (expr->scope()->ContextLocalCount() > 0) {
1373 VisitNewLocalBlockContext(expr->scope()); 1332 VisitNewLocalBlockContext(expr->scope());
1374 ContextScope scope(this, expr->scope()); 1333 ContextScope scope(this, expr->scope());
1375 VisitDeclarations(expr->scope()->declarations()); 1334 VisitDeclarations(expr->scope()->declarations());
1376 VisitClassLiteralContents(expr); 1335 VisitClassLiteralContents(expr);
1377 } else { 1336 } else {
1378 VisitDeclarations(expr->scope()->declarations()); 1337 VisitDeclarations(expr->scope()->declarations());
1379 VisitClassLiteralContents(expr); 1338 VisitClassLiteralContents(expr);
1380 } 1339 }
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
1518 1477
1519 void BytecodeGenerator::VisitNativeFunctionLiteral( 1478 void BytecodeGenerator::VisitNativeFunctionLiteral(
1520 NativeFunctionLiteral* expr) { 1479 NativeFunctionLiteral* expr) {
1521 // Find or build a shared function info for the native function template. 1480 // Find or build a shared function info for the native function template.
1522 Handle<SharedFunctionInfo> shared_info = 1481 Handle<SharedFunctionInfo> shared_info =
1523 Compiler::GetSharedFunctionInfoForNative(expr->extension(), expr->name()); 1482 Compiler::GetSharedFunctionInfoForNative(expr->extension(), expr->name());
1524 builder()->CreateClosure(shared_info, NOT_TENURED); 1483 builder()->CreateClosure(shared_info, NOT_TENURED);
1525 execution_result()->SetResultInAccumulator(); 1484 execution_result()->SetResultInAccumulator();
1526 } 1485 }
1527 1486
1528
1529 void BytecodeGenerator::VisitDoExpression(DoExpression* expr) { 1487 void BytecodeGenerator::VisitDoExpression(DoExpression* expr) {
1530 VisitBlock(expr->block()); 1488 VisitBlock(expr->block());
1531 VisitVariableProxy(expr->result()); 1489 VisitVariableProxy(expr->result());
1532 } 1490 }
1533 1491
1534
1535 void BytecodeGenerator::VisitConditional(Conditional* expr) { 1492 void BytecodeGenerator::VisitConditional(Conditional* expr) {
1536 // TODO(rmcilroy): Spot easy cases where there code would not need to 1493 // TODO(rmcilroy): Spot easy cases where there code would not need to
1537 // emit the then block or the else block, e.g. condition is 1494 // emit the then block or the else block, e.g. condition is
1538 // obviously true/1/false/0. 1495 // obviously true/1/false/0.
1539 1496
1540 BytecodeLabel else_label, end_label; 1497 BytecodeLabel else_label, end_label;
1541 1498
1542 VisitForAccumulatorValue(expr->condition()); 1499 VisitForAccumulatorValue(expr->condition());
1543 builder()->JumpIfFalse(&else_label); 1500 builder()->JumpIfFalse(&else_label);
1544 1501
1545 VisitForAccumulatorValue(expr->then_expression()); 1502 VisitForAccumulatorValue(expr->then_expression());
1546 builder()->Jump(&end_label); 1503 builder()->Jump(&end_label);
1547 1504
1548 builder()->Bind(&else_label); 1505 builder()->Bind(&else_label);
1549 VisitForAccumulatorValue(expr->else_expression()); 1506 VisitForAccumulatorValue(expr->else_expression());
1550 builder()->Bind(&end_label); 1507 builder()->Bind(&end_label);
1551 1508
1552 execution_result()->SetResultInAccumulator(); 1509 execution_result()->SetResultInAccumulator();
1553 } 1510 }
1554 1511
1555
1556 void BytecodeGenerator::VisitLiteral(Literal* expr) { 1512 void BytecodeGenerator::VisitLiteral(Literal* expr) {
1557 if (!execution_result()->IsEffect()) { 1513 if (!execution_result()->IsEffect()) {
1558 Handle<Object> value = expr->value(); 1514 Handle<Object> value = expr->value();
1559 if (value->IsSmi()) { 1515 if (value->IsSmi()) {
1560 builder()->LoadLiteral(Smi::cast(*value)); 1516 builder()->LoadLiteral(Smi::cast(*value));
1561 } else if (value->IsUndefined()) { 1517 } else if (value->IsUndefined()) {
1562 builder()->LoadUndefined(); 1518 builder()->LoadUndefined();
1563 } else if (value->IsTrue()) { 1519 } else if (value->IsTrue()) {
1564 builder()->LoadTrue(); 1520 builder()->LoadTrue();
1565 } else if (value->IsFalse()) { 1521 } else if (value->IsFalse()) {
1566 builder()->LoadFalse(); 1522 builder()->LoadFalse();
1567 } else if (value->IsNull()) { 1523 } else if (value->IsNull()) {
1568 builder()->LoadNull(); 1524 builder()->LoadNull();
1569 } else if (value->IsTheHole()) { 1525 } else if (value->IsTheHole()) {
1570 builder()->LoadTheHole(); 1526 builder()->LoadTheHole();
1571 } else { 1527 } else {
1572 builder()->LoadLiteral(value); 1528 builder()->LoadLiteral(value);
1573 } 1529 }
1574 execution_result()->SetResultInAccumulator(); 1530 execution_result()->SetResultInAccumulator();
1575 } 1531 }
1576 } 1532 }
1577 1533
1578
1579 void BytecodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 1534 void BytecodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
1580 // Materialize a regular expression literal. 1535 // Materialize a regular expression literal.
1581 builder()->CreateRegExpLiteral(expr->pattern(), expr->literal_index(), 1536 builder()->CreateRegExpLiteral(expr->pattern(), expr->literal_index(),
1582 expr->flags()); 1537 expr->flags());
1583 execution_result()->SetResultInAccumulator(); 1538 execution_result()->SetResultInAccumulator();
1584 } 1539 }
1585 1540
1586
1587 void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { 1541 void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
1588 // Copy the literal boilerplate. 1542 // Copy the literal boilerplate.
1589 int fast_clone_properties_count = 0; 1543 int fast_clone_properties_count = 0;
1590 if (FastCloneShallowObjectStub::IsSupported(expr)) { 1544 if (FastCloneShallowObjectStub::IsSupported(expr)) {
1591 STATIC_ASSERT( 1545 STATIC_ASSERT(
1592 FastCloneShallowObjectStub::kMaximumClonedProperties <= 1546 FastCloneShallowObjectStub::kMaximumClonedProperties <=
1593 1 << CreateObjectLiteralFlags::FastClonePropertiesCountBits::kShift); 1547 1 << CreateObjectLiteralFlags::FastClonePropertiesCountBits::kShift);
1594 fast_clone_properties_count = 1548 fast_clone_properties_count =
1595 FastCloneShallowObjectStub::PropertiesCount(expr->properties_count()); 1549 FastCloneShallowObjectStub::PropertiesCount(expr->properties_count());
1596 } 1550 }
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
1780 case ObjectLiteral::Property::SETTER: 1734 case ObjectLiteral::Property::SETTER:
1781 builder()->CallRuntime(Runtime::kDefineSetterPropertyUnchecked, 1735 builder()->CallRuntime(Runtime::kDefineSetterPropertyUnchecked,
1782 literal_argument, 4); 1736 literal_argument, 4);
1783 break; 1737 break;
1784 } 1738 }
1785 } 1739 }
1786 1740
1787 execution_result()->SetResultInRegister(literal); 1741 execution_result()->SetResultInRegister(literal);
1788 } 1742 }
1789 1743
1790
1791 void BytecodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { 1744 void BytecodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
1792 // Deep-copy the literal boilerplate. 1745 // Deep-copy the literal boilerplate.
1793 builder()->CreateArrayLiteral(expr->constant_elements(), 1746 builder()->CreateArrayLiteral(expr->constant_elements(),
1794 expr->literal_index(), 1747 expr->literal_index(),
1795 expr->ComputeFlags(true)); 1748 expr->ComputeFlags(true));
1796 Register index, literal; 1749 Register index, literal;
1797 1750
1798 // Evaluate all the non-constant subexpressions and store them into the 1751 // Evaluate all the non-constant subexpressions and store them into the
1799 // newly cloned array. 1752 // newly cloned array.
1800 bool literal_in_accumulator = true; 1753 bool literal_in_accumulator = true;
(...skipping 19 matching lines...) Expand all
1820 language_mode()); 1773 language_mode());
1821 } 1774 }
1822 1775
1823 if (!literal_in_accumulator) { 1776 if (!literal_in_accumulator) {
1824 // Restore literal array into accumulator. 1777 // Restore literal array into accumulator.
1825 builder()->LoadAccumulatorWithRegister(literal); 1778 builder()->LoadAccumulatorWithRegister(literal);
1826 } 1779 }
1827 execution_result()->SetResultInAccumulator(); 1780 execution_result()->SetResultInAccumulator();
1828 } 1781 }
1829 1782
1830
1831 void BytecodeGenerator::VisitVariableProxy(VariableProxy* proxy) { 1783 void BytecodeGenerator::VisitVariableProxy(VariableProxy* proxy) {
1832 builder()->SetExpressionPosition(proxy); 1784 builder()->SetExpressionPosition(proxy);
1833 VisitVariableLoad(proxy->var(), proxy->VariableFeedbackSlot()); 1785 VisitVariableLoad(proxy->var(), proxy->VariableFeedbackSlot());
1834 } 1786 }
1835 1787
1836 void BytecodeGenerator::BuildHoleCheckForVariableLoad(VariableMode mode, 1788 void BytecodeGenerator::BuildHoleCheckForVariableLoad(VariableMode mode,
1837 Handle<String> name) { 1789 Handle<String> name) {
1838 if (mode == LET || mode == CONST) { 1790 if (mode == LET || mode == CONST) {
1839 BuildThrowIfHole(name); 1791 BuildThrowIfHole(name);
1840 } 1792 }
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
2122 break; 2074 break;
2123 } 2075 }
2124 case VariableLocation::LOOKUP: { 2076 case VariableLocation::LOOKUP: {
2125 DCHECK_NE(CONST_LEGACY, variable->mode()); 2077 DCHECK_NE(CONST_LEGACY, variable->mode());
2126 builder()->StoreLookupSlot(variable->name(), language_mode()); 2078 builder()->StoreLookupSlot(variable->name(), language_mode());
2127 break; 2079 break;
2128 } 2080 }
2129 } 2081 }
2130 } 2082 }
2131 2083
2132
2133 void BytecodeGenerator::VisitAssignment(Assignment* expr) { 2084 void BytecodeGenerator::VisitAssignment(Assignment* expr) {
2134 DCHECK(expr->target()->IsValidReferenceExpressionOrThis()); 2085 DCHECK(expr->target()->IsValidReferenceExpressionOrThis());
2135 Register object, key, home_object, value; 2086 Register object, key, home_object, value;
2136 Handle<String> name; 2087 Handle<String> name;
2137 2088
2138 // Left-hand side can only be a property, a global or a variable slot. 2089 // Left-hand side can only be a property, a global or a variable slot.
2139 Property* property = expr->target()->AsProperty(); 2090 Property* property = expr->target()->AsProperty();
2140 LhsKind assign_type = Property::GetAssignType(property); 2091 LhsKind assign_type = Property::GetAssignType(property);
2141 2092
2142 // Evaluate LHS expression. 2093 // Evaluate LHS expression.
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
2350 VisitForAccumulatorValue(expr->exception()); 2301 VisitForAccumulatorValue(expr->exception());
2351 builder()->SetExpressionPosition(expr); 2302 builder()->SetExpressionPosition(expr);
2352 builder()->Throw(); 2303 builder()->Throw();
2353 // Throw statements are modeled as expressions instead of statements. These 2304 // Throw statements are modeled as expressions instead of statements. These
2354 // are converted from assignment statements in Rewriter::ReWrite pass. An 2305 // are converted from assignment statements in Rewriter::ReWrite pass. An
2355 // assignment statement expects a value in the accumulator. This is a hack to 2306 // assignment statement expects a value in the accumulator. This is a hack to
2356 // avoid DCHECK fails assert accumulator has been set. 2307 // avoid DCHECK fails assert accumulator has been set.
2357 execution_result()->SetResultInAccumulator(); 2308 execution_result()->SetResultInAccumulator();
2358 } 2309 }
2359 2310
2360
2361 void BytecodeGenerator::VisitPropertyLoad(Register obj, Property* expr) { 2311 void BytecodeGenerator::VisitPropertyLoad(Register obj, Property* expr) {
2362 LhsKind property_kind = Property::GetAssignType(expr); 2312 LhsKind property_kind = Property::GetAssignType(expr);
2363 FeedbackVectorSlot slot = expr->PropertyFeedbackSlot(); 2313 FeedbackVectorSlot slot = expr->PropertyFeedbackSlot();
2364 builder()->SetExpressionPosition(expr); 2314 builder()->SetExpressionPosition(expr);
2365 switch (property_kind) { 2315 switch (property_kind) {
2366 case VARIABLE: 2316 case VARIABLE:
2367 UNREACHABLE(); 2317 UNREACHABLE();
2368 case NAMED_PROPERTY: { 2318 case NAMED_PROPERTY: {
2369 builder()->LoadNamedProperty(obj, 2319 builder()->LoadNamedProperty(obj,
2370 expr->key()->AsLiteral()->AsPropertyName(), 2320 expr->key()->AsLiteral()->AsPropertyName(),
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
2644 2594
2645 builder()->SetExpressionPosition(expr); 2595 builder()->SetExpressionPosition(expr);
2646 // The accumulator holds new target which is the same as the 2596 // The accumulator holds new target which is the same as the
2647 // constructor for CallNew. 2597 // constructor for CallNew.
2648 builder() 2598 builder()
2649 ->LoadAccumulatorWithRegister(constructor) 2599 ->LoadAccumulatorWithRegister(constructor)
2650 .New(constructor, first_arg, args->length()); 2600 .New(constructor, first_arg, args->length());
2651 execution_result()->SetResultInAccumulator(); 2601 execution_result()->SetResultInAccumulator();
2652 } 2602 }
2653 2603
2654
2655 void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) { 2604 void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) {
2656 ZoneList<Expression*>* args = expr->arguments(); 2605 ZoneList<Expression*>* args = expr->arguments();
2657 if (expr->is_jsruntime()) { 2606 if (expr->is_jsruntime()) {
2658 // Allocate a register for the receiver and load it with undefined. 2607 // Allocate a register for the receiver and load it with undefined.
2659 register_allocator()->PrepareForConsecutiveAllocations(1 + args->length()); 2608 register_allocator()->PrepareForConsecutiveAllocations(1 + args->length());
2660 Register receiver = register_allocator()->NextConsecutiveRegister(); 2609 Register receiver = register_allocator()->NextConsecutiveRegister();
2661 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver); 2610 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver);
2662 Register first_arg = VisitArguments(args); 2611 Register first_arg = VisitArguments(args);
2663 CHECK(args->length() == 0 || first_arg.index() == receiver.index() + 1); 2612 CHECK(args->length() == 0 || first_arg.index() == receiver.index() + 1);
2664 builder()->CallJSRuntime(expr->context_index(), receiver, 2613 builder()->CallJSRuntime(expr->context_index(), receiver,
2665 1 + args->length()); 2614 1 + args->length());
2666 } else { 2615 } else {
2667 // Evaluate all arguments to the runtime call. 2616 // Evaluate all arguments to the runtime call.
2668 Register first_arg = VisitArguments(args); 2617 Register first_arg = VisitArguments(args);
2669 Runtime::FunctionId function_id = expr->function()->function_id; 2618 Runtime::FunctionId function_id = expr->function()->function_id;
2670 builder()->CallRuntime(function_id, first_arg, args->length()); 2619 builder()->CallRuntime(function_id, first_arg, args->length());
2671 } 2620 }
2672 execution_result()->SetResultInAccumulator(); 2621 execution_result()->SetResultInAccumulator();
2673 } 2622 }
2674 2623
2675
2676 void BytecodeGenerator::VisitVoid(UnaryOperation* expr) { 2624 void BytecodeGenerator::VisitVoid(UnaryOperation* expr) {
2677 VisitForEffect(expr->expression()); 2625 VisitForEffect(expr->expression());
2678 builder()->LoadUndefined(); 2626 builder()->LoadUndefined();
2679 execution_result()->SetResultInAccumulator(); 2627 execution_result()->SetResultInAccumulator();
2680 } 2628 }
2681 2629
2682
2683 void BytecodeGenerator::VisitTypeOf(UnaryOperation* expr) { 2630 void BytecodeGenerator::VisitTypeOf(UnaryOperation* expr) {
2684 if (expr->expression()->IsVariableProxy()) { 2631 if (expr->expression()->IsVariableProxy()) {
2685 // Typeof does not throw a reference error on global variables, hence we 2632 // Typeof does not throw a reference error on global variables, hence we
2686 // perform a non-contextual load in case the operand is a variable proxy. 2633 // perform a non-contextual load in case the operand is a variable proxy.
2687 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 2634 VariableProxy* proxy = expr->expression()->AsVariableProxy();
2688 VisitVariableLoadForAccumulatorValue( 2635 VisitVariableLoadForAccumulatorValue(
2689 proxy->var(), proxy->VariableFeedbackSlot(), INSIDE_TYPEOF); 2636 proxy->var(), proxy->VariableFeedbackSlot(), INSIDE_TYPEOF);
2690 } else { 2637 } else {
2691 VisitForAccumulatorValue(expr->expression()); 2638 VisitForAccumulatorValue(expr->expression());
2692 } 2639 }
2693 builder()->TypeOf(); 2640 builder()->TypeOf();
2694 execution_result()->SetResultInAccumulator(); 2641 execution_result()->SetResultInAccumulator();
2695 } 2642 }
2696 2643
2697
2698 void BytecodeGenerator::VisitNot(UnaryOperation* expr) { 2644 void BytecodeGenerator::VisitNot(UnaryOperation* expr) {
2699 VisitForAccumulatorValue(expr->expression()); 2645 VisitForAccumulatorValue(expr->expression());
2700 builder()->LogicalNot(); 2646 builder()->LogicalNot();
2701 execution_result()->SetResultInAccumulator(); 2647 execution_result()->SetResultInAccumulator();
2702 } 2648 }
2703 2649
2704
2705 void BytecodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 2650 void BytecodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
2706 switch (expr->op()) { 2651 switch (expr->op()) {
2707 case Token::Value::NOT: 2652 case Token::Value::NOT:
2708 VisitNot(expr); 2653 VisitNot(expr);
2709 break; 2654 break;
2710 case Token::Value::TYPEOF: 2655 case Token::Value::TYPEOF:
2711 VisitTypeOf(expr); 2656 VisitTypeOf(expr);
2712 break; 2657 break;
2713 case Token::Value::VOID: 2658 case Token::Value::VOID:
2714 VisitVoid(expr); 2659 VisitVoid(expr);
2715 break; 2660 break;
2716 case Token::Value::DELETE: 2661 case Token::Value::DELETE:
2717 VisitDelete(expr); 2662 VisitDelete(expr);
2718 break; 2663 break;
2719 case Token::Value::BIT_NOT: 2664 case Token::Value::BIT_NOT:
2720 case Token::Value::ADD: 2665 case Token::Value::ADD:
2721 case Token::Value::SUB: 2666 case Token::Value::SUB:
2722 // These operators are converted to an equivalent binary operators in 2667 // These operators are converted to an equivalent binary operators in
2723 // the parser. These operators are not expected to be visited here. 2668 // the parser. These operators are not expected to be visited here.
2724 UNREACHABLE(); 2669 UNREACHABLE();
2725 default: 2670 default:
2726 UNREACHABLE(); 2671 UNREACHABLE();
2727 } 2672 }
2728 } 2673 }
2729 2674
2730
2731 void BytecodeGenerator::VisitDelete(UnaryOperation* expr) { 2675 void BytecodeGenerator::VisitDelete(UnaryOperation* expr) {
2732 if (expr->expression()->IsProperty()) { 2676 if (expr->expression()->IsProperty()) {
2733 // Delete of an object property is allowed both in sloppy 2677 // Delete of an object property is allowed both in sloppy
2734 // and strict modes. 2678 // and strict modes.
2735 Property* property = expr->expression()->AsProperty(); 2679 Property* property = expr->expression()->AsProperty();
2736 Register object = VisitForRegisterValue(property->obj()); 2680 Register object = VisitForRegisterValue(property->obj());
2737 VisitForAccumulatorValue(property->key()); 2681 VisitForAccumulatorValue(property->key());
2738 builder()->Delete(object, language_mode()); 2682 builder()->Delete(object, language_mode());
2739 } else if (expr->expression()->IsVariableProxy()) { 2683 } else if (expr->expression()->IsVariableProxy()) {
2740 // Delete of an unqualified identifier is allowed in sloppy mode but is 2684 // Delete of an unqualified identifier is allowed in sloppy mode but is
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
2782 UNREACHABLE(); 2726 UNREACHABLE();
2783 } 2727 }
2784 } else { 2728 } else {
2785 // Delete of an unresolvable reference returns true. 2729 // Delete of an unresolvable reference returns true.
2786 VisitForEffect(expr->expression()); 2730 VisitForEffect(expr->expression());
2787 builder()->LoadTrue(); 2731 builder()->LoadTrue();
2788 } 2732 }
2789 execution_result()->SetResultInAccumulator(); 2733 execution_result()->SetResultInAccumulator();
2790 } 2734 }
2791 2735
2792
2793 void BytecodeGenerator::VisitCountOperation(CountOperation* expr) { 2736 void BytecodeGenerator::VisitCountOperation(CountOperation* expr) {
2794 DCHECK(expr->expression()->IsValidReferenceExpressionOrThis()); 2737 DCHECK(expr->expression()->IsValidReferenceExpressionOrThis());
2795 2738
2796 // Left-hand side can only be a property, a global or a variable slot. 2739 // Left-hand side can only be a property, a global or a variable slot.
2797 Property* property = expr->expression()->AsProperty(); 2740 Property* property = expr->expression()->AsProperty();
2798 LhsKind assign_type = Property::GetAssignType(property); 2741 LhsKind assign_type = Property::GetAssignType(property);
2799 2742
2800 // TODO(rmcilroy): Set is_postfix to false if visiting for effect. 2743 // TODO(rmcilroy): Set is_postfix to false if visiting for effect.
2801 bool is_postfix = expr->is_postfix(); 2744 bool is_postfix = expr->is_postfix();
2802 2745
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
2904 } 2847 }
2905 2848
2906 // Restore old value for postfix expressions. 2849 // Restore old value for postfix expressions.
2907 if (is_postfix) { 2850 if (is_postfix) {
2908 execution_result()->SetResultInRegister(old_value); 2851 execution_result()->SetResultInRegister(old_value);
2909 } else { 2852 } else {
2910 execution_result()->SetResultInAccumulator(); 2853 execution_result()->SetResultInAccumulator();
2911 } 2854 }
2912 } 2855 }
2913 2856
2914
2915 void BytecodeGenerator::VisitBinaryOperation(BinaryOperation* binop) { 2857 void BytecodeGenerator::VisitBinaryOperation(BinaryOperation* binop) {
2916 switch (binop->op()) { 2858 switch (binop->op()) {
2917 case Token::COMMA: 2859 case Token::COMMA:
2918 VisitCommaExpression(binop); 2860 VisitCommaExpression(binop);
2919 break; 2861 break;
2920 case Token::OR: 2862 case Token::OR:
2921 VisitLogicalOrExpression(binop); 2863 VisitLogicalOrExpression(binop);
2922 break; 2864 break;
2923 case Token::AND: 2865 case Token::AND:
2924 VisitLogicalAndExpression(binop); 2866 VisitLogicalAndExpression(binop);
2925 break; 2867 break;
2926 default: 2868 default:
2927 VisitArithmeticExpression(binop); 2869 VisitArithmeticExpression(binop);
2928 break; 2870 break;
2929 } 2871 }
2930 } 2872 }
2931 2873
2932
2933 void BytecodeGenerator::VisitCompareOperation(CompareOperation* expr) { 2874 void BytecodeGenerator::VisitCompareOperation(CompareOperation* expr) {
2934 Register lhs = VisitForRegisterValue(expr->left()); 2875 Register lhs = VisitForRegisterValue(expr->left());
2935 VisitForAccumulatorValue(expr->right()); 2876 VisitForAccumulatorValue(expr->right());
2936 builder()->SetExpressionPosition(expr); 2877 builder()->SetExpressionPosition(expr);
2937 builder()->CompareOperation(expr->op(), lhs); 2878 builder()->CompareOperation(expr->op(), lhs);
2938 execution_result()->SetResultInAccumulator(); 2879 execution_result()->SetResultInAccumulator();
2939 } 2880 }
2940 2881
2941
2942 void BytecodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) { 2882 void BytecodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) {
2943 Register lhs = VisitForRegisterValue(expr->left()); 2883 Register lhs = VisitForRegisterValue(expr->left());
2944 VisitForAccumulatorValue(expr->right()); 2884 VisitForAccumulatorValue(expr->right());
2945 builder()->BinaryOperation(expr->op(), lhs); 2885 builder()->BinaryOperation(expr->op(), lhs);
2946 execution_result()->SetResultInAccumulator(); 2886 execution_result()->SetResultInAccumulator();
2947 } 2887 }
2948 2888
2949
2950 void BytecodeGenerator::VisitSpread(Spread* expr) { UNREACHABLE(); } 2889 void BytecodeGenerator::VisitSpread(Spread* expr) { UNREACHABLE(); }
2951 2890
2952
2953 void BytecodeGenerator::VisitEmptyParentheses(EmptyParentheses* expr) { 2891 void BytecodeGenerator::VisitEmptyParentheses(EmptyParentheses* expr) {
2954 UNREACHABLE(); 2892 UNREACHABLE();
2955 } 2893 }
2956 2894
2957
2958 void BytecodeGenerator::VisitThisFunction(ThisFunction* expr) { 2895 void BytecodeGenerator::VisitThisFunction(ThisFunction* expr) {
2959 execution_result()->SetResultInRegister(Register::function_closure()); 2896 execution_result()->SetResultInRegister(Register::function_closure());
2960 } 2897 }
2961 2898
2962
2963 void BytecodeGenerator::VisitSuperCallReference(SuperCallReference* expr) { 2899 void BytecodeGenerator::VisitSuperCallReference(SuperCallReference* expr) {
2964 // Handled by VisitCall(). 2900 // Handled by VisitCall().
2965 UNREACHABLE(); 2901 UNREACHABLE();
2966 } 2902 }
2967 2903
2968
2969 void BytecodeGenerator::VisitSuperPropertyReference( 2904 void BytecodeGenerator::VisitSuperPropertyReference(
2970 SuperPropertyReference* expr) { 2905 SuperPropertyReference* expr) {
2971 builder()->CallRuntime(Runtime::kThrowUnsupportedSuperError, Register(0), 0); 2906 builder()->CallRuntime(Runtime::kThrowUnsupportedSuperError, Register(0), 0);
2972 execution_result()->SetResultInAccumulator(); 2907 execution_result()->SetResultInAccumulator();
2973 } 2908 }
2974 2909
2975
2976 void BytecodeGenerator::VisitCommaExpression(BinaryOperation* binop) { 2910 void BytecodeGenerator::VisitCommaExpression(BinaryOperation* binop) {
2977 VisitForEffect(binop->left()); 2911 VisitForEffect(binop->left());
2978 Visit(binop->right()); 2912 Visit(binop->right());
2979 } 2913 }
2980 2914
2981
2982 void BytecodeGenerator::VisitLogicalOrExpression(BinaryOperation* binop) { 2915 void BytecodeGenerator::VisitLogicalOrExpression(BinaryOperation* binop) {
2983 Expression* left = binop->left(); 2916 Expression* left = binop->left();
2984 Expression* right = binop->right(); 2917 Expression* right = binop->right();
2985 2918
2986 // Short-circuit evaluation- If it is known that left is always true, 2919 // Short-circuit evaluation- If it is known that left is always true,
2987 // no need to visit right 2920 // no need to visit right
2988 if (left->ToBooleanIsTrue()) { 2921 if (left->ToBooleanIsTrue()) {
2989 VisitForAccumulatorValue(left); 2922 VisitForAccumulatorValue(left);
2990 } else { 2923 } else {
2991 BytecodeLabel end_label; 2924 BytecodeLabel end_label;
2992 VisitForAccumulatorValue(left); 2925 VisitForAccumulatorValue(left);
2993 builder()->JumpIfTrue(&end_label); 2926 builder()->JumpIfTrue(&end_label);
2994 VisitForAccumulatorValue(right); 2927 VisitForAccumulatorValue(right);
2995 builder()->Bind(&end_label); 2928 builder()->Bind(&end_label);
2996 } 2929 }
2997 execution_result()->SetResultInAccumulator(); 2930 execution_result()->SetResultInAccumulator();
2998 } 2931 }
2999 2932
3000
3001 void BytecodeGenerator::VisitLogicalAndExpression(BinaryOperation* binop) { 2933 void BytecodeGenerator::VisitLogicalAndExpression(BinaryOperation* binop) {
3002 Expression* left = binop->left(); 2934 Expression* left = binop->left();
3003 Expression* right = binop->right(); 2935 Expression* right = binop->right();
3004 2936
3005 // Short-circuit evaluation- If it is known that left is always false, 2937 // Short-circuit evaluation- If it is known that left is always false,
3006 // no need to visit right 2938 // no need to visit right
3007 if (left->ToBooleanIsFalse()) { 2939 if (left->ToBooleanIsFalse()) {
3008 VisitForAccumulatorValue(left); 2940 VisitForAccumulatorValue(left);
3009 } else { 2941 } else {
3010 BytecodeLabel end_label; 2942 BytecodeLabel end_label;
3011 VisitForAccumulatorValue(left); 2943 VisitForAccumulatorValue(left);
3012 builder()->JumpIfFalse(&end_label); 2944 builder()->JumpIfFalse(&end_label);
3013 VisitForAccumulatorValue(right); 2945 VisitForAccumulatorValue(right);
3014 builder()->Bind(&end_label); 2946 builder()->Bind(&end_label);
3015 } 2947 }
3016 execution_result()->SetResultInAccumulator(); 2948 execution_result()->SetResultInAccumulator();
3017 } 2949 }
3018 2950
3019
3020 void BytecodeGenerator::VisitRewritableExpression(RewritableExpression* expr) { 2951 void BytecodeGenerator::VisitRewritableExpression(RewritableExpression* expr) {
3021 Visit(expr->expression()); 2952 Visit(expr->expression());
3022 } 2953 }
3023 2954
3024
3025 void BytecodeGenerator::VisitNewLocalFunctionContext() { 2955 void BytecodeGenerator::VisitNewLocalFunctionContext() {
3026 AccumulatorResultScope accumulator_execution_result(this); 2956 AccumulatorResultScope accumulator_execution_result(this);
3027 Scope* scope = this->scope(); 2957 Scope* scope = this->scope();
3028 2958
3029 // Allocate a new local context. 2959 // Allocate a new local context.
3030 if (scope->is_script_scope()) { 2960 if (scope->is_script_scope()) {
3031 RegisterAllocationScope register_scope(this); 2961 RegisterAllocationScope register_scope(this);
3032 Register closure = register_allocator()->NewRegister(); 2962 Register closure = register_allocator()->NewRegister();
3033 Register scope_info = register_allocator()->NewRegister(); 2963 Register scope_info = register_allocator()->NewRegister();
3034 DCHECK(Register::AreContiguous(closure, scope_info)); 2964 DCHECK(Register::AreContiguous(closure, scope_info));
3035 builder() 2965 builder()
3036 ->LoadAccumulatorWithRegister(Register::function_closure()) 2966 ->LoadAccumulatorWithRegister(Register::function_closure())
3037 .StoreAccumulatorInRegister(closure) 2967 .StoreAccumulatorInRegister(closure)
3038 .LoadLiteral(scope->GetScopeInfo(isolate())) 2968 .LoadLiteral(scope->GetScopeInfo(isolate()))
3039 .StoreAccumulatorInRegister(scope_info) 2969 .StoreAccumulatorInRegister(scope_info)
3040 .CallRuntime(Runtime::kNewScriptContext, closure, 2); 2970 .CallRuntime(Runtime::kNewScriptContext, closure, 2);
3041 } else { 2971 } else {
3042 builder()->CallRuntime(Runtime::kNewFunctionContext, 2972 builder()->CallRuntime(Runtime::kNewFunctionContext,
3043 Register::function_closure(), 1); 2973 Register::function_closure(), 1);
3044 } 2974 }
3045 execution_result()->SetResultInAccumulator(); 2975 execution_result()->SetResultInAccumulator();
3046 } 2976 }
3047 2977
3048
3049 void BytecodeGenerator::VisitBuildLocalActivationContext() { 2978 void BytecodeGenerator::VisitBuildLocalActivationContext() {
3050 Scope* scope = this->scope(); 2979 Scope* scope = this->scope();
3051 2980
3052 if (scope->has_this_declaration() && scope->receiver()->IsContextSlot()) { 2981 if (scope->has_this_declaration() && scope->receiver()->IsContextSlot()) {
3053 Variable* variable = scope->receiver(); 2982 Variable* variable = scope->receiver();
3054 Register receiver(builder()->Parameter(0)); 2983 Register receiver(builder()->Parameter(0));
3055 // Context variable (at bottom of the context chain). 2984 // Context variable (at bottom of the context chain).
3056 DCHECK_EQ(0, scope->ContextChainLength(variable->scope())); 2985 DCHECK_EQ(0, scope->ContextChainLength(variable->scope()));
3057 builder()->LoadAccumulatorWithRegister(receiver).StoreContextSlot( 2986 builder()->LoadAccumulatorWithRegister(receiver).StoreContextSlot(
3058 execution_context()->reg(), variable->index()); 2987 execution_context()->reg(), variable->index());
3059 } 2988 }
3060 2989
3061 // Copy parameters into context if necessary. 2990 // Copy parameters into context if necessary.
3062 int num_parameters = scope->num_parameters(); 2991 int num_parameters = scope->num_parameters();
3063 for (int i = 0; i < num_parameters; i++) { 2992 for (int i = 0; i < num_parameters; i++) {
3064 Variable* variable = scope->parameter(i); 2993 Variable* variable = scope->parameter(i);
3065 if (!variable->IsContextSlot()) continue; 2994 if (!variable->IsContextSlot()) continue;
3066 2995
3067 // The parameter indices are shifted by 1 (receiver is variable 2996 // The parameter indices are shifted by 1 (receiver is variable
3068 // index -1 but is parameter index 0 in BytecodeArrayBuilder). 2997 // index -1 but is parameter index 0 in BytecodeArrayBuilder).
3069 Register parameter(builder()->Parameter(i + 1)); 2998 Register parameter(builder()->Parameter(i + 1));
3070 // Context variable (at bottom of the context chain). 2999 // Context variable (at bottom of the context chain).
3071 DCHECK_EQ(0, scope->ContextChainLength(variable->scope())); 3000 DCHECK_EQ(0, scope->ContextChainLength(variable->scope()));
3072 builder()->LoadAccumulatorWithRegister(parameter) 3001 builder()->LoadAccumulatorWithRegister(parameter)
3073 .StoreContextSlot(execution_context()->reg(), variable->index()); 3002 .StoreContextSlot(execution_context()->reg(), variable->index());
3074 } 3003 }
3075 } 3004 }
3076 3005
3077
3078 void BytecodeGenerator::VisitNewLocalBlockContext(Scope* scope) { 3006 void BytecodeGenerator::VisitNewLocalBlockContext(Scope* scope) {
3079 AccumulatorResultScope accumulator_execution_result(this); 3007 AccumulatorResultScope accumulator_execution_result(this);
3080 DCHECK(scope->is_block_scope()); 3008 DCHECK(scope->is_block_scope());
3081 3009
3082 // Allocate a new local block context. 3010 // Allocate a new local block context.
3083 register_allocator()->PrepareForConsecutiveAllocations(2); 3011 register_allocator()->PrepareForConsecutiveAllocations(2);
3084 Register scope_info = register_allocator()->NextConsecutiveRegister(); 3012 Register scope_info = register_allocator()->NextConsecutiveRegister();
3085 Register closure = register_allocator()->NextConsecutiveRegister(); 3013 Register closure = register_allocator()->NextConsecutiveRegister();
3086 3014
3087 builder() 3015 builder()
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
3121 builder() 3049 builder()
3122 ->StoreAccumulatorInRegister(exception) 3050 ->StoreAccumulatorInRegister(exception)
3123 .LoadLiteral(variable->name()) 3051 .LoadLiteral(variable->name())
3124 .StoreAccumulatorInRegister(name); 3052 .StoreAccumulatorInRegister(name);
3125 VisitFunctionClosureForContext(); 3053 VisitFunctionClosureForContext();
3126 builder()->StoreAccumulatorInRegister(closure).CallRuntime( 3054 builder()->StoreAccumulatorInRegister(closure).CallRuntime(
3127 Runtime::kPushCatchContext, name, 3); 3055 Runtime::kPushCatchContext, name, 3);
3128 execution_result()->SetResultInAccumulator(); 3056 execution_result()->SetResultInAccumulator();
3129 } 3057 }
3130 3058
3131
3132 void BytecodeGenerator::VisitObjectLiteralAccessor( 3059 void BytecodeGenerator::VisitObjectLiteralAccessor(
3133 Register home_object, ObjectLiteralProperty* property, Register value_out) { 3060 Register home_object, ObjectLiteralProperty* property, Register value_out) {
3134 // TODO(rmcilroy): Replace value_out with VisitForRegister(); 3061 // TODO(rmcilroy): Replace value_out with VisitForRegister();
3135 if (property == nullptr) { 3062 if (property == nullptr) {
3136 builder()->LoadNull().StoreAccumulatorInRegister(value_out); 3063 builder()->LoadNull().StoreAccumulatorInRegister(value_out);
3137 } else { 3064 } else {
3138 VisitForAccumulatorValue(property->value()); 3065 VisitForAccumulatorValue(property->value());
3139 builder()->StoreAccumulatorInRegister(value_out); 3066 builder()->StoreAccumulatorInRegister(value_out);
3140 VisitSetHomeObject(value_out, home_object, property); 3067 VisitSetHomeObject(value_out, home_object, property);
3141 } 3068 }
3142 } 3069 }
3143 3070
3144 void BytecodeGenerator::VisitSetHomeObject(Register value, Register home_object, 3071 void BytecodeGenerator::VisitSetHomeObject(Register value, Register home_object,
3145 ObjectLiteralProperty* property, 3072 ObjectLiteralProperty* property,
3146 int slot_number) { 3073 int slot_number) {
3147 Expression* expr = property->value(); 3074 Expression* expr = property->value();
3148 if (FunctionLiteral::NeedsHomeObject(expr)) { 3075 if (FunctionLiteral::NeedsHomeObject(expr)) {
3149 Handle<Name> name = isolate()->factory()->home_object_symbol(); 3076 Handle<Name> name = isolate()->factory()->home_object_symbol();
3150 FeedbackVectorSlot slot = property->GetSlot(slot_number); 3077 FeedbackVectorSlot slot = property->GetSlot(slot_number);
3151 builder() 3078 builder()
3152 ->LoadAccumulatorWithRegister(home_object) 3079 ->LoadAccumulatorWithRegister(home_object)
3153 .StoreNamedProperty(value, name, feedback_index(slot), language_mode()); 3080 .StoreNamedProperty(value, name, feedback_index(slot), language_mode());
3154 } 3081 }
3155 } 3082 }
3156 3083
3157
3158 void BytecodeGenerator::VisitArgumentsObject(Variable* variable) { 3084 void BytecodeGenerator::VisitArgumentsObject(Variable* variable) {
3159 if (variable == nullptr) return; 3085 if (variable == nullptr) return;
3160 3086
3161 DCHECK(variable->IsContextSlot() || variable->IsStackAllocated()); 3087 DCHECK(variable->IsContextSlot() || variable->IsStackAllocated());
3162 3088
3163 // Allocate and initialize a new arguments object and assign to the 3089 // Allocate and initialize a new arguments object and assign to the
3164 // {arguments} variable. 3090 // {arguments} variable.
3165 CreateArgumentsType type = 3091 CreateArgumentsType type =
3166 is_strict(language_mode()) || !info()->has_simple_parameters() 3092 is_strict(language_mode()) || !info()->has_simple_parameters()
3167 ? CreateArgumentsType::kUnmappedArguments 3093 ? CreateArgumentsType::kUnmappedArguments
(...skipping 14 matching lines...) Expand all
3182 } 3108 }
3183 3109
3184 void BytecodeGenerator::VisitThisFunctionVariable(Variable* variable) { 3110 void BytecodeGenerator::VisitThisFunctionVariable(Variable* variable) {
3185 if (variable == nullptr) return; 3111 if (variable == nullptr) return;
3186 3112
3187 // Store the closure we were called with in the given variable. 3113 // Store the closure we were called with in the given variable.
3188 builder()->LoadAccumulatorWithRegister(Register::function_closure()); 3114 builder()->LoadAccumulatorWithRegister(Register::function_closure());
3189 VisitVariableAssignment(variable, Token::INIT, FeedbackVectorSlot::Invalid()); 3115 VisitVariableAssignment(variable, Token::INIT, FeedbackVectorSlot::Invalid());
3190 } 3116 }
3191 3117
3192
3193 void BytecodeGenerator::VisitNewTargetVariable(Variable* variable) { 3118 void BytecodeGenerator::VisitNewTargetVariable(Variable* variable) {
3194 if (variable == nullptr) return; 3119 if (variable == nullptr) return;
3195 3120
3196 // Store the new target we were called with in the given variable. 3121 // Store the new target we were called with in the given variable.
3197 builder()->LoadAccumulatorWithRegister(Register::new_target()); 3122 builder()->LoadAccumulatorWithRegister(Register::new_target());
3198 VisitVariableAssignment(variable, Token::INIT, FeedbackVectorSlot::Invalid()); 3123 VisitVariableAssignment(variable, Token::INIT, FeedbackVectorSlot::Invalid());
3199 } 3124 }
3200 3125
3201
3202 void BytecodeGenerator::VisitFunctionClosureForContext() { 3126 void BytecodeGenerator::VisitFunctionClosureForContext() {
3203 AccumulatorResultScope accumulator_execution_result(this); 3127 AccumulatorResultScope accumulator_execution_result(this);
3204 Scope* closure_scope = execution_context()->scope()->ClosureScope(); 3128 Scope* closure_scope = execution_context()->scope()->ClosureScope();
3205 if (closure_scope->is_script_scope() || 3129 if (closure_scope->is_script_scope() ||
3206 closure_scope->is_module_scope()) { 3130 closure_scope->is_module_scope()) {
3207 // Contexts nested in the native context have a canonical empty function as 3131 // Contexts nested in the native context have a canonical empty function as
3208 // their closure, not the anonymous closure containing the global code. 3132 // their closure, not the anonymous closure containing the global code.
3209 Register native_context = register_allocator()->NewRegister(); 3133 Register native_context = register_allocator()->NewRegister();
3210 builder() 3134 builder()
3211 ->LoadContextSlot(execution_context()->reg(), 3135 ->LoadContextSlot(execution_context()->reg(),
3212 Context::NATIVE_CONTEXT_INDEX) 3136 Context::NATIVE_CONTEXT_INDEX)
3213 .StoreAccumulatorInRegister(native_context) 3137 .StoreAccumulatorInRegister(native_context)
3214 .LoadContextSlot(native_context, Context::CLOSURE_INDEX); 3138 .LoadContextSlot(native_context, Context::CLOSURE_INDEX);
3215 } else if (closure_scope->is_eval_scope()) { 3139 } else if (closure_scope->is_eval_scope()) {
3216 // Contexts created by a call to eval have the same closure as the 3140 // Contexts created by a call to eval have the same closure as the
3217 // context calling eval, not the anonymous closure containing the eval 3141 // context calling eval, not the anonymous closure containing the eval
3218 // code. Fetch it from the context. 3142 // code. Fetch it from the context.
3219 builder()->LoadContextSlot(execution_context()->reg(), 3143 builder()->LoadContextSlot(execution_context()->reg(),
3220 Context::CLOSURE_INDEX); 3144 Context::CLOSURE_INDEX);
3221 } else { 3145 } else {
3222 DCHECK(closure_scope->is_function_scope()); 3146 DCHECK(closure_scope->is_function_scope());
3223 builder()->LoadAccumulatorWithRegister(Register::function_closure()); 3147 builder()->LoadAccumulatorWithRegister(Register::function_closure());
3224 } 3148 }
3225 execution_result()->SetResultInAccumulator(); 3149 execution_result()->SetResultInAccumulator();
3226 } 3150 }
3227 3151
3228
3229 // Visits the expression |expr| and places the result in the accumulator. 3152 // Visits the expression |expr| and places the result in the accumulator.
3230 void BytecodeGenerator::VisitForAccumulatorValue(Expression* expr) { 3153 void BytecodeGenerator::VisitForAccumulatorValue(Expression* expr) {
3231 AccumulatorResultScope accumulator_scope(this); 3154 AccumulatorResultScope accumulator_scope(this);
3232 Visit(expr); 3155 Visit(expr);
3233 } 3156 }
3234 3157
3235 void BytecodeGenerator::VisitForAccumulatorValueOrTheHole(Expression* expr) { 3158 void BytecodeGenerator::VisitForAccumulatorValueOrTheHole(Expression* expr) {
3236 if (expr == nullptr) { 3159 if (expr == nullptr) {
3237 builder()->LoadTheHole(); 3160 builder()->LoadTheHole();
3238 } else { 3161 } else {
3239 VisitForAccumulatorValue(expr); 3162 VisitForAccumulatorValue(expr);
3240 } 3163 }
3241 } 3164 }
3242 3165
3243 // Visits the expression |expr| and discards the result. 3166 // Visits the expression |expr| and discards the result.
3244 void BytecodeGenerator::VisitForEffect(Expression* expr) { 3167 void BytecodeGenerator::VisitForEffect(Expression* expr) {
3245 EffectResultScope effect_scope(this); 3168 EffectResultScope effect_scope(this);
3246 Visit(expr); 3169 Visit(expr);
3247 } 3170 }
3248 3171
3249
3250 // Visits the expression |expr| and returns the register containing 3172 // Visits the expression |expr| and returns the register containing
3251 // the expression result. 3173 // the expression result.
3252 Register BytecodeGenerator::VisitForRegisterValue(Expression* expr) { 3174 Register BytecodeGenerator::VisitForRegisterValue(Expression* expr) {
3253 RegisterResultScope register_scope(this); 3175 RegisterResultScope register_scope(this);
3254 Visit(expr); 3176 Visit(expr);
3255 return register_scope.ResultRegister(); 3177 return register_scope.ResultRegister();
3256 } 3178 }
3257 3179
3258 // Visits the expression |expr| and stores the expression result in 3180 // Visits the expression |expr| and stores the expression result in
3259 // |destination|. 3181 // |destination|.
3260 void BytecodeGenerator::VisitForRegisterValue(Expression* expr, 3182 void BytecodeGenerator::VisitForRegisterValue(Expression* expr,
3261 Register destination) { 3183 Register destination) {
3262 AccumulatorResultScope register_scope(this); 3184 AccumulatorResultScope register_scope(this);
3263 Visit(expr); 3185 Visit(expr);
3264 builder()->StoreAccumulatorInRegister(destination); 3186 builder()->StoreAccumulatorInRegister(destination);
3265 } 3187 }
3266 3188
3267 void BytecodeGenerator::VisitInScope(Statement* stmt, Scope* scope) { 3189 void BytecodeGenerator::VisitInScope(Statement* stmt, Scope* scope) {
3268 ContextScope context_scope(this, scope); 3190 ContextScope context_scope(this, scope);
3269 DCHECK(scope->declarations()->is_empty()); 3191 DCHECK(scope->declarations()->is_empty());
3270 Visit(stmt); 3192 Visit(stmt);
3271 } 3193 }
3272 3194
3273
3274 LanguageMode BytecodeGenerator::language_mode() const { 3195 LanguageMode BytecodeGenerator::language_mode() const {
3275 return execution_context()->scope()->language_mode(); 3196 return execution_context()->scope()->language_mode();
3276 } 3197 }
3277 3198
3278
3279 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { 3199 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const {
3280 return TypeFeedbackVector::GetIndex(slot); 3200 return TypeFeedbackVector::GetIndex(slot);
3281 } 3201 }
3282 3202
3283 } // namespace interpreter 3203 } // namespace interpreter
3284 } // namespace internal 3204 } // namespace internal
3285 } // namespace v8 3205 } // namespace v8
OLDNEW
« no previous file with comments | « src/interpreter/bytecode-generator.h ('k') | src/interpreter/bytecode-label.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698