| 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 763 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 774 VisitForAccumulatorValue(function); | 774 VisitForAccumulatorValue(function); |
| 775 __ pop(r2); | 775 __ pop(r2); |
| 776 } else { | 776 } else { |
| 777 __ mov(r2, r0); | 777 __ mov(r2, r0); |
| 778 __ LoadRoot(r0, Heap::kTheHoleValueRootIndex); | 778 __ LoadRoot(r0, Heap::kTheHoleValueRootIndex); |
| 779 } | 779 } |
| 780 ASSERT(prop->key()->AsLiteral() != NULL && | 780 ASSERT(prop->key()->AsLiteral() != NULL && |
| 781 prop->key()->AsLiteral()->handle()->IsSmi()); | 781 prop->key()->AsLiteral()->handle()->IsSmi()); |
| 782 __ mov(r1, Operand(prop->key()->AsLiteral()->handle())); | 782 __ mov(r1, Operand(prop->key()->AsLiteral()->handle())); |
| 783 | 783 |
| 784 Handle<Code> ic(isolate()->builtins()->builtin(is_strict_mode() | 784 Handle<Code> ic = is_strict_mode() |
| 785 ? Builtins::KeyedStoreIC_Initialize_Strict | 785 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() |
| 786 : Builtins::KeyedStoreIC_Initialize)); | 786 : isolate()->builtins()->KeyedStoreIC_Initialize(); |
| 787 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 787 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 788 // Value in r0 is ignored (declarations are statements). | 788 // Value in r0 is ignored (declarations are statements). |
| 789 } | 789 } |
| 790 } | 790 } |
| 791 } | 791 } |
| 792 | 792 |
| 793 | 793 |
| 794 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { | 794 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { |
| 795 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); | 795 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); |
| 796 } | 796 } |
| (...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1179 key_literal != NULL && | 1179 key_literal != NULL && |
| 1180 obj_proxy->IsArguments() && | 1180 obj_proxy->IsArguments() && |
| 1181 key_literal->handle()->IsSmi()) { | 1181 key_literal->handle()->IsSmi()) { |
| 1182 // Load arguments object if there are no eval-introduced | 1182 // Load arguments object if there are no eval-introduced |
| 1183 // variables. Then load the argument from the arguments | 1183 // variables. Then load the argument from the arguments |
| 1184 // object using keyed load. | 1184 // object using keyed load. |
| 1185 __ ldr(r1, | 1185 __ ldr(r1, |
| 1186 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), | 1186 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), |
| 1187 slow)); | 1187 slow)); |
| 1188 __ mov(r0, Operand(key_literal->handle())); | 1188 __ mov(r0, Operand(key_literal->handle())); |
| 1189 Handle<Code> ic(isolate()->builtins()->builtin( | 1189 Handle<Code> ic = |
| 1190 Builtins::KeyedLoadIC_Initialize)); | 1190 isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 1191 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1191 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1192 __ jmp(done); | 1192 __ jmp(done); |
| 1193 } | 1193 } |
| 1194 } | 1194 } |
| 1195 } | 1195 } |
| 1196 } | 1196 } |
| 1197 } | 1197 } |
| 1198 | 1198 |
| 1199 | 1199 |
| 1200 void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions( | 1200 void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions( |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1246 __ ldr(next, FieldMemOperand(next, JSFunction::kContextOffset)); | 1246 __ ldr(next, FieldMemOperand(next, JSFunction::kContextOffset)); |
| 1247 __ b(&loop); | 1247 __ b(&loop); |
| 1248 __ bind(&fast); | 1248 __ bind(&fast); |
| 1249 } | 1249 } |
| 1250 | 1250 |
| 1251 __ ldr(r0, GlobalObjectOperand()); | 1251 __ ldr(r0, GlobalObjectOperand()); |
| 1252 __ mov(r2, Operand(slot->var()->name())); | 1252 __ mov(r2, Operand(slot->var()->name())); |
| 1253 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) | 1253 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) |
| 1254 ? RelocInfo::CODE_TARGET | 1254 ? RelocInfo::CODE_TARGET |
| 1255 : RelocInfo::CODE_TARGET_CONTEXT; | 1255 : RelocInfo::CODE_TARGET_CONTEXT; |
| 1256 Handle<Code> ic(isolate()->builtins()->builtin( | 1256 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
| 1257 Builtins::LoadIC_Initialize)); | |
| 1258 EmitCallIC(ic, mode); | 1257 EmitCallIC(ic, mode); |
| 1259 } | 1258 } |
| 1260 | 1259 |
| 1261 | 1260 |
| 1262 void FullCodeGenerator::EmitVariableLoad(Variable* var) { | 1261 void FullCodeGenerator::EmitVariableLoad(Variable* var) { |
| 1263 // Four cases: non-this global variables, lookup slots, all other | 1262 // Four cases: non-this global variables, lookup slots, all other |
| 1264 // types of slots, and parameters that rewrite to explicit property | 1263 // types of slots, and parameters that rewrite to explicit property |
| 1265 // accesses on the arguments object. | 1264 // accesses on the arguments object. |
| 1266 Slot* slot = var->AsSlot(); | 1265 Slot* slot = var->AsSlot(); |
| 1267 Property* property = var->AsProperty(); | 1266 Property* property = var->AsProperty(); |
| 1268 | 1267 |
| 1269 if (var->is_global() && !var->is_this()) { | 1268 if (var->is_global() && !var->is_this()) { |
| 1270 Comment cmnt(masm_, "Global variable"); | 1269 Comment cmnt(masm_, "Global variable"); |
| 1271 // Use inline caching. Variable name is passed in r2 and the global | 1270 // Use inline caching. Variable name is passed in r2 and the global |
| 1272 // object (receiver) in r0. | 1271 // object (receiver) in r0. |
| 1273 __ ldr(r0, GlobalObjectOperand()); | 1272 __ ldr(r0, GlobalObjectOperand()); |
| 1274 __ mov(r2, Operand(var->name())); | 1273 __ mov(r2, Operand(var->name())); |
| 1275 Handle<Code> ic(isolate()->builtins()->builtin( | 1274 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
| 1276 Builtins::LoadIC_Initialize)); | |
| 1277 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); | 1275 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); |
| 1278 context()->Plug(r0); | 1276 context()->Plug(r0); |
| 1279 | 1277 |
| 1280 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { | 1278 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { |
| 1281 Label done, slow; | 1279 Label done, slow; |
| 1282 | 1280 |
| 1283 // Generate code for loading from variables potentially shadowed | 1281 // Generate code for loading from variables potentially shadowed |
| 1284 // by eval-introduced variables. | 1282 // by eval-introduced variables. |
| 1285 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); | 1283 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); |
| 1286 | 1284 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1325 | 1323 |
| 1326 // Assert that the key is a smi. | 1324 // Assert that the key is a smi. |
| 1327 Literal* key_literal = property->key()->AsLiteral(); | 1325 Literal* key_literal = property->key()->AsLiteral(); |
| 1328 ASSERT_NOT_NULL(key_literal); | 1326 ASSERT_NOT_NULL(key_literal); |
| 1329 ASSERT(key_literal->handle()->IsSmi()); | 1327 ASSERT(key_literal->handle()->IsSmi()); |
| 1330 | 1328 |
| 1331 // Load the key. | 1329 // Load the key. |
| 1332 __ mov(r0, Operand(key_literal->handle())); | 1330 __ mov(r0, Operand(key_literal->handle())); |
| 1333 | 1331 |
| 1334 // Call keyed load IC. It has arguments key and receiver in r0 and r1. | 1332 // Call keyed load IC. It has arguments key and receiver in r0 and r1. |
| 1335 Handle<Code> ic(isolate()->builtins()->builtin( | 1333 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 1336 Builtins::KeyedLoadIC_Initialize)); | |
| 1337 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1334 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1338 context()->Plug(r0); | 1335 context()->Plug(r0); |
| 1339 } | 1336 } |
| 1340 } | 1337 } |
| 1341 | 1338 |
| 1342 | 1339 |
| 1343 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { | 1340 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { |
| 1344 Comment cmnt(masm_, "[ RegExpLiteral"); | 1341 Comment cmnt(masm_, "[ RegExpLiteral"); |
| 1345 Label materialized; | 1342 Label materialized; |
| 1346 // Registers will be used as follows: | 1343 // Registers will be used as follows: |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1435 UNREACHABLE(); | 1432 UNREACHABLE(); |
| 1436 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1433 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1437 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value())); | 1434 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value())); |
| 1438 // Fall through. | 1435 // Fall through. |
| 1439 case ObjectLiteral::Property::COMPUTED: | 1436 case ObjectLiteral::Property::COMPUTED: |
| 1440 if (key->handle()->IsSymbol()) { | 1437 if (key->handle()->IsSymbol()) { |
| 1441 if (property->emit_store()) { | 1438 if (property->emit_store()) { |
| 1442 VisitForAccumulatorValue(value); | 1439 VisitForAccumulatorValue(value); |
| 1443 __ mov(r2, Operand(key->handle())); | 1440 __ mov(r2, Operand(key->handle())); |
| 1444 __ ldr(r1, MemOperand(sp)); | 1441 __ ldr(r1, MemOperand(sp)); |
| 1445 Handle<Code> ic(isolate()->builtins()->builtin( | 1442 Handle<Code> ic = isolate()->builtins()->StoreIC_Initialize(); |
| 1446 Builtins::StoreIC_Initialize)); | |
| 1447 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1443 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1448 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1444 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
| 1449 } else { | 1445 } else { |
| 1450 VisitForEffect(value); | 1446 VisitForEffect(value); |
| 1451 } | 1447 } |
| 1452 break; | 1448 break; |
| 1453 } | 1449 } |
| 1454 // Fall through. | 1450 // Fall through. |
| 1455 case ObjectLiteral::Property::PROTOTYPE: | 1451 case ObjectLiteral::Property::PROTOTYPE: |
| 1456 // Duplicate receiver on stack. | 1452 // Duplicate receiver on stack. |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1691 break; | 1687 break; |
| 1692 } | 1688 } |
| 1693 } | 1689 } |
| 1694 | 1690 |
| 1695 | 1691 |
| 1696 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 1692 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
| 1697 SetSourcePosition(prop->position()); | 1693 SetSourcePosition(prop->position()); |
| 1698 Literal* key = prop->key()->AsLiteral(); | 1694 Literal* key = prop->key()->AsLiteral(); |
| 1699 __ mov(r2, Operand(key->handle())); | 1695 __ mov(r2, Operand(key->handle())); |
| 1700 // Call load IC. It has arguments receiver and property name r0 and r2. | 1696 // Call load IC. It has arguments receiver and property name r0 and r2. |
| 1701 Handle<Code> ic(isolate()->builtins()->builtin( | 1697 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
| 1702 Builtins::LoadIC_Initialize)); | |
| 1703 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1698 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1704 } | 1699 } |
| 1705 | 1700 |
| 1706 | 1701 |
| 1707 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 1702 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
| 1708 SetSourcePosition(prop->position()); | 1703 SetSourcePosition(prop->position()); |
| 1709 // Call keyed load IC. It has arguments key and receiver in r0 and r1. | 1704 // Call keyed load IC. It has arguments key and receiver in r0 and r1. |
| 1710 Handle<Code> ic(isolate()->builtins()->builtin( | 1705 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 1711 Builtins::KeyedLoadIC_Initialize)); | |
| 1712 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1706 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1713 } | 1707 } |
| 1714 | 1708 |
| 1715 | 1709 |
| 1716 void FullCodeGenerator::EmitInlineSmiBinaryOp(Expression* expr, | 1710 void FullCodeGenerator::EmitInlineSmiBinaryOp(Expression* expr, |
| 1717 Token::Value op, | 1711 Token::Value op, |
| 1718 OverwriteMode mode, | 1712 OverwriteMode mode, |
| 1719 Expression* left_expr, | 1713 Expression* left_expr, |
| 1720 Expression* right_expr) { | 1714 Expression* right_expr) { |
| 1721 Label done, smi_case, stub_call; | 1715 Label done, smi_case, stub_call; |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1846 EffectContext context(this); | 1840 EffectContext context(this); |
| 1847 EmitVariableAssignment(var, Token::ASSIGN); | 1841 EmitVariableAssignment(var, Token::ASSIGN); |
| 1848 break; | 1842 break; |
| 1849 } | 1843 } |
| 1850 case NAMED_PROPERTY: { | 1844 case NAMED_PROPERTY: { |
| 1851 __ push(r0); // Preserve value. | 1845 __ push(r0); // Preserve value. |
| 1852 VisitForAccumulatorValue(prop->obj()); | 1846 VisitForAccumulatorValue(prop->obj()); |
| 1853 __ mov(r1, r0); | 1847 __ mov(r1, r0); |
| 1854 __ pop(r0); // Restore value. | 1848 __ pop(r0); // Restore value. |
| 1855 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); | 1849 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); |
| 1856 Handle<Code> ic(isolate()->builtins()->builtin( | 1850 Handle<Code> ic = is_strict_mode() |
| 1857 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict | 1851 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
| 1858 : Builtins::StoreIC_Initialize)); | 1852 : isolate()->builtins()->StoreIC_Initialize(); |
| 1859 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1853 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1860 break; | 1854 break; |
| 1861 } | 1855 } |
| 1862 case KEYED_PROPERTY: { | 1856 case KEYED_PROPERTY: { |
| 1863 __ push(r0); // Preserve value. | 1857 __ push(r0); // Preserve value. |
| 1864 if (prop->is_synthetic()) { | 1858 if (prop->is_synthetic()) { |
| 1865 ASSERT(prop->obj()->AsVariableProxy() != NULL); | 1859 ASSERT(prop->obj()->AsVariableProxy() != NULL); |
| 1866 ASSERT(prop->key()->AsLiteral() != NULL); | 1860 ASSERT(prop->key()->AsLiteral() != NULL); |
| 1867 { AccumulatorValueContext for_object(this); | 1861 { AccumulatorValueContext for_object(this); |
| 1868 EmitVariableLoad(prop->obj()->AsVariableProxy()->var()); | 1862 EmitVariableLoad(prop->obj()->AsVariableProxy()->var()); |
| 1869 } | 1863 } |
| 1870 __ mov(r2, r0); | 1864 __ mov(r2, r0); |
| 1871 __ mov(r1, Operand(prop->key()->AsLiteral()->handle())); | 1865 __ mov(r1, Operand(prop->key()->AsLiteral()->handle())); |
| 1872 } else { | 1866 } else { |
| 1873 VisitForStackValue(prop->obj()); | 1867 VisitForStackValue(prop->obj()); |
| 1874 VisitForAccumulatorValue(prop->key()); | 1868 VisitForAccumulatorValue(prop->key()); |
| 1875 __ mov(r1, r0); | 1869 __ mov(r1, r0); |
| 1876 __ pop(r2); | 1870 __ pop(r2); |
| 1877 } | 1871 } |
| 1878 __ pop(r0); // Restore value. | 1872 __ pop(r0); // Restore value. |
| 1879 Handle<Code> ic(isolate()->builtins()->builtin( | 1873 Handle<Code> ic = is_strict_mode() |
| 1880 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict | 1874 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() |
| 1881 : Builtins::KeyedStoreIC_Initialize)); | 1875 : isolate()->builtins()->KeyedStoreIC_Initialize(); |
| 1882 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1876 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1883 break; | 1877 break; |
| 1884 } | 1878 } |
| 1885 } | 1879 } |
| 1886 PrepareForBailoutForId(bailout_ast_id, TOS_REG); | 1880 PrepareForBailoutForId(bailout_ast_id, TOS_REG); |
| 1887 context()->Plug(r0); | 1881 context()->Plug(r0); |
| 1888 } | 1882 } |
| 1889 | 1883 |
| 1890 | 1884 |
| 1891 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 1885 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
| 1892 Token::Value op) { | 1886 Token::Value op) { |
| 1893 // Left-hand sides that rewrite to explicit property accesses do not reach | 1887 // Left-hand sides that rewrite to explicit property accesses do not reach |
| 1894 // here. | 1888 // here. |
| 1895 ASSERT(var != NULL); | 1889 ASSERT(var != NULL); |
| 1896 ASSERT(var->is_global() || var->AsSlot() != NULL); | 1890 ASSERT(var->is_global() || var->AsSlot() != NULL); |
| 1897 | 1891 |
| 1898 if (var->is_global()) { | 1892 if (var->is_global()) { |
| 1899 ASSERT(!var->is_this()); | 1893 ASSERT(!var->is_this()); |
| 1900 // Assignment to a global variable. Use inline caching for the | 1894 // Assignment to a global variable. Use inline caching for the |
| 1901 // assignment. Right-hand-side value is passed in r0, variable name in | 1895 // assignment. Right-hand-side value is passed in r0, variable name in |
| 1902 // r2, and the global object in r1. | 1896 // r2, and the global object in r1. |
| 1903 __ mov(r2, Operand(var->name())); | 1897 __ mov(r2, Operand(var->name())); |
| 1904 __ ldr(r1, GlobalObjectOperand()); | 1898 __ ldr(r1, GlobalObjectOperand()); |
| 1905 Handle<Code> ic(isolate()->builtins()->builtin( | 1899 Handle<Code> ic = is_strict_mode() |
| 1906 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict | 1900 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
| 1907 : Builtins::StoreIC_Initialize)); | 1901 : isolate()->builtins()->StoreIC_Initialize(); |
| 1908 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); | 1902 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); |
| 1909 | 1903 |
| 1910 } else if (op == Token::INIT_CONST) { | 1904 } else if (op == Token::INIT_CONST) { |
| 1911 // Like var declarations, const declarations are hoisted to function | 1905 // Like var declarations, const declarations are hoisted to function |
| 1912 // scope. However, unlike var initializers, const initializers are able | 1906 // scope. However, unlike var initializers, const initializers are able |
| 1913 // to drill a hole to that function context, even from inside a 'with' | 1907 // to drill a hole to that function context, even from inside a 'with' |
| 1914 // context. We thus bypass the normal static scope lookup. | 1908 // context. We thus bypass the normal static scope lookup. |
| 1915 Slot* slot = var->AsSlot(); | 1909 Slot* slot = var->AsSlot(); |
| 1916 Label skip; | 1910 Label skip; |
| 1917 switch (slot->type()) { | 1911 switch (slot->type()) { |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2004 SetSourcePosition(expr->position()); | 1998 SetSourcePosition(expr->position()); |
| 2005 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); | 1999 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); |
| 2006 // Load receiver to r1. Leave a copy in the stack if needed for turning the | 2000 // Load receiver to r1. Leave a copy in the stack if needed for turning the |
| 2007 // receiver into fast case. | 2001 // receiver into fast case. |
| 2008 if (expr->ends_initialization_block()) { | 2002 if (expr->ends_initialization_block()) { |
| 2009 __ ldr(r1, MemOperand(sp)); | 2003 __ ldr(r1, MemOperand(sp)); |
| 2010 } else { | 2004 } else { |
| 2011 __ pop(r1); | 2005 __ pop(r1); |
| 2012 } | 2006 } |
| 2013 | 2007 |
| 2014 Handle<Code> ic(isolate()->builtins()->builtin( | 2008 Handle<Code> ic = is_strict_mode() |
| 2015 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict | 2009 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
| 2016 : Builtins::StoreIC_Initialize)); | 2010 : isolate()->builtins()->StoreIC_Initialize(); |
| 2017 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 2011 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 2018 | 2012 |
| 2019 // If the assignment ends an initialization block, revert to fast case. | 2013 // If the assignment ends an initialization block, revert to fast case. |
| 2020 if (expr->ends_initialization_block()) { | 2014 if (expr->ends_initialization_block()) { |
| 2021 __ push(r0); // Result of assignment, saved even if not needed. | 2015 __ push(r0); // Result of assignment, saved even if not needed. |
| 2022 // Receiver is under the result value. | 2016 // Receiver is under the result value. |
| 2023 __ ldr(ip, MemOperand(sp, kPointerSize)); | 2017 __ ldr(ip, MemOperand(sp, kPointerSize)); |
| 2024 __ push(ip); | 2018 __ push(ip); |
| 2025 __ CallRuntime(Runtime::kToFastProperties, 1); | 2019 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 2026 __ pop(r0); | 2020 __ pop(r0); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2050 SetSourcePosition(expr->position()); | 2044 SetSourcePosition(expr->position()); |
| 2051 __ pop(r1); // Key. | 2045 __ pop(r1); // Key. |
| 2052 // Load receiver to r2. Leave a copy in the stack if needed for turning the | 2046 // Load receiver to r2. Leave a copy in the stack if needed for turning the |
| 2053 // receiver into fast case. | 2047 // receiver into fast case. |
| 2054 if (expr->ends_initialization_block()) { | 2048 if (expr->ends_initialization_block()) { |
| 2055 __ ldr(r2, MemOperand(sp)); | 2049 __ ldr(r2, MemOperand(sp)); |
| 2056 } else { | 2050 } else { |
| 2057 __ pop(r2); | 2051 __ pop(r2); |
| 2058 } | 2052 } |
| 2059 | 2053 |
| 2060 Handle<Code> ic(isolate()->builtins()->builtin( | 2054 Handle<Code> ic = is_strict_mode() |
| 2061 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict | 2055 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() |
| 2062 : Builtins::KeyedStoreIC_Initialize)); | 2056 : isolate()->builtins()->KeyedStoreIC_Initialize(); |
| 2063 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 2057 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 2064 | 2058 |
| 2065 // If the assignment ends an initialization block, revert to fast case. | 2059 // If the assignment ends an initialization block, revert to fast case. |
| 2066 if (expr->ends_initialization_block()) { | 2060 if (expr->ends_initialization_block()) { |
| 2067 __ push(r0); // Result of assignment, saved even if not needed. | 2061 __ push(r0); // Result of assignment, saved even if not needed. |
| 2068 // Receiver is under the result value. | 2062 // Receiver is under the result value. |
| 2069 __ ldr(ip, MemOperand(sp, kPointerSize)); | 2063 __ ldr(ip, MemOperand(sp, kPointerSize)); |
| 2070 __ push(ip); | 2064 __ push(ip); |
| 2071 __ CallRuntime(Runtime::kToFastProperties, 1); | 2065 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 2072 __ pop(r0); | 2066 __ pop(r0); |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2337 MemOperand operand = EmitSlotSearch(slot, r1); | 2331 MemOperand operand = EmitSlotSearch(slot, r1); |
| 2338 __ ldr(r1, operand); | 2332 __ ldr(r1, operand); |
| 2339 | 2333 |
| 2340 ASSERT(prop->key()->AsLiteral() != NULL); | 2334 ASSERT(prop->key()->AsLiteral() != NULL); |
| 2341 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); | 2335 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); |
| 2342 __ mov(r0, Operand(prop->key()->AsLiteral()->handle())); | 2336 __ mov(r0, Operand(prop->key()->AsLiteral()->handle())); |
| 2343 | 2337 |
| 2344 // Record source code position for IC call. | 2338 // Record source code position for IC call. |
| 2345 SetSourcePosition(prop->position()); | 2339 SetSourcePosition(prop->position()); |
| 2346 | 2340 |
| 2347 Handle<Code> ic(isolate()->builtins()->builtin( | 2341 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 2348 Builtins::KeyedLoadIC_Initialize)); | |
| 2349 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 2342 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 2350 __ ldr(r1, GlobalObjectOperand()); | 2343 __ ldr(r1, GlobalObjectOperand()); |
| 2351 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); | 2344 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); |
| 2352 __ Push(r0, r1); // Function, receiver. | 2345 __ Push(r0, r1); // Function, receiver. |
| 2353 EmitCallWithStub(expr); | 2346 EmitCallWithStub(expr); |
| 2354 } else { | 2347 } else { |
| 2355 { PreservePositionScope scope(masm()->positions_recorder()); | 2348 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2356 VisitForStackValue(prop->obj()); | 2349 VisitForStackValue(prop->obj()); |
| 2357 } | 2350 } |
| 2358 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); | 2351 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2406 } | 2399 } |
| 2407 | 2400 |
| 2408 // Call the construct call builtin that handles allocation and | 2401 // Call the construct call builtin that handles allocation and |
| 2409 // constructor invocation. | 2402 // constructor invocation. |
| 2410 SetSourcePosition(expr->position()); | 2403 SetSourcePosition(expr->position()); |
| 2411 | 2404 |
| 2412 // Load function and argument count into r1 and r0. | 2405 // Load function and argument count into r1 and r0. |
| 2413 __ mov(r0, Operand(arg_count)); | 2406 __ mov(r0, Operand(arg_count)); |
| 2414 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize)); | 2407 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize)); |
| 2415 | 2408 |
| 2416 Handle<Code> construct_builtin(isolate()->builtins()->builtin( | 2409 Handle<Code> construct_builtin = |
| 2417 Builtins::JSConstructCall)); | 2410 isolate()->builtins()->JSConstructCall(); |
| 2418 __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL); | 2411 __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL); |
| 2419 context()->Plug(r0); | 2412 context()->Plug(r0); |
| 2420 } | 2413 } |
| 2421 | 2414 |
| 2422 | 2415 |
| 2423 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) { | 2416 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) { |
| 2424 ASSERT(args->length() == 1); | 2417 ASSERT(args->length() == 1); |
| 2425 | 2418 |
| 2426 VisitForAccumulatorValue(args->at(0)); | 2419 VisitForAccumulatorValue(args->at(0)); |
| 2427 | 2420 |
| (...skipping 1479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3907 } else { | 3900 } else { |
| 3908 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 3901 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| 3909 Token::ASSIGN); | 3902 Token::ASSIGN); |
| 3910 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3903 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 3911 context()->Plug(r0); | 3904 context()->Plug(r0); |
| 3912 } | 3905 } |
| 3913 break; | 3906 break; |
| 3914 case NAMED_PROPERTY: { | 3907 case NAMED_PROPERTY: { |
| 3915 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); | 3908 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); |
| 3916 __ pop(r1); | 3909 __ pop(r1); |
| 3917 Handle<Code> ic(isolate()->builtins()->builtin( | 3910 Handle<Code> ic = is_strict_mode() |
| 3918 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict | 3911 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
| 3919 : Builtins::StoreIC_Initialize)); | 3912 : isolate()->builtins()->StoreIC_Initialize(); |
| 3920 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3913 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 3921 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3914 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 3922 if (expr->is_postfix()) { | 3915 if (expr->is_postfix()) { |
| 3923 if (!context()->IsEffect()) { | 3916 if (!context()->IsEffect()) { |
| 3924 context()->PlugTOS(); | 3917 context()->PlugTOS(); |
| 3925 } | 3918 } |
| 3926 } else { | 3919 } else { |
| 3927 context()->Plug(r0); | 3920 context()->Plug(r0); |
| 3928 } | 3921 } |
| 3929 break; | 3922 break; |
| 3930 } | 3923 } |
| 3931 case KEYED_PROPERTY: { | 3924 case KEYED_PROPERTY: { |
| 3932 __ pop(r1); // Key. | 3925 __ pop(r1); // Key. |
| 3933 __ pop(r2); // Receiver. | 3926 __ pop(r2); // Receiver. |
| 3934 Handle<Code> ic(isolate()->builtins()->builtin( | 3927 Handle<Code> ic = is_strict_mode() |
| 3935 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict | 3928 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() |
| 3936 : Builtins::KeyedStoreIC_Initialize)); | 3929 : isolate()->builtins()->KeyedStoreIC_Initialize(); |
| 3937 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3930 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 3938 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3931 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 3939 if (expr->is_postfix()) { | 3932 if (expr->is_postfix()) { |
| 3940 if (!context()->IsEffect()) { | 3933 if (!context()->IsEffect()) { |
| 3941 context()->PlugTOS(); | 3934 context()->PlugTOS(); |
| 3942 } | 3935 } |
| 3943 } else { | 3936 } else { |
| 3944 context()->Plug(r0); | 3937 context()->Plug(r0); |
| 3945 } | 3938 } |
| 3946 break; | 3939 break; |
| 3947 } | 3940 } |
| 3948 } | 3941 } |
| 3949 } | 3942 } |
| 3950 | 3943 |
| 3951 | 3944 |
| 3952 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 3945 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
| 3953 ASSERT(!context()->IsEffect()); | 3946 ASSERT(!context()->IsEffect()); |
| 3954 ASSERT(!context()->IsTest()); | 3947 ASSERT(!context()->IsTest()); |
| 3955 VariableProxy* proxy = expr->AsVariableProxy(); | 3948 VariableProxy* proxy = expr->AsVariableProxy(); |
| 3956 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { | 3949 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { |
| 3957 Comment cmnt(masm_, "Global variable"); | 3950 Comment cmnt(masm_, "Global variable"); |
| 3958 __ ldr(r0, GlobalObjectOperand()); | 3951 __ ldr(r0, GlobalObjectOperand()); |
| 3959 __ mov(r2, Operand(proxy->name())); | 3952 __ mov(r2, Operand(proxy->name())); |
| 3960 Handle<Code> ic(isolate()->builtins()->builtin( | 3953 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
| 3961 Builtins::LoadIC_Initialize)); | |
| 3962 // Use a regular load, not a contextual load, to avoid a reference | 3954 // Use a regular load, not a contextual load, to avoid a reference |
| 3963 // error. | 3955 // error. |
| 3964 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3956 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 3965 PrepareForBailout(expr, TOS_REG); | 3957 PrepareForBailout(expr, TOS_REG); |
| 3966 context()->Plug(r0); | 3958 context()->Plug(r0); |
| 3967 } else if (proxy != NULL && | 3959 } else if (proxy != NULL && |
| 3968 proxy->var()->AsSlot() != NULL && | 3960 proxy->var()->AsSlot() != NULL && |
| 3969 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { | 3961 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { |
| 3970 Label done, slow; | 3962 Label done, slow; |
| 3971 | 3963 |
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4314 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. | 4306 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. |
| 4315 __ add(pc, r1, Operand(masm_->CodeObject())); | 4307 __ add(pc, r1, Operand(masm_->CodeObject())); |
| 4316 } | 4308 } |
| 4317 | 4309 |
| 4318 | 4310 |
| 4319 #undef __ | 4311 #undef __ |
| 4320 | 4312 |
| 4321 } } // namespace v8::internal | 4313 } } // namespace v8::internal |
| 4322 | 4314 |
| 4323 #endif // V8_TARGET_ARCH_ARM | 4315 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |