| 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 780 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 791 __ mov(a0, result_register()); | 791 __ mov(a0, result_register()); |
| 792 __ pop(a2); | 792 __ pop(a2); |
| 793 | 793 |
| 794 ASSERT(prop->key()->AsLiteral() != NULL && | 794 ASSERT(prop->key()->AsLiteral() != NULL && |
| 795 prop->key()->AsLiteral()->handle()->IsSmi()); | 795 prop->key()->AsLiteral()->handle()->IsSmi()); |
| 796 __ li(a1, Operand(prop->key()->AsLiteral()->handle())); | 796 __ li(a1, Operand(prop->key()->AsLiteral()->handle())); |
| 797 | 797 |
| 798 Handle<Code> ic = is_strict_mode() | 798 Handle<Code> ic = is_strict_mode() |
| 799 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() | 799 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() |
| 800 : isolate()->builtins()->KeyedStoreIC_Initialize(); | 800 : isolate()->builtins()->KeyedStoreIC_Initialize(); |
| 801 __ CallWithAstId(ic); | 801 __ Call(ic); |
| 802 // Value in v0 is ignored (declarations are statements). | 802 // Value in v0 is ignored (declarations are statements). |
| 803 } | 803 } |
| 804 } | 804 } |
| 805 } | 805 } |
| 806 | 806 |
| 807 | 807 |
| 808 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { | 808 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { |
| 809 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); | 809 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); |
| 810 } | 810 } |
| 811 | 811 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 866 __ Branch(&next_test, ne, a1, Operand(a0)); | 866 __ Branch(&next_test, ne, a1, Operand(a0)); |
| 867 __ Drop(1); // Switch value is no longer needed. | 867 __ Drop(1); // Switch value is no longer needed. |
| 868 __ Branch(clause->body_target()); | 868 __ Branch(clause->body_target()); |
| 869 | 869 |
| 870 __ bind(&slow_case); | 870 __ bind(&slow_case); |
| 871 } | 871 } |
| 872 | 872 |
| 873 // Record position before stub call for type feedback. | 873 // Record position before stub call for type feedback. |
| 874 SetSourcePosition(clause->position()); | 874 SetSourcePosition(clause->position()); |
| 875 Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT); | 875 Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT); |
| 876 __ CallWithAstId(ic, RelocInfo::CODE_TARGET, clause->CompareId()); | 876 __ Call(ic, RelocInfo::CODE_TARGET, clause->CompareId()); |
| 877 patch_site.EmitPatchInfo(); | 877 patch_site.EmitPatchInfo(); |
| 878 | 878 |
| 879 __ Branch(&next_test, ne, v0, Operand(zero_reg)); | 879 __ Branch(&next_test, ne, v0, Operand(zero_reg)); |
| 880 __ Drop(1); // Switch value is no longer needed. | 880 __ Drop(1); // Switch value is no longer needed. |
| 881 __ Branch(clause->body_target()); | 881 __ Branch(clause->body_target()); |
| 882 } | 882 } |
| 883 | 883 |
| 884 // Discard the test value and jump to the default if present, otherwise to | 884 // Discard the test value and jump to the default if present, otherwise to |
| 885 // the end of the statement. | 885 // the end of the statement. |
| 886 __ bind(&next_test); | 886 __ bind(&next_test); |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1166 __ Branch(&loop); | 1166 __ Branch(&loop); |
| 1167 __ bind(&fast); | 1167 __ bind(&fast); |
| 1168 } | 1168 } |
| 1169 | 1169 |
| 1170 __ lw(a0, GlobalObjectOperand()); | 1170 __ lw(a0, GlobalObjectOperand()); |
| 1171 __ li(a2, Operand(slot->var()->name())); | 1171 __ li(a2, Operand(slot->var()->name())); |
| 1172 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) | 1172 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) |
| 1173 ? RelocInfo::CODE_TARGET | 1173 ? RelocInfo::CODE_TARGET |
| 1174 : RelocInfo::CODE_TARGET_CONTEXT; | 1174 : RelocInfo::CODE_TARGET_CONTEXT; |
| 1175 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1175 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
| 1176 __ CallWithAstId(ic, mode); | 1176 __ Call(ic, mode); |
| 1177 } | 1177 } |
| 1178 | 1178 |
| 1179 | 1179 |
| 1180 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions( | 1180 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions( |
| 1181 Slot* slot, | 1181 Slot* slot, |
| 1182 Label* slow) { | 1182 Label* slow) { |
| 1183 ASSERT(slot->type() == Slot::CONTEXT); | 1183 ASSERT(slot->type() == Slot::CONTEXT); |
| 1184 Register context = cp; | 1184 Register context = cp; |
| 1185 Register next = a3; | 1185 Register next = a3; |
| 1186 Register temp = t0; | 1186 Register temp = t0; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1246 key_literal->handle()->IsSmi()) { | 1246 key_literal->handle()->IsSmi()) { |
| 1247 // Load arguments object if there are no eval-introduced | 1247 // Load arguments object if there are no eval-introduced |
| 1248 // variables. Then load the argument from the arguments | 1248 // variables. Then load the argument from the arguments |
| 1249 // object using keyed load. | 1249 // object using keyed load. |
| 1250 __ lw(a1, | 1250 __ lw(a1, |
| 1251 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), | 1251 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), |
| 1252 slow)); | 1252 slow)); |
| 1253 __ li(a0, Operand(key_literal->handle())); | 1253 __ li(a0, Operand(key_literal->handle())); |
| 1254 Handle<Code> ic = | 1254 Handle<Code> ic = |
| 1255 isolate()->builtins()->KeyedLoadIC_Initialize(); | 1255 isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 1256 __ CallWithAstId(ic, RelocInfo::CODE_TARGET, GetPropertyId(property)); | 1256 __ Call(ic, RelocInfo::CODE_TARGET, GetPropertyId(property)); |
| 1257 __ Branch(done); | 1257 __ Branch(done); |
| 1258 } | 1258 } |
| 1259 } | 1259 } |
| 1260 } | 1260 } |
| 1261 } | 1261 } |
| 1262 } | 1262 } |
| 1263 | 1263 |
| 1264 | 1264 |
| 1265 void FullCodeGenerator::EmitVariableLoad(Variable* var) { | 1265 void FullCodeGenerator::EmitVariableLoad(Variable* var) { |
| 1266 // Three cases: non-this global variables, lookup slots, and all other | 1266 // Three cases: non-this global variables, lookup slots, and all other |
| 1267 // types of slots. | 1267 // types of slots. |
| 1268 Slot* slot = var->AsSlot(); | 1268 Slot* slot = var->AsSlot(); |
| 1269 ASSERT((var->is_global() && !var->is_this()) == (slot == NULL)); | 1269 ASSERT((var->is_global() && !var->is_this()) == (slot == NULL)); |
| 1270 | 1270 |
| 1271 if (slot == NULL) { | 1271 if (slot == NULL) { |
| 1272 Comment cmnt(masm_, "Global variable"); | 1272 Comment cmnt(masm_, "Global variable"); |
| 1273 // Use inline caching. Variable name is passed in a2 and the global | 1273 // Use inline caching. Variable name is passed in a2 and the global |
| 1274 // object (receiver) in a0. | 1274 // object (receiver) in a0. |
| 1275 __ lw(a0, GlobalObjectOperand()); | 1275 __ lw(a0, GlobalObjectOperand()); |
| 1276 __ li(a2, Operand(var->name())); | 1276 __ li(a2, Operand(var->name())); |
| 1277 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1277 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
| 1278 __ CallWithAstId(ic, RelocInfo::CODE_TARGET_CONTEXT); | 1278 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); |
| 1279 context()->Plug(v0); | 1279 context()->Plug(v0); |
| 1280 | 1280 |
| 1281 } else if (slot->type() == Slot::LOOKUP) { | 1281 } else if (slot->type() == Slot::LOOKUP) { |
| 1282 Label done, slow; | 1282 Label done, slow; |
| 1283 | 1283 |
| 1284 // Generate code for loading from variables potentially shadowed | 1284 // Generate code for loading from variables potentially shadowed |
| 1285 // by eval-introduced variables. | 1285 // by eval-introduced variables. |
| 1286 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); | 1286 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); |
| 1287 | 1287 |
| 1288 __ bind(&slow); | 1288 __ bind(&slow); |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1414 case ObjectLiteral::Property::COMPUTED: | 1414 case ObjectLiteral::Property::COMPUTED: |
| 1415 if (key->handle()->IsSymbol()) { | 1415 if (key->handle()->IsSymbol()) { |
| 1416 if (property->emit_store()) { | 1416 if (property->emit_store()) { |
| 1417 VisitForAccumulatorValue(value); | 1417 VisitForAccumulatorValue(value); |
| 1418 __ mov(a0, result_register()); | 1418 __ mov(a0, result_register()); |
| 1419 __ li(a2, Operand(key->handle())); | 1419 __ li(a2, Operand(key->handle())); |
| 1420 __ lw(a1, MemOperand(sp)); | 1420 __ lw(a1, MemOperand(sp)); |
| 1421 Handle<Code> ic = is_strict_mode() | 1421 Handle<Code> ic = is_strict_mode() |
| 1422 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 1422 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
| 1423 : isolate()->builtins()->StoreIC_Initialize(); | 1423 : isolate()->builtins()->StoreIC_Initialize(); |
| 1424 __ CallWithAstId(ic, RelocInfo::CODE_TARGET, key->id()); | 1424 __ Call(ic, RelocInfo::CODE_TARGET, key->id()); |
| 1425 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1425 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
| 1426 } else { | 1426 } else { |
| 1427 VisitForEffect(value); | 1427 VisitForEffect(value); |
| 1428 } | 1428 } |
| 1429 break; | 1429 break; |
| 1430 } | 1430 } |
| 1431 // Fall through. | 1431 // Fall through. |
| 1432 case ObjectLiteral::Property::PROTOTYPE: | 1432 case ObjectLiteral::Property::PROTOTYPE: |
| 1433 // Duplicate receiver on stack. | 1433 // Duplicate receiver on stack. |
| 1434 __ lw(a0, MemOperand(sp)); | 1434 __ lw(a0, MemOperand(sp)); |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1658 } | 1658 } |
| 1659 | 1659 |
| 1660 | 1660 |
| 1661 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 1661 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
| 1662 SetSourcePosition(prop->position()); | 1662 SetSourcePosition(prop->position()); |
| 1663 Literal* key = prop->key()->AsLiteral(); | 1663 Literal* key = prop->key()->AsLiteral(); |
| 1664 __ mov(a0, result_register()); | 1664 __ mov(a0, result_register()); |
| 1665 __ li(a2, Operand(key->handle())); | 1665 __ li(a2, Operand(key->handle())); |
| 1666 // Call load IC. It has arguments receiver and property name a0 and a2. | 1666 // Call load IC. It has arguments receiver and property name a0 and a2. |
| 1667 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1667 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
| 1668 __ CallWithAstId(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); | 1668 __ Call(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); |
| 1669 } | 1669 } |
| 1670 | 1670 |
| 1671 | 1671 |
| 1672 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 1672 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
| 1673 SetSourcePosition(prop->position()); | 1673 SetSourcePosition(prop->position()); |
| 1674 __ mov(a0, result_register()); | 1674 __ mov(a0, result_register()); |
| 1675 // Call keyed load IC. It has arguments key and receiver in a0 and a1. | 1675 // Call keyed load IC. It has arguments key and receiver in a0 and a1. |
| 1676 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 1676 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 1677 __ CallWithAstId(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); | 1677 __ Call(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); |
| 1678 } | 1678 } |
| 1679 | 1679 |
| 1680 | 1680 |
| 1681 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 1681 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
| 1682 Token::Value op, | 1682 Token::Value op, |
| 1683 OverwriteMode mode, | 1683 OverwriteMode mode, |
| 1684 Expression* left_expr, | 1684 Expression* left_expr, |
| 1685 Expression* right_expr) { | 1685 Expression* right_expr) { |
| 1686 Label done, smi_case, stub_call; | 1686 Label done, smi_case, stub_call; |
| 1687 | 1687 |
| 1688 Register scratch1 = a2; | 1688 Register scratch1 = a2; |
| 1689 Register scratch2 = a3; | 1689 Register scratch2 = a3; |
| 1690 | 1690 |
| 1691 // Get the arguments. | 1691 // Get the arguments. |
| 1692 Register left = a1; | 1692 Register left = a1; |
| 1693 Register right = a0; | 1693 Register right = a0; |
| 1694 __ pop(left); | 1694 __ pop(left); |
| 1695 __ mov(a0, result_register()); | 1695 __ mov(a0, result_register()); |
| 1696 | 1696 |
| 1697 // Perform combined smi check on both operands. | 1697 // Perform combined smi check on both operands. |
| 1698 __ Or(scratch1, left, Operand(right)); | 1698 __ Or(scratch1, left, Operand(right)); |
| 1699 STATIC_ASSERT(kSmiTag == 0); | 1699 STATIC_ASSERT(kSmiTag == 0); |
| 1700 JumpPatchSite patch_site(masm_); | 1700 JumpPatchSite patch_site(masm_); |
| 1701 patch_site.EmitJumpIfSmi(scratch1, &smi_case); | 1701 patch_site.EmitJumpIfSmi(scratch1, &smi_case); |
| 1702 | 1702 |
| 1703 __ bind(&stub_call); | 1703 __ bind(&stub_call); |
| 1704 BinaryOpStub stub(op, mode); | 1704 BinaryOpStub stub(op, mode); |
| 1705 __ CallWithAstId(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); | 1705 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); |
| 1706 patch_site.EmitPatchInfo(); | 1706 patch_site.EmitPatchInfo(); |
| 1707 __ jmp(&done); | 1707 __ jmp(&done); |
| 1708 | 1708 |
| 1709 __ bind(&smi_case); | 1709 __ bind(&smi_case); |
| 1710 // Smi case. This code works the same way as the smi-smi case in the type | 1710 // Smi case. This code works the same way as the smi-smi case in the type |
| 1711 // recording binary operation stub, see | 1711 // recording binary operation stub, see |
| 1712 // BinaryOpStub::GenerateSmiSmiOperation for comments. | 1712 // BinaryOpStub::GenerateSmiSmiOperation for comments. |
| 1713 switch (op) { | 1713 switch (op) { |
| 1714 case Token::SAR: | 1714 case Token::SAR: |
| 1715 __ Branch(&stub_call); | 1715 __ Branch(&stub_call); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1778 } | 1778 } |
| 1779 | 1779 |
| 1780 | 1780 |
| 1781 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, | 1781 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, |
| 1782 Token::Value op, | 1782 Token::Value op, |
| 1783 OverwriteMode mode) { | 1783 OverwriteMode mode) { |
| 1784 __ mov(a0, result_register()); | 1784 __ mov(a0, result_register()); |
| 1785 __ pop(a1); | 1785 __ pop(a1); |
| 1786 BinaryOpStub stub(op, mode); | 1786 BinaryOpStub stub(op, mode); |
| 1787 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 1787 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
| 1788 __ CallWithAstId(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); | 1788 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); |
| 1789 patch_site.EmitPatchInfo(); | 1789 patch_site.EmitPatchInfo(); |
| 1790 context()->Plug(v0); | 1790 context()->Plug(v0); |
| 1791 } | 1791 } |
| 1792 | 1792 |
| 1793 | 1793 |
| 1794 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) { | 1794 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) { |
| 1795 // Invalid left-hand sides are rewritten to have a 'throw | 1795 // Invalid left-hand sides are rewritten to have a 'throw |
| 1796 // ReferenceError' on the left-hand side. | 1796 // ReferenceError' on the left-hand side. |
| 1797 if (!expr->IsValidLeftHandSide()) { | 1797 if (!expr->IsValidLeftHandSide()) { |
| 1798 VisitForEffect(expr); | 1798 VisitForEffect(expr); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1819 } | 1819 } |
| 1820 case NAMED_PROPERTY: { | 1820 case NAMED_PROPERTY: { |
| 1821 __ push(result_register()); // Preserve value. | 1821 __ push(result_register()); // Preserve value. |
| 1822 VisitForAccumulatorValue(prop->obj()); | 1822 VisitForAccumulatorValue(prop->obj()); |
| 1823 __ mov(a1, result_register()); | 1823 __ mov(a1, result_register()); |
| 1824 __ pop(a0); // Restore value. | 1824 __ pop(a0); // Restore value. |
| 1825 __ li(a2, Operand(prop->key()->AsLiteral()->handle())); | 1825 __ li(a2, Operand(prop->key()->AsLiteral()->handle())); |
| 1826 Handle<Code> ic = is_strict_mode() | 1826 Handle<Code> ic = is_strict_mode() |
| 1827 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 1827 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
| 1828 : isolate()->builtins()->StoreIC_Initialize(); | 1828 : isolate()->builtins()->StoreIC_Initialize(); |
| 1829 __ CallWithAstId(ic); | 1829 __ Call(ic); |
| 1830 break; | 1830 break; |
| 1831 } | 1831 } |
| 1832 case KEYED_PROPERTY: { | 1832 case KEYED_PROPERTY: { |
| 1833 __ push(result_register()); // Preserve value. | 1833 __ push(result_register()); // Preserve value. |
| 1834 VisitForStackValue(prop->obj()); | 1834 VisitForStackValue(prop->obj()); |
| 1835 VisitForAccumulatorValue(prop->key()); | 1835 VisitForAccumulatorValue(prop->key()); |
| 1836 __ mov(a1, result_register()); | 1836 __ mov(a1, result_register()); |
| 1837 __ pop(a2); | 1837 __ pop(a2); |
| 1838 __ pop(a0); // Restore value. | 1838 __ pop(a0); // Restore value. |
| 1839 Handle<Code> ic = is_strict_mode() | 1839 Handle<Code> ic = is_strict_mode() |
| 1840 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() | 1840 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() |
| 1841 : isolate()->builtins()->KeyedStoreIC_Initialize(); | 1841 : isolate()->builtins()->KeyedStoreIC_Initialize(); |
| 1842 __ CallWithAstId(ic); | 1842 __ Call(ic); |
| 1843 break; | 1843 break; |
| 1844 } | 1844 } |
| 1845 } | 1845 } |
| 1846 PrepareForBailoutForId(bailout_ast_id, TOS_REG); | 1846 PrepareForBailoutForId(bailout_ast_id, TOS_REG); |
| 1847 context()->Plug(v0); | 1847 context()->Plug(v0); |
| 1848 } | 1848 } |
| 1849 | 1849 |
| 1850 | 1850 |
| 1851 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 1851 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
| 1852 Token::Value op) { | 1852 Token::Value op) { |
| 1853 ASSERT(var != NULL); | 1853 ASSERT(var != NULL); |
| 1854 ASSERT(var->is_global() || var->AsSlot() != NULL); | 1854 ASSERT(var->is_global() || var->AsSlot() != NULL); |
| 1855 | 1855 |
| 1856 if (var->is_global()) { | 1856 if (var->is_global()) { |
| 1857 ASSERT(!var->is_this()); | 1857 ASSERT(!var->is_this()); |
| 1858 // Assignment to a global variable. Use inline caching for the | 1858 // Assignment to a global variable. Use inline caching for the |
| 1859 // assignment. Right-hand-side value is passed in a0, variable name in | 1859 // assignment. Right-hand-side value is passed in a0, variable name in |
| 1860 // a2, and the global object in a1. | 1860 // a2, and the global object in a1. |
| 1861 __ mov(a0, result_register()); | 1861 __ mov(a0, result_register()); |
| 1862 __ li(a2, Operand(var->name())); | 1862 __ li(a2, Operand(var->name())); |
| 1863 __ lw(a1, GlobalObjectOperand()); | 1863 __ lw(a1, GlobalObjectOperand()); |
| 1864 Handle<Code> ic = is_strict_mode() | 1864 Handle<Code> ic = is_strict_mode() |
| 1865 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 1865 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
| 1866 : isolate()->builtins()->StoreIC_Initialize(); | 1866 : isolate()->builtins()->StoreIC_Initialize(); |
| 1867 __ CallWithAstId(ic, RelocInfo::CODE_TARGET_CONTEXT); | 1867 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); |
| 1868 | 1868 |
| 1869 } else if (op == Token::INIT_CONST) { | 1869 } else if (op == Token::INIT_CONST) { |
| 1870 // Like var declarations, const declarations are hoisted to function | 1870 // Like var declarations, const declarations are hoisted to function |
| 1871 // scope. However, unlike var initializers, const initializers are able | 1871 // scope. However, unlike var initializers, const initializers are able |
| 1872 // to drill a hole to that function context, even from inside a 'with' | 1872 // to drill a hole to that function context, even from inside a 'with' |
| 1873 // context. We thus bypass the normal static scope lookup. | 1873 // context. We thus bypass the normal static scope lookup. |
| 1874 Slot* slot = var->AsSlot(); | 1874 Slot* slot = var->AsSlot(); |
| 1875 Label skip; | 1875 Label skip; |
| 1876 switch (slot->type()) { | 1876 switch (slot->type()) { |
| 1877 case Slot::PARAMETER: | 1877 case Slot::PARAMETER: |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1955 // receiver into fast case. | 1955 // receiver into fast case. |
| 1956 if (expr->ends_initialization_block()) { | 1956 if (expr->ends_initialization_block()) { |
| 1957 __ lw(a1, MemOperand(sp)); | 1957 __ lw(a1, MemOperand(sp)); |
| 1958 } else { | 1958 } else { |
| 1959 __ pop(a1); | 1959 __ pop(a1); |
| 1960 } | 1960 } |
| 1961 | 1961 |
| 1962 Handle<Code> ic = is_strict_mode() | 1962 Handle<Code> ic = is_strict_mode() |
| 1963 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 1963 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
| 1964 : isolate()->builtins()->StoreIC_Initialize(); | 1964 : isolate()->builtins()->StoreIC_Initialize(); |
| 1965 __ CallWithAstId(ic, RelocInfo::CODE_TARGET, expr->id()); | 1965 __ Call(ic, RelocInfo::CODE_TARGET, expr->id()); |
| 1966 | 1966 |
| 1967 // If the assignment ends an initialization block, revert to fast case. | 1967 // If the assignment ends an initialization block, revert to fast case. |
| 1968 if (expr->ends_initialization_block()) { | 1968 if (expr->ends_initialization_block()) { |
| 1969 __ push(v0); // Result of assignment, saved even if not needed. | 1969 __ push(v0); // Result of assignment, saved even if not needed. |
| 1970 // Receiver is under the result value. | 1970 // Receiver is under the result value. |
| 1971 __ lw(t0, MemOperand(sp, kPointerSize)); | 1971 __ lw(t0, MemOperand(sp, kPointerSize)); |
| 1972 __ push(t0); | 1972 __ push(t0); |
| 1973 __ CallRuntime(Runtime::kToFastProperties, 1); | 1973 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 1974 __ pop(v0); | 1974 __ pop(v0); |
| 1975 __ Drop(1); | 1975 __ Drop(1); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2007 // receiver into fast case. | 2007 // receiver into fast case. |
| 2008 if (expr->ends_initialization_block()) { | 2008 if (expr->ends_initialization_block()) { |
| 2009 __ lw(a2, MemOperand(sp)); | 2009 __ lw(a2, MemOperand(sp)); |
| 2010 } else { | 2010 } else { |
| 2011 __ pop(a2); | 2011 __ pop(a2); |
| 2012 } | 2012 } |
| 2013 | 2013 |
| 2014 Handle<Code> ic = is_strict_mode() | 2014 Handle<Code> ic = is_strict_mode() |
| 2015 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() | 2015 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() |
| 2016 : isolate()->builtins()->KeyedStoreIC_Initialize(); | 2016 : isolate()->builtins()->KeyedStoreIC_Initialize(); |
| 2017 __ CallWithAstId(ic, RelocInfo::CODE_TARGET, expr->id()); | 2017 __ Call(ic, RelocInfo::CODE_TARGET, expr->id()); |
| 2018 | 2018 |
| 2019 // If the assignment ends an initialization block, revert to fast case. | 2019 // If the assignment ends an initialization block, revert to fast case. |
| 2020 if (expr->ends_initialization_block()) { | 2020 if (expr->ends_initialization_block()) { |
| 2021 __ push(v0); // Result of assignment, saved even if not needed. | 2021 __ push(v0); // Result of assignment, saved even if not needed. |
| 2022 // Receiver is under the result value. | 2022 // Receiver is under the result value. |
| 2023 __ lw(t0, MemOperand(sp, kPointerSize)); | 2023 __ lw(t0, MemOperand(sp, kPointerSize)); |
| 2024 __ push(t0); | 2024 __ push(t0); |
| 2025 __ CallRuntime(Runtime::kToFastProperties, 1); | 2025 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 2026 __ pop(v0); | 2026 __ pop(v0); |
| 2027 __ Drop(1); | 2027 __ Drop(1); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2060 VisitForStackValue(args->at(i)); | 2060 VisitForStackValue(args->at(i)); |
| 2061 } | 2061 } |
| 2062 __ li(a2, Operand(name)); | 2062 __ li(a2, Operand(name)); |
| 2063 } | 2063 } |
| 2064 // Record source position for debugger. | 2064 // Record source position for debugger. |
| 2065 SetSourcePosition(expr->position()); | 2065 SetSourcePosition(expr->position()); |
| 2066 // Call the IC initialization code. | 2066 // Call the IC initialization code. |
| 2067 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 2067 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
| 2068 Handle<Code> ic = | 2068 Handle<Code> ic = |
| 2069 isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop, mode); | 2069 isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop, mode); |
| 2070 __ CallWithAstId(ic, mode, expr->id()); | 2070 __ Call(ic, mode, expr->id()); |
| 2071 RecordJSReturnSite(expr); | 2071 RecordJSReturnSite(expr); |
| 2072 // Restore context register. | 2072 // Restore context register. |
| 2073 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2073 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2074 context()->Plug(v0); | 2074 context()->Plug(v0); |
| 2075 } | 2075 } |
| 2076 | 2076 |
| 2077 | 2077 |
| 2078 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, | 2078 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, |
| 2079 Expression* key) { | 2079 Expression* key) { |
| 2080 // Load the key. | 2080 // Load the key. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2094 VisitForStackValue(args->at(i)); | 2094 VisitForStackValue(args->at(i)); |
| 2095 } | 2095 } |
| 2096 } | 2096 } |
| 2097 // Record source position for debugger. | 2097 // Record source position for debugger. |
| 2098 SetSourcePosition(expr->position()); | 2098 SetSourcePosition(expr->position()); |
| 2099 // Call the IC initialization code. | 2099 // Call the IC initialization code. |
| 2100 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 2100 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
| 2101 Handle<Code> ic = | 2101 Handle<Code> ic = |
| 2102 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop); | 2102 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop); |
| 2103 __ lw(a2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. | 2103 __ lw(a2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. |
| 2104 __ CallWithAstId(ic, RelocInfo::CODE_TARGET, expr->id()); | 2104 __ Call(ic, RelocInfo::CODE_TARGET, expr->id()); |
| 2105 RecordJSReturnSite(expr); | 2105 RecordJSReturnSite(expr); |
| 2106 // Restore context register. | 2106 // Restore context register. |
| 2107 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2107 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2108 context()->DropAndPlug(1, v0); // Drop the key still on the stack. | 2108 context()->DropAndPlug(1, v0); // Drop the key still on the stack. |
| 2109 } | 2109 } |
| 2110 | 2110 |
| 2111 | 2111 |
| 2112 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { | 2112 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { |
| 2113 // Code common for calls using the call stub. | 2113 // Code common for calls using the call stub. |
| 2114 ZoneList<Expression*>* args = expr->arguments(); | 2114 ZoneList<Expression*>* args = expr->arguments(); |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2294 __ lw(a1, operand); | 2294 __ lw(a1, operand); |
| 2295 | 2295 |
| 2296 ASSERT(prop->key()->AsLiteral() != NULL); | 2296 ASSERT(prop->key()->AsLiteral() != NULL); |
| 2297 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); | 2297 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); |
| 2298 __ li(a0, Operand(prop->key()->AsLiteral()->handle())); | 2298 __ li(a0, Operand(prop->key()->AsLiteral()->handle())); |
| 2299 | 2299 |
| 2300 // Record source code position for IC call. | 2300 // Record source code position for IC call. |
| 2301 SetSourcePosition(prop->position()); | 2301 SetSourcePosition(prop->position()); |
| 2302 | 2302 |
| 2303 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2303 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 2304 __ CallWithAstId(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); | 2304 __ Call(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); |
| 2305 __ lw(a1, GlobalObjectOperand()); | 2305 __ lw(a1, GlobalObjectOperand()); |
| 2306 __ lw(a1, FieldMemOperand(a1, GlobalObject::kGlobalReceiverOffset)); | 2306 __ lw(a1, FieldMemOperand(a1, GlobalObject::kGlobalReceiverOffset)); |
| 2307 __ Push(v0, a1); // Function, receiver. | 2307 __ Push(v0, a1); // Function, receiver. |
| 2308 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); | 2308 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); |
| 2309 } else { | 2309 } else { |
| 2310 { PreservePositionScope scope(masm()->positions_recorder()); | 2310 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2311 VisitForStackValue(prop->obj()); | 2311 VisitForStackValue(prop->obj()); |
| 2312 } | 2312 } |
| 2313 EmitKeyedCallWithIC(expr, prop->key()); | 2313 EmitKeyedCallWithIC(expr, prop->key()); |
| 2314 } | 2314 } |
| (...skipping 1342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3657 } | 3657 } |
| 3658 | 3658 |
| 3659 if (expr->is_jsruntime()) { | 3659 if (expr->is_jsruntime()) { |
| 3660 // Call the JS runtime function. | 3660 // Call the JS runtime function. |
| 3661 __ li(a2, Operand(expr->name())); | 3661 __ li(a2, Operand(expr->name())); |
| 3662 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; | 3662 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; |
| 3663 Handle<Code> ic = | 3663 Handle<Code> ic = |
| 3664 isolate()->stub_cache()->ComputeCallInitialize(arg_count, | 3664 isolate()->stub_cache()->ComputeCallInitialize(arg_count, |
| 3665 NOT_IN_LOOP, | 3665 NOT_IN_LOOP, |
| 3666 mode); | 3666 mode); |
| 3667 __ CallWithAstId(ic, mode, expr->id()); | 3667 __ Call(ic, mode, expr->id()); |
| 3668 // Restore context register. | 3668 // Restore context register. |
| 3669 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3669 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 3670 } else { | 3670 } else { |
| 3671 // Call the C runtime function. | 3671 // Call the C runtime function. |
| 3672 __ CallRuntime(expr->function(), arg_count); | 3672 __ CallRuntime(expr->function(), arg_count); |
| 3673 } | 3673 } |
| 3674 context()->Plug(v0); | 3674 context()->Plug(v0); |
| 3675 } | 3675 } |
| 3676 | 3676 |
| 3677 | 3677 |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3800 // TODO(svenpanne): Allowing format strings in Comment would be nice here... | 3800 // TODO(svenpanne): Allowing format strings in Comment would be nice here... |
| 3801 Comment cmt(masm_, comment); | 3801 Comment cmt(masm_, comment); |
| 3802 bool can_overwrite = expr->expression()->ResultOverwriteAllowed(); | 3802 bool can_overwrite = expr->expression()->ResultOverwriteAllowed(); |
| 3803 UnaryOverwriteMode overwrite = | 3803 UnaryOverwriteMode overwrite = |
| 3804 can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE; | 3804 can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE; |
| 3805 UnaryOpStub stub(expr->op(), overwrite); | 3805 UnaryOpStub stub(expr->op(), overwrite); |
| 3806 // GenericUnaryOpStub expects the argument to be in a0. | 3806 // GenericUnaryOpStub expects the argument to be in a0. |
| 3807 VisitForAccumulatorValue(expr->expression()); | 3807 VisitForAccumulatorValue(expr->expression()); |
| 3808 SetSourcePosition(expr->position()); | 3808 SetSourcePosition(expr->position()); |
| 3809 __ mov(a0, result_register()); | 3809 __ mov(a0, result_register()); |
| 3810 __ CallWithAstId(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); | 3810 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); |
| 3811 context()->Plug(v0); | 3811 context()->Plug(v0); |
| 3812 } | 3812 } |
| 3813 | 3813 |
| 3814 | 3814 |
| 3815 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { | 3815 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
| 3816 Comment cmnt(masm_, "[ CountOperation"); | 3816 Comment cmnt(masm_, "[ CountOperation"); |
| 3817 SetSourcePosition(expr->position()); | 3817 SetSourcePosition(expr->position()); |
| 3818 | 3818 |
| 3819 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError' | 3819 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError' |
| 3820 // as the left-hand side. | 3820 // as the left-hand side. |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3911 // We could eliminate this smi check if we split the code at | 3911 // We could eliminate this smi check if we split the code at |
| 3912 // the first smi check before calling ToNumber. | 3912 // the first smi check before calling ToNumber. |
| 3913 patch_site.EmitJumpIfSmi(v0, &done); | 3913 patch_site.EmitJumpIfSmi(v0, &done); |
| 3914 __ bind(&stub_call); | 3914 __ bind(&stub_call); |
| 3915 } | 3915 } |
| 3916 | 3916 |
| 3917 // Record position before stub call. | 3917 // Record position before stub call. |
| 3918 SetSourcePosition(expr->position()); | 3918 SetSourcePosition(expr->position()); |
| 3919 | 3919 |
| 3920 BinaryOpStub stub(Token::ADD, NO_OVERWRITE); | 3920 BinaryOpStub stub(Token::ADD, NO_OVERWRITE); |
| 3921 __ CallWithAstId(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId()); | 3921 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId()); |
| 3922 patch_site.EmitPatchInfo(); | 3922 patch_site.EmitPatchInfo(); |
| 3923 __ bind(&done); | 3923 __ bind(&done); |
| 3924 | 3924 |
| 3925 // Store the value returned in v0. | 3925 // Store the value returned in v0. |
| 3926 switch (assign_type) { | 3926 switch (assign_type) { |
| 3927 case VARIABLE: | 3927 case VARIABLE: |
| 3928 if (expr->is_postfix()) { | 3928 if (expr->is_postfix()) { |
| 3929 { EffectContext context(this); | 3929 { EffectContext context(this); |
| 3930 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 3930 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| 3931 Token::ASSIGN); | 3931 Token::ASSIGN); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 3944 context()->Plug(v0); | 3944 context()->Plug(v0); |
| 3945 } | 3945 } |
| 3946 break; | 3946 break; |
| 3947 case NAMED_PROPERTY: { | 3947 case NAMED_PROPERTY: { |
| 3948 __ mov(a0, result_register()); // Value. | 3948 __ mov(a0, result_register()); // Value. |
| 3949 __ li(a2, Operand(prop->key()->AsLiteral()->handle())); // Name. | 3949 __ li(a2, Operand(prop->key()->AsLiteral()->handle())); // Name. |
| 3950 __ pop(a1); // Receiver. | 3950 __ pop(a1); // Receiver. |
| 3951 Handle<Code> ic = is_strict_mode() | 3951 Handle<Code> ic = is_strict_mode() |
| 3952 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 3952 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
| 3953 : isolate()->builtins()->StoreIC_Initialize(); | 3953 : isolate()->builtins()->StoreIC_Initialize(); |
| 3954 __ CallWithAstId(ic, RelocInfo::CODE_TARGET, expr->id()); | 3954 __ Call(ic, RelocInfo::CODE_TARGET, expr->id()); |
| 3955 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3955 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 3956 if (expr->is_postfix()) { | 3956 if (expr->is_postfix()) { |
| 3957 if (!context()->IsEffect()) { | 3957 if (!context()->IsEffect()) { |
| 3958 context()->PlugTOS(); | 3958 context()->PlugTOS(); |
| 3959 } | 3959 } |
| 3960 } else { | 3960 } else { |
| 3961 context()->Plug(v0); | 3961 context()->Plug(v0); |
| 3962 } | 3962 } |
| 3963 break; | 3963 break; |
| 3964 } | 3964 } |
| 3965 case KEYED_PROPERTY: { | 3965 case KEYED_PROPERTY: { |
| 3966 __ mov(a0, result_register()); // Value. | 3966 __ mov(a0, result_register()); // Value. |
| 3967 __ pop(a1); // Key. | 3967 __ pop(a1); // Key. |
| 3968 __ pop(a2); // Receiver. | 3968 __ pop(a2); // Receiver. |
| 3969 Handle<Code> ic = is_strict_mode() | 3969 Handle<Code> ic = is_strict_mode() |
| 3970 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() | 3970 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() |
| 3971 : isolate()->builtins()->KeyedStoreIC_Initialize(); | 3971 : isolate()->builtins()->KeyedStoreIC_Initialize(); |
| 3972 __ CallWithAstId(ic, RelocInfo::CODE_TARGET, expr->id()); | 3972 __ Call(ic, RelocInfo::CODE_TARGET, expr->id()); |
| 3973 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3973 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 3974 if (expr->is_postfix()) { | 3974 if (expr->is_postfix()) { |
| 3975 if (!context()->IsEffect()) { | 3975 if (!context()->IsEffect()) { |
| 3976 context()->PlugTOS(); | 3976 context()->PlugTOS(); |
| 3977 } | 3977 } |
| 3978 } else { | 3978 } else { |
| 3979 context()->Plug(v0); | 3979 context()->Plug(v0); |
| 3980 } | 3980 } |
| 3981 break; | 3981 break; |
| 3982 } | 3982 } |
| 3983 } | 3983 } |
| 3984 } | 3984 } |
| 3985 | 3985 |
| 3986 | 3986 |
| 3987 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 3987 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
| 3988 VariableProxy* proxy = expr->AsVariableProxy(); | 3988 VariableProxy* proxy = expr->AsVariableProxy(); |
| 3989 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { | 3989 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { |
| 3990 Comment cmnt(masm_, "Global variable"); | 3990 Comment cmnt(masm_, "Global variable"); |
| 3991 __ lw(a0, GlobalObjectOperand()); | 3991 __ lw(a0, GlobalObjectOperand()); |
| 3992 __ li(a2, Operand(proxy->name())); | 3992 __ li(a2, Operand(proxy->name())); |
| 3993 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 3993 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
| 3994 // Use a regular load, not a contextual load, to avoid a reference | 3994 // Use a regular load, not a contextual load, to avoid a reference |
| 3995 // error. | 3995 // error. |
| 3996 __ CallWithAstId(ic); | 3996 __ Call(ic); |
| 3997 PrepareForBailout(expr, TOS_REG); | 3997 PrepareForBailout(expr, TOS_REG); |
| 3998 context()->Plug(v0); | 3998 context()->Plug(v0); |
| 3999 } else if (proxy != NULL && | 3999 } else if (proxy != NULL && |
| 4000 proxy->var()->AsSlot() != NULL && | 4000 proxy->var()->AsSlot() != NULL && |
| 4001 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { | 4001 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { |
| 4002 Label done, slow; | 4002 Label done, slow; |
| 4003 | 4003 |
| 4004 // Generate code for loading from variables potentially shadowed | 4004 // Generate code for loading from variables potentially shadowed |
| 4005 // by eval-introduced variables. | 4005 // by eval-introduced variables. |
| 4006 Slot* slot = proxy->var()->AsSlot(); | 4006 Slot* slot = proxy->var()->AsSlot(); |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4183 if (inline_smi_code) { | 4183 if (inline_smi_code) { |
| 4184 Label slow_case; | 4184 Label slow_case; |
| 4185 __ Or(a2, a0, Operand(a1)); | 4185 __ Or(a2, a0, Operand(a1)); |
| 4186 patch_site.EmitJumpIfNotSmi(a2, &slow_case); | 4186 patch_site.EmitJumpIfNotSmi(a2, &slow_case); |
| 4187 Split(cc, a1, Operand(a0), if_true, if_false, NULL); | 4187 Split(cc, a1, Operand(a0), if_true, if_false, NULL); |
| 4188 __ bind(&slow_case); | 4188 __ bind(&slow_case); |
| 4189 } | 4189 } |
| 4190 // Record position and call the compare IC. | 4190 // Record position and call the compare IC. |
| 4191 SetSourcePosition(expr->position()); | 4191 SetSourcePosition(expr->position()); |
| 4192 Handle<Code> ic = CompareIC::GetUninitialized(op); | 4192 Handle<Code> ic = CompareIC::GetUninitialized(op); |
| 4193 __ CallWithAstId(ic, RelocInfo::CODE_TARGET, expr->id()); | 4193 __ Call(ic, RelocInfo::CODE_TARGET, expr->id()); |
| 4194 patch_site.EmitPatchInfo(); | 4194 patch_site.EmitPatchInfo(); |
| 4195 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 4195 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); |
| 4196 Split(cc, v0, Operand(zero_reg), if_true, if_false, fall_through); | 4196 Split(cc, v0, Operand(zero_reg), if_true, if_false, fall_through); |
| 4197 } | 4197 } |
| 4198 } | 4198 } |
| 4199 | 4199 |
| 4200 // Convert the result of the comparison into one expected for this | 4200 // Convert the result of the comparison into one expected for this |
| 4201 // expression's context. | 4201 // expression's context. |
| 4202 context()->Plug(if_true, if_false); | 4202 context()->Plug(if_true, if_false); |
| 4203 } | 4203 } |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4309 __ Addu(at, a1, Operand(masm_->CodeObject())); | 4309 __ Addu(at, a1, Operand(masm_->CodeObject())); |
| 4310 __ Jump(at); | 4310 __ Jump(at); |
| 4311 } | 4311 } |
| 4312 | 4312 |
| 4313 | 4313 |
| 4314 #undef __ | 4314 #undef __ |
| 4315 | 4315 |
| 4316 } } // namespace v8::internal | 4316 } } // namespace v8::internal |
| 4317 | 4317 |
| 4318 #endif // V8_TARGET_ARCH_MIPS | 4318 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |