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 689 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
700 Expression::Context context) { | 700 Expression::Context context) { |
701 // Four cases: non-this global variables, lookup slots, all other | 701 // Four cases: non-this global variables, lookup slots, all other |
702 // types of slots, and parameters that rewrite to explicit property | 702 // types of slots, and parameters that rewrite to explicit property |
703 // accesses on the arguments object. | 703 // accesses on the arguments object. |
704 Slot* slot = var->slot(); | 704 Slot* slot = var->slot(); |
705 Property* property = var->AsProperty(); | 705 Property* property = var->AsProperty(); |
706 | 706 |
707 if (var->is_global() && !var->is_this()) { | 707 if (var->is_global() && !var->is_this()) { |
708 Comment cmnt(masm_, "Global variable"); | 708 Comment cmnt(masm_, "Global variable"); |
709 // Use inline caching. Variable name is passed in r2 and the global | 709 // Use inline caching. Variable name is passed in r2 and the global |
710 // object on the stack. | 710 // object (receiver) in r0. |
711 __ ldr(r0, CodeGenerator::GlobalObject()); | 711 __ ldr(r0, CodeGenerator::GlobalObject()); |
712 __ push(r0); | |
713 __ mov(r2, Operand(var->name())); | 712 __ mov(r2, Operand(var->name())); |
714 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 713 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
715 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); | 714 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); |
716 DropAndApply(1, context, r0); | 715 Apply(context, r0); |
717 | 716 |
718 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { | 717 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { |
719 Comment cmnt(masm_, "Lookup slot"); | 718 Comment cmnt(masm_, "Lookup slot"); |
720 __ mov(r1, Operand(var->name())); | 719 __ mov(r1, Operand(var->name())); |
721 __ stm(db_w, sp, cp.bit() | r1.bit()); // Context and name. | 720 __ stm(db_w, sp, cp.bit() | r1.bit()); // Context and name. |
722 __ CallRuntime(Runtime::kLoadContextSlot, 2); | 721 __ CallRuntime(Runtime::kLoadContextSlot, 2); |
723 Apply(context, r0); | 722 Apply(context, r0); |
724 | 723 |
725 } else if (slot != NULL) { | 724 } else if (slot != NULL) { |
726 Comment cmnt(masm_, (slot->type() == Slot::CONTEXT) | 725 Comment cmnt(masm_, (slot->type() == Slot::CONTEXT) |
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1012 EmitKeyedPropertyAssignment(expr); | 1011 EmitKeyedPropertyAssignment(expr); |
1013 break; | 1012 break; |
1014 } | 1013 } |
1015 } | 1014 } |
1016 | 1015 |
1017 | 1016 |
1018 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 1017 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
1019 SetSourcePosition(prop->position()); | 1018 SetSourcePosition(prop->position()); |
1020 Literal* key = prop->key()->AsLiteral(); | 1019 Literal* key = prop->key()->AsLiteral(); |
1021 __ mov(r2, Operand(key->handle())); | 1020 __ mov(r2, Operand(key->handle())); |
1022 __ ldr(r0, MemOperand(sp, 0)); | 1021 // Call load IC. It has arguments receiver and property name r0 and r2. |
1023 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 1022 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
1024 __ Call(ic, RelocInfo::CODE_TARGET); | 1023 __ Call(ic, RelocInfo::CODE_TARGET); |
1025 } | 1024 } |
1026 | 1025 |
1027 | 1026 |
1028 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 1027 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
1029 SetSourcePosition(prop->position()); | 1028 SetSourcePosition(prop->position()); |
1030 // Call keyed load IC. It has arguments key and receiver in r0 and r1. | 1029 // Call keyed load IC. It has arguments key and receiver in r0 and r1. |
1031 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 1030 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
1032 __ Call(ic, RelocInfo::CODE_TARGET); | 1031 __ Call(ic, RelocInfo::CODE_TARGET); |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1206 } else { | 1205 } else { |
1207 Apply(context_, r0); | 1206 Apply(context_, r0); |
1208 } | 1207 } |
1209 } | 1208 } |
1210 | 1209 |
1211 | 1210 |
1212 void FullCodeGenerator::VisitProperty(Property* expr) { | 1211 void FullCodeGenerator::VisitProperty(Property* expr) { |
1213 Comment cmnt(masm_, "[ Property"); | 1212 Comment cmnt(masm_, "[ Property"); |
1214 Expression* key = expr->key(); | 1213 Expression* key = expr->key(); |
1215 | 1214 |
1216 // Evaluate receiver. | |
1217 VisitForValue(expr->obj(), kStack); | |
1218 | |
1219 if (key->IsPropertyName()) { | 1215 if (key->IsPropertyName()) { |
| 1216 VisitForValue(expr->obj(), kAccumulator); |
1220 EmitNamedPropertyLoad(expr); | 1217 EmitNamedPropertyLoad(expr); |
1221 // Drop receiver left on the stack by IC. | 1218 Apply(context_, r0); |
1222 DropAndApply(1, context_, r0); | |
1223 } else { | 1219 } else { |
| 1220 VisitForValue(expr->obj(), kStack); |
1224 VisitForValue(expr->key(), kAccumulator); | 1221 VisitForValue(expr->key(), kAccumulator); |
1225 __ pop(r1); | 1222 __ pop(r1); |
1226 EmitKeyedPropertyLoad(expr); | 1223 EmitKeyedPropertyLoad(expr); |
1227 Apply(context_, r0); | 1224 Apply(context_, r0); |
1228 } | 1225 } |
1229 } | 1226 } |
1230 | 1227 |
1231 void FullCodeGenerator::EmitCallWithIC(Call* expr, | 1228 void FullCodeGenerator::EmitCallWithIC(Call* expr, |
1232 Handle<Object> name, | 1229 Handle<Object> name, |
1233 RelocInfo::Mode mode) { | 1230 RelocInfo::Mode mode) { |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1486 } | 1483 } |
1487 | 1484 |
1488 case Token::TYPEOF: { | 1485 case Token::TYPEOF: { |
1489 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); | 1486 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); |
1490 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 1487 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
1491 if (proxy != NULL && | 1488 if (proxy != NULL && |
1492 !proxy->var()->is_this() && | 1489 !proxy->var()->is_this() && |
1493 proxy->var()->is_global()) { | 1490 proxy->var()->is_global()) { |
1494 Comment cmnt(masm_, "Global variable"); | 1491 Comment cmnt(masm_, "Global variable"); |
1495 __ ldr(r0, CodeGenerator::GlobalObject()); | 1492 __ ldr(r0, CodeGenerator::GlobalObject()); |
1496 __ push(r0); | |
1497 __ mov(r2, Operand(proxy->name())); | 1493 __ mov(r2, Operand(proxy->name())); |
1498 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 1494 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
1499 // Use a regular load, not a contextual load, to avoid a reference | 1495 // Use a regular load, not a contextual load, to avoid a reference |
1500 // error. | 1496 // error. |
1501 __ Call(ic, RelocInfo::CODE_TARGET); | 1497 __ Call(ic, RelocInfo::CODE_TARGET); |
1502 __ str(r0, MemOperand(sp)); | 1498 __ push(r0); |
1503 } else if (proxy != NULL && | 1499 } else if (proxy != NULL && |
1504 proxy->var()->slot() != NULL && | 1500 proxy->var()->slot() != NULL && |
1505 proxy->var()->slot()->type() == Slot::LOOKUP) { | 1501 proxy->var()->slot()->type() == Slot::LOOKUP) { |
1506 __ mov(r0, Operand(proxy->name())); | 1502 __ mov(r0, Operand(proxy->name())); |
1507 __ stm(db_w, sp, cp.bit() | r0.bit()); | 1503 __ stm(db_w, sp, cp.bit() | r0.bit()); |
1508 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); | 1504 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); |
1509 __ push(r0); | 1505 __ push(r0); |
1510 } else { | 1506 } else { |
1511 // This expression cannot throw a reference error at the top level. | 1507 // This expression cannot throw a reference error at the top level. |
1512 VisitForValue(expr->expression(), kStack); | 1508 VisitForValue(expr->expression(), kStack); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1598 location_ = kAccumulator; | 1594 location_ = kAccumulator; |
1599 EmitVariableLoad(expr->expression()->AsVariableProxy()->var(), | 1595 EmitVariableLoad(expr->expression()->AsVariableProxy()->var(), |
1600 Expression::kValue); | 1596 Expression::kValue); |
1601 location_ = saved_location; | 1597 location_ = saved_location; |
1602 } else { | 1598 } else { |
1603 // Reserve space for result of postfix operation. | 1599 // Reserve space for result of postfix operation. |
1604 if (expr->is_postfix() && context_ != Expression::kEffect) { | 1600 if (expr->is_postfix() && context_ != Expression::kEffect) { |
1605 __ mov(ip, Operand(Smi::FromInt(0))); | 1601 __ mov(ip, Operand(Smi::FromInt(0))); |
1606 __ push(ip); | 1602 __ push(ip); |
1607 } | 1603 } |
1608 VisitForValue(prop->obj(), kStack); | |
1609 if (assign_type == NAMED_PROPERTY) { | 1604 if (assign_type == NAMED_PROPERTY) { |
| 1605 // Put the object both on the stack and in the accumulator. |
| 1606 VisitForValue(prop->obj(), kAccumulator); |
| 1607 __ push(r0); |
1610 EmitNamedPropertyLoad(prop); | 1608 EmitNamedPropertyLoad(prop); |
1611 } else { | 1609 } else { |
| 1610 VisitForValue(prop->obj(), kStack); |
1612 VisitForValue(prop->key(), kAccumulator); | 1611 VisitForValue(prop->key(), kAccumulator); |
1613 __ ldr(r1, MemOperand(sp, 0)); | 1612 __ ldr(r1, MemOperand(sp, 0)); |
1614 __ push(r0); | 1613 __ push(r0); |
1615 EmitKeyedPropertyLoad(prop); | 1614 EmitKeyedPropertyLoad(prop); |
1616 } | 1615 } |
1617 } | 1616 } |
1618 | 1617 |
1619 // Call ToNumber only if operand is not a smi. | 1618 // Call ToNumber only if operand is not a smi. |
1620 Label no_conversion; | 1619 Label no_conversion; |
1621 __ tst(r0, Operand(kSmiTagMask)); | 1620 __ tst(r0, Operand(kSmiTagMask)); |
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1923 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. | 1922 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. |
1924 __ add(pc, r1, Operand(masm_->CodeObject())); | 1923 __ add(pc, r1, Operand(masm_->CodeObject())); |
1925 } | 1924 } |
1926 | 1925 |
1927 | 1926 |
1928 #undef __ | 1927 #undef __ |
1929 | 1928 |
1930 } } // namespace v8::internal | 1929 } } // namespace v8::internal |
1931 | 1930 |
1932 #endif // V8_TARGET_ARCH_ARM | 1931 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |