OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/ast.h" | 7 #include "src/ast.h" |
8 #include "src/ast-numbering.h" | 8 #include "src/ast-numbering.h" |
9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 1055 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1066 EmitBinaryOp(expr, op, mode); | 1066 EmitBinaryOp(expr, op, mode); |
1067 } | 1067 } |
1068 } | 1068 } |
1069 | 1069 |
1070 | 1070 |
1071 void FullCodeGenerator::VisitBlock(Block* stmt) { | 1071 void FullCodeGenerator::VisitBlock(Block* stmt) { |
1072 Comment cmnt(masm_, "[ Block"); | 1072 Comment cmnt(masm_, "[ Block"); |
1073 NestedBlock nested_block(this, stmt); | 1073 NestedBlock nested_block(this, stmt); |
1074 SetStatementPosition(stmt); | 1074 SetStatementPosition(stmt); |
1075 | 1075 |
1076 Scope* saved_scope = scope(); | 1076 { |
1077 // Push a block context when entering a block with block scoped variables. | 1077 EnterBlockScopeIfNeeded block_scope_state( |
1078 if (stmt->scope() == NULL) { | 1078 this, stmt->scope(), stmt->EntryId(), stmt->DeclsId(), stmt->ExitId()); |
1079 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); | 1079 VisitStatements(stmt->statements()); |
1080 } else { | 1080 __ bind(nested_block.break_label()); |
1081 scope_ = stmt->scope(); | |
1082 DCHECK(!scope_->is_module_scope()); | |
1083 { Comment cmnt(masm_, "[ Extend block context"); | |
1084 __ Push(scope_->GetScopeInfo()); | |
1085 PushFunctionArgumentForContextAllocation(); | |
1086 __ CallRuntime(Runtime::kPushBlockContext, 2); | |
1087 | |
1088 // Replace the context stored in the frame. | |
1089 StoreToFrameField(StandardFrameConstants::kContextOffset, | |
1090 context_register()); | |
1091 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); | |
1092 } | |
1093 { Comment cmnt(masm_, "[ Declarations"); | |
1094 VisitDeclarations(scope_->declarations()); | |
1095 PrepareForBailoutForId(stmt->DeclsId(), NO_REGISTERS); | |
1096 } | |
1097 } | 1081 } |
1098 | |
1099 VisitStatements(stmt->statements()); | |
1100 scope_ = saved_scope; | |
1101 __ bind(nested_block.break_label()); | |
1102 | |
1103 // Pop block context if necessary. | |
1104 if (stmt->scope() != NULL) { | |
1105 LoadContextField(context_register(), Context::PREVIOUS_INDEX); | |
1106 // Update local stack frame context field. | |
1107 StoreToFrameField(StandardFrameConstants::kContextOffset, | |
1108 context_register()); | |
1109 } | |
1110 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); | |
1111 } | 1082 } |
1112 | 1083 |
1113 | 1084 |
1114 void FullCodeGenerator::VisitModuleStatement(ModuleStatement* stmt) { | 1085 void FullCodeGenerator::VisitModuleStatement(ModuleStatement* stmt) { |
1115 Comment cmnt(masm_, "[ Module context"); | 1086 Comment cmnt(masm_, "[ Module context"); |
1116 | 1087 |
1117 __ Push(Smi::FromInt(stmt->proxy()->interface()->Index())); | 1088 __ Push(Smi::FromInt(stmt->proxy()->interface()->Index())); |
1118 __ Push(Smi::FromInt(0)); | 1089 __ Push(Smi::FromInt(0)); |
1119 __ CallRuntime(Runtime::kPushModuleContext, 2); | 1090 __ CallRuntime(Runtime::kPushModuleContext, 2); |
1120 StoreToFrameField( | 1091 StoreToFrameField( |
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1601 SetStackOverflow(); | 1572 SetStackOverflow(); |
1602 return; | 1573 return; |
1603 } | 1574 } |
1604 EmitNewClosure(function_info, expr->pretenure()); | 1575 EmitNewClosure(function_info, expr->pretenure()); |
1605 } | 1576 } |
1606 | 1577 |
1607 | 1578 |
1608 void FullCodeGenerator::VisitClassLiteral(ClassLiteral* lit) { | 1579 void FullCodeGenerator::VisitClassLiteral(ClassLiteral* lit) { |
1609 Comment cmnt(masm_, "[ ClassLiteral"); | 1580 Comment cmnt(masm_, "[ ClassLiteral"); |
1610 | 1581 |
1611 if (lit->raw_name() != NULL) { | 1582 { |
1612 __ Push(lit->name()); | 1583 EnterBlockScopeIfNeeded block_scope_state( |
1613 } else { | 1584 this, lit->scope(), BailoutId::None(), BailoutId::None(), |
1614 __ Push(isolate()->factory()->undefined_value()); | 1585 BailoutId::None()); |
| 1586 |
| 1587 if (lit->raw_name() != NULL) { |
| 1588 __ Push(lit->name()); |
| 1589 } else { |
| 1590 __ Push(isolate()->factory()->undefined_value()); |
| 1591 } |
| 1592 |
| 1593 if (lit->extends() != NULL) { |
| 1594 VisitForStackValue(lit->extends()); |
| 1595 } else { |
| 1596 __ Push(isolate()->factory()->the_hole_value()); |
| 1597 } |
| 1598 |
| 1599 VisitForStackValue(lit->constructor()); |
| 1600 |
| 1601 __ Push(script()); |
| 1602 __ Push(Smi::FromInt(lit->start_position())); |
| 1603 __ Push(Smi::FromInt(lit->end_position())); |
| 1604 |
| 1605 __ CallRuntime(Runtime::kDefineClass, 6); |
| 1606 EmitClassDefineProperties(lit); |
| 1607 |
| 1608 if (lit->scope() != NULL) { |
| 1609 DCHECK_NOT_NULL(lit->class_variable_proxy()); |
| 1610 EmitVariableAssignment(lit->class_variable_proxy()->var(), |
| 1611 Token::INIT_CONST); |
| 1612 } |
1615 } | 1613 } |
1616 | 1614 |
1617 if (lit->extends() != NULL) { | |
1618 VisitForStackValue(lit->extends()); | |
1619 } else { | |
1620 __ Push(isolate()->factory()->the_hole_value()); | |
1621 } | |
1622 | |
1623 VisitForStackValue(lit->constructor()); | |
1624 | |
1625 __ Push(script()); | |
1626 __ Push(Smi::FromInt(lit->start_position())); | |
1627 __ Push(Smi::FromInt(lit->end_position())); | |
1628 | |
1629 __ CallRuntime(Runtime::kDefineClass, 6); | |
1630 EmitClassDefineProperties(lit); | |
1631 | |
1632 context()->Plug(result_register()); | 1615 context()->Plug(result_register()); |
1633 } | 1616 } |
1634 | 1617 |
1635 | 1618 |
1636 void FullCodeGenerator::VisitNativeFunctionLiteral( | 1619 void FullCodeGenerator::VisitNativeFunctionLiteral( |
1637 NativeFunctionLiteral* expr) { | 1620 NativeFunctionLiteral* expr) { |
1638 Comment cmnt(masm_, "[ NativeFunctionLiteral"); | 1621 Comment cmnt(masm_, "[ NativeFunctionLiteral"); |
1639 | 1622 |
1640 // Compute the function template for the native function. | 1623 // Compute the function template for the native function. |
1641 Handle<String> name = expr->name(); | 1624 Handle<String> name = expr->name(); |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1788 CHECK_EQ((static_cast<int>(loop_depth) <= loop_nesting_level), | 1771 CHECK_EQ((static_cast<int>(loop_depth) <= loop_nesting_level), |
1789 GetBackEdgeState(isolate, | 1772 GetBackEdgeState(isolate, |
1790 unoptimized, | 1773 unoptimized, |
1791 back_edges.pc(i)) != INTERRUPT); | 1774 back_edges.pc(i)) != INTERRUPT); |
1792 } | 1775 } |
1793 return true; | 1776 return true; |
1794 } | 1777 } |
1795 #endif // DEBUG | 1778 #endif // DEBUG |
1796 | 1779 |
1797 | 1780 |
| 1781 FullCodeGenerator::EnterBlockScopeIfNeeded::EnterBlockScopeIfNeeded( |
| 1782 FullCodeGenerator* codegen, Scope* scope, BailoutId entry_id, |
| 1783 BailoutId declarations_id, BailoutId exit_id) |
| 1784 : codegen_(codegen), scope_(scope), exit_id_(exit_id) { |
| 1785 saved_scope_ = codegen_->scope(); |
| 1786 |
| 1787 if (scope == NULL) { |
| 1788 codegen_->PrepareForBailoutForId(entry_id, NO_REGISTERS); |
| 1789 } else { |
| 1790 codegen_->scope_ = scope; |
| 1791 { |
| 1792 Comment cmnt(masm(), "[ Extend block context"); |
| 1793 __ Push(scope->GetScopeInfo()); |
| 1794 codegen_->PushFunctionArgumentForContextAllocation(); |
| 1795 __ CallRuntime(Runtime::kPushBlockContext, 2); |
| 1796 |
| 1797 // Replace the context stored in the frame. |
| 1798 codegen_->StoreToFrameField(StandardFrameConstants::kContextOffset, |
| 1799 codegen_->context_register()); |
| 1800 codegen_->PrepareForBailoutForId(entry_id, NO_REGISTERS); |
| 1801 } |
| 1802 { |
| 1803 Comment cmnt(masm(), "[ Declarations"); |
| 1804 codegen_->VisitDeclarations(scope->declarations()); |
| 1805 codegen_->PrepareForBailoutForId(declarations_id, NO_REGISTERS); |
| 1806 } |
| 1807 } |
| 1808 } |
| 1809 |
| 1810 |
| 1811 FullCodeGenerator::EnterBlockScopeIfNeeded::~EnterBlockScopeIfNeeded() { |
| 1812 if (scope_ != NULL) { |
| 1813 codegen_->LoadContextField(codegen_->context_register(), |
| 1814 Context::PREVIOUS_INDEX); |
| 1815 // Update local stack frame context field. |
| 1816 codegen_->StoreToFrameField(StandardFrameConstants::kContextOffset, |
| 1817 codegen_->context_register()); |
| 1818 } |
| 1819 codegen_->PrepareForBailoutForId(exit_id_, NO_REGISTERS); |
| 1820 codegen_->scope_ = saved_scope_; |
| 1821 } |
| 1822 |
| 1823 |
1798 #undef __ | 1824 #undef __ |
1799 | 1825 |
1800 | 1826 |
1801 } } // namespace v8::internal | 1827 } } // namespace v8::internal |
OLD | NEW |