| 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 |