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 720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
731 Move(r1, object_slot); | 731 Move(r1, object_slot); |
732 | 732 |
733 // Assert that the key is a smi. | 733 // Assert that the key is a smi. |
734 Literal* key_literal = property->key()->AsLiteral(); | 734 Literal* key_literal = property->key()->AsLiteral(); |
735 ASSERT_NOT_NULL(key_literal); | 735 ASSERT_NOT_NULL(key_literal); |
736 ASSERT(key_literal->handle()->IsSmi()); | 736 ASSERT(key_literal->handle()->IsSmi()); |
737 | 737 |
738 // Load the key. | 738 // Load the key. |
739 __ mov(r0, Operand(key_literal->handle())); | 739 __ mov(r0, Operand(key_literal->handle())); |
740 | 740 |
741 // Push both as arguments to ic. | 741 // Call keyed load IC. It has arguments key and receiver in r0 and r1. |
742 __ Push(r1, r0); | |
743 | |
744 // Call keyed load IC. It has all arguments on the stack and the key in r0. | |
745 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 742 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
746 __ Call(ic, RelocInfo::CODE_TARGET); | 743 __ Call(ic, RelocInfo::CODE_TARGET); |
747 | 744 Apply(context, r0); |
748 // Drop key and object left on the stack by IC, and push the result. | |
749 DropAndApply(2, context, r0); | |
750 } | 745 } |
751 } | 746 } |
752 | 747 |
753 | 748 |
754 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { | 749 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { |
755 Comment cmnt(masm_, "[ RegExpLiteral"); | 750 Comment cmnt(masm_, "[ RegExpLiteral"); |
756 Label done; | 751 Label done; |
757 // Registers will be used as follows: | 752 // Registers will be used as follows: |
758 // r4 = JS function, literals array | 753 // r4 = JS function, literals array |
759 // r3 = literal index | 754 // r3 = literal index |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
928 case NAMED_PROPERTY: | 923 case NAMED_PROPERTY: |
929 if (expr->is_compound()) { | 924 if (expr->is_compound()) { |
930 // We need the receiver both on the stack and in the accumulator. | 925 // We need the receiver both on the stack and in the accumulator. |
931 VisitForValue(prop->obj(), kAccumulator); | 926 VisitForValue(prop->obj(), kAccumulator); |
932 __ push(result_register()); | 927 __ push(result_register()); |
933 } else { | 928 } else { |
934 VisitForValue(prop->obj(), kStack); | 929 VisitForValue(prop->obj(), kStack); |
935 } | 930 } |
936 break; | 931 break; |
937 case KEYED_PROPERTY: | 932 case KEYED_PROPERTY: |
938 VisitForValue(prop->obj(), kStack); | 933 // We need the key and receiver on both the stack and in r0 and r1. |
939 VisitForValue(prop->key(), kStack); | 934 if (expr->is_compound()) { |
| 935 VisitForValue(prop->obj(), kStack); |
| 936 VisitForValue(prop->key(), kAccumulator); |
| 937 __ ldr(r1, MemOperand(sp, 0)); |
| 938 __ push(r0); |
| 939 } else { |
| 940 VisitForValue(prop->obj(), kStack); |
| 941 VisitForValue(prop->key(), kStack); |
| 942 } |
940 break; | 943 break; |
941 } | 944 } |
942 | 945 |
943 // If we have a compound assignment: Get value of LHS expression and | 946 // If we have a compound assignment: Get value of LHS expression and |
944 // store in on top of the stack. | 947 // store in on top of the stack. |
945 if (expr->is_compound()) { | 948 if (expr->is_compound()) { |
946 Location saved_location = location_; | 949 Location saved_location = location_; |
947 location_ = kStack; | 950 location_ = kStack; |
948 switch (assign_type) { | 951 switch (assign_type) { |
949 case VARIABLE: | 952 case VARIABLE: |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
998 Literal* key = prop->key()->AsLiteral(); | 1001 Literal* key = prop->key()->AsLiteral(); |
999 __ mov(r2, Operand(key->handle())); | 1002 __ mov(r2, Operand(key->handle())); |
1000 __ ldr(r0, MemOperand(sp, 0)); | 1003 __ ldr(r0, MemOperand(sp, 0)); |
1001 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 1004 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
1002 __ Call(ic, RelocInfo::CODE_TARGET); | 1005 __ Call(ic, RelocInfo::CODE_TARGET); |
1003 } | 1006 } |
1004 | 1007 |
1005 | 1008 |
1006 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 1009 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
1007 SetSourcePosition(prop->position()); | 1010 SetSourcePosition(prop->position()); |
1008 // Call keyed load IC. It has all arguments on the stack and the key in r0. | 1011 // Call keyed load IC. It has arguments key and receiver in r0 and r1. |
1009 __ ldr(r0, MemOperand(sp, 0)); | |
1010 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 1012 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
1011 __ Call(ic, RelocInfo::CODE_TARGET); | 1013 __ Call(ic, RelocInfo::CODE_TARGET); |
1012 } | 1014 } |
1013 | 1015 |
1014 | 1016 |
1015 void FullCodeGenerator::EmitBinaryOp(Token::Value op, | 1017 void FullCodeGenerator::EmitBinaryOp(Token::Value op, |
1016 Expression::Context context) { | 1018 Expression::Context context) { |
1017 __ pop(r1); | 1019 __ pop(r1); |
1018 GenericBinaryOpStub stub(op, NO_OVERWRITE, r1, r0); | 1020 GenericBinaryOpStub stub(op, NO_OVERWRITE, r1, r0); |
1019 __ CallStub(&stub); | 1021 __ CallStub(&stub); |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1164 Expression* key = expr->key(); | 1166 Expression* key = expr->key(); |
1165 | 1167 |
1166 // Evaluate receiver. | 1168 // Evaluate receiver. |
1167 VisitForValue(expr->obj(), kStack); | 1169 VisitForValue(expr->obj(), kStack); |
1168 | 1170 |
1169 if (key->IsPropertyName()) { | 1171 if (key->IsPropertyName()) { |
1170 EmitNamedPropertyLoad(expr); | 1172 EmitNamedPropertyLoad(expr); |
1171 // Drop receiver left on the stack by IC. | 1173 // Drop receiver left on the stack by IC. |
1172 DropAndApply(1, context_, r0); | 1174 DropAndApply(1, context_, r0); |
1173 } else { | 1175 } else { |
1174 VisitForValue(expr->key(), kStack); | 1176 VisitForValue(expr->key(), kAccumulator); |
| 1177 __ pop(r1); |
1175 EmitKeyedPropertyLoad(expr); | 1178 EmitKeyedPropertyLoad(expr); |
1176 // Drop key and receiver left on the stack by IC. | 1179 Apply(context_, r0); |
1177 DropAndApply(2, context_, r0); | |
1178 } | 1180 } |
1179 } | 1181 } |
1180 | 1182 |
1181 void FullCodeGenerator::EmitCallWithIC(Call* expr, | 1183 void FullCodeGenerator::EmitCallWithIC(Call* expr, |
1182 Handle<Object> name, | 1184 Handle<Object> name, |
1183 RelocInfo::Mode mode) { | 1185 RelocInfo::Mode mode) { |
1184 // Code common for calls using the IC. | 1186 // Code common for calls using the IC. |
1185 ZoneList<Expression*>* args = expr->arguments(); | 1187 ZoneList<Expression*>* args = expr->arguments(); |
1186 int arg_count = args->length(); | 1188 int arg_count = args->length(); |
1187 for (int i = 0; i < arg_count; i++) { | 1189 for (int i = 0; i < arg_count; i++) { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1239 Property* prop = fun->AsProperty(); | 1241 Property* prop = fun->AsProperty(); |
1240 Literal* key = prop->key()->AsLiteral(); | 1242 Literal* key = prop->key()->AsLiteral(); |
1241 if (key != NULL && key->handle()->IsSymbol()) { | 1243 if (key != NULL && key->handle()->IsSymbol()) { |
1242 // Call to a named property, use call IC. | 1244 // Call to a named property, use call IC. |
1243 VisitForValue(prop->obj(), kStack); | 1245 VisitForValue(prop->obj(), kStack); |
1244 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); | 1246 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); |
1245 } else { | 1247 } else { |
1246 // Call to a keyed property, use keyed load IC followed by function | 1248 // Call to a keyed property, use keyed load IC followed by function |
1247 // call. | 1249 // call. |
1248 VisitForValue(prop->obj(), kStack); | 1250 VisitForValue(prop->obj(), kStack); |
1249 VisitForValue(prop->key(), kStack); | 1251 VisitForValue(prop->key(), kAccumulator); |
1250 // Record source code position for IC call. | 1252 // Record source code position for IC call. |
1251 SetSourcePosition(prop->position()); | 1253 SetSourcePosition(prop->position()); |
1252 // Call keyed load IC. It has all arguments on the stack and the key in | 1254 if (prop->is_synthetic()) { |
1253 // r0. | 1255 __ pop(r1); // We do not need to keep the receiver. |
1254 __ ldr(r0, MemOperand(sp, 0)); | 1256 } else { |
| 1257 __ ldr(r1, MemOperand(sp, 0)); // Keep receiver, to call function on. |
| 1258 } |
| 1259 |
1255 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 1260 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
1256 __ Call(ic, RelocInfo::CODE_TARGET); | 1261 __ Call(ic, RelocInfo::CODE_TARGET); |
1257 // Load receiver object into r1. | |
1258 if (prop->is_synthetic()) { | 1262 if (prop->is_synthetic()) { |
| 1263 // Push result (function). |
| 1264 __ push(r0); |
| 1265 // Push Global receiver. |
1259 __ ldr(r1, CodeGenerator::GlobalObject()); | 1266 __ ldr(r1, CodeGenerator::GlobalObject()); |
1260 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); | 1267 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); |
| 1268 __ push(r1); |
1261 } else { | 1269 } else { |
1262 __ ldr(r1, MemOperand(sp, kPointerSize)); | 1270 // Pop receiver. |
| 1271 __ pop(r1); |
| 1272 // Push result (function). |
| 1273 __ push(r0); |
| 1274 __ push(r1); |
1263 } | 1275 } |
1264 // Overwrite (object, key) with (function, receiver). | |
1265 __ str(r0, MemOperand(sp, kPointerSize)); | |
1266 __ str(r1, MemOperand(sp)); | |
1267 EmitCallWithStub(expr); | 1276 EmitCallWithStub(expr); |
1268 } | 1277 } |
1269 } else { | 1278 } else { |
1270 // Call to some other expression. If the expression is an anonymous | 1279 // Call to some other expression. If the expression is an anonymous |
1271 // function literal not called in a loop, mark it as one that should | 1280 // function literal not called in a loop, mark it as one that should |
1272 // also use the fast code generator. | 1281 // also use the fast code generator. |
1273 FunctionLiteral* lit = fun->AsFunctionLiteral(); | 1282 FunctionLiteral* lit = fun->AsFunctionLiteral(); |
1274 if (lit != NULL && | 1283 if (lit != NULL && |
1275 lit->name()->Equals(Heap::empty_string()) && | 1284 lit->name()->Equals(Heap::empty_string()) && |
1276 loop_depth() == 0) { | 1285 loop_depth() == 0) { |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1545 } else { | 1554 } else { |
1546 // Reserve space for result of postfix operation. | 1555 // Reserve space for result of postfix operation. |
1547 if (expr->is_postfix() && context_ != Expression::kEffect) { | 1556 if (expr->is_postfix() && context_ != Expression::kEffect) { |
1548 __ mov(ip, Operand(Smi::FromInt(0))); | 1557 __ mov(ip, Operand(Smi::FromInt(0))); |
1549 __ push(ip); | 1558 __ push(ip); |
1550 } | 1559 } |
1551 VisitForValue(prop->obj(), kStack); | 1560 VisitForValue(prop->obj(), kStack); |
1552 if (assign_type == NAMED_PROPERTY) { | 1561 if (assign_type == NAMED_PROPERTY) { |
1553 EmitNamedPropertyLoad(prop); | 1562 EmitNamedPropertyLoad(prop); |
1554 } else { | 1563 } else { |
1555 VisitForValue(prop->key(), kStack); | 1564 VisitForValue(prop->key(), kAccumulator); |
| 1565 __ ldr(r1, MemOperand(sp, 0)); |
| 1566 __ push(r0); |
1556 EmitKeyedPropertyLoad(prop); | 1567 EmitKeyedPropertyLoad(prop); |
1557 } | 1568 } |
1558 } | 1569 } |
1559 | 1570 |
1560 // Call ToNumber only if operand is not a smi. | 1571 // Call ToNumber only if operand is not a smi. |
1561 Label no_conversion; | 1572 Label no_conversion; |
1562 __ tst(r0, Operand(kSmiTagMask)); | 1573 __ tst(r0, Operand(kSmiTagMask)); |
1563 __ b(eq, &no_conversion); | 1574 __ b(eq, &no_conversion); |
1564 __ push(r0); | 1575 __ push(r0); |
1565 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS); | 1576 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS); |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1859 __ pop(result_register()); | 1870 __ pop(result_register()); |
1860 ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize); | 1871 ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize); |
1861 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. | 1872 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. |
1862 __ add(pc, r1, Operand(masm_->CodeObject())); | 1873 __ add(pc, r1, Operand(masm_->CodeObject())); |
1863 } | 1874 } |
1864 | 1875 |
1865 | 1876 |
1866 #undef __ | 1877 #undef __ |
1867 | 1878 |
1868 } } // namespace v8::internal | 1879 } } // namespace v8::internal |
OLD | NEW |