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 770 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
781 VisitForAccumulatorValue(function); | 781 VisitForAccumulatorValue(function); |
782 __ pop(r2); | 782 __ pop(r2); |
783 | 783 |
784 ASSERT(prop->key()->AsLiteral() != NULL && | 784 ASSERT(prop->key()->AsLiteral() != NULL && |
785 prop->key()->AsLiteral()->handle()->IsSmi()); | 785 prop->key()->AsLiteral()->handle()->IsSmi()); |
786 __ mov(r1, Operand(prop->key()->AsLiteral()->handle())); | 786 __ mov(r1, Operand(prop->key()->AsLiteral()->handle())); |
787 | 787 |
788 Handle<Code> ic = is_strict_mode() | 788 Handle<Code> ic = is_strict_mode() |
789 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() | 789 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() |
790 : isolate()->builtins()->KeyedStoreIC_Initialize(); | 790 : isolate()->builtins()->KeyedStoreIC_Initialize(); |
791 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); | 791 __ Call(ic); |
792 // Value in r0 is ignored (declarations are statements). | 792 // Value in r0 is ignored (declarations are statements). |
793 } | 793 } |
794 } | 794 } |
795 } | 795 } |
796 | 796 |
797 | 797 |
798 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { | 798 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { |
799 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); | 799 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); |
800 } | 800 } |
801 | 801 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
855 __ cmp(r1, r0); | 855 __ cmp(r1, r0); |
856 __ b(ne, &next_test); | 856 __ b(ne, &next_test); |
857 __ Drop(1); // Switch value is no longer needed. | 857 __ Drop(1); // Switch value is no longer needed. |
858 __ b(clause->body_target()); | 858 __ b(clause->body_target()); |
859 __ bind(&slow_case); | 859 __ bind(&slow_case); |
860 } | 860 } |
861 | 861 |
862 // Record position before stub call for type feedback. | 862 // Record position before stub call for type feedback. |
863 SetSourcePosition(clause->position()); | 863 SetSourcePosition(clause->position()); |
864 Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT); | 864 Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT); |
865 EmitCallIC(ic, RelocInfo::CODE_TARGET, clause->CompareId()); | 865 __ Call(ic, RelocInfo::CODE_TARGET, clause->CompareId()); |
866 patch_site.EmitPatchInfo(); | 866 patch_site.EmitPatchInfo(); |
867 | 867 |
868 __ cmp(r0, Operand(0)); | 868 __ cmp(r0, Operand(0)); |
869 __ b(ne, &next_test); | 869 __ b(ne, &next_test); |
870 __ Drop(1); // Switch value is no longer needed. | 870 __ Drop(1); // Switch value is no longer needed. |
871 __ b(clause->body_target()); | 871 __ b(clause->body_target()); |
872 } | 872 } |
873 | 873 |
874 // Discard the test value and jump to the default if present, otherwise to | 874 // Discard the test value and jump to the default if present, otherwise to |
875 // the end of the statement. | 875 // the end of the statement. |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1163 __ b(&loop); | 1163 __ b(&loop); |
1164 __ bind(&fast); | 1164 __ bind(&fast); |
1165 } | 1165 } |
1166 | 1166 |
1167 __ ldr(r0, GlobalObjectOperand()); | 1167 __ ldr(r0, GlobalObjectOperand()); |
1168 __ mov(r2, Operand(slot->var()->name())); | 1168 __ mov(r2, Operand(slot->var()->name())); |
1169 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) | 1169 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) |
1170 ? RelocInfo::CODE_TARGET | 1170 ? RelocInfo::CODE_TARGET |
1171 : RelocInfo::CODE_TARGET_CONTEXT; | 1171 : RelocInfo::CODE_TARGET_CONTEXT; |
1172 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1172 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
1173 EmitCallIC(ic, mode, AstNode::kNoNumber); | 1173 __ Call(ic, mode); |
1174 } | 1174 } |
1175 | 1175 |
1176 | 1176 |
1177 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions( | 1177 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions( |
1178 Slot* slot, | 1178 Slot* slot, |
1179 Label* slow) { | 1179 Label* slow) { |
1180 ASSERT(slot->type() == Slot::CONTEXT); | 1180 ASSERT(slot->type() == Slot::CONTEXT); |
1181 Register context = cp; | 1181 Register context = cp; |
1182 Register next = r3; | 1182 Register next = r3; |
1183 Register temp = r4; | 1183 Register temp = r4; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1244 key_literal->handle()->IsSmi()) { | 1244 key_literal->handle()->IsSmi()) { |
1245 // Load arguments object if there are no eval-introduced | 1245 // Load arguments object if there are no eval-introduced |
1246 // variables. Then load the argument from the arguments | 1246 // variables. Then load the argument from the arguments |
1247 // object using keyed load. | 1247 // object using keyed load. |
1248 __ ldr(r1, | 1248 __ ldr(r1, |
1249 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), | 1249 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), |
1250 slow)); | 1250 slow)); |
1251 __ mov(r0, Operand(key_literal->handle())); | 1251 __ mov(r0, Operand(key_literal->handle())); |
1252 Handle<Code> ic = | 1252 Handle<Code> ic = |
1253 isolate()->builtins()->KeyedLoadIC_Initialize(); | 1253 isolate()->builtins()->KeyedLoadIC_Initialize(); |
1254 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(property)); | 1254 __ Call(ic, RelocInfo::CODE_TARGET, GetPropertyId(property)); |
1255 __ jmp(done); | 1255 __ jmp(done); |
1256 } | 1256 } |
1257 } | 1257 } |
1258 } | 1258 } |
1259 } | 1259 } |
1260 } | 1260 } |
1261 | 1261 |
1262 | 1262 |
1263 void FullCodeGenerator::EmitVariableLoad(Variable* var) { | 1263 void FullCodeGenerator::EmitVariableLoad(Variable* var) { |
1264 // Three cases: non-this global variables, lookup slots, and all other | 1264 // Three cases: non-this global variables, lookup slots, and all other |
1265 // types of slots. | 1265 // types of slots. |
1266 Slot* slot = var->AsSlot(); | 1266 Slot* slot = var->AsSlot(); |
1267 ASSERT((var->is_global() && !var->is_this()) == (slot == NULL)); | 1267 ASSERT((var->is_global() && !var->is_this()) == (slot == NULL)); |
1268 | 1268 |
1269 if (slot == NULL) { | 1269 if (slot == NULL) { |
1270 Comment cmnt(masm_, "Global variable"); | 1270 Comment cmnt(masm_, "Global variable"); |
1271 // Use inline caching. Variable name is passed in r2 and the global | 1271 // Use inline caching. Variable name is passed in r2 and the global |
1272 // object (receiver) in r0. | 1272 // object (receiver) in r0. |
1273 __ ldr(r0, GlobalObjectOperand()); | 1273 __ ldr(r0, GlobalObjectOperand()); |
1274 __ mov(r2, Operand(var->name())); | 1274 __ mov(r2, Operand(var->name())); |
1275 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1275 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
1276 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT, AstNode::kNoNumber); | 1276 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); |
1277 context()->Plug(r0); | 1277 context()->Plug(r0); |
1278 | 1278 |
1279 } else if (slot->type() == Slot::LOOKUP) { | 1279 } else if (slot->type() == Slot::LOOKUP) { |
1280 Label done, slow; | 1280 Label done, slow; |
1281 | 1281 |
1282 // Generate code for loading from variables potentially shadowed | 1282 // Generate code for loading from variables potentially shadowed |
1283 // by eval-introduced variables. | 1283 // by eval-introduced variables. |
1284 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); | 1284 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); |
1285 | 1285 |
1286 __ bind(&slow); | 1286 __ bind(&slow); |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1410 // Fall through. | 1410 // Fall through. |
1411 case ObjectLiteral::Property::COMPUTED: | 1411 case ObjectLiteral::Property::COMPUTED: |
1412 if (key->handle()->IsSymbol()) { | 1412 if (key->handle()->IsSymbol()) { |
1413 if (property->emit_store()) { | 1413 if (property->emit_store()) { |
1414 VisitForAccumulatorValue(value); | 1414 VisitForAccumulatorValue(value); |
1415 __ mov(r2, Operand(key->handle())); | 1415 __ mov(r2, Operand(key->handle())); |
1416 __ ldr(r1, MemOperand(sp)); | 1416 __ ldr(r1, MemOperand(sp)); |
1417 Handle<Code> ic = is_strict_mode() | 1417 Handle<Code> ic = is_strict_mode() |
1418 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 1418 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
1419 : isolate()->builtins()->StoreIC_Initialize(); | 1419 : isolate()->builtins()->StoreIC_Initialize(); |
1420 EmitCallIC(ic, RelocInfo::CODE_TARGET, key->id()); | 1420 __ Call(ic, RelocInfo::CODE_TARGET, key->id()); |
1421 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1421 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
1422 } else { | 1422 } else { |
1423 VisitForEffect(value); | 1423 VisitForEffect(value); |
1424 } | 1424 } |
1425 break; | 1425 break; |
1426 } | 1426 } |
1427 // Fall through. | 1427 // Fall through. |
1428 case ObjectLiteral::Property::PROTOTYPE: | 1428 case ObjectLiteral::Property::PROTOTYPE: |
1429 // Duplicate receiver on stack. | 1429 // Duplicate receiver on stack. |
1430 __ ldr(r0, MemOperand(sp)); | 1430 __ ldr(r0, MemOperand(sp)); |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1650 } | 1650 } |
1651 } | 1651 } |
1652 | 1652 |
1653 | 1653 |
1654 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 1654 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
1655 SetSourcePosition(prop->position()); | 1655 SetSourcePosition(prop->position()); |
1656 Literal* key = prop->key()->AsLiteral(); | 1656 Literal* key = prop->key()->AsLiteral(); |
1657 __ mov(r2, Operand(key->handle())); | 1657 __ mov(r2, Operand(key->handle())); |
1658 // Call load IC. It has arguments receiver and property name r0 and r2. | 1658 // Call load IC. It has arguments receiver and property name r0 and r2. |
1659 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1659 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
1660 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); | 1660 __ Call(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); |
1661 } | 1661 } |
1662 | 1662 |
1663 | 1663 |
1664 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 1664 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
1665 SetSourcePosition(prop->position()); | 1665 SetSourcePosition(prop->position()); |
1666 // Call keyed load IC. It has arguments key and receiver in r0 and r1. | 1666 // Call keyed load IC. It has arguments key and receiver in r0 and r1. |
1667 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 1667 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
1668 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); | 1668 __ Call(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); |
1669 } | 1669 } |
1670 | 1670 |
1671 | 1671 |
1672 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 1672 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
1673 Token::Value op, | 1673 Token::Value op, |
1674 OverwriteMode mode, | 1674 OverwriteMode mode, |
1675 Expression* left_expr, | 1675 Expression* left_expr, |
1676 Expression* right_expr) { | 1676 Expression* right_expr) { |
1677 Label done, smi_case, stub_call; | 1677 Label done, smi_case, stub_call; |
1678 | 1678 |
1679 Register scratch1 = r2; | 1679 Register scratch1 = r2; |
1680 Register scratch2 = r3; | 1680 Register scratch2 = r3; |
1681 | 1681 |
1682 // Get the arguments. | 1682 // Get the arguments. |
1683 Register left = r1; | 1683 Register left = r1; |
1684 Register right = r0; | 1684 Register right = r0; |
1685 __ pop(left); | 1685 __ pop(left); |
1686 | 1686 |
1687 // Perform combined smi check on both operands. | 1687 // Perform combined smi check on both operands. |
1688 __ orr(scratch1, left, Operand(right)); | 1688 __ orr(scratch1, left, Operand(right)); |
1689 STATIC_ASSERT(kSmiTag == 0); | 1689 STATIC_ASSERT(kSmiTag == 0); |
1690 JumpPatchSite patch_site(masm_); | 1690 JumpPatchSite patch_site(masm_); |
1691 patch_site.EmitJumpIfSmi(scratch1, &smi_case); | 1691 patch_site.EmitJumpIfSmi(scratch1, &smi_case); |
1692 | 1692 |
1693 __ bind(&stub_call); | 1693 __ bind(&stub_call); |
1694 BinaryOpStub stub(op, mode); | 1694 BinaryOpStub stub(op, mode); |
1695 EmitCallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); | 1695 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); |
1696 patch_site.EmitPatchInfo(); | 1696 patch_site.EmitPatchInfo(); |
1697 __ jmp(&done); | 1697 __ jmp(&done); |
1698 | 1698 |
1699 __ bind(&smi_case); | 1699 __ bind(&smi_case); |
1700 // Smi case. This code works the same way as the smi-smi case in the type | 1700 // Smi case. This code works the same way as the smi-smi case in the type |
1701 // recording binary operation stub, see | 1701 // recording binary operation stub, see |
1702 // BinaryOpStub::GenerateSmiSmiOperation for comments. | 1702 // BinaryOpStub::GenerateSmiSmiOperation for comments. |
1703 switch (op) { | 1703 switch (op) { |
1704 case Token::SAR: | 1704 case Token::SAR: |
1705 __ b(&stub_call); | 1705 __ b(&stub_call); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1768 context()->Plug(r0); | 1768 context()->Plug(r0); |
1769 } | 1769 } |
1770 | 1770 |
1771 | 1771 |
1772 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, | 1772 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, |
1773 Token::Value op, | 1773 Token::Value op, |
1774 OverwriteMode mode) { | 1774 OverwriteMode mode) { |
1775 __ pop(r1); | 1775 __ pop(r1); |
1776 BinaryOpStub stub(op, mode); | 1776 BinaryOpStub stub(op, mode); |
1777 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 1777 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
1778 EmitCallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); | 1778 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); |
1779 patch_site.EmitPatchInfo(); | 1779 patch_site.EmitPatchInfo(); |
1780 context()->Plug(r0); | 1780 context()->Plug(r0); |
1781 } | 1781 } |
1782 | 1782 |
1783 | 1783 |
1784 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) { | 1784 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) { |
1785 // Invalid left-hand sides are rewritten to have a 'throw | 1785 // Invalid left-hand sides are rewritten to have a 'throw |
1786 // ReferenceError' on the left-hand side. | 1786 // ReferenceError' on the left-hand side. |
1787 if (!expr->IsValidLeftHandSide()) { | 1787 if (!expr->IsValidLeftHandSide()) { |
1788 VisitForEffect(expr); | 1788 VisitForEffect(expr); |
(...skipping 20 matching lines...) Expand all Loading... |
1809 } | 1809 } |
1810 case NAMED_PROPERTY: { | 1810 case NAMED_PROPERTY: { |
1811 __ push(r0); // Preserve value. | 1811 __ push(r0); // Preserve value. |
1812 VisitForAccumulatorValue(prop->obj()); | 1812 VisitForAccumulatorValue(prop->obj()); |
1813 __ mov(r1, r0); | 1813 __ mov(r1, r0); |
1814 __ pop(r0); // Restore value. | 1814 __ pop(r0); // Restore value. |
1815 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); | 1815 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); |
1816 Handle<Code> ic = is_strict_mode() | 1816 Handle<Code> ic = is_strict_mode() |
1817 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 1817 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
1818 : isolate()->builtins()->StoreIC_Initialize(); | 1818 : isolate()->builtins()->StoreIC_Initialize(); |
1819 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); | 1819 __ Call(ic); |
1820 break; | 1820 break; |
1821 } | 1821 } |
1822 case KEYED_PROPERTY: { | 1822 case KEYED_PROPERTY: { |
1823 __ push(r0); // Preserve value. | 1823 __ push(r0); // Preserve value. |
1824 VisitForStackValue(prop->obj()); | 1824 VisitForStackValue(prop->obj()); |
1825 VisitForAccumulatorValue(prop->key()); | 1825 VisitForAccumulatorValue(prop->key()); |
1826 __ mov(r1, r0); | 1826 __ mov(r1, r0); |
1827 __ pop(r2); | 1827 __ pop(r2); |
1828 __ pop(r0); // Restore value. | 1828 __ pop(r0); // Restore value. |
1829 Handle<Code> ic = is_strict_mode() | 1829 Handle<Code> ic = is_strict_mode() |
1830 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() | 1830 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() |
1831 : isolate()->builtins()->KeyedStoreIC_Initialize(); | 1831 : isolate()->builtins()->KeyedStoreIC_Initialize(); |
1832 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); | 1832 __ Call(ic); |
1833 break; | 1833 break; |
1834 } | 1834 } |
1835 } | 1835 } |
1836 PrepareForBailoutForId(bailout_ast_id, TOS_REG); | 1836 PrepareForBailoutForId(bailout_ast_id, TOS_REG); |
1837 context()->Plug(r0); | 1837 context()->Plug(r0); |
1838 } | 1838 } |
1839 | 1839 |
1840 | 1840 |
1841 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 1841 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
1842 Token::Value op) { | 1842 Token::Value op) { |
1843 ASSERT(var != NULL); | 1843 ASSERT(var != NULL); |
1844 ASSERT(var->is_global() || var->AsSlot() != NULL); | 1844 ASSERT(var->is_global() || var->AsSlot() != NULL); |
1845 | 1845 |
1846 if (var->is_global()) { | 1846 if (var->is_global()) { |
1847 ASSERT(!var->is_this()); | 1847 ASSERT(!var->is_this()); |
1848 // Assignment to a global variable. Use inline caching for the | 1848 // Assignment to a global variable. Use inline caching for the |
1849 // assignment. Right-hand-side value is passed in r0, variable name in | 1849 // assignment. Right-hand-side value is passed in r0, variable name in |
1850 // r2, and the global object in r1. | 1850 // r2, and the global object in r1. |
1851 __ mov(r2, Operand(var->name())); | 1851 __ mov(r2, Operand(var->name())); |
1852 __ ldr(r1, GlobalObjectOperand()); | 1852 __ ldr(r1, GlobalObjectOperand()); |
1853 Handle<Code> ic = is_strict_mode() | 1853 Handle<Code> ic = is_strict_mode() |
1854 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 1854 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
1855 : isolate()->builtins()->StoreIC_Initialize(); | 1855 : isolate()->builtins()->StoreIC_Initialize(); |
1856 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT, AstNode::kNoNumber); | 1856 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); |
1857 | 1857 |
1858 } else if (op == Token::INIT_CONST) { | 1858 } else if (op == Token::INIT_CONST) { |
1859 // Like var declarations, const declarations are hoisted to function | 1859 // Like var declarations, const declarations are hoisted to function |
1860 // scope. However, unlike var initializers, const initializers are able | 1860 // scope. However, unlike var initializers, const initializers are able |
1861 // to drill a hole to that function context, even from inside a 'with' | 1861 // to drill a hole to that function context, even from inside a 'with' |
1862 // context. We thus bypass the normal static scope lookup. | 1862 // context. We thus bypass the normal static scope lookup. |
1863 Slot* slot = var->AsSlot(); | 1863 Slot* slot = var->AsSlot(); |
1864 Label skip; | 1864 Label skip; |
1865 switch (slot->type()) { | 1865 switch (slot->type()) { |
1866 case Slot::PARAMETER: | 1866 case Slot::PARAMETER: |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1944 // receiver into fast case. | 1944 // receiver into fast case. |
1945 if (expr->ends_initialization_block()) { | 1945 if (expr->ends_initialization_block()) { |
1946 __ ldr(r1, MemOperand(sp)); | 1946 __ ldr(r1, MemOperand(sp)); |
1947 } else { | 1947 } else { |
1948 __ pop(r1); | 1948 __ pop(r1); |
1949 } | 1949 } |
1950 | 1950 |
1951 Handle<Code> ic = is_strict_mode() | 1951 Handle<Code> ic = is_strict_mode() |
1952 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 1952 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
1953 : isolate()->builtins()->StoreIC_Initialize(); | 1953 : isolate()->builtins()->StoreIC_Initialize(); |
1954 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 1954 __ Call(ic, RelocInfo::CODE_TARGET, expr->id()); |
1955 | 1955 |
1956 // If the assignment ends an initialization block, revert to fast case. | 1956 // If the assignment ends an initialization block, revert to fast case. |
1957 if (expr->ends_initialization_block()) { | 1957 if (expr->ends_initialization_block()) { |
1958 __ push(r0); // Result of assignment, saved even if not needed. | 1958 __ push(r0); // Result of assignment, saved even if not needed. |
1959 // Receiver is under the result value. | 1959 // Receiver is under the result value. |
1960 __ ldr(ip, MemOperand(sp, kPointerSize)); | 1960 __ ldr(ip, MemOperand(sp, kPointerSize)); |
1961 __ push(ip); | 1961 __ push(ip); |
1962 __ CallRuntime(Runtime::kToFastProperties, 1); | 1962 __ CallRuntime(Runtime::kToFastProperties, 1); |
1963 __ pop(r0); | 1963 __ pop(r0); |
1964 __ Drop(1); | 1964 __ Drop(1); |
(...skipping 25 matching lines...) Expand all Loading... |
1990 // receiver into fast case. | 1990 // receiver into fast case. |
1991 if (expr->ends_initialization_block()) { | 1991 if (expr->ends_initialization_block()) { |
1992 __ ldr(r2, MemOperand(sp)); | 1992 __ ldr(r2, MemOperand(sp)); |
1993 } else { | 1993 } else { |
1994 __ pop(r2); | 1994 __ pop(r2); |
1995 } | 1995 } |
1996 | 1996 |
1997 Handle<Code> ic = is_strict_mode() | 1997 Handle<Code> ic = is_strict_mode() |
1998 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() | 1998 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() |
1999 : isolate()->builtins()->KeyedStoreIC_Initialize(); | 1999 : isolate()->builtins()->KeyedStoreIC_Initialize(); |
2000 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 2000 __ Call(ic, RelocInfo::CODE_TARGET, expr->id()); |
2001 | 2001 |
2002 // If the assignment ends an initialization block, revert to fast case. | 2002 // If the assignment ends an initialization block, revert to fast case. |
2003 if (expr->ends_initialization_block()) { | 2003 if (expr->ends_initialization_block()) { |
2004 __ push(r0); // Result of assignment, saved even if not needed. | 2004 __ push(r0); // Result of assignment, saved even if not needed. |
2005 // Receiver is under the result value. | 2005 // Receiver is under the result value. |
2006 __ ldr(ip, MemOperand(sp, kPointerSize)); | 2006 __ ldr(ip, MemOperand(sp, kPointerSize)); |
2007 __ push(ip); | 2007 __ push(ip); |
2008 __ CallRuntime(Runtime::kToFastProperties, 1); | 2008 __ CallRuntime(Runtime::kToFastProperties, 1); |
2009 __ pop(r0); | 2009 __ pop(r0); |
2010 __ Drop(1); | 2010 __ Drop(1); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2042 VisitForStackValue(args->at(i)); | 2042 VisitForStackValue(args->at(i)); |
2043 } | 2043 } |
2044 __ mov(r2, Operand(name)); | 2044 __ mov(r2, Operand(name)); |
2045 } | 2045 } |
2046 // Record source position for debugger. | 2046 // Record source position for debugger. |
2047 SetSourcePosition(expr->position()); | 2047 SetSourcePosition(expr->position()); |
2048 // Call the IC initialization code. | 2048 // Call the IC initialization code. |
2049 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 2049 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
2050 Handle<Code> ic = | 2050 Handle<Code> ic = |
2051 isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop, mode); | 2051 isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop, mode); |
2052 EmitCallIC(ic, mode, expr->id()); | 2052 __ Call(ic, mode, expr->id()); |
2053 RecordJSReturnSite(expr); | 2053 RecordJSReturnSite(expr); |
2054 // Restore context register. | 2054 // Restore context register. |
2055 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2055 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2056 context()->Plug(r0); | 2056 context()->Plug(r0); |
2057 } | 2057 } |
2058 | 2058 |
2059 | 2059 |
2060 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, | 2060 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, |
2061 Expression* key) { | 2061 Expression* key) { |
2062 // Load the key. | 2062 // Load the key. |
(...skipping 13 matching lines...) Expand all Loading... |
2076 VisitForStackValue(args->at(i)); | 2076 VisitForStackValue(args->at(i)); |
2077 } | 2077 } |
2078 } | 2078 } |
2079 // Record source position for debugger. | 2079 // Record source position for debugger. |
2080 SetSourcePosition(expr->position()); | 2080 SetSourcePosition(expr->position()); |
2081 // Call the IC initialization code. | 2081 // Call the IC initialization code. |
2082 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 2082 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
2083 Handle<Code> ic = | 2083 Handle<Code> ic = |
2084 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop); | 2084 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop); |
2085 __ ldr(r2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. | 2085 __ ldr(r2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. |
2086 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 2086 __ Call(ic, RelocInfo::CODE_TARGET, expr->id()); |
2087 RecordJSReturnSite(expr); | 2087 RecordJSReturnSite(expr); |
2088 // Restore context register. | 2088 // Restore context register. |
2089 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2089 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2090 context()->DropAndPlug(1, r0); // Drop the key still on the stack. | 2090 context()->DropAndPlug(1, r0); // Drop the key still on the stack. |
2091 } | 2091 } |
2092 | 2092 |
2093 | 2093 |
2094 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { | 2094 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { |
2095 // Code common for calls using the call stub. | 2095 // Code common for calls using the call stub. |
2096 ZoneList<Expression*>* args = expr->arguments(); | 2096 ZoneList<Expression*>* args = expr->arguments(); |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2259 Literal* key = prop->key()->AsLiteral(); | 2259 Literal* key = prop->key()->AsLiteral(); |
2260 if (key != NULL && key->handle()->IsSymbol()) { | 2260 if (key != NULL && key->handle()->IsSymbol()) { |
2261 // Call to a named property, use call IC. | 2261 // Call to a named property, use call IC. |
2262 { PreservePositionScope scope(masm()->positions_recorder()); | 2262 { PreservePositionScope scope(masm()->positions_recorder()); |
2263 VisitForStackValue(prop->obj()); | 2263 VisitForStackValue(prop->obj()); |
2264 } | 2264 } |
2265 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); | 2265 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); |
2266 } else { | 2266 } else { |
2267 // Call to a keyed property. | 2267 // Call to a keyed property. |
2268 // For a synthetic property use keyed load IC followed by function call, | 2268 // For a synthetic property use keyed load IC followed by function call, |
2269 // for a regular property use keyed EmitCallIC. | 2269 // for a regular property use EmitKeyedCallWithIC. |
2270 if (prop->is_synthetic()) { | 2270 if (prop->is_synthetic()) { |
2271 // Do not visit the object and key subexpressions (they are shared | 2271 // Do not visit the object and key subexpressions (they are shared |
2272 // by all occurrences of the same rewritten parameter). | 2272 // by all occurrences of the same rewritten parameter). |
2273 ASSERT(prop->obj()->AsVariableProxy() != NULL); | 2273 ASSERT(prop->obj()->AsVariableProxy() != NULL); |
2274 ASSERT(prop->obj()->AsVariableProxy()->var()->AsSlot() != NULL); | 2274 ASSERT(prop->obj()->AsVariableProxy()->var()->AsSlot() != NULL); |
2275 Slot* slot = prop->obj()->AsVariableProxy()->var()->AsSlot(); | 2275 Slot* slot = prop->obj()->AsVariableProxy()->var()->AsSlot(); |
2276 MemOperand operand = EmitSlotSearch(slot, r1); | 2276 MemOperand operand = EmitSlotSearch(slot, r1); |
2277 __ ldr(r1, operand); | 2277 __ ldr(r1, operand); |
2278 | 2278 |
2279 ASSERT(prop->key()->AsLiteral() != NULL); | 2279 ASSERT(prop->key()->AsLiteral() != NULL); |
2280 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); | 2280 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); |
2281 __ mov(r0, Operand(prop->key()->AsLiteral()->handle())); | 2281 __ mov(r0, Operand(prop->key()->AsLiteral()->handle())); |
2282 | 2282 |
2283 // Record source code position for IC call. | 2283 // Record source code position for IC call. |
2284 SetSourcePosition(prop->position()); | 2284 SetSourcePosition(prop->position()); |
2285 | 2285 |
2286 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2286 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
2287 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); | 2287 __ Call(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); |
2288 __ ldr(r1, GlobalObjectOperand()); | 2288 __ ldr(r1, GlobalObjectOperand()); |
2289 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); | 2289 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); |
2290 __ Push(r0, r1); // Function, receiver. | 2290 __ Push(r0, r1); // Function, receiver. |
2291 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); | 2291 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); |
2292 } else { | 2292 } else { |
2293 { PreservePositionScope scope(masm()->positions_recorder()); | 2293 { PreservePositionScope scope(masm()->positions_recorder()); |
2294 VisitForStackValue(prop->obj()); | 2294 VisitForStackValue(prop->obj()); |
2295 } | 2295 } |
2296 EmitKeyedCallWithIC(expr, prop->key()); | 2296 EmitKeyedCallWithIC(expr, prop->key()); |
2297 } | 2297 } |
(...skipping 1301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3599 } | 3599 } |
3600 | 3600 |
3601 if (expr->is_jsruntime()) { | 3601 if (expr->is_jsruntime()) { |
3602 // Call the JS runtime function. | 3602 // Call the JS runtime function. |
3603 __ mov(r2, Operand(expr->name())); | 3603 __ mov(r2, Operand(expr->name())); |
3604 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; | 3604 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; |
3605 Handle<Code> ic = | 3605 Handle<Code> ic = |
3606 isolate()->stub_cache()->ComputeCallInitialize(arg_count, | 3606 isolate()->stub_cache()->ComputeCallInitialize(arg_count, |
3607 NOT_IN_LOOP, | 3607 NOT_IN_LOOP, |
3608 mode); | 3608 mode); |
3609 EmitCallIC(ic, mode, expr->id()); | 3609 __ Call(ic, mode, expr->id()); |
3610 // Restore context register. | 3610 // Restore context register. |
3611 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3611 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
3612 } else { | 3612 } else { |
3613 // Call the C runtime function. | 3613 // Call the C runtime function. |
3614 __ CallRuntime(expr->function(), arg_count); | 3614 __ CallRuntime(expr->function(), arg_count); |
3615 } | 3615 } |
3616 context()->Plug(r0); | 3616 context()->Plug(r0); |
3617 } | 3617 } |
3618 | 3618 |
3619 | 3619 |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3741 // TODO(svenpanne): Allowing format strings in Comment would be nice here... | 3741 // TODO(svenpanne): Allowing format strings in Comment would be nice here... |
3742 Comment cmt(masm_, comment); | 3742 Comment cmt(masm_, comment); |
3743 bool can_overwrite = expr->expression()->ResultOverwriteAllowed(); | 3743 bool can_overwrite = expr->expression()->ResultOverwriteAllowed(); |
3744 UnaryOverwriteMode overwrite = | 3744 UnaryOverwriteMode overwrite = |
3745 can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE; | 3745 can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE; |
3746 UnaryOpStub stub(expr->op(), overwrite); | 3746 UnaryOpStub stub(expr->op(), overwrite); |
3747 // UnaryOpStub expects the argument to be in the | 3747 // UnaryOpStub expects the argument to be in the |
3748 // accumulator register r0. | 3748 // accumulator register r0. |
3749 VisitForAccumulatorValue(expr->expression()); | 3749 VisitForAccumulatorValue(expr->expression()); |
3750 SetSourcePosition(expr->position()); | 3750 SetSourcePosition(expr->position()); |
3751 EmitCallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); | 3751 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); |
3752 context()->Plug(r0); | 3752 context()->Plug(r0); |
3753 } | 3753 } |
3754 | 3754 |
3755 | 3755 |
3756 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { | 3756 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
3757 Comment cmnt(masm_, "[ CountOperation"); | 3757 Comment cmnt(masm_, "[ CountOperation"); |
3758 SetSourcePosition(expr->position()); | 3758 SetSourcePosition(expr->position()); |
3759 | 3759 |
3760 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError' | 3760 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError' |
3761 // as the left-hand side. | 3761 // as the left-hand side. |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3852 __ bind(&stub_call); | 3852 __ bind(&stub_call); |
3853 // Call stub. Undo operation first. | 3853 // Call stub. Undo operation first. |
3854 __ sub(r0, r0, Operand(Smi::FromInt(count_value))); | 3854 __ sub(r0, r0, Operand(Smi::FromInt(count_value))); |
3855 } | 3855 } |
3856 __ mov(r1, Operand(Smi::FromInt(count_value))); | 3856 __ mov(r1, Operand(Smi::FromInt(count_value))); |
3857 | 3857 |
3858 // Record position before stub call. | 3858 // Record position before stub call. |
3859 SetSourcePosition(expr->position()); | 3859 SetSourcePosition(expr->position()); |
3860 | 3860 |
3861 BinaryOpStub stub(Token::ADD, NO_OVERWRITE); | 3861 BinaryOpStub stub(Token::ADD, NO_OVERWRITE); |
3862 EmitCallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId()); | 3862 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId()); |
3863 patch_site.EmitPatchInfo(); | 3863 patch_site.EmitPatchInfo(); |
3864 __ bind(&done); | 3864 __ bind(&done); |
3865 | 3865 |
3866 // Store the value returned in r0. | 3866 // Store the value returned in r0. |
3867 switch (assign_type) { | 3867 switch (assign_type) { |
3868 case VARIABLE: | 3868 case VARIABLE: |
3869 if (expr->is_postfix()) { | 3869 if (expr->is_postfix()) { |
3870 { EffectContext context(this); | 3870 { EffectContext context(this); |
3871 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 3871 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
3872 Token::ASSIGN); | 3872 Token::ASSIGN); |
(...skipping 11 matching lines...) Expand all Loading... |
3884 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3884 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
3885 context()->Plug(r0); | 3885 context()->Plug(r0); |
3886 } | 3886 } |
3887 break; | 3887 break; |
3888 case NAMED_PROPERTY: { | 3888 case NAMED_PROPERTY: { |
3889 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); | 3889 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); |
3890 __ pop(r1); | 3890 __ pop(r1); |
3891 Handle<Code> ic = is_strict_mode() | 3891 Handle<Code> ic = is_strict_mode() |
3892 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 3892 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
3893 : isolate()->builtins()->StoreIC_Initialize(); | 3893 : isolate()->builtins()->StoreIC_Initialize(); |
3894 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 3894 __ Call(ic, RelocInfo::CODE_TARGET, expr->id()); |
3895 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3895 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
3896 if (expr->is_postfix()) { | 3896 if (expr->is_postfix()) { |
3897 if (!context()->IsEffect()) { | 3897 if (!context()->IsEffect()) { |
3898 context()->PlugTOS(); | 3898 context()->PlugTOS(); |
3899 } | 3899 } |
3900 } else { | 3900 } else { |
3901 context()->Plug(r0); | 3901 context()->Plug(r0); |
3902 } | 3902 } |
3903 break; | 3903 break; |
3904 } | 3904 } |
3905 case KEYED_PROPERTY: { | 3905 case KEYED_PROPERTY: { |
3906 __ pop(r1); // Key. | 3906 __ pop(r1); // Key. |
3907 __ pop(r2); // Receiver. | 3907 __ pop(r2); // Receiver. |
3908 Handle<Code> ic = is_strict_mode() | 3908 Handle<Code> ic = is_strict_mode() |
3909 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() | 3909 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() |
3910 : isolate()->builtins()->KeyedStoreIC_Initialize(); | 3910 : isolate()->builtins()->KeyedStoreIC_Initialize(); |
3911 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 3911 __ Call(ic, RelocInfo::CODE_TARGET, expr->id()); |
3912 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3912 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
3913 if (expr->is_postfix()) { | 3913 if (expr->is_postfix()) { |
3914 if (!context()->IsEffect()) { | 3914 if (!context()->IsEffect()) { |
3915 context()->PlugTOS(); | 3915 context()->PlugTOS(); |
3916 } | 3916 } |
3917 } else { | 3917 } else { |
3918 context()->Plug(r0); | 3918 context()->Plug(r0); |
3919 } | 3919 } |
3920 break; | 3920 break; |
3921 } | 3921 } |
3922 } | 3922 } |
3923 } | 3923 } |
3924 | 3924 |
3925 | 3925 |
3926 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 3926 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
3927 ASSERT(!context()->IsEffect()); | 3927 ASSERT(!context()->IsEffect()); |
3928 ASSERT(!context()->IsTest()); | 3928 ASSERT(!context()->IsTest()); |
3929 VariableProxy* proxy = expr->AsVariableProxy(); | 3929 VariableProxy* proxy = expr->AsVariableProxy(); |
3930 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { | 3930 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { |
3931 Comment cmnt(masm_, "Global variable"); | 3931 Comment cmnt(masm_, "Global variable"); |
3932 __ ldr(r0, GlobalObjectOperand()); | 3932 __ ldr(r0, GlobalObjectOperand()); |
3933 __ mov(r2, Operand(proxy->name())); | 3933 __ mov(r2, Operand(proxy->name())); |
3934 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 3934 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
3935 // Use a regular load, not a contextual load, to avoid a reference | 3935 // Use a regular load, not a contextual load, to avoid a reference |
3936 // error. | 3936 // error. |
3937 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); | 3937 __ Call(ic); |
3938 PrepareForBailout(expr, TOS_REG); | 3938 PrepareForBailout(expr, TOS_REG); |
3939 context()->Plug(r0); | 3939 context()->Plug(r0); |
3940 } else if (proxy != NULL && | 3940 } else if (proxy != NULL && |
3941 proxy->var()->AsSlot() != NULL && | 3941 proxy->var()->AsSlot() != NULL && |
3942 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { | 3942 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { |
3943 Label done, slow; | 3943 Label done, slow; |
3944 | 3944 |
3945 // Generate code for loading from variables potentially shadowed | 3945 // Generate code for loading from variables potentially shadowed |
3946 // by eval-introduced variables. | 3946 // by eval-introduced variables. |
3947 Slot* slot = proxy->var()->AsSlot(); | 3947 Slot* slot = proxy->var()->AsSlot(); |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4126 __ orr(r2, r0, Operand(r1)); | 4126 __ orr(r2, r0, Operand(r1)); |
4127 patch_site.EmitJumpIfNotSmi(r2, &slow_case); | 4127 patch_site.EmitJumpIfNotSmi(r2, &slow_case); |
4128 __ cmp(r1, r0); | 4128 __ cmp(r1, r0); |
4129 Split(cond, if_true, if_false, NULL); | 4129 Split(cond, if_true, if_false, NULL); |
4130 __ bind(&slow_case); | 4130 __ bind(&slow_case); |
4131 } | 4131 } |
4132 | 4132 |
4133 // Record position and call the compare IC. | 4133 // Record position and call the compare IC. |
4134 SetSourcePosition(expr->position()); | 4134 SetSourcePosition(expr->position()); |
4135 Handle<Code> ic = CompareIC::GetUninitialized(op); | 4135 Handle<Code> ic = CompareIC::GetUninitialized(op); |
4136 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 4136 __ Call(ic, RelocInfo::CODE_TARGET, expr->id()); |
4137 patch_site.EmitPatchInfo(); | 4137 patch_site.EmitPatchInfo(); |
4138 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 4138 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); |
4139 __ cmp(r0, Operand(0)); | 4139 __ cmp(r0, Operand(0)); |
4140 Split(cond, if_true, if_false, fall_through); | 4140 Split(cond, if_true, if_false, fall_through); |
4141 } | 4141 } |
4142 } | 4142 } |
4143 | 4143 |
4144 // Convert the result of the comparison into one expected for this | 4144 // Convert the result of the comparison into one expected for this |
4145 // expression's context. | 4145 // expression's context. |
4146 context()->Plug(if_true, if_false); | 4146 context()->Plug(if_true, if_false); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4188 Register FullCodeGenerator::result_register() { | 4188 Register FullCodeGenerator::result_register() { |
4189 return r0; | 4189 return r0; |
4190 } | 4190 } |
4191 | 4191 |
4192 | 4192 |
4193 Register FullCodeGenerator::context_register() { | 4193 Register FullCodeGenerator::context_register() { |
4194 return cp; | 4194 return cp; |
4195 } | 4195 } |
4196 | 4196 |
4197 | 4197 |
4198 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, | |
4199 RelocInfo::Mode mode, | |
4200 unsigned ast_id) { | |
4201 ASSERT(mode == RelocInfo::CODE_TARGET || | |
4202 mode == RelocInfo::CODE_TARGET_CONTEXT); | |
4203 __ Call(ic, mode, ast_id); | |
4204 } | |
4205 | |
4206 | |
4207 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { | 4198 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { |
4208 ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset); | 4199 ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset); |
4209 __ str(value, MemOperand(fp, frame_offset)); | 4200 __ str(value, MemOperand(fp, frame_offset)); |
4210 } | 4201 } |
4211 | 4202 |
4212 | 4203 |
4213 void FullCodeGenerator::LoadContextField(Register dst, int context_index) { | 4204 void FullCodeGenerator::LoadContextField(Register dst, int context_index) { |
4214 __ ldr(dst, ContextOperand(cp, context_index)); | 4205 __ ldr(dst, ContextOperand(cp, context_index)); |
4215 } | 4206 } |
4216 | 4207 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4261 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. | 4252 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. |
4262 __ add(pc, r1, Operand(masm_->CodeObject())); | 4253 __ add(pc, r1, Operand(masm_->CodeObject())); |
4263 } | 4254 } |
4264 | 4255 |
4265 | 4256 |
4266 #undef __ | 4257 #undef __ |
4267 | 4258 |
4268 } } // namespace v8::internal | 4259 } } // namespace v8::internal |
4269 | 4260 |
4270 #endif // V8_TARGET_ARCH_ARM | 4261 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |