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 778 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
789 __ mov(a0, result_register()); | 789 __ mov(a0, result_register()); |
790 __ pop(a2); | 790 __ pop(a2); |
791 | 791 |
792 ASSERT(prop->key()->AsLiteral() != NULL && | 792 ASSERT(prop->key()->AsLiteral() != NULL && |
793 prop->key()->AsLiteral()->handle()->IsSmi()); | 793 prop->key()->AsLiteral()->handle()->IsSmi()); |
794 __ li(a1, Operand(prop->key()->AsLiteral()->handle())); | 794 __ li(a1, Operand(prop->key()->AsLiteral()->handle())); |
795 | 795 |
796 Handle<Code> ic = is_strict_mode() | 796 Handle<Code> ic = is_strict_mode() |
797 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() | 797 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() |
798 : isolate()->builtins()->KeyedStoreIC_Initialize(); | 798 : isolate()->builtins()->KeyedStoreIC_Initialize(); |
799 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); | 799 __ CallWithAstId(ic); |
800 // Value in v0 is ignored (declarations are statements). | 800 // Value in v0 is ignored (declarations are statements). |
801 } | 801 } |
802 } | 802 } |
803 } | 803 } |
804 | 804 |
805 | 805 |
806 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { | 806 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { |
807 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); | 807 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); |
808 } | 808 } |
809 | 809 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
864 __ Branch(&next_test, ne, a1, Operand(a0)); | 864 __ Branch(&next_test, ne, a1, Operand(a0)); |
865 __ Drop(1); // Switch value is no longer needed. | 865 __ Drop(1); // Switch value is no longer needed. |
866 __ Branch(clause->body_target()); | 866 __ Branch(clause->body_target()); |
867 | 867 |
868 __ bind(&slow_case); | 868 __ bind(&slow_case); |
869 } | 869 } |
870 | 870 |
871 // Record position before stub call for type feedback. | 871 // Record position before stub call for type feedback. |
872 SetSourcePosition(clause->position()); | 872 SetSourcePosition(clause->position()); |
873 Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT); | 873 Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT); |
874 EmitCallIC(ic, RelocInfo::CODE_TARGET, clause->CompareId()); | 874 __ CallWithAstId(ic, RelocInfo::CODE_TARGET, clause->CompareId()); |
875 patch_site.EmitPatchInfo(); | 875 patch_site.EmitPatchInfo(); |
876 | 876 |
877 __ Branch(&next_test, ne, v0, Operand(zero_reg)); | 877 __ Branch(&next_test, ne, v0, Operand(zero_reg)); |
878 __ Drop(1); // Switch value is no longer needed. | 878 __ Drop(1); // Switch value is no longer needed. |
879 __ Branch(clause->body_target()); | 879 __ Branch(clause->body_target()); |
880 } | 880 } |
881 | 881 |
882 // Discard the test value and jump to the default if present, otherwise to | 882 // Discard the test value and jump to the default if present, otherwise to |
883 // the end of the statement. | 883 // the end of the statement. |
884 __ bind(&next_test); | 884 __ bind(&next_test); |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1164 __ Branch(&loop); | 1164 __ Branch(&loop); |
1165 __ bind(&fast); | 1165 __ bind(&fast); |
1166 } | 1166 } |
1167 | 1167 |
1168 __ lw(a0, GlobalObjectOperand()); | 1168 __ lw(a0, GlobalObjectOperand()); |
1169 __ li(a2, Operand(slot->var()->name())); | 1169 __ li(a2, Operand(slot->var()->name())); |
1170 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) | 1170 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) |
1171 ? RelocInfo::CODE_TARGET | 1171 ? RelocInfo::CODE_TARGET |
1172 : RelocInfo::CODE_TARGET_CONTEXT; | 1172 : RelocInfo::CODE_TARGET_CONTEXT; |
1173 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1173 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
1174 EmitCallIC(ic, mode, AstNode::kNoNumber); | 1174 __ CallWithAstId(ic, mode); |
1175 } | 1175 } |
1176 | 1176 |
1177 | 1177 |
1178 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions( | 1178 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions( |
1179 Slot* slot, | 1179 Slot* slot, |
1180 Label* slow) { | 1180 Label* slow) { |
1181 ASSERT(slot->type() == Slot::CONTEXT); | 1181 ASSERT(slot->type() == Slot::CONTEXT); |
1182 Register context = cp; | 1182 Register context = cp; |
1183 Register next = a3; | 1183 Register next = a3; |
1184 Register temp = t0; | 1184 Register temp = t0; |
(...skipping 59 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 __ lw(a1, | 1248 __ lw(a1, |
1249 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), | 1249 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), |
1250 slow)); | 1250 slow)); |
1251 __ li(a0, Operand(key_literal->handle())); | 1251 __ li(a0, 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 __ CallWithAstId(ic, RelocInfo::CODE_TARGET, GetPropertyId(property)); |
1255 __ Branch(done); | 1255 __ Branch(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 a2 and the global | 1271 // Use inline caching. Variable name is passed in a2 and the global |
1272 // object (receiver) in a0. | 1272 // object (receiver) in a0. |
1273 __ lw(a0, GlobalObjectOperand()); | 1273 __ lw(a0, GlobalObjectOperand()); |
1274 __ li(a2, Operand(var->name())); | 1274 __ li(a2, 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 __ CallWithAstId(ic, RelocInfo::CODE_TARGET_CONTEXT); |
1277 context()->Plug(v0); | 1277 context()->Plug(v0); |
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 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1412 case ObjectLiteral::Property::COMPUTED: | 1412 case ObjectLiteral::Property::COMPUTED: |
1413 if (key->handle()->IsSymbol()) { | 1413 if (key->handle()->IsSymbol()) { |
1414 if (property->emit_store()) { | 1414 if (property->emit_store()) { |
1415 VisitForAccumulatorValue(value); | 1415 VisitForAccumulatorValue(value); |
1416 __ mov(a0, result_register()); | 1416 __ mov(a0, result_register()); |
1417 __ li(a2, Operand(key->handle())); | 1417 __ li(a2, Operand(key->handle())); |
1418 __ lw(a1, MemOperand(sp)); | 1418 __ lw(a1, MemOperand(sp)); |
1419 Handle<Code> ic = is_strict_mode() | 1419 Handle<Code> ic = is_strict_mode() |
1420 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 1420 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
1421 : isolate()->builtins()->StoreIC_Initialize(); | 1421 : isolate()->builtins()->StoreIC_Initialize(); |
1422 EmitCallIC(ic, RelocInfo::CODE_TARGET, key->id()); | 1422 __ CallWithAstId(ic, RelocInfo::CODE_TARGET, key->id()); |
1423 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1423 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
1424 } else { | 1424 } else { |
1425 VisitForEffect(value); | 1425 VisitForEffect(value); |
1426 } | 1426 } |
1427 break; | 1427 break; |
1428 } | 1428 } |
1429 // Fall through. | 1429 // Fall through. |
1430 case ObjectLiteral::Property::PROTOTYPE: | 1430 case ObjectLiteral::Property::PROTOTYPE: |
1431 // Duplicate receiver on stack. | 1431 // Duplicate receiver on stack. |
1432 __ lw(a0, MemOperand(sp)); | 1432 __ lw(a0, MemOperand(sp)); |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1656 } | 1656 } |
1657 | 1657 |
1658 | 1658 |
1659 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 1659 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
1660 SetSourcePosition(prop->position()); | 1660 SetSourcePosition(prop->position()); |
1661 Literal* key = prop->key()->AsLiteral(); | 1661 Literal* key = prop->key()->AsLiteral(); |
1662 __ mov(a0, result_register()); | 1662 __ mov(a0, result_register()); |
1663 __ li(a2, Operand(key->handle())); | 1663 __ li(a2, Operand(key->handle())); |
1664 // Call load IC. It has arguments receiver and property name a0 and a2. | 1664 // Call load IC. It has arguments receiver and property name a0 and a2. |
1665 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1665 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
1666 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); | 1666 __ CallWithAstId(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); |
1667 } | 1667 } |
1668 | 1668 |
1669 | 1669 |
1670 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 1670 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
1671 SetSourcePosition(prop->position()); | 1671 SetSourcePosition(prop->position()); |
1672 __ mov(a0, result_register()); | 1672 __ mov(a0, result_register()); |
1673 // Call keyed load IC. It has arguments key and receiver in a0 and a1. | 1673 // Call keyed load IC. It has arguments key and receiver in a0 and a1. |
1674 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 1674 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
1675 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); | 1675 __ CallWithAstId(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); |
1676 } | 1676 } |
1677 | 1677 |
1678 | 1678 |
1679 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 1679 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
1680 Token::Value op, | 1680 Token::Value op, |
1681 OverwriteMode mode, | 1681 OverwriteMode mode, |
1682 Expression* left_expr, | 1682 Expression* left_expr, |
1683 Expression* right_expr) { | 1683 Expression* right_expr) { |
1684 Label done, smi_case, stub_call; | 1684 Label done, smi_case, stub_call; |
1685 | 1685 |
1686 Register scratch1 = a2; | 1686 Register scratch1 = a2; |
1687 Register scratch2 = a3; | 1687 Register scratch2 = a3; |
1688 | 1688 |
1689 // Get the arguments. | 1689 // Get the arguments. |
1690 Register left = a1; | 1690 Register left = a1; |
1691 Register right = a0; | 1691 Register right = a0; |
1692 __ pop(left); | 1692 __ pop(left); |
1693 __ mov(a0, result_register()); | 1693 __ mov(a0, result_register()); |
1694 | 1694 |
1695 // Perform combined smi check on both operands. | 1695 // Perform combined smi check on both operands. |
1696 __ Or(scratch1, left, Operand(right)); | 1696 __ Or(scratch1, left, Operand(right)); |
1697 STATIC_ASSERT(kSmiTag == 0); | 1697 STATIC_ASSERT(kSmiTag == 0); |
1698 JumpPatchSite patch_site(masm_); | 1698 JumpPatchSite patch_site(masm_); |
1699 patch_site.EmitJumpIfSmi(scratch1, &smi_case); | 1699 patch_site.EmitJumpIfSmi(scratch1, &smi_case); |
1700 | 1700 |
1701 __ bind(&stub_call); | 1701 __ bind(&stub_call); |
1702 BinaryOpStub stub(op, mode); | 1702 BinaryOpStub stub(op, mode); |
1703 EmitCallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); | 1703 __ CallWithAstId(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); |
1704 patch_site.EmitPatchInfo(); | 1704 patch_site.EmitPatchInfo(); |
1705 __ jmp(&done); | 1705 __ jmp(&done); |
1706 | 1706 |
1707 __ bind(&smi_case); | 1707 __ bind(&smi_case); |
1708 // Smi case. This code works the same way as the smi-smi case in the type | 1708 // Smi case. This code works the same way as the smi-smi case in the type |
1709 // recording binary operation stub, see | 1709 // recording binary operation stub, see |
1710 // BinaryOpStub::GenerateSmiSmiOperation for comments. | 1710 // BinaryOpStub::GenerateSmiSmiOperation for comments. |
1711 switch (op) { | 1711 switch (op) { |
1712 case Token::SAR: | 1712 case Token::SAR: |
1713 __ Branch(&stub_call); | 1713 __ Branch(&stub_call); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1776 } | 1776 } |
1777 | 1777 |
1778 | 1778 |
1779 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, | 1779 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, |
1780 Token::Value op, | 1780 Token::Value op, |
1781 OverwriteMode mode) { | 1781 OverwriteMode mode) { |
1782 __ mov(a0, result_register()); | 1782 __ mov(a0, result_register()); |
1783 __ pop(a1); | 1783 __ pop(a1); |
1784 BinaryOpStub stub(op, mode); | 1784 BinaryOpStub stub(op, mode); |
1785 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 1785 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
1786 EmitCallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); | 1786 __ CallWithAstId(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); |
1787 patch_site.EmitPatchInfo(); | 1787 patch_site.EmitPatchInfo(); |
1788 context()->Plug(v0); | 1788 context()->Plug(v0); |
1789 } | 1789 } |
1790 | 1790 |
1791 | 1791 |
1792 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) { | 1792 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) { |
1793 // Invalid left-hand sides are rewritten to have a 'throw | 1793 // Invalid left-hand sides are rewritten to have a 'throw |
1794 // ReferenceError' on the left-hand side. | 1794 // ReferenceError' on the left-hand side. |
1795 if (!expr->IsValidLeftHandSide()) { | 1795 if (!expr->IsValidLeftHandSide()) { |
1796 VisitForEffect(expr); | 1796 VisitForEffect(expr); |
(...skipping 20 matching lines...) Expand all Loading... |
1817 } | 1817 } |
1818 case NAMED_PROPERTY: { | 1818 case NAMED_PROPERTY: { |
1819 __ push(result_register()); // Preserve value. | 1819 __ push(result_register()); // Preserve value. |
1820 VisitForAccumulatorValue(prop->obj()); | 1820 VisitForAccumulatorValue(prop->obj()); |
1821 __ mov(a1, result_register()); | 1821 __ mov(a1, result_register()); |
1822 __ pop(a0); // Restore value. | 1822 __ pop(a0); // Restore value. |
1823 __ li(a2, Operand(prop->key()->AsLiteral()->handle())); | 1823 __ li(a2, Operand(prop->key()->AsLiteral()->handle())); |
1824 Handle<Code> ic = is_strict_mode() | 1824 Handle<Code> ic = is_strict_mode() |
1825 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 1825 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
1826 : isolate()->builtins()->StoreIC_Initialize(); | 1826 : isolate()->builtins()->StoreIC_Initialize(); |
1827 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); | 1827 __ CallWithAstId(ic); |
1828 break; | 1828 break; |
1829 } | 1829 } |
1830 case KEYED_PROPERTY: { | 1830 case KEYED_PROPERTY: { |
1831 __ push(result_register()); // Preserve value. | 1831 __ push(result_register()); // Preserve value. |
1832 VisitForStackValue(prop->obj()); | 1832 VisitForStackValue(prop->obj()); |
1833 VisitForAccumulatorValue(prop->key()); | 1833 VisitForAccumulatorValue(prop->key()); |
1834 __ mov(a1, result_register()); | 1834 __ mov(a1, result_register()); |
1835 __ pop(a2); | 1835 __ pop(a2); |
1836 __ pop(a0); // Restore value. | 1836 __ pop(a0); // Restore value. |
1837 Handle<Code> ic = is_strict_mode() | 1837 Handle<Code> ic = is_strict_mode() |
1838 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() | 1838 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() |
1839 : isolate()->builtins()->KeyedStoreIC_Initialize(); | 1839 : isolate()->builtins()->KeyedStoreIC_Initialize(); |
1840 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); | 1840 __ CallWithAstId(ic); |
1841 break; | 1841 break; |
1842 } | 1842 } |
1843 } | 1843 } |
1844 PrepareForBailoutForId(bailout_ast_id, TOS_REG); | 1844 PrepareForBailoutForId(bailout_ast_id, TOS_REG); |
1845 context()->Plug(v0); | 1845 context()->Plug(v0); |
1846 } | 1846 } |
1847 | 1847 |
1848 | 1848 |
1849 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 1849 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
1850 Token::Value op) { | 1850 Token::Value op) { |
1851 ASSERT(var != NULL); | 1851 ASSERT(var != NULL); |
1852 ASSERT(var->is_global() || var->AsSlot() != NULL); | 1852 ASSERT(var->is_global() || var->AsSlot() != NULL); |
1853 | 1853 |
1854 if (var->is_global()) { | 1854 if (var->is_global()) { |
1855 ASSERT(!var->is_this()); | 1855 ASSERT(!var->is_this()); |
1856 // Assignment to a global variable. Use inline caching for the | 1856 // Assignment to a global variable. Use inline caching for the |
1857 // assignment. Right-hand-side value is passed in a0, variable name in | 1857 // assignment. Right-hand-side value is passed in a0, variable name in |
1858 // a2, and the global object in a1. | 1858 // a2, and the global object in a1. |
1859 __ mov(a0, result_register()); | 1859 __ mov(a0, result_register()); |
1860 __ li(a2, Operand(var->name())); | 1860 __ li(a2, Operand(var->name())); |
1861 __ lw(a1, GlobalObjectOperand()); | 1861 __ lw(a1, GlobalObjectOperand()); |
1862 Handle<Code> ic = is_strict_mode() | 1862 Handle<Code> ic = is_strict_mode() |
1863 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 1863 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
1864 : isolate()->builtins()->StoreIC_Initialize(); | 1864 : isolate()->builtins()->StoreIC_Initialize(); |
1865 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT, AstNode::kNoNumber); | 1865 __ CallWithAstId(ic, RelocInfo::CODE_TARGET_CONTEXT); |
1866 | 1866 |
1867 } else if (op == Token::INIT_CONST) { | 1867 } else if (op == Token::INIT_CONST) { |
1868 // Like var declarations, const declarations are hoisted to function | 1868 // Like var declarations, const declarations are hoisted to function |
1869 // scope. However, unlike var initializers, const initializers are able | 1869 // scope. However, unlike var initializers, const initializers are able |
1870 // to drill a hole to that function context, even from inside a 'with' | 1870 // to drill a hole to that function context, even from inside a 'with' |
1871 // context. We thus bypass the normal static scope lookup. | 1871 // context. We thus bypass the normal static scope lookup. |
1872 Slot* slot = var->AsSlot(); | 1872 Slot* slot = var->AsSlot(); |
1873 Label skip; | 1873 Label skip; |
1874 switch (slot->type()) { | 1874 switch (slot->type()) { |
1875 case Slot::PARAMETER: | 1875 case Slot::PARAMETER: |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1953 // receiver into fast case. | 1953 // receiver into fast case. |
1954 if (expr->ends_initialization_block()) { | 1954 if (expr->ends_initialization_block()) { |
1955 __ lw(a1, MemOperand(sp)); | 1955 __ lw(a1, MemOperand(sp)); |
1956 } else { | 1956 } else { |
1957 __ pop(a1); | 1957 __ pop(a1); |
1958 } | 1958 } |
1959 | 1959 |
1960 Handle<Code> ic = is_strict_mode() | 1960 Handle<Code> ic = is_strict_mode() |
1961 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 1961 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
1962 : isolate()->builtins()->StoreIC_Initialize(); | 1962 : isolate()->builtins()->StoreIC_Initialize(); |
1963 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 1963 __ CallWithAstId(ic, RelocInfo::CODE_TARGET, expr->id()); |
1964 | 1964 |
1965 // If the assignment ends an initialization block, revert to fast case. | 1965 // If the assignment ends an initialization block, revert to fast case. |
1966 if (expr->ends_initialization_block()) { | 1966 if (expr->ends_initialization_block()) { |
1967 __ push(v0); // Result of assignment, saved even if not needed. | 1967 __ push(v0); // Result of assignment, saved even if not needed. |
1968 // Receiver is under the result value. | 1968 // Receiver is under the result value. |
1969 __ lw(t0, MemOperand(sp, kPointerSize)); | 1969 __ lw(t0, MemOperand(sp, kPointerSize)); |
1970 __ push(t0); | 1970 __ push(t0); |
1971 __ CallRuntime(Runtime::kToFastProperties, 1); | 1971 __ CallRuntime(Runtime::kToFastProperties, 1); |
1972 __ pop(v0); | 1972 __ pop(v0); |
1973 __ Drop(1); | 1973 __ Drop(1); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2005 // receiver into fast case. | 2005 // receiver into fast case. |
2006 if (expr->ends_initialization_block()) { | 2006 if (expr->ends_initialization_block()) { |
2007 __ lw(a2, MemOperand(sp)); | 2007 __ lw(a2, MemOperand(sp)); |
2008 } else { | 2008 } else { |
2009 __ pop(a2); | 2009 __ pop(a2); |
2010 } | 2010 } |
2011 | 2011 |
2012 Handle<Code> ic = is_strict_mode() | 2012 Handle<Code> ic = is_strict_mode() |
2013 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() | 2013 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() |
2014 : isolate()->builtins()->KeyedStoreIC_Initialize(); | 2014 : isolate()->builtins()->KeyedStoreIC_Initialize(); |
2015 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 2015 __ CallWithAstId(ic, RelocInfo::CODE_TARGET, expr->id()); |
2016 | 2016 |
2017 // If the assignment ends an initialization block, revert to fast case. | 2017 // If the assignment ends an initialization block, revert to fast case. |
2018 if (expr->ends_initialization_block()) { | 2018 if (expr->ends_initialization_block()) { |
2019 __ push(v0); // Result of assignment, saved even if not needed. | 2019 __ push(v0); // Result of assignment, saved even if not needed. |
2020 // Receiver is under the result value. | 2020 // Receiver is under the result value. |
2021 __ lw(t0, MemOperand(sp, kPointerSize)); | 2021 __ lw(t0, MemOperand(sp, kPointerSize)); |
2022 __ push(t0); | 2022 __ push(t0); |
2023 __ CallRuntime(Runtime::kToFastProperties, 1); | 2023 __ CallRuntime(Runtime::kToFastProperties, 1); |
2024 __ pop(v0); | 2024 __ pop(v0); |
2025 __ Drop(1); | 2025 __ Drop(1); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2058 VisitForStackValue(args->at(i)); | 2058 VisitForStackValue(args->at(i)); |
2059 } | 2059 } |
2060 __ li(a2, Operand(name)); | 2060 __ li(a2, Operand(name)); |
2061 } | 2061 } |
2062 // Record source position for debugger. | 2062 // Record source position for debugger. |
2063 SetSourcePosition(expr->position()); | 2063 SetSourcePosition(expr->position()); |
2064 // Call the IC initialization code. | 2064 // Call the IC initialization code. |
2065 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 2065 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
2066 Handle<Code> ic = | 2066 Handle<Code> ic = |
2067 isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop, mode); | 2067 isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop, mode); |
2068 EmitCallIC(ic, mode, expr->id()); | 2068 __ CallWithAstId(ic, mode, expr->id()); |
2069 RecordJSReturnSite(expr); | 2069 RecordJSReturnSite(expr); |
2070 // Restore context register. | 2070 // Restore context register. |
2071 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2071 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2072 context()->Plug(v0); | 2072 context()->Plug(v0); |
2073 } | 2073 } |
2074 | 2074 |
2075 | 2075 |
2076 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, | 2076 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, |
2077 Expression* key) { | 2077 Expression* key) { |
2078 // Load the key. | 2078 // Load the key. |
(...skipping 13 matching lines...) Expand all Loading... |
2092 VisitForStackValue(args->at(i)); | 2092 VisitForStackValue(args->at(i)); |
2093 } | 2093 } |
2094 } | 2094 } |
2095 // Record source position for debugger. | 2095 // Record source position for debugger. |
2096 SetSourcePosition(expr->position()); | 2096 SetSourcePosition(expr->position()); |
2097 // Call the IC initialization code. | 2097 // Call the IC initialization code. |
2098 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 2098 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
2099 Handle<Code> ic = | 2099 Handle<Code> ic = |
2100 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop); | 2100 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop); |
2101 __ lw(a2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. | 2101 __ lw(a2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. |
2102 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 2102 __ CallWithAstId(ic, RelocInfo::CODE_TARGET, expr->id()); |
2103 RecordJSReturnSite(expr); | 2103 RecordJSReturnSite(expr); |
2104 // Restore context register. | 2104 // Restore context register. |
2105 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2105 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2106 context()->DropAndPlug(1, v0); // Drop the key still on the stack. | 2106 context()->DropAndPlug(1, v0); // Drop the key still on the stack. |
2107 } | 2107 } |
2108 | 2108 |
2109 | 2109 |
2110 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { | 2110 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { |
2111 // Code common for calls using the call stub. | 2111 // Code common for calls using the call stub. |
2112 ZoneList<Expression*>* args = expr->arguments(); | 2112 ZoneList<Expression*>* args = expr->arguments(); |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2273 Literal* key = prop->key()->AsLiteral(); | 2273 Literal* key = prop->key()->AsLiteral(); |
2274 if (key != NULL && key->handle()->IsSymbol()) { | 2274 if (key != NULL && key->handle()->IsSymbol()) { |
2275 // Call to a named property, use call IC. | 2275 // Call to a named property, use call IC. |
2276 { PreservePositionScope scope(masm()->positions_recorder()); | 2276 { PreservePositionScope scope(masm()->positions_recorder()); |
2277 VisitForStackValue(prop->obj()); | 2277 VisitForStackValue(prop->obj()); |
2278 } | 2278 } |
2279 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); | 2279 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); |
2280 } else { | 2280 } else { |
2281 // Call to a keyed property. | 2281 // Call to a keyed property. |
2282 // For a synthetic property use keyed load IC followed by function call, | 2282 // For a synthetic property use keyed load IC followed by function call, |
2283 // for a regular property use keyed EmitCallIC. | 2283 // for a regular property use EmitKeyedCallWithIC. |
2284 if (prop->is_synthetic()) { | 2284 if (prop->is_synthetic()) { |
2285 // Do not visit the object and key subexpressions (they are shared | 2285 // Do not visit the object and key subexpressions (they are shared |
2286 // by all occurrences of the same rewritten parameter). | 2286 // by all occurrences of the same rewritten parameter). |
2287 ASSERT(prop->obj()->AsVariableProxy() != NULL); | 2287 ASSERT(prop->obj()->AsVariableProxy() != NULL); |
2288 ASSERT(prop->obj()->AsVariableProxy()->var()->AsSlot() != NULL); | 2288 ASSERT(prop->obj()->AsVariableProxy()->var()->AsSlot() != NULL); |
2289 Slot* slot = prop->obj()->AsVariableProxy()->var()->AsSlot(); | 2289 Slot* slot = prop->obj()->AsVariableProxy()->var()->AsSlot(); |
2290 MemOperand operand = EmitSlotSearch(slot, a1); | 2290 MemOperand operand = EmitSlotSearch(slot, a1); |
2291 __ lw(a1, operand); | 2291 __ lw(a1, operand); |
2292 | 2292 |
2293 ASSERT(prop->key()->AsLiteral() != NULL); | 2293 ASSERT(prop->key()->AsLiteral() != NULL); |
2294 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); | 2294 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); |
2295 __ li(a0, Operand(prop->key()->AsLiteral()->handle())); | 2295 __ li(a0, Operand(prop->key()->AsLiteral()->handle())); |
2296 | 2296 |
2297 // Record source code position for IC call. | 2297 // Record source code position for IC call. |
2298 SetSourcePosition(prop->position()); | 2298 SetSourcePosition(prop->position()); |
2299 | 2299 |
2300 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2300 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
2301 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); | 2301 __ CallWithAstId(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); |
2302 __ lw(a1, GlobalObjectOperand()); | 2302 __ lw(a1, GlobalObjectOperand()); |
2303 __ lw(a1, FieldMemOperand(a1, GlobalObject::kGlobalReceiverOffset)); | 2303 __ lw(a1, FieldMemOperand(a1, GlobalObject::kGlobalReceiverOffset)); |
2304 __ Push(v0, a1); // Function, receiver. | 2304 __ Push(v0, a1); // Function, receiver. |
2305 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); | 2305 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); |
2306 } else { | 2306 } else { |
2307 { PreservePositionScope scope(masm()->positions_recorder()); | 2307 { PreservePositionScope scope(masm()->positions_recorder()); |
2308 VisitForStackValue(prop->obj()); | 2308 VisitForStackValue(prop->obj()); |
2309 } | 2309 } |
2310 EmitKeyedCallWithIC(expr, prop->key()); | 2310 EmitKeyedCallWithIC(expr, prop->key()); |
2311 } | 2311 } |
(...skipping 1309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3621 } | 3621 } |
3622 | 3622 |
3623 if (expr->is_jsruntime()) { | 3623 if (expr->is_jsruntime()) { |
3624 // Call the JS runtime function. | 3624 // Call the JS runtime function. |
3625 __ li(a2, Operand(expr->name())); | 3625 __ li(a2, Operand(expr->name())); |
3626 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; | 3626 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; |
3627 Handle<Code> ic = | 3627 Handle<Code> ic = |
3628 isolate()->stub_cache()->ComputeCallInitialize(arg_count, | 3628 isolate()->stub_cache()->ComputeCallInitialize(arg_count, |
3629 NOT_IN_LOOP, | 3629 NOT_IN_LOOP, |
3630 mode); | 3630 mode); |
3631 EmitCallIC(ic, mode, expr->id()); | 3631 __ CallWithAstId(ic, mode, expr->id()); |
3632 // Restore context register. | 3632 // Restore context register. |
3633 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3633 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
3634 } else { | 3634 } else { |
3635 // Call the C runtime function. | 3635 // Call the C runtime function. |
3636 __ CallRuntime(expr->function(), arg_count); | 3636 __ CallRuntime(expr->function(), arg_count); |
3637 } | 3637 } |
3638 context()->Plug(v0); | 3638 context()->Plug(v0); |
3639 } | 3639 } |
3640 | 3640 |
3641 | 3641 |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3764 // TODO(svenpanne): Allowing format strings in Comment would be nice here... | 3764 // TODO(svenpanne): Allowing format strings in Comment would be nice here... |
3765 Comment cmt(masm_, comment); | 3765 Comment cmt(masm_, comment); |
3766 bool can_overwrite = expr->expression()->ResultOverwriteAllowed(); | 3766 bool can_overwrite = expr->expression()->ResultOverwriteAllowed(); |
3767 UnaryOverwriteMode overwrite = | 3767 UnaryOverwriteMode overwrite = |
3768 can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE; | 3768 can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE; |
3769 UnaryOpStub stub(expr->op(), overwrite); | 3769 UnaryOpStub stub(expr->op(), overwrite); |
3770 // GenericUnaryOpStub expects the argument to be in a0. | 3770 // GenericUnaryOpStub expects the argument to be in a0. |
3771 VisitForAccumulatorValue(expr->expression()); | 3771 VisitForAccumulatorValue(expr->expression()); |
3772 SetSourcePosition(expr->position()); | 3772 SetSourcePosition(expr->position()); |
3773 __ mov(a0, result_register()); | 3773 __ mov(a0, result_register()); |
3774 EmitCallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); | 3774 __ CallWithAstId(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); |
3775 context()->Plug(v0); | 3775 context()->Plug(v0); |
3776 } | 3776 } |
3777 | 3777 |
3778 | 3778 |
3779 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { | 3779 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
3780 Comment cmnt(masm_, "[ CountOperation"); | 3780 Comment cmnt(masm_, "[ CountOperation"); |
3781 SetSourcePosition(expr->position()); | 3781 SetSourcePosition(expr->position()); |
3782 | 3782 |
3783 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError' | 3783 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError' |
3784 // as the left-hand side. | 3784 // as the left-hand side. |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3875 // We could eliminate this smi check if we split the code at | 3875 // We could eliminate this smi check if we split the code at |
3876 // the first smi check before calling ToNumber. | 3876 // the first smi check before calling ToNumber. |
3877 patch_site.EmitJumpIfSmi(v0, &done); | 3877 patch_site.EmitJumpIfSmi(v0, &done); |
3878 __ bind(&stub_call); | 3878 __ bind(&stub_call); |
3879 } | 3879 } |
3880 | 3880 |
3881 // Record position before stub call. | 3881 // Record position before stub call. |
3882 SetSourcePosition(expr->position()); | 3882 SetSourcePosition(expr->position()); |
3883 | 3883 |
3884 BinaryOpStub stub(Token::ADD, NO_OVERWRITE); | 3884 BinaryOpStub stub(Token::ADD, NO_OVERWRITE); |
3885 EmitCallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId()); | 3885 __ CallWithAstId(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId()); |
3886 patch_site.EmitPatchInfo(); | 3886 patch_site.EmitPatchInfo(); |
3887 __ bind(&done); | 3887 __ bind(&done); |
3888 | 3888 |
3889 // Store the value returned in v0. | 3889 // Store the value returned in v0. |
3890 switch (assign_type) { | 3890 switch (assign_type) { |
3891 case VARIABLE: | 3891 case VARIABLE: |
3892 if (expr->is_postfix()) { | 3892 if (expr->is_postfix()) { |
3893 { EffectContext context(this); | 3893 { EffectContext context(this); |
3894 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 3894 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
3895 Token::ASSIGN); | 3895 Token::ASSIGN); |
(...skipping 12 matching lines...) Expand all Loading... |
3908 context()->Plug(v0); | 3908 context()->Plug(v0); |
3909 } | 3909 } |
3910 break; | 3910 break; |
3911 case NAMED_PROPERTY: { | 3911 case NAMED_PROPERTY: { |
3912 __ mov(a0, result_register()); // Value. | 3912 __ mov(a0, result_register()); // Value. |
3913 __ li(a2, Operand(prop->key()->AsLiteral()->handle())); // Name. | 3913 __ li(a2, Operand(prop->key()->AsLiteral()->handle())); // Name. |
3914 __ pop(a1); // Receiver. | 3914 __ pop(a1); // Receiver. |
3915 Handle<Code> ic = is_strict_mode() | 3915 Handle<Code> ic = is_strict_mode() |
3916 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 3916 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
3917 : isolate()->builtins()->StoreIC_Initialize(); | 3917 : isolate()->builtins()->StoreIC_Initialize(); |
3918 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 3918 __ CallWithAstId(ic, RelocInfo::CODE_TARGET, expr->id()); |
3919 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3919 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
3920 if (expr->is_postfix()) { | 3920 if (expr->is_postfix()) { |
3921 if (!context()->IsEffect()) { | 3921 if (!context()->IsEffect()) { |
3922 context()->PlugTOS(); | 3922 context()->PlugTOS(); |
3923 } | 3923 } |
3924 } else { | 3924 } else { |
3925 context()->Plug(v0); | 3925 context()->Plug(v0); |
3926 } | 3926 } |
3927 break; | 3927 break; |
3928 } | 3928 } |
3929 case KEYED_PROPERTY: { | 3929 case KEYED_PROPERTY: { |
3930 __ mov(a0, result_register()); // Value. | 3930 __ mov(a0, result_register()); // Value. |
3931 __ pop(a1); // Key. | 3931 __ pop(a1); // Key. |
3932 __ pop(a2); // Receiver. | 3932 __ pop(a2); // Receiver. |
3933 Handle<Code> ic = is_strict_mode() | 3933 Handle<Code> ic = is_strict_mode() |
3934 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() | 3934 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() |
3935 : isolate()->builtins()->KeyedStoreIC_Initialize(); | 3935 : isolate()->builtins()->KeyedStoreIC_Initialize(); |
3936 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 3936 __ CallWithAstId(ic, RelocInfo::CODE_TARGET, expr->id()); |
3937 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3937 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
3938 if (expr->is_postfix()) { | 3938 if (expr->is_postfix()) { |
3939 if (!context()->IsEffect()) { | 3939 if (!context()->IsEffect()) { |
3940 context()->PlugTOS(); | 3940 context()->PlugTOS(); |
3941 } | 3941 } |
3942 } else { | 3942 } else { |
3943 context()->Plug(v0); | 3943 context()->Plug(v0); |
3944 } | 3944 } |
3945 break; | 3945 break; |
3946 } | 3946 } |
3947 } | 3947 } |
3948 } | 3948 } |
3949 | 3949 |
3950 | 3950 |
3951 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 3951 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
3952 VariableProxy* proxy = expr->AsVariableProxy(); | 3952 VariableProxy* proxy = expr->AsVariableProxy(); |
3953 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { | 3953 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { |
3954 Comment cmnt(masm_, "Global variable"); | 3954 Comment cmnt(masm_, "Global variable"); |
3955 __ lw(a0, GlobalObjectOperand()); | 3955 __ lw(a0, GlobalObjectOperand()); |
3956 __ li(a2, Operand(proxy->name())); | 3956 __ li(a2, Operand(proxy->name())); |
3957 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 3957 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
3958 // Use a regular load, not a contextual load, to avoid a reference | 3958 // Use a regular load, not a contextual load, to avoid a reference |
3959 // error. | 3959 // error. |
3960 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); | 3960 __ CallWithAstId(ic); |
3961 PrepareForBailout(expr, TOS_REG); | 3961 PrepareForBailout(expr, TOS_REG); |
3962 context()->Plug(v0); | 3962 context()->Plug(v0); |
3963 } else if (proxy != NULL && | 3963 } else if (proxy != NULL && |
3964 proxy->var()->AsSlot() != NULL && | 3964 proxy->var()->AsSlot() != NULL && |
3965 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { | 3965 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { |
3966 Label done, slow; | 3966 Label done, slow; |
3967 | 3967 |
3968 // Generate code for loading from variables potentially shadowed | 3968 // Generate code for loading from variables potentially shadowed |
3969 // by eval-introduced variables. | 3969 // by eval-introduced variables. |
3970 Slot* slot = proxy->var()->AsSlot(); | 3970 Slot* slot = proxy->var()->AsSlot(); |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4147 if (inline_smi_code) { | 4147 if (inline_smi_code) { |
4148 Label slow_case; | 4148 Label slow_case; |
4149 __ Or(a2, a0, Operand(a1)); | 4149 __ Or(a2, a0, Operand(a1)); |
4150 patch_site.EmitJumpIfNotSmi(a2, &slow_case); | 4150 patch_site.EmitJumpIfNotSmi(a2, &slow_case); |
4151 Split(cc, a1, Operand(a0), if_true, if_false, NULL); | 4151 Split(cc, a1, Operand(a0), if_true, if_false, NULL); |
4152 __ bind(&slow_case); | 4152 __ bind(&slow_case); |
4153 } | 4153 } |
4154 // Record position and call the compare IC. | 4154 // Record position and call the compare IC. |
4155 SetSourcePosition(expr->position()); | 4155 SetSourcePosition(expr->position()); |
4156 Handle<Code> ic = CompareIC::GetUninitialized(op); | 4156 Handle<Code> ic = CompareIC::GetUninitialized(op); |
4157 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 4157 __ CallWithAstId(ic, RelocInfo::CODE_TARGET, expr->id()); |
4158 patch_site.EmitPatchInfo(); | 4158 patch_site.EmitPatchInfo(); |
4159 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 4159 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); |
4160 Split(cc, v0, Operand(zero_reg), if_true, if_false, fall_through); | 4160 Split(cc, v0, Operand(zero_reg), if_true, if_false, fall_through); |
4161 } | 4161 } |
4162 } | 4162 } |
4163 | 4163 |
4164 // Convert the result of the comparison into one expected for this | 4164 // Convert the result of the comparison into one expected for this |
4165 // expression's context. | 4165 // expression's context. |
4166 context()->Plug(if_true, if_false); | 4166 context()->Plug(if_true, if_false); |
4167 } | 4167 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4207 Register FullCodeGenerator::result_register() { | 4207 Register FullCodeGenerator::result_register() { |
4208 return v0; | 4208 return v0; |
4209 } | 4209 } |
4210 | 4210 |
4211 | 4211 |
4212 Register FullCodeGenerator::context_register() { | 4212 Register FullCodeGenerator::context_register() { |
4213 return cp; | 4213 return cp; |
4214 } | 4214 } |
4215 | 4215 |
4216 | 4216 |
4217 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, | |
4218 RelocInfo::Mode mode, | |
4219 unsigned ast_id) { | |
4220 ASSERT(mode == RelocInfo::CODE_TARGET || | |
4221 mode == RelocInfo::CODE_TARGET_CONTEXT); | |
4222 if (ast_id == kNoASTId || mode == RelocInfo::CODE_TARGET_CONTEXT) { | |
4223 __ Call(ic, mode); | |
4224 } else { | |
4225 ASSERT(mode == RelocInfo::CODE_TARGET); | |
4226 __ CallWithAstId(ic, RelocInfo::CODE_TARGET_WITH_ID, ast_id); | |
4227 } | |
4228 } | |
4229 | |
4230 | |
4231 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { | 4217 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { |
4232 ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset); | 4218 ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset); |
4233 __ sw(value, MemOperand(fp, frame_offset)); | 4219 __ sw(value, MemOperand(fp, frame_offset)); |
4234 } | 4220 } |
4235 | 4221 |
4236 | 4222 |
4237 void FullCodeGenerator::LoadContextField(Register dst, int context_index) { | 4223 void FullCodeGenerator::LoadContextField(Register dst, int context_index) { |
4238 __ lw(dst, ContextOperand(cp, context_index)); | 4224 __ lw(dst, ContextOperand(cp, context_index)); |
4239 } | 4225 } |
4240 | 4226 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4286 __ Addu(at, a1, Operand(masm_->CodeObject())); | 4272 __ Addu(at, a1, Operand(masm_->CodeObject())); |
4287 __ Jump(at); | 4273 __ Jump(at); |
4288 } | 4274 } |
4289 | 4275 |
4290 | 4276 |
4291 #undef __ | 4277 #undef __ |
4292 | 4278 |
4293 } } // namespace v8::internal | 4279 } } // namespace v8::internal |
4294 | 4280 |
4295 #endif // V8_TARGET_ARCH_MIPS | 4281 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |