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