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