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 738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
749 VisitForAccumulatorValue(function); | 749 VisitForAccumulatorValue(function); |
750 __ pop(edx); | 750 __ pop(edx); |
751 | 751 |
752 ASSERT(prop->key()->AsLiteral() != NULL && | 752 ASSERT(prop->key()->AsLiteral() != NULL && |
753 prop->key()->AsLiteral()->handle()->IsSmi()); | 753 prop->key()->AsLiteral()->handle()->IsSmi()); |
754 __ SafeSet(ecx, Immediate(prop->key()->AsLiteral()->handle())); | 754 __ SafeSet(ecx, Immediate(prop->key()->AsLiteral()->handle())); |
755 | 755 |
756 Handle<Code> ic = is_strict_mode() | 756 Handle<Code> ic = is_strict_mode() |
757 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() | 757 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() |
758 : isolate()->builtins()->KeyedStoreIC_Initialize(); | 758 : isolate()->builtins()->KeyedStoreIC_Initialize(); |
759 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); | 759 __ call(ic); |
760 } | 760 } |
761 } | 761 } |
762 } | 762 } |
763 | 763 |
764 | 764 |
765 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { | 765 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { |
766 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); | 766 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); |
767 } | 767 } |
768 | 768 |
769 | 769 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
822 __ cmp(edx, Operand(eax)); | 822 __ cmp(edx, Operand(eax)); |
823 __ j(not_equal, &next_test); | 823 __ j(not_equal, &next_test); |
824 __ Drop(1); // Switch value is no longer needed. | 824 __ Drop(1); // Switch value is no longer needed. |
825 __ jmp(clause->body_target()); | 825 __ jmp(clause->body_target()); |
826 __ bind(&slow_case); | 826 __ bind(&slow_case); |
827 } | 827 } |
828 | 828 |
829 // Record position before stub call for type feedback. | 829 // Record position before stub call for type feedback. |
830 SetSourcePosition(clause->position()); | 830 SetSourcePosition(clause->position()); |
831 Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT); | 831 Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT); |
832 EmitCallIC(ic, RelocInfo::CODE_TARGET, clause->CompareId()); | 832 __ call(ic, RelocInfo::CODE_TARGET, clause->CompareId()); |
833 patch_site.EmitPatchInfo(); | 833 patch_site.EmitPatchInfo(); |
834 __ test(eax, Operand(eax)); | 834 __ test(eax, Operand(eax)); |
835 __ j(not_equal, &next_test); | 835 __ j(not_equal, &next_test); |
836 __ Drop(1); // Switch value is no longer needed. | 836 __ Drop(1); // Switch value is no longer needed. |
837 __ jmp(clause->body_target()); | 837 __ jmp(clause->body_target()); |
838 } | 838 } |
839 | 839 |
840 // Discard the test value and jump to the default if present, otherwise to | 840 // Discard the test value and jump to the default if present, otherwise to |
841 // the end of the statement. | 841 // the end of the statement. |
842 __ bind(&next_test); | 842 __ bind(&next_test); |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1116 } | 1116 } |
1117 | 1117 |
1118 // All extension objects were empty and it is safe to use a global | 1118 // All extension objects were empty and it is safe to use a global |
1119 // load IC call. | 1119 // load IC call. |
1120 __ mov(eax, GlobalObjectOperand()); | 1120 __ mov(eax, GlobalObjectOperand()); |
1121 __ mov(ecx, slot->var()->name()); | 1121 __ mov(ecx, slot->var()->name()); |
1122 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1122 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
1123 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) | 1123 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) |
1124 ? RelocInfo::CODE_TARGET | 1124 ? RelocInfo::CODE_TARGET |
1125 : RelocInfo::CODE_TARGET_CONTEXT; | 1125 : RelocInfo::CODE_TARGET_CONTEXT; |
1126 EmitCallIC(ic, mode, AstNode::kNoNumber); | 1126 __ call(ic, mode); |
1127 } | 1127 } |
1128 | 1128 |
1129 | 1129 |
1130 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions( | 1130 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions( |
1131 Slot* slot, | 1131 Slot* slot, |
1132 Label* slow) { | 1132 Label* slow) { |
1133 ASSERT(slot->type() == Slot::CONTEXT); | 1133 ASSERT(slot->type() == Slot::CONTEXT); |
1134 Register context = esi; | 1134 Register context = esi; |
1135 Register temp = ebx; | 1135 Register temp = ebx; |
1136 | 1136 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1196 key_literal->handle()->IsSmi()) { | 1196 key_literal->handle()->IsSmi()) { |
1197 // Load arguments object if there are no eval-introduced | 1197 // Load arguments object if there are no eval-introduced |
1198 // variables. Then load the argument from the arguments | 1198 // variables. Then load the argument from the arguments |
1199 // object using keyed load. | 1199 // object using keyed load. |
1200 __ mov(edx, | 1200 __ mov(edx, |
1201 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), | 1201 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), |
1202 slow)); | 1202 slow)); |
1203 __ SafeSet(eax, Immediate(key_literal->handle())); | 1203 __ SafeSet(eax, Immediate(key_literal->handle())); |
1204 Handle<Code> ic = | 1204 Handle<Code> ic = |
1205 isolate()->builtins()->KeyedLoadIC_Initialize(); | 1205 isolate()->builtins()->KeyedLoadIC_Initialize(); |
1206 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(property)); | 1206 __ call(ic, RelocInfo::CODE_TARGET, GetPropertyId(property)); |
1207 __ jmp(done); | 1207 __ jmp(done); |
1208 } | 1208 } |
1209 } | 1209 } |
1210 } | 1210 } |
1211 } | 1211 } |
1212 } | 1212 } |
1213 | 1213 |
1214 | 1214 |
1215 void FullCodeGenerator::EmitVariableLoad(Variable* var) { | 1215 void FullCodeGenerator::EmitVariableLoad(Variable* var) { |
1216 // Three cases: non-this global variables, lookup slots, and all other | 1216 // Three cases: non-this global variables, lookup slots, and all other |
1217 // types of slots. | 1217 // types of slots. |
1218 Slot* slot = var->AsSlot(); | 1218 Slot* slot = var->AsSlot(); |
1219 ASSERT((var->is_global() && !var->is_this()) == (slot == NULL)); | 1219 ASSERT((var->is_global() && !var->is_this()) == (slot == NULL)); |
1220 | 1220 |
1221 if (slot == NULL) { | 1221 if (slot == NULL) { |
1222 Comment cmnt(masm_, "Global variable"); | 1222 Comment cmnt(masm_, "Global variable"); |
1223 // Use inline caching. Variable name is passed in ecx and the global | 1223 // Use inline caching. Variable name is passed in ecx and the global |
1224 // object on the stack. | 1224 // object on the stack. |
1225 __ mov(eax, GlobalObjectOperand()); | 1225 __ mov(eax, GlobalObjectOperand()); |
1226 __ mov(ecx, var->name()); | 1226 __ mov(ecx, var->name()); |
1227 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1227 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
1228 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT, AstNode::kNoNumber); | 1228 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); |
1229 context()->Plug(eax); | 1229 context()->Plug(eax); |
1230 | 1230 |
1231 } else if (slot->type() == Slot::LOOKUP) { | 1231 } else if (slot->type() == Slot::LOOKUP) { |
1232 Label done, slow; | 1232 Label done, slow; |
1233 | 1233 |
1234 // Generate code for loading from variables potentially shadowed | 1234 // Generate code for loading from variables potentially shadowed |
1235 // by eval-introduced variables. | 1235 // by eval-introduced variables. |
1236 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); | 1236 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); |
1237 | 1237 |
1238 __ bind(&slow); | 1238 __ bind(&slow); |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1364 // Fall through. | 1364 // Fall through. |
1365 case ObjectLiteral::Property::COMPUTED: | 1365 case ObjectLiteral::Property::COMPUTED: |
1366 if (key->handle()->IsSymbol()) { | 1366 if (key->handle()->IsSymbol()) { |
1367 if (property->emit_store()) { | 1367 if (property->emit_store()) { |
1368 VisitForAccumulatorValue(value); | 1368 VisitForAccumulatorValue(value); |
1369 __ mov(ecx, Immediate(key->handle())); | 1369 __ mov(ecx, Immediate(key->handle())); |
1370 __ mov(edx, Operand(esp, 0)); | 1370 __ mov(edx, Operand(esp, 0)); |
1371 Handle<Code> ic = is_strict_mode() | 1371 Handle<Code> ic = is_strict_mode() |
1372 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 1372 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
1373 : isolate()->builtins()->StoreIC_Initialize(); | 1373 : isolate()->builtins()->StoreIC_Initialize(); |
1374 EmitCallIC(ic, RelocInfo::CODE_TARGET, key->id()); | 1374 __ call(ic, RelocInfo::CODE_TARGET, key->id()); |
1375 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1375 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
1376 } else { | 1376 } else { |
1377 VisitForEffect(value); | 1377 VisitForEffect(value); |
1378 } | 1378 } |
1379 break; | 1379 break; |
1380 } | 1380 } |
1381 // Fall through. | 1381 // Fall through. |
1382 case ObjectLiteral::Property::PROTOTYPE: | 1382 case ObjectLiteral::Property::PROTOTYPE: |
1383 __ push(Operand(esp, 0)); // Duplicate receiver. | 1383 __ push(Operand(esp, 0)); // Duplicate receiver. |
1384 VisitForStackValue(key); | 1384 VisitForStackValue(key); |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1597 } | 1597 } |
1598 } | 1598 } |
1599 | 1599 |
1600 | 1600 |
1601 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 1601 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
1602 SetSourcePosition(prop->position()); | 1602 SetSourcePosition(prop->position()); |
1603 Literal* key = prop->key()->AsLiteral(); | 1603 Literal* key = prop->key()->AsLiteral(); |
1604 ASSERT(!key->handle()->IsSmi()); | 1604 ASSERT(!key->handle()->IsSmi()); |
1605 __ mov(ecx, Immediate(key->handle())); | 1605 __ mov(ecx, Immediate(key->handle())); |
1606 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1606 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
1607 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); | 1607 __ call(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); |
1608 } | 1608 } |
1609 | 1609 |
1610 | 1610 |
1611 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 1611 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
1612 SetSourcePosition(prop->position()); | 1612 SetSourcePosition(prop->position()); |
1613 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 1613 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
1614 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); | 1614 __ call(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); |
1615 } | 1615 } |
1616 | 1616 |
1617 | 1617 |
1618 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 1618 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
1619 Token::Value op, | 1619 Token::Value op, |
1620 OverwriteMode mode, | 1620 OverwriteMode mode, |
1621 Expression* left, | 1621 Expression* left, |
1622 Expression* right) { | 1622 Expression* right) { |
1623 // Do combined smi check of the operands. Left operand is on the | 1623 // Do combined smi check of the operands. Left operand is on the |
1624 // stack. Right operand is in eax. | 1624 // stack. Right operand is in eax. |
1625 Label smi_case, done, stub_call; | 1625 Label smi_case, done, stub_call; |
1626 __ pop(edx); | 1626 __ pop(edx); |
1627 __ mov(ecx, eax); | 1627 __ mov(ecx, eax); |
1628 __ or_(eax, Operand(edx)); | 1628 __ or_(eax, Operand(edx)); |
1629 JumpPatchSite patch_site(masm_); | 1629 JumpPatchSite patch_site(masm_); |
1630 patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear); | 1630 patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear); |
1631 | 1631 |
1632 __ bind(&stub_call); | 1632 __ bind(&stub_call); |
1633 __ mov(eax, ecx); | 1633 __ mov(eax, ecx); |
1634 BinaryOpStub stub(op, mode); | 1634 BinaryOpStub stub(op, mode); |
1635 EmitCallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); | 1635 __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); |
1636 patch_site.EmitPatchInfo(); | 1636 patch_site.EmitPatchInfo(); |
1637 __ jmp(&done, Label::kNear); | 1637 __ jmp(&done, Label::kNear); |
1638 | 1638 |
1639 // Smi case. | 1639 // Smi case. |
1640 __ bind(&smi_case); | 1640 __ bind(&smi_case); |
1641 __ mov(eax, edx); // Copy left operand in case of a stub call. | 1641 __ mov(eax, edx); // Copy left operand in case of a stub call. |
1642 | 1642 |
1643 switch (op) { | 1643 switch (op) { |
1644 case Token::SAR: | 1644 case Token::SAR: |
1645 __ SmiUntag(eax); | 1645 __ SmiUntag(eax); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1710 context()->Plug(eax); | 1710 context()->Plug(eax); |
1711 } | 1711 } |
1712 | 1712 |
1713 | 1713 |
1714 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, | 1714 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, |
1715 Token::Value op, | 1715 Token::Value op, |
1716 OverwriteMode mode) { | 1716 OverwriteMode mode) { |
1717 __ pop(edx); | 1717 __ pop(edx); |
1718 BinaryOpStub stub(op, mode); | 1718 BinaryOpStub stub(op, mode); |
1719 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 1719 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
1720 EmitCallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); | 1720 __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); |
1721 patch_site.EmitPatchInfo(); | 1721 patch_site.EmitPatchInfo(); |
1722 context()->Plug(eax); | 1722 context()->Plug(eax); |
1723 } | 1723 } |
1724 | 1724 |
1725 | 1725 |
1726 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) { | 1726 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) { |
1727 // Invalid left-hand sides are rewritten to have a 'throw | 1727 // Invalid left-hand sides are rewritten to have a 'throw |
1728 // ReferenceError' on the left-hand side. | 1728 // ReferenceError' on the left-hand side. |
1729 if (!expr->IsValidLeftHandSide()) { | 1729 if (!expr->IsValidLeftHandSide()) { |
1730 VisitForEffect(expr); | 1730 VisitForEffect(expr); |
(...skipping 20 matching lines...) Expand all Loading... |
1751 } | 1751 } |
1752 case NAMED_PROPERTY: { | 1752 case NAMED_PROPERTY: { |
1753 __ push(eax); // Preserve value. | 1753 __ push(eax); // Preserve value. |
1754 VisitForAccumulatorValue(prop->obj()); | 1754 VisitForAccumulatorValue(prop->obj()); |
1755 __ mov(edx, eax); | 1755 __ mov(edx, eax); |
1756 __ pop(eax); // Restore value. | 1756 __ pop(eax); // Restore value. |
1757 __ mov(ecx, prop->key()->AsLiteral()->handle()); | 1757 __ mov(ecx, prop->key()->AsLiteral()->handle()); |
1758 Handle<Code> ic = is_strict_mode() | 1758 Handle<Code> ic = is_strict_mode() |
1759 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 1759 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
1760 : isolate()->builtins()->StoreIC_Initialize(); | 1760 : isolate()->builtins()->StoreIC_Initialize(); |
1761 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); | 1761 __ call(ic); |
1762 break; | 1762 break; |
1763 } | 1763 } |
1764 case KEYED_PROPERTY: { | 1764 case KEYED_PROPERTY: { |
1765 __ push(eax); // Preserve value. | 1765 __ push(eax); // Preserve value. |
1766 if (prop->is_synthetic()) { | 1766 if (prop->is_synthetic()) { |
1767 ASSERT(prop->obj()->AsVariableProxy() != NULL); | 1767 ASSERT(prop->obj()->AsVariableProxy() != NULL); |
1768 ASSERT(prop->key()->AsLiteral() != NULL); | 1768 ASSERT(prop->key()->AsLiteral() != NULL); |
1769 { AccumulatorValueContext for_object(this); | 1769 { AccumulatorValueContext for_object(this); |
1770 EmitVariableLoad(prop->obj()->AsVariableProxy()->var()); | 1770 EmitVariableLoad(prop->obj()->AsVariableProxy()->var()); |
1771 } | 1771 } |
1772 __ mov(edx, eax); | 1772 __ mov(edx, eax); |
1773 __ SafeSet(ecx, Immediate(prop->key()->AsLiteral()->handle())); | 1773 __ SafeSet(ecx, Immediate(prop->key()->AsLiteral()->handle())); |
1774 } else { | 1774 } else { |
1775 VisitForStackValue(prop->obj()); | 1775 VisitForStackValue(prop->obj()); |
1776 VisitForAccumulatorValue(prop->key()); | 1776 VisitForAccumulatorValue(prop->key()); |
1777 __ mov(ecx, eax); | 1777 __ mov(ecx, eax); |
1778 __ pop(edx); | 1778 __ pop(edx); |
1779 } | 1779 } |
1780 __ pop(eax); // Restore value. | 1780 __ pop(eax); // Restore value. |
1781 Handle<Code> ic = is_strict_mode() | 1781 Handle<Code> ic = is_strict_mode() |
1782 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() | 1782 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() |
1783 : isolate()->builtins()->KeyedStoreIC_Initialize(); | 1783 : isolate()->builtins()->KeyedStoreIC_Initialize(); |
1784 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); | 1784 __ call(ic); |
1785 break; | 1785 break; |
1786 } | 1786 } |
1787 } | 1787 } |
1788 PrepareForBailoutForId(bailout_ast_id, TOS_REG); | 1788 PrepareForBailoutForId(bailout_ast_id, TOS_REG); |
1789 context()->Plug(eax); | 1789 context()->Plug(eax); |
1790 } | 1790 } |
1791 | 1791 |
1792 | 1792 |
1793 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 1793 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
1794 Token::Value op) { | 1794 Token::Value op) { |
1795 ASSERT(var != NULL); | 1795 ASSERT(var != NULL); |
1796 ASSERT(var->is_global() || var->AsSlot() != NULL); | 1796 ASSERT(var->is_global() || var->AsSlot() != NULL); |
1797 | 1797 |
1798 if (var->is_global()) { | 1798 if (var->is_global()) { |
1799 ASSERT(!var->is_this()); | 1799 ASSERT(!var->is_this()); |
1800 // Assignment to a global variable. Use inline caching for the | 1800 // Assignment to a global variable. Use inline caching for the |
1801 // assignment. Right-hand-side value is passed in eax, variable name in | 1801 // assignment. Right-hand-side value is passed in eax, variable name in |
1802 // ecx, and the global object on the stack. | 1802 // ecx, and the global object on the stack. |
1803 __ mov(ecx, var->name()); | 1803 __ mov(ecx, var->name()); |
1804 __ mov(edx, GlobalObjectOperand()); | 1804 __ mov(edx, GlobalObjectOperand()); |
1805 Handle<Code> ic = is_strict_mode() | 1805 Handle<Code> ic = is_strict_mode() |
1806 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 1806 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
1807 : isolate()->builtins()->StoreIC_Initialize(); | 1807 : isolate()->builtins()->StoreIC_Initialize(); |
1808 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT, AstNode::kNoNumber); | 1808 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); |
1809 | 1809 |
1810 } else if (op == Token::INIT_CONST) { | 1810 } else if (op == Token::INIT_CONST) { |
1811 // Like var declarations, const declarations are hoisted to function | 1811 // Like var declarations, const declarations are hoisted to function |
1812 // scope. However, unlike var initializers, const initializers are able | 1812 // scope. However, unlike var initializers, const initializers are able |
1813 // to drill a hole to that function context, even from inside a 'with' | 1813 // to drill a hole to that function context, even from inside a 'with' |
1814 // context. We thus bypass the normal static scope lookup. | 1814 // context. We thus bypass the normal static scope lookup. |
1815 Slot* slot = var->AsSlot(); | 1815 Slot* slot = var->AsSlot(); |
1816 Label skip; | 1816 Label skip; |
1817 switch (slot->type()) { | 1817 switch (slot->type()) { |
1818 case Slot::PARAMETER: | 1818 case Slot::PARAMETER: |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1891 SetSourcePosition(expr->position()); | 1891 SetSourcePosition(expr->position()); |
1892 __ mov(ecx, prop->key()->AsLiteral()->handle()); | 1892 __ mov(ecx, prop->key()->AsLiteral()->handle()); |
1893 if (expr->ends_initialization_block()) { | 1893 if (expr->ends_initialization_block()) { |
1894 __ mov(edx, Operand(esp, 0)); | 1894 __ mov(edx, Operand(esp, 0)); |
1895 } else { | 1895 } else { |
1896 __ pop(edx); | 1896 __ pop(edx); |
1897 } | 1897 } |
1898 Handle<Code> ic = is_strict_mode() | 1898 Handle<Code> ic = is_strict_mode() |
1899 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 1899 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
1900 : isolate()->builtins()->StoreIC_Initialize(); | 1900 : isolate()->builtins()->StoreIC_Initialize(); |
1901 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 1901 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); |
1902 | 1902 |
1903 // If the assignment ends an initialization block, revert to fast case. | 1903 // If the assignment ends an initialization block, revert to fast case. |
1904 if (expr->ends_initialization_block()) { | 1904 if (expr->ends_initialization_block()) { |
1905 __ push(eax); // Result of assignment, saved even if not needed. | 1905 __ push(eax); // Result of assignment, saved even if not needed. |
1906 __ push(Operand(esp, kPointerSize)); // Receiver is under value. | 1906 __ push(Operand(esp, kPointerSize)); // Receiver is under value. |
1907 __ CallRuntime(Runtime::kToFastProperties, 1); | 1907 __ CallRuntime(Runtime::kToFastProperties, 1); |
1908 __ pop(eax); | 1908 __ pop(eax); |
1909 __ Drop(1); | 1909 __ Drop(1); |
1910 } | 1910 } |
1911 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 1911 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
(...skipping 19 matching lines...) Expand all Loading... |
1931 if (expr->ends_initialization_block()) { | 1931 if (expr->ends_initialization_block()) { |
1932 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later. | 1932 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later. |
1933 } else { | 1933 } else { |
1934 __ pop(edx); | 1934 __ pop(edx); |
1935 } | 1935 } |
1936 // Record source code position before IC call. | 1936 // Record source code position before IC call. |
1937 SetSourcePosition(expr->position()); | 1937 SetSourcePosition(expr->position()); |
1938 Handle<Code> ic = is_strict_mode() | 1938 Handle<Code> ic = is_strict_mode() |
1939 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() | 1939 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() |
1940 : isolate()->builtins()->KeyedStoreIC_Initialize(); | 1940 : isolate()->builtins()->KeyedStoreIC_Initialize(); |
1941 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 1941 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); |
1942 | 1942 |
1943 // If the assignment ends an initialization block, revert to fast case. | 1943 // If the assignment ends an initialization block, revert to fast case. |
1944 if (expr->ends_initialization_block()) { | 1944 if (expr->ends_initialization_block()) { |
1945 __ pop(edx); | 1945 __ pop(edx); |
1946 __ push(eax); // Result of assignment, saved even if not needed. | 1946 __ push(eax); // Result of assignment, saved even if not needed. |
1947 __ push(edx); | 1947 __ push(edx); |
1948 __ CallRuntime(Runtime::kToFastProperties, 1); | 1948 __ CallRuntime(Runtime::kToFastProperties, 1); |
1949 __ pop(eax); | 1949 __ pop(eax); |
1950 } | 1950 } |
1951 | 1951 |
(...skipping 30 matching lines...) Expand all Loading... |
1982 for (int i = 0; i < arg_count; i++) { | 1982 for (int i = 0; i < arg_count; i++) { |
1983 VisitForStackValue(args->at(i)); | 1983 VisitForStackValue(args->at(i)); |
1984 } | 1984 } |
1985 __ Set(ecx, Immediate(name)); | 1985 __ Set(ecx, Immediate(name)); |
1986 } | 1986 } |
1987 // Record source position of the IC call. | 1987 // Record source position of the IC call. |
1988 SetSourcePosition(expr->position()); | 1988 SetSourcePosition(expr->position()); |
1989 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 1989 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
1990 Handle<Code> ic = | 1990 Handle<Code> ic = |
1991 isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop, mode); | 1991 isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop, mode); |
1992 EmitCallIC(ic, mode, expr->id()); | 1992 __ call(ic, mode, expr->id()); |
1993 RecordJSReturnSite(expr); | 1993 RecordJSReturnSite(expr); |
1994 // Restore context register. | 1994 // Restore context register. |
1995 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 1995 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
1996 context()->Plug(eax); | 1996 context()->Plug(eax); |
1997 } | 1997 } |
1998 | 1998 |
1999 | 1999 |
2000 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, | 2000 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, |
2001 Expression* key) { | 2001 Expression* key) { |
2002 // Load the key. | 2002 // Load the key. |
(...skipping 12 matching lines...) Expand all Loading... |
2015 for (int i = 0; i < arg_count; i++) { | 2015 for (int i = 0; i < arg_count; i++) { |
2016 VisitForStackValue(args->at(i)); | 2016 VisitForStackValue(args->at(i)); |
2017 } | 2017 } |
2018 } | 2018 } |
2019 // Record source position of the IC call. | 2019 // Record source position of the IC call. |
2020 SetSourcePosition(expr->position()); | 2020 SetSourcePosition(expr->position()); |
2021 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 2021 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
2022 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize( | 2022 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize( |
2023 arg_count, in_loop); | 2023 arg_count, in_loop); |
2024 __ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key. | 2024 __ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key. |
2025 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 2025 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); |
2026 RecordJSReturnSite(expr); | 2026 RecordJSReturnSite(expr); |
2027 // Restore context register. | 2027 // Restore context register. |
2028 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 2028 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
2029 context()->DropAndPlug(1, eax); // Drop the key still on the stack. | 2029 context()->DropAndPlug(1, eax); // Drop the key still on the stack. |
2030 } | 2030 } |
2031 | 2031 |
2032 | 2032 |
2033 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { | 2033 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { |
2034 // Code common for calls using the call stub. | 2034 // Code common for calls using the call stub. |
2035 ZoneList<Expression*>* args = expr->arguments(); | 2035 ZoneList<Expression*>* args = expr->arguments(); |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2191 Literal* key = prop->key()->AsLiteral(); | 2191 Literal* key = prop->key()->AsLiteral(); |
2192 if (key != NULL && key->handle()->IsSymbol()) { | 2192 if (key != NULL && key->handle()->IsSymbol()) { |
2193 // Call to a named property, use call IC. | 2193 // Call to a named property, use call IC. |
2194 { PreservePositionScope scope(masm()->positions_recorder()); | 2194 { PreservePositionScope scope(masm()->positions_recorder()); |
2195 VisitForStackValue(prop->obj()); | 2195 VisitForStackValue(prop->obj()); |
2196 } | 2196 } |
2197 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); | 2197 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); |
2198 } else { | 2198 } else { |
2199 // Call to a keyed property. | 2199 // Call to a keyed property. |
2200 // For a synthetic property use keyed load IC followed by function call, | 2200 // For a synthetic property use keyed load IC followed by function call, |
2201 // for a regular property use keyed EmitCallIC. | 2201 // for a regular property use EmitKeyedCallWithIC. |
2202 if (prop->is_synthetic()) { | 2202 if (prop->is_synthetic()) { |
2203 // Do not visit the object and key subexpressions (they are shared | 2203 // Do not visit the object and key subexpressions (they are shared |
2204 // by all occurrences of the same rewritten parameter). | 2204 // by all occurrences of the same rewritten parameter). |
2205 ASSERT(prop->obj()->AsVariableProxy() != NULL); | 2205 ASSERT(prop->obj()->AsVariableProxy() != NULL); |
2206 ASSERT(prop->obj()->AsVariableProxy()->var()->AsSlot() != NULL); | 2206 ASSERT(prop->obj()->AsVariableProxy()->var()->AsSlot() != NULL); |
2207 Slot* slot = prop->obj()->AsVariableProxy()->var()->AsSlot(); | 2207 Slot* slot = prop->obj()->AsVariableProxy()->var()->AsSlot(); |
2208 MemOperand operand = EmitSlotSearch(slot, edx); | 2208 MemOperand operand = EmitSlotSearch(slot, edx); |
2209 __ mov(edx, operand); | 2209 __ mov(edx, operand); |
2210 | 2210 |
2211 ASSERT(prop->key()->AsLiteral() != NULL); | 2211 ASSERT(prop->key()->AsLiteral() != NULL); |
2212 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); | 2212 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); |
2213 __ mov(eax, prop->key()->AsLiteral()->handle()); | 2213 __ mov(eax, prop->key()->AsLiteral()->handle()); |
2214 | 2214 |
2215 // Record source code position for IC call. | 2215 // Record source code position for IC call. |
2216 SetSourcePosition(prop->position()); | 2216 SetSourcePosition(prop->position()); |
2217 | 2217 |
2218 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2218 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
2219 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); | 2219 __ call(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); |
2220 // Push result (function). | 2220 // Push result (function). |
2221 __ push(eax); | 2221 __ push(eax); |
2222 // Push Global receiver. | 2222 // Push Global receiver. |
2223 __ mov(ecx, GlobalObjectOperand()); | 2223 __ mov(ecx, GlobalObjectOperand()); |
2224 __ push(FieldOperand(ecx, GlobalObject::kGlobalReceiverOffset)); | 2224 __ push(FieldOperand(ecx, GlobalObject::kGlobalReceiverOffset)); |
2225 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); | 2225 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); |
2226 } else { | 2226 } else { |
2227 { PreservePositionScope scope(masm()->positions_recorder()); | 2227 { PreservePositionScope scope(masm()->positions_recorder()); |
2228 VisitForStackValue(prop->obj()); | 2228 VisitForStackValue(prop->obj()); |
2229 } | 2229 } |
(...skipping 1325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3555 VisitForStackValue(args->at(i)); | 3555 VisitForStackValue(args->at(i)); |
3556 } | 3556 } |
3557 | 3557 |
3558 if (expr->is_jsruntime()) { | 3558 if (expr->is_jsruntime()) { |
3559 // Call the JS runtime function via a call IC. | 3559 // Call the JS runtime function via a call IC. |
3560 __ Set(ecx, Immediate(expr->name())); | 3560 __ Set(ecx, Immediate(expr->name())); |
3561 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 3561 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
3562 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; | 3562 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; |
3563 Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize( | 3563 Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize( |
3564 arg_count, in_loop, mode); | 3564 arg_count, in_loop, mode); |
3565 EmitCallIC(ic, mode, expr->id()); | 3565 __ call(ic, mode, expr->id()); |
3566 // Restore context register. | 3566 // Restore context register. |
3567 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 3567 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
3568 } else { | 3568 } else { |
3569 // Call the C runtime function. | 3569 // Call the C runtime function. |
3570 __ CallRuntime(expr->function(), arg_count); | 3570 __ CallRuntime(expr->function(), arg_count); |
3571 } | 3571 } |
3572 context()->Plug(eax); | 3572 context()->Plug(eax); |
3573 } | 3573 } |
3574 | 3574 |
3575 | 3575 |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3694 // TODO(svenpanne): Allowing format strings in Comment would be nice here... | 3694 // TODO(svenpanne): Allowing format strings in Comment would be nice here... |
3695 Comment cmt(masm_, comment); | 3695 Comment cmt(masm_, comment); |
3696 bool can_overwrite = expr->expression()->ResultOverwriteAllowed(); | 3696 bool can_overwrite = expr->expression()->ResultOverwriteAllowed(); |
3697 UnaryOverwriteMode overwrite = | 3697 UnaryOverwriteMode overwrite = |
3698 can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE; | 3698 can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE; |
3699 UnaryOpStub stub(expr->op(), overwrite); | 3699 UnaryOpStub stub(expr->op(), overwrite); |
3700 // UnaryOpStub expects the argument to be in the | 3700 // UnaryOpStub expects the argument to be in the |
3701 // accumulator register eax. | 3701 // accumulator register eax. |
3702 VisitForAccumulatorValue(expr->expression()); | 3702 VisitForAccumulatorValue(expr->expression()); |
3703 SetSourcePosition(expr->position()); | 3703 SetSourcePosition(expr->position()); |
3704 EmitCallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); | 3704 __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); |
3705 context()->Plug(eax); | 3705 context()->Plug(eax); |
3706 } | 3706 } |
3707 | 3707 |
3708 | 3708 |
3709 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { | 3709 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
3710 Comment cmnt(masm_, "[ CountOperation"); | 3710 Comment cmnt(masm_, "[ CountOperation"); |
3711 SetSourcePosition(expr->position()); | 3711 SetSourcePosition(expr->position()); |
3712 | 3712 |
3713 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError' | 3713 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError' |
3714 // as the left-hand side. | 3714 // as the left-hand side. |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3814 } | 3814 } |
3815 } | 3815 } |
3816 | 3816 |
3817 // Record position before stub call. | 3817 // Record position before stub call. |
3818 SetSourcePosition(expr->position()); | 3818 SetSourcePosition(expr->position()); |
3819 | 3819 |
3820 // Call stub for +1/-1. | 3820 // Call stub for +1/-1. |
3821 __ mov(edx, eax); | 3821 __ mov(edx, eax); |
3822 __ mov(eax, Immediate(Smi::FromInt(1))); | 3822 __ mov(eax, Immediate(Smi::FromInt(1))); |
3823 BinaryOpStub stub(expr->binary_op(), NO_OVERWRITE); | 3823 BinaryOpStub stub(expr->binary_op(), NO_OVERWRITE); |
3824 EmitCallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId()); | 3824 __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId()); |
3825 patch_site.EmitPatchInfo(); | 3825 patch_site.EmitPatchInfo(); |
3826 __ bind(&done); | 3826 __ bind(&done); |
3827 | 3827 |
3828 // Store the value returned in eax. | 3828 // Store the value returned in eax. |
3829 switch (assign_type) { | 3829 switch (assign_type) { |
3830 case VARIABLE: | 3830 case VARIABLE: |
3831 if (expr->is_postfix()) { | 3831 if (expr->is_postfix()) { |
3832 // Perform the assignment as if via '='. | 3832 // Perform the assignment as if via '='. |
3833 { EffectContext context(this); | 3833 { EffectContext context(this); |
3834 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 3834 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
(...skipping 13 matching lines...) Expand all Loading... |
3848 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3848 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
3849 context()->Plug(eax); | 3849 context()->Plug(eax); |
3850 } | 3850 } |
3851 break; | 3851 break; |
3852 case NAMED_PROPERTY: { | 3852 case NAMED_PROPERTY: { |
3853 __ mov(ecx, prop->key()->AsLiteral()->handle()); | 3853 __ mov(ecx, prop->key()->AsLiteral()->handle()); |
3854 __ pop(edx); | 3854 __ pop(edx); |
3855 Handle<Code> ic = is_strict_mode() | 3855 Handle<Code> ic = is_strict_mode() |
3856 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 3856 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
3857 : isolate()->builtins()->StoreIC_Initialize(); | 3857 : isolate()->builtins()->StoreIC_Initialize(); |
3858 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 3858 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); |
3859 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3859 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
3860 if (expr->is_postfix()) { | 3860 if (expr->is_postfix()) { |
3861 if (!context()->IsEffect()) { | 3861 if (!context()->IsEffect()) { |
3862 context()->PlugTOS(); | 3862 context()->PlugTOS(); |
3863 } | 3863 } |
3864 } else { | 3864 } else { |
3865 context()->Plug(eax); | 3865 context()->Plug(eax); |
3866 } | 3866 } |
3867 break; | 3867 break; |
3868 } | 3868 } |
3869 case KEYED_PROPERTY: { | 3869 case KEYED_PROPERTY: { |
3870 __ pop(ecx); | 3870 __ pop(ecx); |
3871 __ pop(edx); | 3871 __ pop(edx); |
3872 Handle<Code> ic = is_strict_mode() | 3872 Handle<Code> ic = is_strict_mode() |
3873 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() | 3873 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() |
3874 : isolate()->builtins()->KeyedStoreIC_Initialize(); | 3874 : isolate()->builtins()->KeyedStoreIC_Initialize(); |
3875 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 3875 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); |
3876 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3876 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
3877 if (expr->is_postfix()) { | 3877 if (expr->is_postfix()) { |
3878 // Result is on the stack | 3878 // Result is on the stack |
3879 if (!context()->IsEffect()) { | 3879 if (!context()->IsEffect()) { |
3880 context()->PlugTOS(); | 3880 context()->PlugTOS(); |
3881 } | 3881 } |
3882 } else { | 3882 } else { |
3883 context()->Plug(eax); | 3883 context()->Plug(eax); |
3884 } | 3884 } |
3885 break; | 3885 break; |
3886 } | 3886 } |
3887 } | 3887 } |
3888 } | 3888 } |
3889 | 3889 |
3890 | 3890 |
3891 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 3891 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
3892 VariableProxy* proxy = expr->AsVariableProxy(); | 3892 VariableProxy* proxy = expr->AsVariableProxy(); |
3893 ASSERT(!context()->IsEffect()); | 3893 ASSERT(!context()->IsEffect()); |
3894 ASSERT(!context()->IsTest()); | 3894 ASSERT(!context()->IsTest()); |
3895 | 3895 |
3896 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { | 3896 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { |
3897 Comment cmnt(masm_, "Global variable"); | 3897 Comment cmnt(masm_, "Global variable"); |
3898 __ mov(eax, GlobalObjectOperand()); | 3898 __ mov(eax, GlobalObjectOperand()); |
3899 __ mov(ecx, Immediate(proxy->name())); | 3899 __ mov(ecx, Immediate(proxy->name())); |
3900 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 3900 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
3901 // Use a regular load, not a contextual load, to avoid a reference | 3901 // Use a regular load, not a contextual load, to avoid a reference |
3902 // error. | 3902 // error. |
3903 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); | 3903 __ call(ic); |
3904 PrepareForBailout(expr, TOS_REG); | 3904 PrepareForBailout(expr, TOS_REG); |
3905 context()->Plug(eax); | 3905 context()->Plug(eax); |
3906 } else if (proxy != NULL && | 3906 } else if (proxy != NULL && |
3907 proxy->var()->AsSlot() != NULL && | 3907 proxy->var()->AsSlot() != NULL && |
3908 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { | 3908 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { |
3909 Label done, slow; | 3909 Label done, slow; |
3910 | 3910 |
3911 // Generate code for loading from variables potentially shadowed | 3911 // Generate code for loading from variables potentially shadowed |
3912 // by eval-introduced variables. | 3912 // by eval-introduced variables. |
3913 Slot* slot = proxy->var()->AsSlot(); | 3913 Slot* slot = proxy->var()->AsSlot(); |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4088 __ or_(ecx, Operand(eax)); | 4088 __ or_(ecx, Operand(eax)); |
4089 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear); | 4089 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear); |
4090 __ cmp(edx, Operand(eax)); | 4090 __ cmp(edx, Operand(eax)); |
4091 Split(cc, if_true, if_false, NULL); | 4091 Split(cc, if_true, if_false, NULL); |
4092 __ bind(&slow_case); | 4092 __ bind(&slow_case); |
4093 } | 4093 } |
4094 | 4094 |
4095 // Record position and call the compare IC. | 4095 // Record position and call the compare IC. |
4096 SetSourcePosition(expr->position()); | 4096 SetSourcePosition(expr->position()); |
4097 Handle<Code> ic = CompareIC::GetUninitialized(op); | 4097 Handle<Code> ic = CompareIC::GetUninitialized(op); |
4098 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 4098 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); |
4099 patch_site.EmitPatchInfo(); | 4099 patch_site.EmitPatchInfo(); |
4100 | 4100 |
4101 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 4101 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); |
4102 __ test(eax, Operand(eax)); | 4102 __ test(eax, Operand(eax)); |
4103 Split(cc, if_true, if_false, fall_through); | 4103 Split(cc, if_true, if_false, fall_through); |
4104 } | 4104 } |
4105 } | 4105 } |
4106 | 4106 |
4107 // Convert the result of the comparison into one expected for this | 4107 // Convert the result of the comparison into one expected for this |
4108 // expression's context. | 4108 // expression's context. |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4148 Register FullCodeGenerator::result_register() { | 4148 Register FullCodeGenerator::result_register() { |
4149 return eax; | 4149 return eax; |
4150 } | 4150 } |
4151 | 4151 |
4152 | 4152 |
4153 Register FullCodeGenerator::context_register() { | 4153 Register FullCodeGenerator::context_register() { |
4154 return esi; | 4154 return esi; |
4155 } | 4155 } |
4156 | 4156 |
4157 | 4157 |
4158 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, | |
4159 RelocInfo::Mode mode, | |
4160 unsigned ast_id) { | |
4161 ASSERT(mode == RelocInfo::CODE_TARGET || | |
4162 mode == RelocInfo::CODE_TARGET_CONTEXT); | |
4163 __ call(ic, mode, ast_id); | |
4164 } | |
4165 | |
4166 | |
4167 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { | 4158 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { |
4168 ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset); | 4159 ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset); |
4169 __ mov(Operand(ebp, frame_offset), value); | 4160 __ mov(Operand(ebp, frame_offset), value); |
4170 } | 4161 } |
4171 | 4162 |
4172 | 4163 |
4173 void FullCodeGenerator::LoadContextField(Register dst, int context_index) { | 4164 void FullCodeGenerator::LoadContextField(Register dst, int context_index) { |
4174 __ mov(dst, ContextOperand(esi, context_index)); | 4165 __ mov(dst, ContextOperand(esi, context_index)); |
4175 } | 4166 } |
4176 | 4167 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4223 // And return. | 4214 // And return. |
4224 __ ret(0); | 4215 __ ret(0); |
4225 } | 4216 } |
4226 | 4217 |
4227 | 4218 |
4228 #undef __ | 4219 #undef __ |
4229 | 4220 |
4230 } } // namespace v8::internal | 4221 } } // namespace v8::internal |
4231 | 4222 |
4232 #endif // V8_TARGET_ARCH_IA32 | 4223 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |