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 |