Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(551)

Side by Side Diff: arguments/src/arm/full-codegen-arm.cc

Issue 6665067: [Arguments] Remove synthetic properties and all code dealing with them. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental
Patch Set: Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 663 matching lines...) Expand 10 before | Expand all | Expand 10 after
674 } 674 }
675 } 675 }
676 676
677 677
678 void FullCodeGenerator::EmitDeclaration(Variable* variable, 678 void FullCodeGenerator::EmitDeclaration(Variable* variable,
679 Variable::Mode mode, 679 Variable::Mode mode,
680 FunctionLiteral* function) { 680 FunctionLiteral* function) {
681 Comment cmnt(masm_, "[ Declaration"); 681 Comment cmnt(masm_, "[ Declaration");
682 ASSERT(variable != NULL); // Must have been resolved. 682 ASSERT(variable != NULL); // Must have been resolved.
683 Slot* slot = variable->AsSlot(); 683 Slot* slot = variable->AsSlot();
684 Property* prop = variable->AsProperty();
685 684
686 if (slot != NULL) { 685 if (slot != NULL) {
687 switch (slot->type()) { 686 switch (slot->type()) {
688 case Slot::PARAMETER: 687 case Slot::PARAMETER:
689 case Slot::LOCAL: 688 case Slot::LOCAL:
690 if (mode == Variable::CONST) { 689 if (mode == Variable::CONST) {
691 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 690 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
692 __ str(ip, MemOperand(fp, SlotOffset(slot))); 691 __ str(ip, MemOperand(fp, SlotOffset(slot)));
693 } else if (function != NULL) { 692 } else if (function != NULL) {
694 VisitForAccumulatorValue(function); 693 VisitForAccumulatorValue(function);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
743 // Push initial value for function declaration. 742 // Push initial value for function declaration.
744 VisitForStackValue(function); 743 VisitForStackValue(function);
745 } else { 744 } else {
746 __ mov(r0, Operand(Smi::FromInt(0))); // No initial value! 745 __ mov(r0, Operand(Smi::FromInt(0))); // No initial value!
747 __ Push(cp, r2, r1, r0); 746 __ Push(cp, r2, r1, r0);
748 } 747 }
749 __ CallRuntime(Runtime::kDeclareContextSlot, 4); 748 __ CallRuntime(Runtime::kDeclareContextSlot, 4);
750 break; 749 break;
751 } 750 }
752 } 751 }
753
754 } else if (prop != NULL) {
755 if (function != NULL || mode == Variable::CONST) {
756 // We are declaring a function or constant that rewrites to a
757 // property. Use (keyed) IC to set the initial value. We
758 // cannot visit the rewrite because it's shared and we risk
759 // recording duplicate AST IDs for bailouts from optimized code.
760 ASSERT(prop->obj()->AsVariableProxy() != NULL);
761 { AccumulatorValueContext for_object(this);
762 EmitVariableLoad(prop->obj()->AsVariableProxy()->var());
763 }
764 if (function != NULL) {
765 __ push(r0);
766 VisitForAccumulatorValue(function);
767 __ pop(r2);
768 } else {
769 __ mov(r2, r0);
770 __ LoadRoot(r0, Heap::kTheHoleValueRootIndex);
771 }
772 ASSERT(prop->key()->AsLiteral() != NULL &&
773 prop->key()->AsLiteral()->handle()->IsSmi());
774 __ mov(r1, Operand(prop->key()->AsLiteral()->handle()));
775
776 Handle<Code> ic(Builtins::builtin(
777 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict
778 : Builtins::KeyedStoreIC_Initialize));
779 EmitCallIC(ic, RelocInfo::CODE_TARGET);
780 // Value in r0 is ignored (declarations are statements).
781 }
782 } 752 }
783 } 753 }
784 754
785 755
786 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { 756 void FullCodeGenerator::VisitDeclaration(Declaration* decl) {
787 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); 757 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun());
788 } 758 }
789 759
790 760
791 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 761 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after
1144 // Generate fast-case code for variables that might be shadowed by 1114 // Generate fast-case code for variables that might be shadowed by
1145 // eval-introduced variables. Eval is used a lot without 1115 // eval-introduced variables. Eval is used a lot without
1146 // introducing variables. In those cases, we do not want to 1116 // introducing variables. In those cases, we do not want to
1147 // perform a runtime call for all variables in the scope 1117 // perform a runtime call for all variables in the scope
1148 // containing the eval. 1118 // containing the eval.
1149 if (slot->var()->mode() == Variable::DYNAMIC_GLOBAL) { 1119 if (slot->var()->mode() == Variable::DYNAMIC_GLOBAL) {
1150 EmitLoadGlobalSlotCheckExtensions(slot, typeof_state, slow); 1120 EmitLoadGlobalSlotCheckExtensions(slot, typeof_state, slow);
1151 __ jmp(done); 1121 __ jmp(done);
1152 } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) { 1122 } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) {
1153 Slot* potential_slot = slot->var()->local_if_not_shadowed()->AsSlot(); 1123 Slot* potential_slot = slot->var()->local_if_not_shadowed()->AsSlot();
1154 Expression* rewrite = slot->var()->local_if_not_shadowed()->rewrite();
1155 if (potential_slot != NULL) { 1124 if (potential_slot != NULL) {
1156 // Generate fast case for locals that rewrite to slots. 1125 // Generate fast case for locals that rewrite to slots.
1157 __ ldr(r0, ContextSlotOperandCheckExtensions(potential_slot, slow)); 1126 __ ldr(r0, ContextSlotOperandCheckExtensions(potential_slot, slow));
1158 if (potential_slot->var()->mode() == Variable::CONST) { 1127 if (potential_slot->var()->mode() == Variable::CONST) {
1159 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 1128 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
1160 __ cmp(r0, ip); 1129 __ cmp(r0, ip);
1161 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq); 1130 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq);
1162 } 1131 }
1163 __ jmp(done); 1132 __ jmp(done);
1164 } else if (rewrite != NULL) {
1165 // Generate fast case for calls of an argument function.
1166 Property* property = rewrite->AsProperty();
1167 if (property != NULL) {
1168 VariableProxy* obj_proxy = property->obj()->AsVariableProxy();
1169 Literal* key_literal = property->key()->AsLiteral();
1170 if (obj_proxy != NULL &&
1171 key_literal != NULL &&
1172 obj_proxy->IsArguments() &&
1173 key_literal->handle()->IsSmi()) {
1174 // Load arguments object if there are no eval-introduced
1175 // variables. Then load the argument from the arguments
1176 // object using keyed load.
1177 __ ldr(r1,
1178 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(),
1179 slow));
1180 __ mov(r0, Operand(key_literal->handle()));
1181 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
1182 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1183 __ jmp(done);
1184 }
1185 }
1186 } 1133 }
1187 } 1134 }
1188 } 1135 }
1189 1136
1190 1137
1191 void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions( 1138 void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions(
1192 Slot* slot, 1139 Slot* slot,
1193 TypeofState typeof_state, 1140 TypeofState typeof_state,
1194 Label* slow) { 1141 Label* slow) {
1195 Register current = cp; 1142 Register current = cp;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1243 __ mov(r2, Operand(slot->var()->name())); 1190 __ mov(r2, Operand(slot->var()->name()));
1244 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) 1191 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
1245 ? RelocInfo::CODE_TARGET 1192 ? RelocInfo::CODE_TARGET
1246 : RelocInfo::CODE_TARGET_CONTEXT; 1193 : RelocInfo::CODE_TARGET_CONTEXT;
1247 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 1194 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
1248 EmitCallIC(ic, mode); 1195 EmitCallIC(ic, mode);
1249 } 1196 }
1250 1197
1251 1198
1252 void FullCodeGenerator::EmitVariableLoad(Variable* var) { 1199 void FullCodeGenerator::EmitVariableLoad(Variable* var) {
1253 // Four cases: non-this global variables, lookup slots, all other 1200 // Three cases: non-this global variables, lookup slots, and all other
1254 // types of slots, and parameters that rewrite to explicit property 1201 // types of slots.
1255 // accesses on the arguments object.
1256 Slot* slot = var->AsSlot(); 1202 Slot* slot = var->AsSlot();
1257 Property* property = var->AsProperty(); 1203 ASSERT((var->is_global() && !var->is_this()) == (slot == NULL));
1258 1204
1259 if (var->is_global() && !var->is_this()) { 1205 if (slot == NULL) {
1260 Comment cmnt(masm_, "Global variable"); 1206 Comment cmnt(masm_, "Global variable");
1261 // Use inline caching. Variable name is passed in r2 and the global 1207 // Use inline caching. Variable name is passed in r2 and the global
1262 // object (receiver) in r0. 1208 // object (receiver) in r0.
1263 __ ldr(r0, GlobalObjectOperand()); 1209 __ ldr(r0, GlobalObjectOperand());
1264 __ mov(r2, Operand(var->name())); 1210 __ mov(r2, Operand(var->name()));
1265 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 1211 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
1266 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); 1212 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
1267 context()->Plug(r0); 1213 context()->Plug(r0);
1268 1214
1269 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { 1215 } else if (slot->type() == Slot::LOOKUP) {
1270 Label done, slow; 1216 Label done, slow;
1271 1217
1272 // Generate code for loading from variables potentially shadowed 1218 // Generate code for loading from variables potentially shadowed
1273 // by eval-introduced variables. 1219 // by eval-introduced variables.
1274 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); 1220 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done);
1275 1221
1276 __ bind(&slow); 1222 __ bind(&slow);
1277 Comment cmnt(masm_, "Lookup slot"); 1223 Comment cmnt(masm_, "Lookup slot");
1278 __ mov(r1, Operand(var->name())); 1224 __ mov(r1, Operand(var->name()));
1279 __ Push(cp, r1); // Context and name. 1225 __ Push(cp, r1); // Context and name.
1280 __ CallRuntime(Runtime::kLoadContextSlot, 2); 1226 __ CallRuntime(Runtime::kLoadContextSlot, 2);
1281 __ bind(&done); 1227 __ bind(&done);
1282 1228
1283 context()->Plug(r0); 1229 context()->Plug(r0);
1284 1230
1285 } else if (slot != NULL) { 1231 } else {
1286 Comment cmnt(masm_, (slot->type() == Slot::CONTEXT) 1232 Comment cmnt(masm_, (slot->type() == Slot::CONTEXT)
1287 ? "Context slot" 1233 ? "Context slot"
1288 : "Stack slot"); 1234 : "Stack slot");
1289 if (var->mode() == Variable::CONST) { 1235 if (var->mode() == Variable::CONST) {
1290 // Constants may be the hole value if they have not been initialized. 1236 // Constants may be the hole value if they have not been initialized.
1291 // Unhole them. 1237 // Unhole them.
1292 MemOperand slot_operand = EmitSlotSearch(slot, r0); 1238 MemOperand slot_operand = EmitSlotSearch(slot, r0);
1293 __ ldr(r0, slot_operand); 1239 __ ldr(r0, slot_operand);
1294 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 1240 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
1295 __ cmp(r0, ip); 1241 __ cmp(r0, ip);
1296 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq); 1242 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq);
1297 context()->Plug(r0); 1243 context()->Plug(r0);
1298 } else { 1244 } else {
1299 context()->Plug(slot); 1245 context()->Plug(slot);
1300 } 1246 }
1301 } else {
1302 Comment cmnt(masm_, "Rewritten parameter");
1303 ASSERT_NOT_NULL(property);
1304 // Rewritten parameter accesses are of the form "slot[literal]".
1305
1306 // Assert that the object is in a slot.
1307 Variable* object_var = property->obj()->AsVariableProxy()->AsVariable();
1308 ASSERT_NOT_NULL(object_var);
1309 Slot* object_slot = object_var->AsSlot();
1310 ASSERT_NOT_NULL(object_slot);
1311
1312 // Load the object.
1313 Move(r1, object_slot);
1314
1315 // Assert that the key is a smi.
1316 Literal* key_literal = property->key()->AsLiteral();
1317 ASSERT_NOT_NULL(key_literal);
1318 ASSERT(key_literal->handle()->IsSmi());
1319
1320 // Load the key.
1321 __ mov(r0, Operand(key_literal->handle()));
1322
1323 // Call keyed load IC. It has arguments key and receiver in r0 and r1.
1324 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
1325 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1326 context()->Plug(r0);
1327 } 1247 }
1328 } 1248 }
1329 1249
1330 1250
1331 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 1251 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
1332 Comment cmnt(masm_, "[ RegExpLiteral"); 1252 Comment cmnt(masm_, "[ RegExpLiteral");
1333 Label materialized; 1253 Label materialized;
1334 // Registers will be used as follows: 1254 // Registers will be used as follows:
1335 // r5 = materialized value (RegExp literal) 1255 // r5 = materialized value (RegExp literal)
1336 // r4 = JS function, literals array 1256 // r4 = JS function, literals array
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
1540 void FullCodeGenerator::VisitAssignment(Assignment* expr) { 1460 void FullCodeGenerator::VisitAssignment(Assignment* expr) {
1541 Comment cmnt(masm_, "[ Assignment"); 1461 Comment cmnt(masm_, "[ Assignment");
1542 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError' 1462 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError'
1543 // on the left-hand side. 1463 // on the left-hand side.
1544 if (!expr->target()->IsValidLeftHandSide()) { 1464 if (!expr->target()->IsValidLeftHandSide()) {
1545 VisitForEffect(expr->target()); 1465 VisitForEffect(expr->target());
1546 return; 1466 return;
1547 } 1467 }
1548 1468
1549 // Left-hand side can only be a property, a global or a (parameter or local) 1469 // Left-hand side can only be a property, a global or a (parameter or local)
1550 // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY. 1470 // slot.
1551 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 1471 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
1552 LhsKind assign_type = VARIABLE; 1472 LhsKind assign_type = VARIABLE;
1553 Property* property = expr->target()->AsProperty(); 1473 Property* property = expr->target()->AsProperty();
1554 if (property != NULL) { 1474 if (property != NULL) {
1555 assign_type = (property->key()->IsPropertyName()) 1475 assign_type = (property->key()->IsPropertyName())
1556 ? NAMED_PROPERTY 1476 ? NAMED_PROPERTY
1557 : KEYED_PROPERTY; 1477 : KEYED_PROPERTY;
1558 } 1478 }
1559 1479
1560 // Evaluate LHS expression. 1480 // Evaluate LHS expression.
1561 switch (assign_type) { 1481 switch (assign_type) {
1562 case VARIABLE: 1482 case VARIABLE:
1563 // Nothing to do here. 1483 // Nothing to do here.
1564 break; 1484 break;
1565 case NAMED_PROPERTY: 1485 case NAMED_PROPERTY:
1566 if (expr->is_compound()) { 1486 if (expr->is_compound()) {
1567 // We need the receiver both on the stack and in the accumulator. 1487 // We need the receiver both on the stack and in the accumulator.
1568 VisitForAccumulatorValue(property->obj()); 1488 VisitForAccumulatorValue(property->obj());
1569 __ push(result_register()); 1489 __ push(result_register());
1570 } else { 1490 } else {
1571 VisitForStackValue(property->obj()); 1491 VisitForStackValue(property->obj());
1572 } 1492 }
1573 break; 1493 break;
1574 case KEYED_PROPERTY: 1494 case KEYED_PROPERTY:
1575 if (expr->is_compound()) { 1495 if (expr->is_compound()) {
1576 if (property->is_arguments_access()) { 1496 VisitForStackValue(property->obj());
1577 VariableProxy* obj_proxy = property->obj()->AsVariableProxy(); 1497 VisitForAccumulatorValue(property->key());
1578 __ ldr(r0, EmitSlotSearch(obj_proxy->var()->AsSlot(), r0));
1579 __ push(r0);
1580 __ mov(r0, Operand(property->key()->AsLiteral()->handle()));
1581 } else {
1582 VisitForStackValue(property->obj());
1583 VisitForAccumulatorValue(property->key());
1584 }
1585 __ ldr(r1, MemOperand(sp, 0)); 1498 __ ldr(r1, MemOperand(sp, 0));
1586 __ push(r0); 1499 __ push(r0);
1587 } else { 1500 } else {
1588 if (property->is_arguments_access()) { 1501 VisitForStackValue(property->obj());
1589 VariableProxy* obj_proxy = property->obj()->AsVariableProxy(); 1502 VisitForStackValue(property->key());
1590 __ ldr(r1, EmitSlotSearch(obj_proxy->var()->AsSlot(), r0));
1591 __ mov(r0, Operand(property->key()->AsLiteral()->handle()));
1592 __ Push(r1, r0);
1593 } else {
1594 VisitForStackValue(property->obj());
1595 VisitForStackValue(property->key());
1596 }
1597 } 1503 }
1598 break; 1504 break;
1599 } 1505 }
1600 1506
1601 // For compound assignments we need another deoptimization point after the 1507 // For compound assignments we need another deoptimization point after the
1602 // variable/property load. 1508 // variable/property load.
1603 if (expr->is_compound()) { 1509 if (expr->is_compound()) {
1604 { AccumulatorValueContext context(this); 1510 { AccumulatorValueContext context(this);
1605 switch (assign_type) { 1511 switch (assign_type) {
1606 case VARIABLE: 1512 case VARIABLE:
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
1792 1698
1793 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) { 1699 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) {
1794 // Invalid left-hand sides are rewritten to have a 'throw 1700 // Invalid left-hand sides are rewritten to have a 'throw
1795 // ReferenceError' on the left-hand side. 1701 // ReferenceError' on the left-hand side.
1796 if (!expr->IsValidLeftHandSide()) { 1702 if (!expr->IsValidLeftHandSide()) {
1797 VisitForEffect(expr); 1703 VisitForEffect(expr);
1798 return; 1704 return;
1799 } 1705 }
1800 1706
1801 // Left-hand side can only be a property, a global or a (parameter or local) 1707 // Left-hand side can only be a property, a global or a (parameter or local)
1802 // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY. 1708 // slot.
1803 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 1709 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
1804 LhsKind assign_type = VARIABLE; 1710 LhsKind assign_type = VARIABLE;
1805 Property* prop = expr->AsProperty(); 1711 Property* prop = expr->AsProperty();
1806 if (prop != NULL) { 1712 if (prop != NULL) {
1807 assign_type = (prop->key()->IsPropertyName()) 1713 assign_type = (prop->key()->IsPropertyName())
1808 ? NAMED_PROPERTY 1714 ? NAMED_PROPERTY
1809 : KEYED_PROPERTY; 1715 : KEYED_PROPERTY;
1810 } 1716 }
1811 1717
1812 switch (assign_type) { 1718 switch (assign_type) {
(...skipping 10 matching lines...) Expand all
1823 __ pop(r0); // Restore value. 1729 __ pop(r0); // Restore value.
1824 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); 1730 __ mov(r2, Operand(prop->key()->AsLiteral()->handle()));
1825 Handle<Code> ic(Builtins::builtin( 1731 Handle<Code> ic(Builtins::builtin(
1826 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict 1732 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict
1827 : Builtins::StoreIC_Initialize)); 1733 : Builtins::StoreIC_Initialize));
1828 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1734 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1829 break; 1735 break;
1830 } 1736 }
1831 case KEYED_PROPERTY: { 1737 case KEYED_PROPERTY: {
1832 __ push(r0); // Preserve value. 1738 __ push(r0); // Preserve value.
1833 if (prop->is_synthetic()) { 1739 VisitForStackValue(prop->obj());
1834 ASSERT(prop->obj()->AsVariableProxy() != NULL); 1740 VisitForAccumulatorValue(prop->key());
1835 ASSERT(prop->key()->AsLiteral() != NULL); 1741 __ mov(r1, r0);
1836 { AccumulatorValueContext for_object(this); 1742 __ pop(r2);
1837 EmitVariableLoad(prop->obj()->AsVariableProxy()->var());
1838 }
1839 __ mov(r2, r0);
1840 __ mov(r1, Operand(prop->key()->AsLiteral()->handle()));
1841 } else {
1842 VisitForStackValue(prop->obj());
1843 VisitForAccumulatorValue(prop->key());
1844 __ mov(r1, r0);
1845 __ pop(r2);
1846 }
1847 __ pop(r0); // Restore value. 1743 __ pop(r0); // Restore value.
1848 Handle<Code> ic(Builtins::builtin( 1744 Handle<Code> ic(Builtins::builtin(
1849 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict 1745 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict
1850 : Builtins::KeyedStoreIC_Initialize)); 1746 : Builtins::KeyedStoreIC_Initialize));
1851 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1747 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1852 break; 1748 break;
1853 } 1749 }
1854 } 1750 }
1855 PrepareForBailoutForId(bailout_ast_id, TOS_REG); 1751 PrepareForBailoutForId(bailout_ast_id, TOS_REG);
1856 context()->Plug(r0); 1752 context()->Plug(r0);
1857 } 1753 }
1858 1754
1859 1755
1860 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 1756 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
1861 Token::Value op) { 1757 Token::Value op) {
1862 // Left-hand sides that rewrite to explicit property accesses do not reach
1863 // here.
1864 ASSERT(var != NULL); 1758 ASSERT(var != NULL);
1865 ASSERT(var->is_global() || var->AsSlot() != NULL); 1759 ASSERT(var->is_global() || var->AsSlot() != NULL);
1866 1760
1867 if (var->is_global()) { 1761 if (var->is_global()) {
1868 ASSERT(!var->is_this()); 1762 ASSERT(!var->is_this());
1869 // Assignment to a global variable. Use inline caching for the 1763 // Assignment to a global variable. Use inline caching for the
1870 // assignment. Right-hand-side value is passed in r0, variable name in 1764 // assignment. Right-hand-side value is passed in r0, variable name in
1871 // r2, and the global object in r1. 1765 // r2, and the global object in r1.
1872 __ mov(r2, Operand(var->name())); 1766 __ mov(r2, Operand(var->name()));
1873 __ ldr(r1, GlobalObjectOperand()); 1767 __ ldr(r1, GlobalObjectOperand());
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
2286 Property* prop = fun->AsProperty(); 2180 Property* prop = fun->AsProperty();
2287 Literal* key = prop->key()->AsLiteral(); 2181 Literal* key = prop->key()->AsLiteral();
2288 if (key != NULL && key->handle()->IsSymbol()) { 2182 if (key != NULL && key->handle()->IsSymbol()) {
2289 // Call to a named property, use call IC. 2183 // Call to a named property, use call IC.
2290 { PreservePositionScope scope(masm()->positions_recorder()); 2184 { PreservePositionScope scope(masm()->positions_recorder());
2291 VisitForStackValue(prop->obj()); 2185 VisitForStackValue(prop->obj());
2292 } 2186 }
2293 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); 2187 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET);
2294 } else { 2188 } else {
2295 // Call to a keyed property. 2189 // Call to a keyed property.
2296 // For a synthetic property use keyed load IC followed by function call, 2190 { PreservePositionScope scope(masm()->positions_recorder());
2297 // for a regular property use keyed CallIC. 2191 VisitForStackValue(prop->obj());
2298 if (prop->is_synthetic()) {
2299 // Do not visit the object and key subexpressions (they are shared
2300 // by all occurrences of the same rewritten parameter).
2301 ASSERT(prop->obj()->AsVariableProxy() != NULL);
2302 ASSERT(prop->obj()->AsVariableProxy()->var()->AsSlot() != NULL);
2303 Slot* slot = prop->obj()->AsVariableProxy()->var()->AsSlot();
2304 MemOperand operand = EmitSlotSearch(slot, r1);
2305 __ ldr(r1, operand);
2306
2307 ASSERT(prop->key()->AsLiteral() != NULL);
2308 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi());
2309 __ mov(r0, Operand(prop->key()->AsLiteral()->handle()));
2310
2311 // Record source code position for IC call.
2312 SetSourcePosition(prop->position());
2313
2314 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
2315 EmitCallIC(ic, RelocInfo::CODE_TARGET);
2316 __ ldr(r1, GlobalObjectOperand());
2317 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset));
2318 __ Push(r0, r1); // Function, receiver.
2319 EmitCallWithStub(expr);
2320 } else {
2321 { PreservePositionScope scope(masm()->positions_recorder());
2322 VisitForStackValue(prop->obj());
2323 }
2324 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET);
2325 } 2192 }
2193 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET);
2326 } 2194 }
2327 } else { 2195 } else {
2328 // Call to some other expression. If the expression is an anonymous 2196 // Call to some other expression. If the expression is an anonymous
2329 // function literal not called in a loop, mark it as one that should 2197 // function literal not called in a loop, mark it as one that should
2330 // also use the fast code generator. 2198 // also use the fast code generator.
2331 FunctionLiteral* lit = fun->AsFunctionLiteral(); 2199 FunctionLiteral* lit = fun->AsFunctionLiteral();
2332 if (lit != NULL && 2200 if (lit != NULL &&
2333 lit->name()->Equals(Heap::empty_string()) && 2201 lit->name()->Equals(Heap::empty_string()) &&
2334 loop_depth() == 0) { 2202 loop_depth() == 0) {
2335 lit->set_try_full_codegen(true); 2203 lit->set_try_full_codegen(true);
(...skipping 1251 matching lines...) Expand 10 before | Expand all | Expand 10 after
3587 3455
3588 3456
3589 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 3457 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
3590 switch (expr->op()) { 3458 switch (expr->op()) {
3591 case Token::DELETE: { 3459 case Token::DELETE: {
3592 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 3460 Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
3593 Property* prop = expr->expression()->AsProperty(); 3461 Property* prop = expr->expression()->AsProperty();
3594 Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); 3462 Variable* var = expr->expression()->AsVariableProxy()->AsVariable();
3595 3463
3596 if (prop != NULL) { 3464 if (prop != NULL) {
3597 if (prop->is_synthetic()) { 3465 VisitForStackValue(prop->obj());
3598 // Result of deleting parameters is false, even when they rewrite 3466 VisitForStackValue(prop->key());
3599 // to accesses on the arguments object. 3467 __ mov(r1, Operand(Smi::FromInt(strict_mode_flag())));
3600 context()->Plug(false); 3468 __ push(r1);
3601 } else { 3469 __ InvokeBuiltin(Builtins::DELETE, CALL_JS);
3602 VisitForStackValue(prop->obj()); 3470 context()->Plug(r0);
3603 VisitForStackValue(prop->key());
3604 __ mov(r1, Operand(Smi::FromInt(strict_mode_flag())));
3605 __ push(r1);
3606 __ InvokeBuiltin(Builtins::DELETE, CALL_JS);
3607 context()->Plug(r0);
3608 }
3609 } else if (var != NULL) { 3471 } else if (var != NULL) {
3610 // Delete of an unqualified identifier is disallowed in strict mode 3472 // Delete of an unqualified identifier is disallowed in strict mode
3611 // but "delete this" is. 3473 // but "delete this" is.
3612 ASSERT(strict_mode_flag() == kNonStrictMode || var->is_this()); 3474 ASSERT(strict_mode_flag() == kNonStrictMode || var->is_this());
3613 if (var->is_global()) { 3475 if (var->is_global()) {
3614 __ ldr(r2, GlobalObjectOperand()); 3476 __ ldr(r2, GlobalObjectOperand());
3615 __ mov(r1, Operand(var->name())); 3477 __ mov(r1, Operand(var->name()));
3616 __ mov(r0, Operand(Smi::FromInt(kNonStrictMode))); 3478 __ mov(r0, Operand(Smi::FromInt(kNonStrictMode)));
3617 __ Push(r2, r1, r0); 3479 __ Push(r2, r1, r0);
3618 __ InvokeBuiltin(Builtins::DELETE, CALL_JS); 3480 __ InvokeBuiltin(Builtins::DELETE, CALL_JS);
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
3746 SetSourcePosition(expr->position()); 3608 SetSourcePosition(expr->position());
3747 3609
3748 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError' 3610 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError'
3749 // as the left-hand side. 3611 // as the left-hand side.
3750 if (!expr->expression()->IsValidLeftHandSide()) { 3612 if (!expr->expression()->IsValidLeftHandSide()) {
3751 VisitForEffect(expr->expression()); 3613 VisitForEffect(expr->expression());
3752 return; 3614 return;
3753 } 3615 }
3754 3616
3755 // Expression can only be a property, a global or a (parameter or local) 3617 // Expression can only be a property, a global or a (parameter or local)
3756 // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY. 3618 // slot.
3757 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 3619 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
3758 LhsKind assign_type = VARIABLE; 3620 LhsKind assign_type = VARIABLE;
3759 Property* prop = expr->expression()->AsProperty(); 3621 Property* prop = expr->expression()->AsProperty();
3760 // In case of a property we use the uninitialized expression context 3622 // In case of a property we use the uninitialized expression context
3761 // of the key to detect a named property. 3623 // of the key to detect a named property.
3762 if (prop != NULL) { 3624 if (prop != NULL) {
3763 assign_type = 3625 assign_type =
3764 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY; 3626 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY;
3765 } 3627 }
3766 3628
3767 // Evaluate expression and get value. 3629 // Evaluate expression and get value.
3768 if (assign_type == VARIABLE) { 3630 if (assign_type == VARIABLE) {
3769 ASSERT(expr->expression()->AsVariableProxy()->var() != NULL); 3631 ASSERT(expr->expression()->AsVariableProxy()->var() != NULL);
3770 AccumulatorValueContext context(this); 3632 AccumulatorValueContext context(this);
3771 EmitVariableLoad(expr->expression()->AsVariableProxy()->var()); 3633 EmitVariableLoad(expr->expression()->AsVariableProxy()->var());
3772 } else { 3634 } else {
3773 // Reserve space for result of postfix operation. 3635 // Reserve space for result of postfix operation.
3774 if (expr->is_postfix() && !context()->IsEffect()) { 3636 if (expr->is_postfix() && !context()->IsEffect()) {
3775 __ mov(ip, Operand(Smi::FromInt(0))); 3637 __ mov(ip, Operand(Smi::FromInt(0)));
3776 __ push(ip); 3638 __ push(ip);
3777 } 3639 }
3778 if (assign_type == NAMED_PROPERTY) { 3640 if (assign_type == NAMED_PROPERTY) {
3779 // Put the object both on the stack and in the accumulator. 3641 // Put the object both on the stack and in the accumulator.
3780 VisitForAccumulatorValue(prop->obj()); 3642 VisitForAccumulatorValue(prop->obj());
3781 __ push(r0); 3643 __ push(r0);
3782 EmitNamedPropertyLoad(prop); 3644 EmitNamedPropertyLoad(prop);
3783 } else { 3645 } else {
3784 if (prop->is_arguments_access()) { 3646 VisitForStackValue(prop->obj());
3785 VariableProxy* obj_proxy = prop->obj()->AsVariableProxy(); 3647 VisitForAccumulatorValue(prop->key());
3786 __ ldr(r0, EmitSlotSearch(obj_proxy->var()->AsSlot(), r0));
3787 __ push(r0);
3788 __ mov(r0, Operand(prop->key()->AsLiteral()->handle()));
3789 } else {
3790 VisitForStackValue(prop->obj());
3791 VisitForAccumulatorValue(prop->key());
3792 }
3793 __ ldr(r1, MemOperand(sp, 0)); 3648 __ ldr(r1, MemOperand(sp, 0));
3794 __ push(r0); 3649 __ push(r0);
3795 EmitKeyedPropertyLoad(prop); 3650 EmitKeyedPropertyLoad(prop);
3796 } 3651 }
3797 } 3652 }
3798 3653
3799 // We need a second deoptimization point after loading the value 3654 // We need a second deoptimization point after loading the value
3800 // in case evaluating the property load my have a side effect. 3655 // in case evaluating the property load my have a side effect.
3801 if (assign_type == VARIABLE) { 3656 if (assign_type == VARIABLE) {
3802 PrepareForBailout(expr->expression(), TOS_REG); 3657 PrepareForBailout(expr->expression(), TOS_REG);
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after
4279 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. 4134 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value.
4280 __ add(pc, r1, Operand(masm_->CodeObject())); 4135 __ add(pc, r1, Operand(masm_->CodeObject()));
4281 } 4136 }
4282 4137
4283 4138
4284 #undef __ 4139 #undef __
4285 4140
4286 } } // namespace v8::internal 4141 } } // namespace v8::internal
4287 4142
4288 #endif // V8_TARGET_ARCH_ARM 4143 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « arguments/src/arm/codegen-arm.cc ('k') | arguments/src/ast.h » ('j') | arguments/src/scopes.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698