| 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 |