| 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 |