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