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 |