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 790 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
801 // Four cases: non-this global variables, lookup slots, all other | 801 // Four cases: non-this global variables, lookup slots, all other |
802 // types of slots, and parameters that rewrite to explicit property | 802 // types of slots, and parameters that rewrite to explicit property |
803 // accesses on the arguments object. | 803 // accesses on the arguments object. |
804 Slot* slot = var->slot(); | 804 Slot* slot = var->slot(); |
805 Property* property = var->AsProperty(); | 805 Property* property = var->AsProperty(); |
806 | 806 |
807 if (var->is_global() && !var->is_this()) { | 807 if (var->is_global() && !var->is_this()) { |
808 Comment cmnt(masm_, "Global variable"); | 808 Comment cmnt(masm_, "Global variable"); |
809 // Use inline caching. Variable name is passed in ecx and the global | 809 // Use inline caching. Variable name is passed in ecx and the global |
810 // object on the stack. | 810 // object on the stack. |
811 __ push(CodeGenerator::GlobalObject()); | 811 __ mov(eax, CodeGenerator::GlobalObject()); |
812 __ mov(ecx, var->name()); | 812 __ mov(ecx, var->name()); |
813 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 813 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
814 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); | 814 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); |
815 // By emitting a nop we make sure that we do not have a test eax | 815 // By emitting a nop we make sure that we do not have a test eax |
816 // instruction after the call it is treated specially by the LoadIC code | 816 // instruction after the call it is treated specially by the LoadIC code |
817 // Remember that the assembler may choose to do peephole optimization | 817 // Remember that the assembler may choose to do peephole optimization |
818 // (eg, push/pop elimination). | 818 // (eg, push/pop elimination). |
819 __ nop(); | 819 __ nop(); |
820 DropAndApply(1, context, eax); | 820 Apply(context, eax); |
821 | 821 |
822 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { | 822 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { |
823 Comment cmnt(masm_, "Lookup slot"); | 823 Comment cmnt(masm_, "Lookup slot"); |
824 __ push(esi); // Context. | 824 __ push(esi); // Context. |
825 __ push(Immediate(var->name())); | 825 __ push(Immediate(var->name())); |
826 __ CallRuntime(Runtime::kLoadContextSlot, 2); | 826 __ CallRuntime(Runtime::kLoadContextSlot, 2); |
827 Apply(context, eax); | 827 Apply(context, eax); |
828 | 828 |
829 } else if (slot != NULL) { | 829 } else if (slot != NULL) { |
830 Comment cmnt(masm_, (slot->type() == Slot::CONTEXT) | 830 Comment cmnt(masm_, (slot->type() == Slot::CONTEXT) |
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1176 | 1176 |
1177 // Receiver and key are still on stack. | 1177 // Receiver and key are still on stack. |
1178 DropAndApply(2, context_, eax); | 1178 DropAndApply(2, context_, eax); |
1179 } | 1179 } |
1180 | 1180 |
1181 | 1181 |
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 // Evaluate the receiver. | |
1187 VisitForValue(expr->obj(), kStack); | |
1188 | |
1189 if (key->IsPropertyName()) { | 1186 if (key->IsPropertyName()) { |
| 1187 VisitForValue(expr->obj(), kAccumulator); |
1190 EmitNamedPropertyLoad(expr); | 1188 EmitNamedPropertyLoad(expr); |
1191 // Drop receiver left on the stack by IC. | 1189 Apply(context_, eax); |
1192 DropAndApply(1, context_, eax); | |
1193 } else { | 1190 } else { |
| 1191 VisitForValue(expr->obj(), kStack); |
1194 VisitForValue(expr->key(), kStack); | 1192 VisitForValue(expr->key(), kStack); |
1195 EmitKeyedPropertyLoad(expr); | 1193 EmitKeyedPropertyLoad(expr); |
1196 // Drop key and receiver left on the stack by IC. | 1194 // Drop key and receiver left on the stack by IC. |
1197 DropAndApply(2, context_, eax); | 1195 DropAndApply(2, context_, eax); |
1198 } | 1196 } |
1199 } | 1197 } |
1200 | 1198 |
1201 | 1199 |
1202 void FullCodeGenerator::EmitCallWithIC(Call* expr, | 1200 void FullCodeGenerator::EmitCallWithIC(Call* expr, |
1203 Handle<Object> name, | 1201 Handle<Object> name, |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1448 break; | 1446 break; |
1449 } | 1447 } |
1450 | 1448 |
1451 case Token::TYPEOF: { | 1449 case Token::TYPEOF: { |
1452 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); | 1450 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); |
1453 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 1451 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
1454 if (proxy != NULL && | 1452 if (proxy != NULL && |
1455 !proxy->var()->is_this() && | 1453 !proxy->var()->is_this() && |
1456 proxy->var()->is_global()) { | 1454 proxy->var()->is_global()) { |
1457 Comment cmnt(masm_, "Global variable"); | 1455 Comment cmnt(masm_, "Global variable"); |
1458 __ push(CodeGenerator::GlobalObject()); | 1456 __ mov(eax, CodeGenerator::GlobalObject()); |
1459 __ mov(ecx, Immediate(proxy->name())); | 1457 __ mov(ecx, Immediate(proxy->name())); |
1460 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 1458 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
1461 // Use a regular load, not a contextual load, to avoid a reference | 1459 // Use a regular load, not a contextual load, to avoid a reference |
1462 // error. | 1460 // error. |
1463 __ call(ic, RelocInfo::CODE_TARGET); | 1461 __ call(ic, RelocInfo::CODE_TARGET); |
1464 __ mov(Operand(esp, 0), eax); | 1462 __ push(eax); |
1465 } else if (proxy != NULL && | 1463 } else if (proxy != NULL && |
1466 proxy->var()->slot() != NULL && | 1464 proxy->var()->slot() != NULL && |
1467 proxy->var()->slot()->type() == Slot::LOOKUP) { | 1465 proxy->var()->slot()->type() == Slot::LOOKUP) { |
1468 __ push(esi); | 1466 __ push(esi); |
1469 __ push(Immediate(proxy->name())); | 1467 __ push(Immediate(proxy->name())); |
1470 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); | 1468 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); |
1471 __ push(eax); | 1469 __ push(eax); |
1472 } else { | 1470 } else { |
1473 // This expression cannot throw a reference error at the top level. | 1471 // This expression cannot throw a reference error at the top level. |
1474 VisitForValue(expr->expression(), kStack); | 1472 VisitForValue(expr->expression(), kStack); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1558 Location saved_location = location_; | 1556 Location saved_location = location_; |
1559 location_ = kAccumulator; | 1557 location_ = kAccumulator; |
1560 EmitVariableLoad(expr->expression()->AsVariableProxy()->var(), | 1558 EmitVariableLoad(expr->expression()->AsVariableProxy()->var(), |
1561 Expression::kValue); | 1559 Expression::kValue); |
1562 location_ = saved_location; | 1560 location_ = saved_location; |
1563 } else { | 1561 } else { |
1564 // Reserve space for result of postfix operation. | 1562 // Reserve space for result of postfix operation. |
1565 if (expr->is_postfix() && context_ != Expression::kEffect) { | 1563 if (expr->is_postfix() && context_ != Expression::kEffect) { |
1566 __ push(Immediate(Smi::FromInt(0))); | 1564 __ push(Immediate(Smi::FromInt(0))); |
1567 } | 1565 } |
1568 VisitForValue(prop->obj(), kStack); | |
1569 if (assign_type == NAMED_PROPERTY) { | 1566 if (assign_type == NAMED_PROPERTY) { |
| 1567 // Put the object both on the stack and in the accumulator. |
| 1568 VisitForValue(prop->obj(), kAccumulator); |
| 1569 __ push(eax); |
1570 EmitNamedPropertyLoad(prop); | 1570 EmitNamedPropertyLoad(prop); |
1571 } else { | 1571 } else { |
| 1572 VisitForValue(prop->obj(), kStack); |
1572 VisitForValue(prop->key(), kStack); | 1573 VisitForValue(prop->key(), kStack); |
1573 EmitKeyedPropertyLoad(prop); | 1574 EmitKeyedPropertyLoad(prop); |
1574 } | 1575 } |
1575 } | 1576 } |
1576 | 1577 |
1577 // Call ToNumber only if operand is not a smi. | 1578 // Call ToNumber only if operand is not a smi. |
1578 Label no_conversion; | 1579 Label no_conversion; |
1579 __ test(eax, Immediate(kSmiTagMask)); | 1580 __ test(eax, Immediate(kSmiTagMask)); |
1580 __ j(zero, &no_conversion); | 1581 __ j(zero, &no_conversion); |
1581 __ push(eax); | 1582 __ push(eax); |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1893 __ add(Operand(edx), Immediate(masm_->CodeObject())); | 1894 __ add(Operand(edx), Immediate(masm_->CodeObject())); |
1894 __ mov(Operand(esp, 0), edx); | 1895 __ mov(Operand(esp, 0), edx); |
1895 // And return. | 1896 // And return. |
1896 __ ret(0); | 1897 __ ret(0); |
1897 } | 1898 } |
1898 | 1899 |
1899 | 1900 |
1900 #undef __ | 1901 #undef __ |
1901 | 1902 |
1902 } } // namespace v8::internal | 1903 } } // namespace v8::internal |
OLD | NEW |