Chromium Code Reviews| 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 |