OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |