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