OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 777 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
788 } | 788 } |
789 } | 789 } |
790 | 790 |
791 | 791 |
792 void FullCodeGenerator::VisitBlock(Block* stmt) { | 792 void FullCodeGenerator::VisitBlock(Block* stmt) { |
793 Comment cmnt(masm_, "[ Block"); | 793 Comment cmnt(masm_, "[ Block"); |
794 NestedBlock nested_block(this, stmt); | 794 NestedBlock nested_block(this, stmt); |
795 SetStatementPosition(stmt); | 795 SetStatementPosition(stmt); |
796 | 796 |
797 Scope* saved_scope = scope(); | 797 Scope* saved_scope = scope(); |
798 // Push a block context when entering a block with block scoped variables. | |
799 if (stmt->block_scope() != NULL) { | 798 if (stmt->block_scope() != NULL) { |
800 { Comment cmnt(masm_, "[ Extend block context"); | 799 scope_ = stmt->block_scope(); |
801 scope_ = stmt->block_scope(); | 800 int num_stack_slots = scope_->num_stack_slots(); |
| 801 |
| 802 // Allocate stack locals. |
| 803 if (num_stack_slots > 0) { |
| 804 Comment cmnt(masm_, "[ Allocate block stack locals"); |
| 805 if (num_stack_slots == 1) { |
| 806 __ Push(isolate()->factory()->the_hole_value()); |
| 807 } else { |
| 808 __ Move(result_register(), isolate()->factory()->the_hole_value()); |
| 809 for (int i = 0; i < num_stack_slots; i++) { |
| 810 __ push(result_register()); |
| 811 } |
| 812 } |
| 813 } |
| 814 |
| 815 // Allocate context locals. |
| 816 if (scope_->num_heap_slots() > 0) { |
| 817 Comment cmnt(masm_, "[ Extend block context"); |
802 Handle<ScopeInfo> scope_info = scope_->GetScopeInfo(); | 818 Handle<ScopeInfo> scope_info = scope_->GetScopeInfo(); |
803 int heap_slots = scope_info->ContextLength() - Context::MIN_CONTEXT_SLOTS; | 819 int heap_slots = |
| 820 scope_info->ContextLength() - Context::MIN_CONTEXT_SLOTS; |
804 __ Push(scope_info); | 821 __ Push(scope_info); |
805 PushFunctionArgumentForContextAllocation(); | 822 PushFunctionArgumentForContextAllocation(); |
806 if (heap_slots <= FastNewBlockContextStub::kMaximumSlots) { | 823 if (heap_slots <= FastNewBlockContextStub::kMaximumSlots) { |
807 FastNewBlockContextStub stub(heap_slots); | 824 FastNewBlockContextStub stub(heap_slots); |
808 __ CallStub(&stub); | 825 __ CallStub(&stub); |
809 } else { | 826 } else { |
810 __ CallRuntime(Runtime::kPushBlockContext, 2); | 827 __ CallRuntime(Runtime::kPushBlockContext, 2); |
811 } | 828 } |
812 | 829 |
813 // Replace the context stored in the frame. | 830 // Replace the context stored in the frame. |
814 StoreToFrameField(StandardFrameConstants::kContextOffset, | 831 StoreToFrameField(StandardFrameConstants::kContextOffset, |
815 context_register()); | 832 context_register()); |
816 } | 833 } |
817 { Comment cmnt(masm_, "[ Declarations"); | 834 { Comment cmnt(masm_, "[ Declarations"); |
818 VisitDeclarations(scope_->declarations()); | 835 VisitDeclarations(scope_->declarations()); |
819 } | 836 } |
820 } | 837 } |
821 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); | 838 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); |
822 VisitStatements(stmt->statements()); | 839 VisitStatements(stmt->statements()); |
823 scope_ = saved_scope; | 840 scope_ = saved_scope; |
824 __ bind(nested_block.break_label()); | 841 __ bind(nested_block.break_label()); |
825 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); | 842 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); |
826 | 843 |
827 // Pop block context if necessary. | |
828 if (stmt->block_scope() != NULL) { | 844 if (stmt->block_scope() != NULL) { |
829 LoadContextField(context_register(), Context::PREVIOUS_INDEX); | 845 Scope* scope = stmt->block_scope(); |
830 // Update local stack frame context field. | 846 int num_stack_slots = scope->num_stack_slots(); |
831 StoreToFrameField(StandardFrameConstants::kContextOffset, | 847 |
832 context_register()); | 848 // Pop block context if necessary. |
| 849 if (scope->num_heap_slots() > 0) { |
| 850 LoadContextField(context_register(), Context::PREVIOUS_INDEX); |
| 851 // Update local stack frame context field. |
| 852 StoreToFrameField(StandardFrameConstants::kContextOffset, |
| 853 context_register()); |
| 854 } |
| 855 |
| 856 // Deallocate stack locals. |
| 857 if (num_stack_slots > 0) { |
| 858 __ Drop(num_stack_slots); |
| 859 } |
833 } | 860 } |
834 } | 861 } |
835 | 862 |
836 | 863 |
837 void FullCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { | 864 void FullCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { |
838 Comment cmnt(masm_, "[ ExpressionStatement"); | 865 Comment cmnt(masm_, "[ ExpressionStatement"); |
839 SetStatementPosition(stmt); | 866 SetStatementPosition(stmt); |
840 VisitForEffect(stmt->expression()); | 867 VisitForEffect(stmt->expression()); |
841 } | 868 } |
842 | 869 |
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1264 | 1291 |
1265 | 1292 |
1266 void FullCodeGenerator::VisitThrow(Throw* expr) { | 1293 void FullCodeGenerator::VisitThrow(Throw* expr) { |
1267 Comment cmnt(masm_, "[ Throw"); | 1294 Comment cmnt(masm_, "[ Throw"); |
1268 VisitForStackValue(expr->exception()); | 1295 VisitForStackValue(expr->exception()); |
1269 __ CallRuntime(Runtime::kThrow, 1); | 1296 __ CallRuntime(Runtime::kThrow, 1); |
1270 // Never returns here. | 1297 // Never returns here. |
1271 } | 1298 } |
1272 | 1299 |
1273 | 1300 |
| 1301 FullCodeGenerator::NestedStatement::NestedStatement( |
| 1302 FullCodeGenerator* codegen, int stack_delta) |
| 1303 : codegen_(codegen), stack_delta_(stack_delta) { |
| 1304 // Link into codegen's nesting stack. |
| 1305 previous_ = codegen->nesting_stack_; |
| 1306 codegen->nesting_stack_ = this; |
| 1307 stack_depth_ = stack_delta_; |
| 1308 if (previous_ != NULL) { |
| 1309 stack_depth_ += previous_->StackDepth(); |
| 1310 } else { |
| 1311 stack_depth_ += codegen->function()->scope()->num_stack_slots(); |
| 1312 } |
| 1313 } |
| 1314 |
| 1315 |
| 1316 FullCodeGenerator::NestedBlock::NestedBlock( |
| 1317 FullCodeGenerator* codegen, Block* block) |
| 1318 : Breakable(codegen, |
| 1319 block, |
| 1320 block->block_scope() == NULL ? 0 |
| 1321 : block->block_scope()->num_stack_slots()) { |
| 1322 Scope* scope = block->block_scope(); |
| 1323 if (scope != NULL) { |
| 1324 scope->set_stack_slots_depth(StackDepthBase()); |
| 1325 } |
| 1326 } |
| 1327 |
| 1328 |
| 1329 FullCodeGenerator::NestedStatement* FullCodeGenerator::NestedBlock::Exit( |
| 1330 int* stack_depth, |
| 1331 int* context_length) { |
| 1332 Scope* scope = statement()->AsBlock()->block_scope(); |
| 1333 if (scope != NULL) { |
| 1334 if (scope->num_heap_slots() > 0) ++(*context_length); |
| 1335 *stack_depth += scope->num_stack_slots(); |
| 1336 } |
| 1337 return previous_; |
| 1338 } |
| 1339 |
| 1340 |
1274 FullCodeGenerator::NestedStatement* FullCodeGenerator::TryCatch::Exit( | 1341 FullCodeGenerator::NestedStatement* FullCodeGenerator::TryCatch::Exit( |
1275 int* stack_depth, | 1342 int* stack_depth, |
1276 int* context_length) { | 1343 int* context_length) { |
1277 // The macros used here must preserve the result register. | 1344 // The macros used here must preserve the result register. |
1278 __ Drop(*stack_depth); | 1345 __ Drop(*stack_depth); |
1279 __ PopTryHandler(); | 1346 __ PopTryHandler(); |
1280 *stack_depth = 0; | 1347 *stack_depth = 0; |
1281 return previous_; | 1348 return previous_; |
1282 } | 1349 } |
1283 | 1350 |
(...skipping 17 matching lines...) Expand all Loading... |
1301 } | 1368 } |
1302 | 1369 |
1303 return false; | 1370 return false; |
1304 } | 1371 } |
1305 | 1372 |
1306 | 1373 |
1307 #undef __ | 1374 #undef __ |
1308 | 1375 |
1309 | 1376 |
1310 } } // namespace v8::internal | 1377 } } // namespace v8::internal |
OLD | NEW |