OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 827 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
838 // Rewritten parameter accesses are of the form "slot[literal]". | 838 // Rewritten parameter accesses are of the form "slot[literal]". |
839 | 839 |
840 // Assert that the object is in a slot. | 840 // Assert that the object is in a slot. |
841 Variable* object_var = property->obj()->AsVariableProxy()->AsVariable(); | 841 Variable* object_var = property->obj()->AsVariableProxy()->AsVariable(); |
842 ASSERT_NOT_NULL(object_var); | 842 ASSERT_NOT_NULL(object_var); |
843 Slot* object_slot = object_var->slot(); | 843 Slot* object_slot = object_var->slot(); |
844 ASSERT_NOT_NULL(object_slot); | 844 ASSERT_NOT_NULL(object_slot); |
845 | 845 |
846 // Load the object. | 846 // Load the object. |
847 MemOperand object_loc = EmitSlotSearch(object_slot, eax); | 847 MemOperand object_loc = EmitSlotSearch(object_slot, eax); |
848 __ push(object_loc); | 848 __ mov(edx, object_loc); |
849 | 849 |
850 // Assert that the key is a smi. | 850 // Assert that the key is a smi. |
851 Literal* key_literal = property->key()->AsLiteral(); | 851 Literal* key_literal = property->key()->AsLiteral(); |
852 ASSERT_NOT_NULL(key_literal); | 852 ASSERT_NOT_NULL(key_literal); |
853 ASSERT(key_literal->handle()->IsSmi()); | 853 ASSERT(key_literal->handle()->IsSmi()); |
854 | 854 |
855 // Load the key. | 855 // Load the key. |
856 __ push(Immediate(key_literal->handle())); | 856 __ mov(eax, Immediate(key_literal->handle())); |
857 | 857 |
858 // Do a keyed property load. | 858 // Do a keyed property load. |
859 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 859 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
860 __ call(ic, RelocInfo::CODE_TARGET); | 860 __ call(ic, RelocInfo::CODE_TARGET); |
861 // Notice: We must not have a "test eax, ..." instruction after the | 861 // Notice: We must not have a "test eax, ..." instruction after the |
862 // call. It is treated specially by the LoadIC code. | 862 // call. It is treated specially by the LoadIC code. |
863 __ nop(); | 863 __ nop(); |
864 // Drop key and object left on the stack by IC. | 864 // Drop key and object left on the stack by IC. |
865 DropAndApply(2, context, eax); | 865 Apply(context, eax); |
866 } | 866 } |
867 } | 867 } |
868 | 868 |
869 | 869 |
870 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { | 870 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { |
871 Comment cmnt(masm_, "[ RegExpLiteral"); | 871 Comment cmnt(masm_, "[ RegExpLiteral"); |
872 Label done; | 872 Label done; |
873 // Registers will be used as follows: | 873 // Registers will be used as follows: |
874 // edi = JS function. | 874 // edi = JS function. |
875 // ebx = literals array. | 875 // ebx = literals array. |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1182 void FullCodeGenerator::VisitProperty(Property* expr) { | 1182 void FullCodeGenerator::VisitProperty(Property* expr) { |
1183 Comment cmnt(masm_, "[ Property"); | 1183 Comment cmnt(masm_, "[ Property"); |
1184 Expression* key = expr->key(); | 1184 Expression* key = expr->key(); |
1185 | 1185 |
1186 if (key->IsPropertyName()) { | 1186 if (key->IsPropertyName()) { |
1187 VisitForValue(expr->obj(), kAccumulator); | 1187 VisitForValue(expr->obj(), kAccumulator); |
1188 EmitNamedPropertyLoad(expr); | 1188 EmitNamedPropertyLoad(expr); |
1189 Apply(context_, eax); | 1189 Apply(context_, eax); |
1190 } else { | 1190 } else { |
1191 VisitForValue(expr->obj(), kStack); | 1191 VisitForValue(expr->obj(), kStack); |
1192 VisitForValue(expr->key(), kStack); | 1192 VisitForValue(expr->key(), kAccumulator); |
| 1193 __ pop(edx); |
1193 EmitKeyedPropertyLoad(expr); | 1194 EmitKeyedPropertyLoad(expr); |
1194 // Drop key and receiver left on the stack by IC. | 1195 Apply(context_, eax); |
1195 DropAndApply(2, context_, eax); | |
1196 } | 1196 } |
1197 } | 1197 } |
1198 | 1198 |
1199 | 1199 |
1200 void FullCodeGenerator::EmitCallWithIC(Call* expr, | 1200 void FullCodeGenerator::EmitCallWithIC(Call* expr, |
1201 Handle<Object> name, | 1201 Handle<Object> name, |
1202 RelocInfo::Mode mode) { | 1202 RelocInfo::Mode mode) { |
1203 // Code common for calls using the IC. | 1203 // Code common for calls using the IC. |
1204 ZoneList<Expression*>* args = expr->arguments(); | 1204 ZoneList<Expression*>* args = expr->arguments(); |
1205 int arg_count = args->length(); | 1205 int arg_count = args->length(); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1256 Property* prop = fun->AsProperty(); | 1256 Property* prop = fun->AsProperty(); |
1257 Literal* key = prop->key()->AsLiteral(); | 1257 Literal* key = prop->key()->AsLiteral(); |
1258 if (key != NULL && key->handle()->IsSymbol()) { | 1258 if (key != NULL && key->handle()->IsSymbol()) { |
1259 // Call to a named property, use call IC. | 1259 // Call to a named property, use call IC. |
1260 VisitForValue(prop->obj(), kStack); | 1260 VisitForValue(prop->obj(), kStack); |
1261 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); | 1261 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); |
1262 } else { | 1262 } else { |
1263 // Call to a keyed property, use keyed load IC followed by function | 1263 // Call to a keyed property, use keyed load IC followed by function |
1264 // call. | 1264 // call. |
1265 VisitForValue(prop->obj(), kStack); | 1265 VisitForValue(prop->obj(), kStack); |
1266 VisitForValue(prop->key(), kStack); | 1266 VisitForValue(prop->key(), kAccumulator); |
1267 // Record source code position for IC call. | 1267 // Record source code position for IC call. |
1268 SetSourcePosition(prop->position()); | 1268 SetSourcePosition(prop->position()); |
| 1269 if (prop->is_synthetic()) { |
| 1270 __ pop(edx); // We do not need to keep the receiver. |
| 1271 } else { |
| 1272 __ mov(edx, Operand(esp, 0)); // Keep receiver, to call function on. |
| 1273 } |
| 1274 |
1269 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 1275 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
1270 __ call(ic, RelocInfo::CODE_TARGET); | 1276 __ call(ic, RelocInfo::CODE_TARGET); |
1271 // By emitting a nop we make sure that we do not have a "test eax,..." | 1277 // By emitting a nop we make sure that we do not have a "test eax,..." |
1272 // instruction after the call it is treated specially by the LoadIC code. | 1278 // instruction after the call it is treated specially by the LoadIC code. |
1273 __ nop(); | 1279 __ nop(); |
1274 // Drop key left on the stack by IC. | |
1275 __ Drop(1); | |
1276 // Pop receiver. | |
1277 __ pop(ebx); | |
1278 // Push result (function). | |
1279 __ push(eax); | |
1280 // Push receiver object on stack. | |
1281 if (prop->is_synthetic()) { | 1280 if (prop->is_synthetic()) { |
| 1281 // Push result (function). |
| 1282 __ push(eax); |
| 1283 // Push Global receiver. |
1282 __ mov(ecx, CodeGenerator::GlobalObject()); | 1284 __ mov(ecx, CodeGenerator::GlobalObject()); |
1283 __ push(FieldOperand(ecx, GlobalObject::kGlobalReceiverOffset)); | 1285 __ push(FieldOperand(ecx, GlobalObject::kGlobalReceiverOffset)); |
1284 } else { | 1286 } else { |
| 1287 // Pop receiver. |
| 1288 __ pop(ebx); |
| 1289 // Push result (function). |
| 1290 __ push(eax); |
1285 __ push(ebx); | 1291 __ push(ebx); |
1286 } | 1292 } |
1287 EmitCallWithStub(expr); | 1293 EmitCallWithStub(expr); |
1288 } | 1294 } |
1289 } else { | 1295 } else { |
1290 // Call to some other expression. If the expression is an anonymous | 1296 // Call to some other expression. If the expression is an anonymous |
1291 // function literal not called in a loop, mark it as one that should | 1297 // function literal not called in a loop, mark it as one that should |
1292 // also use the full code generator. | 1298 // also use the full code generator. |
1293 FunctionLiteral* lit = fun->AsFunctionLiteral(); | 1299 FunctionLiteral* lit = fun->AsFunctionLiteral(); |
1294 if (lit != NULL && | 1300 if (lit != NULL && |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1563 if (expr->is_postfix() && context_ != Expression::kEffect) { | 1569 if (expr->is_postfix() && context_ != Expression::kEffect) { |
1564 __ push(Immediate(Smi::FromInt(0))); | 1570 __ push(Immediate(Smi::FromInt(0))); |
1565 } | 1571 } |
1566 if (assign_type == NAMED_PROPERTY) { | 1572 if (assign_type == NAMED_PROPERTY) { |
1567 // Put the object both on the stack and in the accumulator. | 1573 // Put the object both on the stack and in the accumulator. |
1568 VisitForValue(prop->obj(), kAccumulator); | 1574 VisitForValue(prop->obj(), kAccumulator); |
1569 __ push(eax); | 1575 __ push(eax); |
1570 EmitNamedPropertyLoad(prop); | 1576 EmitNamedPropertyLoad(prop); |
1571 } else { | 1577 } else { |
1572 VisitForValue(prop->obj(), kStack); | 1578 VisitForValue(prop->obj(), kStack); |
1573 VisitForValue(prop->key(), kStack); | 1579 VisitForValue(prop->key(), kAccumulator); |
| 1580 __ mov(edx, Operand(esp, 0)); |
| 1581 __ push(eax); |
1574 EmitKeyedPropertyLoad(prop); | 1582 EmitKeyedPropertyLoad(prop); |
1575 } | 1583 } |
1576 } | 1584 } |
1577 | 1585 |
1578 // Call ToNumber only if operand is not a smi. | 1586 // Call ToNumber only if operand is not a smi. |
1579 Label no_conversion; | 1587 Label no_conversion; |
1580 __ test(eax, Immediate(kSmiTagMask)); | 1588 __ test(eax, Immediate(kSmiTagMask)); |
1581 __ j(zero, &no_conversion); | 1589 __ j(zero, &no_conversion); |
1582 __ push(eax); | 1590 __ push(eax); |
1583 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION); | 1591 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION); |
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1894 __ add(Operand(edx), Immediate(masm_->CodeObject())); | 1902 __ add(Operand(edx), Immediate(masm_->CodeObject())); |
1895 __ mov(Operand(esp, 0), edx); | 1903 __ mov(Operand(esp, 0), edx); |
1896 // And return. | 1904 // And return. |
1897 __ ret(0); | 1905 __ ret(0); |
1898 } | 1906 } |
1899 | 1907 |
1900 | 1908 |
1901 #undef __ | 1909 #undef __ |
1902 | 1910 |
1903 } } // namespace v8::internal | 1911 } } // namespace v8::internal |
OLD | NEW |