| OLD | NEW |
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 |
| 11 // with the distribution. | 11 // with the distribution. |
| (...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 598 // subexpression of a typeof. | 598 // subexpression of a typeof. |
| 599 LoadFromSlot(variable->slot(), INSIDE_TYPEOF); | 599 LoadFromSlot(variable->slot(), INSIDE_TYPEOF); |
| 600 frame_->SpillAll(); | 600 frame_->SpillAll(); |
| 601 } else { | 601 } else { |
| 602 // Anything else can be handled normally. | 602 // Anything else can be handled normally. |
| 603 LoadAndSpill(expr); | 603 LoadAndSpill(expr); |
| 604 } | 604 } |
| 605 } | 605 } |
| 606 | 606 |
| 607 | 607 |
| 608 Reference::Reference(CodeGenerator* cgen, Expression* expression) | 608 Reference::Reference(CodeGenerator* cgen, |
| 609 : cgen_(cgen), expression_(expression), type_(ILLEGAL) { | 609 Expression* expression, |
| 610 bool persist_after_get) |
| 611 : cgen_(cgen), |
| 612 expression_(expression), |
| 613 type_(ILLEGAL), |
| 614 persist_after_get_(persist_after_get) { |
| 610 cgen->LoadReference(this); | 615 cgen->LoadReference(this); |
| 611 } | 616 } |
| 612 | 617 |
| 613 | 618 |
| 614 Reference::~Reference() { | 619 Reference::~Reference() { |
| 615 cgen_->UnloadReference(this); | 620 ASSERT(is_unloaded() || is_illegal()); |
| 616 } | 621 } |
| 617 | 622 |
| 618 | 623 |
| 619 void CodeGenerator::LoadReference(Reference* ref) { | 624 void CodeGenerator::LoadReference(Reference* ref) { |
| 620 VirtualFrame::SpilledScope spilled_scope; | 625 VirtualFrame::SpilledScope spilled_scope; |
| 621 Comment cmnt(masm_, "[ LoadReference"); | 626 Comment cmnt(masm_, "[ LoadReference"); |
| 622 Expression* e = ref->expression(); | 627 Expression* e = ref->expression(); |
| 623 Property* property = e->AsProperty(); | 628 Property* property = e->AsProperty(); |
| 624 Variable* var = e->AsVariableProxy()->AsVariable(); | 629 Variable* var = e->AsVariableProxy()->AsVariable(); |
| 625 | 630 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 654 void CodeGenerator::UnloadReference(Reference* ref) { | 659 void CodeGenerator::UnloadReference(Reference* ref) { |
| 655 VirtualFrame::SpilledScope spilled_scope; | 660 VirtualFrame::SpilledScope spilled_scope; |
| 656 // Pop a reference from the stack while preserving TOS. | 661 // Pop a reference from the stack while preserving TOS. |
| 657 Comment cmnt(masm_, "[ UnloadReference"); | 662 Comment cmnt(masm_, "[ UnloadReference"); |
| 658 int size = ref->size(); | 663 int size = ref->size(); |
| 659 if (size > 0) { | 664 if (size > 0) { |
| 660 frame_->EmitPop(r0); | 665 frame_->EmitPop(r0); |
| 661 frame_->Drop(size); | 666 frame_->Drop(size); |
| 662 frame_->EmitPush(r0); | 667 frame_->EmitPush(r0); |
| 663 } | 668 } |
| 669 ref->set_unloaded(); |
| 664 } | 670 } |
| 665 | 671 |
| 666 | 672 |
| 667 // ECMA-262, section 9.2, page 30: ToBoolean(). Convert the given | 673 // ECMA-262, section 9.2, page 30: ToBoolean(). Convert the given |
| 668 // register to a boolean in the condition code register. The code | 674 // register to a boolean in the condition code register. The code |
| 669 // may jump to 'false_target' in case the register converts to 'false'. | 675 // may jump to 'false_target' in case the register converts to 'false'. |
| 670 void CodeGenerator::ToBoolean(JumpTarget* true_target, | 676 void CodeGenerator::ToBoolean(JumpTarget* true_target, |
| 671 JumpTarget* false_target) { | 677 JumpTarget* false_target) { |
| 672 VirtualFrame::SpilledScope spilled_scope; | 678 VirtualFrame::SpilledScope spilled_scope; |
| 673 // Note: The generated code snippet does not change stack variables. | 679 // Note: The generated code snippet does not change stack variables. |
| (...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1237 } else { | 1243 } else { |
| 1238 val = node->fun(); // NULL if we don't have a function | 1244 val = node->fun(); // NULL if we don't have a function |
| 1239 } | 1245 } |
| 1240 | 1246 |
| 1241 if (val != NULL) { | 1247 if (val != NULL) { |
| 1242 { | 1248 { |
| 1243 // Set initial value. | 1249 // Set initial value. |
| 1244 Reference target(this, node->proxy()); | 1250 Reference target(this, node->proxy()); |
| 1245 LoadAndSpill(val); | 1251 LoadAndSpill(val); |
| 1246 target.SetValue(NOT_CONST_INIT); | 1252 target.SetValue(NOT_CONST_INIT); |
| 1247 // The reference is removed from the stack (preserving TOS) when | |
| 1248 // it goes out of scope. | |
| 1249 } | 1253 } |
| 1250 // Get rid of the assigned value (declarations are statements). | 1254 // Get rid of the assigned value (declarations are statements). |
| 1251 frame_->Drop(); | 1255 frame_->Drop(); |
| 1252 } | 1256 } |
| 1253 ASSERT(frame_->height() == original_height); | 1257 ASSERT(frame_->height() == original_height); |
| 1254 } | 1258 } |
| 1255 | 1259 |
| 1256 | 1260 |
| 1257 void CodeGenerator::VisitExpressionStatement(ExpressionStatement* node) { | 1261 void CodeGenerator::VisitExpressionStatement(ExpressionStatement* node) { |
| 1258 #ifdef DEBUG | 1262 #ifdef DEBUG |
| (...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1925 | 1929 |
| 1926 end_del_check.Bind(); | 1930 end_del_check.Bind(); |
| 1927 // Store the entry in the 'each' expression and take another spin in the | 1931 // Store the entry in the 'each' expression and take another spin in the |
| 1928 // loop. r3: i'th entry of the enum cache (or string there of) | 1932 // loop. r3: i'th entry of the enum cache (or string there of) |
| 1929 frame_->EmitPush(r3); // push entry | 1933 frame_->EmitPush(r3); // push entry |
| 1930 { Reference each(this, node->each()); | 1934 { Reference each(this, node->each()); |
| 1931 if (!each.is_illegal()) { | 1935 if (!each.is_illegal()) { |
| 1932 if (each.size() > 0) { | 1936 if (each.size() > 0) { |
| 1933 __ ldr(r0, frame_->ElementAt(each.size())); | 1937 __ ldr(r0, frame_->ElementAt(each.size())); |
| 1934 frame_->EmitPush(r0); | 1938 frame_->EmitPush(r0); |
| 1935 } | 1939 each.SetValue(NOT_CONST_INIT); |
| 1936 // If the reference was to a slot we rely on the convenient property | 1940 frame_->Drop(2); |
| 1937 // that it doesn't matter whether a value (eg, r3 pushed above) is | 1941 } else { |
| 1938 // right on top of or right underneath a zero-sized reference. | 1942 // If the reference was to a slot we rely on the convenient property |
| 1939 each.SetValue(NOT_CONST_INIT); | 1943 // that it doesn't matter whether a value (eg, r3 pushed above) is |
| 1940 if (each.size() > 0) { | 1944 // right on top of or right underneath a zero-sized reference. |
| 1941 // It's safe to pop the value lying on top of the reference before | 1945 each.SetValue(NOT_CONST_INIT); |
| 1942 // unloading the reference itself (which preserves the top of stack, | 1946 frame_->Drop(); |
| 1943 // ie, now the topmost value of the non-zero sized reference), since | |
| 1944 // we will discard the top of stack after unloading the reference | |
| 1945 // anyway. | |
| 1946 frame_->EmitPop(r0); | |
| 1947 } | 1947 } |
| 1948 } | 1948 } |
| 1949 } | 1949 } |
| 1950 // Discard the i'th entry pushed above or else the remainder of the | |
| 1951 // reference, whichever is currently on top of the stack. | |
| 1952 frame_->Drop(); | |
| 1953 | |
| 1954 // Body. | 1950 // Body. |
| 1955 CheckStack(); // TODO(1222600): ignore if body contains calls. | 1951 CheckStack(); // TODO(1222600): ignore if body contains calls. |
| 1956 VisitAndSpill(node->body()); | 1952 VisitAndSpill(node->body()); |
| 1957 | 1953 |
| 1958 // Next. Reestablish a spilled frame in case we are coming here via | 1954 // Next. Reestablish a spilled frame in case we are coming here via |
| 1959 // a continue in the body. | 1955 // a continue in the body. |
| 1960 node->continue_target()->Bind(); | 1956 node->continue_target()->Bind(); |
| 1961 frame_->SpillAll(); | 1957 frame_->SpillAll(); |
| 1962 frame_->EmitPop(r0); | 1958 frame_->EmitPop(r0); |
| 1963 __ add(r0, r0, Operand(Smi::FromInt(1))); | 1959 __ add(r0, r0, Operand(Smi::FromInt(1))); |
| (...skipping 873 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2837 } | 2833 } |
| 2838 | 2834 |
| 2839 | 2835 |
| 2840 void CodeGenerator::VisitAssignment(Assignment* node) { | 2836 void CodeGenerator::VisitAssignment(Assignment* node) { |
| 2841 #ifdef DEBUG | 2837 #ifdef DEBUG |
| 2842 int original_height = frame_->height(); | 2838 int original_height = frame_->height(); |
| 2843 #endif | 2839 #endif |
| 2844 VirtualFrame::SpilledScope spilled_scope; | 2840 VirtualFrame::SpilledScope spilled_scope; |
| 2845 Comment cmnt(masm_, "[ Assignment"); | 2841 Comment cmnt(masm_, "[ Assignment"); |
| 2846 | 2842 |
| 2847 { Reference target(this, node->target()); | 2843 { Reference target(this, node->target(), node->is_compound()); |
| 2848 if (target.is_illegal()) { | 2844 if (target.is_illegal()) { |
| 2849 // Fool the virtual frame into thinking that we left the assignment's | 2845 // Fool the virtual frame into thinking that we left the assignment's |
| 2850 // value on the frame. | 2846 // value on the frame. |
| 2851 __ mov(r0, Operand(Smi::FromInt(0))); | 2847 __ mov(r0, Operand(Smi::FromInt(0))); |
| 2852 frame_->EmitPush(r0); | 2848 frame_->EmitPush(r0); |
| 2853 ASSERT(frame_->height() == original_height + 1); | 2849 ASSERT(frame_->height() == original_height + 1); |
| 2854 return; | 2850 return; |
| 2855 } | 2851 } |
| 2856 | 2852 |
| 2857 if (node->op() == Token::ASSIGN || | 2853 if (node->op() == Token::ASSIGN || |
| 2858 node->op() == Token::INIT_VAR || | 2854 node->op() == Token::INIT_VAR || |
| 2859 node->op() == Token::INIT_CONST) { | 2855 node->op() == Token::INIT_CONST) { |
| 2860 LoadAndSpill(node->value()); | 2856 LoadAndSpill(node->value()); |
| 2861 | 2857 |
| 2862 } else { | 2858 } else { // Assignment is a compound assignment. |
| 2863 // +=, *= and similar binary assignments. | |
| 2864 // Get the old value of the lhs. | 2859 // Get the old value of the lhs. |
| 2865 target.GetValueAndSpill(); | 2860 target.GetValueAndSpill(); |
| 2866 Literal* literal = node->value()->AsLiteral(); | 2861 Literal* literal = node->value()->AsLiteral(); |
| 2867 bool overwrite = | 2862 bool overwrite = |
| 2868 (node->value()->AsBinaryOperation() != NULL && | 2863 (node->value()->AsBinaryOperation() != NULL && |
| 2869 node->value()->AsBinaryOperation()->ResultOverwriteAllowed()); | 2864 node->value()->AsBinaryOperation()->ResultOverwriteAllowed()); |
| 2870 if (literal != NULL && literal->handle()->IsSmi()) { | 2865 if (literal != NULL && literal->handle()->IsSmi()) { |
| 2871 SmiOperation(node->binary_op(), | 2866 SmiOperation(node->binary_op(), |
| 2872 literal->handle(), | 2867 literal->handle(), |
| 2873 false, | 2868 false, |
| 2874 overwrite ? OVERWRITE_RIGHT : NO_OVERWRITE); | 2869 overwrite ? OVERWRITE_RIGHT : NO_OVERWRITE); |
| 2875 frame_->EmitPush(r0); | 2870 frame_->EmitPush(r0); |
| 2876 | 2871 |
| 2877 } else { | 2872 } else { |
| 2878 LoadAndSpill(node->value()); | 2873 LoadAndSpill(node->value()); |
| 2879 GenericBinaryOperation(node->binary_op(), | 2874 GenericBinaryOperation(node->binary_op(), |
| 2880 overwrite ? OVERWRITE_RIGHT : NO_OVERWRITE); | 2875 overwrite ? OVERWRITE_RIGHT : NO_OVERWRITE); |
| 2881 frame_->EmitPush(r0); | 2876 frame_->EmitPush(r0); |
| 2882 } | 2877 } |
| 2883 } | 2878 } |
| 2884 | |
| 2885 Variable* var = node->target()->AsVariableProxy()->AsVariable(); | 2879 Variable* var = node->target()->AsVariableProxy()->AsVariable(); |
| 2886 if (var != NULL && | 2880 if (var != NULL && |
| 2887 (var->mode() == Variable::CONST) && | 2881 (var->mode() == Variable::CONST) && |
| 2888 node->op() != Token::INIT_VAR && node->op() != Token::INIT_CONST) { | 2882 node->op() != Token::INIT_VAR && node->op() != Token::INIT_CONST) { |
| 2889 // Assignment ignored - leave the value on the stack. | 2883 // Assignment ignored - leave the value on the stack. |
| 2890 | 2884 UnloadReference(&target); |
| 2891 } else { | 2885 } else { |
| 2892 CodeForSourcePosition(node->position()); | 2886 CodeForSourcePosition(node->position()); |
| 2893 if (node->op() == Token::INIT_CONST) { | 2887 if (node->op() == Token::INIT_CONST) { |
| 2894 // Dynamic constant initializations must use the function context | 2888 // Dynamic constant initializations must use the function context |
| 2895 // and initialize the actual constant declared. Dynamic variable | 2889 // and initialize the actual constant declared. Dynamic variable |
| 2896 // initializations are simply assignments and use SetValue. | 2890 // initializations are simply assignments and use SetValue. |
| 2897 target.SetValue(CONST_INIT); | 2891 target.SetValue(CONST_INIT); |
| 2898 } else { | 2892 } else { |
| 2899 target.SetValue(NOT_CONST_INIT); | 2893 target.SetValue(NOT_CONST_INIT); |
| 2900 } | 2894 } |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3090 // Remove the function from the stack. | 3084 // Remove the function from the stack. |
| 3091 frame_->Drop(); | 3085 frame_->Drop(); |
| 3092 | 3086 |
| 3093 frame_->EmitPush(r0); // push after get rid of function from the stack | 3087 frame_->EmitPush(r0); // push after get rid of function from the stack |
| 3094 | 3088 |
| 3095 } else { | 3089 } else { |
| 3096 // ------------------------------------------- | 3090 // ------------------------------------------- |
| 3097 // JavaScript example: 'array[index](1, 2, 3)' | 3091 // JavaScript example: 'array[index](1, 2, 3)' |
| 3098 // ------------------------------------------- | 3092 // ------------------------------------------- |
| 3099 | 3093 |
| 3100 // Load the function to call from the property through a reference. | 3094 LoadAndSpill(property->obj()); |
| 3101 Reference ref(this, property); | 3095 LoadAndSpill(property->key()); |
| 3102 ref.GetValueAndSpill(); // receiver | 3096 EmitKeyedLoad(false); |
| 3103 | 3097 frame_->Drop(); // key |
| 3104 // Pass receiver to called function. | 3098 // Put the function below the receiver. |
| 3105 if (property->is_synthetic()) { | 3099 if (property->is_synthetic()) { |
| 3100 // Use the global receiver. |
| 3101 frame_->Drop(); |
| 3102 frame_->EmitPush(r0); |
| 3106 LoadGlobalReceiver(r0); | 3103 LoadGlobalReceiver(r0); |
| 3107 } else { | 3104 } else { |
| 3108 __ ldr(r0, frame_->ElementAt(ref.size())); | 3105 frame_->EmitPop(r1); // receiver |
| 3109 frame_->EmitPush(r0); | 3106 frame_->EmitPush(r0); // function |
| 3107 frame_->EmitPush(r1); // receiver |
| 3110 } | 3108 } |
| 3111 | 3109 |
| 3112 // Call the function. | 3110 // Call the function. |
| 3113 CallWithArguments(args, RECEIVER_MIGHT_BE_VALUE, node->position()); | 3111 CallWithArguments(args, RECEIVER_MIGHT_BE_VALUE, node->position()); |
| 3114 frame_->EmitPush(r0); | 3112 frame_->EmitPush(r0); |
| 3115 } | 3113 } |
| 3116 | 3114 |
| 3117 } else { | 3115 } else { |
| 3118 // ---------------------------------- | 3116 // ---------------------------------- |
| 3119 // JavaScript example: 'foo(1, 2, 3)' // foo is not global | 3117 // JavaScript example: 'foo(1, 2, 3)' // foo is not global |
| (...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3800 | 3798 |
| 3801 Variable* var = node->expression()->AsVariableProxy()->AsVariable(); | 3799 Variable* var = node->expression()->AsVariableProxy()->AsVariable(); |
| 3802 bool is_const = (var != NULL && var->mode() == Variable::CONST); | 3800 bool is_const = (var != NULL && var->mode() == Variable::CONST); |
| 3803 | 3801 |
| 3804 // Postfix: Make room for the result. | 3802 // Postfix: Make room for the result. |
| 3805 if (is_postfix) { | 3803 if (is_postfix) { |
| 3806 __ mov(r0, Operand(0)); | 3804 __ mov(r0, Operand(0)); |
| 3807 frame_->EmitPush(r0); | 3805 frame_->EmitPush(r0); |
| 3808 } | 3806 } |
| 3809 | 3807 |
| 3810 { Reference target(this, node->expression()); | 3808 // A constant reference is not saved to, so a constant reference is not a |
| 3809 // compound assignment reference. |
| 3810 { Reference target(this, node->expression(), !is_const); |
| 3811 if (target.is_illegal()) { | 3811 if (target.is_illegal()) { |
| 3812 // Spoof the virtual frame to have the expected height (one higher | 3812 // Spoof the virtual frame to have the expected height (one higher |
| 3813 // than on entry). | 3813 // than on entry). |
| 3814 if (!is_postfix) { | 3814 if (!is_postfix) { |
| 3815 __ mov(r0, Operand(Smi::FromInt(0))); | 3815 __ mov(r0, Operand(Smi::FromInt(0))); |
| 3816 frame_->EmitPush(r0); | 3816 frame_->EmitPush(r0); |
| 3817 } | 3817 } |
| 3818 ASSERT(frame_->height() == original_height + 1); | 3818 ASSERT(frame_->height() == original_height + 1); |
| 3819 return; | 3819 return; |
| 3820 } | 3820 } |
| (...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4261 } | 4261 } |
| 4262 | 4262 |
| 4263 default: | 4263 default: |
| 4264 UNREACHABLE(); | 4264 UNREACHABLE(); |
| 4265 } | 4265 } |
| 4266 ASSERT((has_cc() && frame_->height() == original_height) || | 4266 ASSERT((has_cc() && frame_->height() == original_height) || |
| 4267 (!has_cc() && frame_->height() == original_height + 1)); | 4267 (!has_cc() && frame_->height() == original_height + 1)); |
| 4268 } | 4268 } |
| 4269 | 4269 |
| 4270 | 4270 |
| 4271 void CodeGenerator::EmitKeyedLoad(bool is_global) { |
| 4272 Comment cmnt(masm_, "[ Load from keyed Property"); |
| 4273 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
| 4274 RelocInfo::Mode rmode = is_global |
| 4275 ? RelocInfo::CODE_TARGET_CONTEXT |
| 4276 : RelocInfo::CODE_TARGET; |
| 4277 frame_->CallCodeObject(ic, rmode, 0); |
| 4278 } |
| 4279 |
| 4280 |
| 4271 #ifdef DEBUG | 4281 #ifdef DEBUG |
| 4272 bool CodeGenerator::HasValidEntryRegisters() { return true; } | 4282 bool CodeGenerator::HasValidEntryRegisters() { return true; } |
| 4273 #endif | 4283 #endif |
| 4274 | 4284 |
| 4275 | 4285 |
| 4276 #undef __ | 4286 #undef __ |
| 4277 #define __ ACCESS_MASM(masm) | 4287 #define __ ACCESS_MASM(masm) |
| 4278 | 4288 |
| 4279 | 4289 |
| 4280 Handle<String> Reference::GetName() { | 4290 Handle<String> Reference::GetName() { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4327 ? RelocInfo::CODE_TARGET | 4337 ? RelocInfo::CODE_TARGET |
| 4328 : RelocInfo::CODE_TARGET_CONTEXT; | 4338 : RelocInfo::CODE_TARGET_CONTEXT; |
| 4329 frame->CallCodeObject(ic, rmode, &name_reg, 0); | 4339 frame->CallCodeObject(ic, rmode, &name_reg, 0); |
| 4330 frame->EmitPush(r0); | 4340 frame->EmitPush(r0); |
| 4331 break; | 4341 break; |
| 4332 } | 4342 } |
| 4333 | 4343 |
| 4334 case KEYED: { | 4344 case KEYED: { |
| 4335 // TODO(181): Implement inlined version of array indexing once | 4345 // TODO(181): Implement inlined version of array indexing once |
| 4336 // loop nesting is properly tracked on ARM. | 4346 // loop nesting is properly tracked on ARM. |
| 4337 VirtualFrame* frame = cgen_->frame(); | |
| 4338 Comment cmnt(masm, "[ Load from keyed Property"); | |
| 4339 ASSERT(property != NULL); | 4347 ASSERT(property != NULL); |
| 4340 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | |
| 4341 Variable* var = expression_->AsVariableProxy()->AsVariable(); | 4348 Variable* var = expression_->AsVariableProxy()->AsVariable(); |
| 4342 ASSERT(var == NULL || var->is_global()); | 4349 ASSERT(var == NULL || var->is_global()); |
| 4343 RelocInfo::Mode rmode = (var == NULL) | 4350 cgen_->EmitKeyedLoad(var != NULL); |
| 4344 ? RelocInfo::CODE_TARGET | 4351 cgen_->frame()->EmitPush(r0); |
| 4345 : RelocInfo::CODE_TARGET_CONTEXT; | |
| 4346 frame->CallCodeObject(ic, rmode, 0); | |
| 4347 frame->EmitPush(r0); | |
| 4348 break; | 4352 break; |
| 4349 } | 4353 } |
| 4350 | 4354 |
| 4351 default: | 4355 default: |
| 4352 UNREACHABLE(); | 4356 UNREACHABLE(); |
| 4353 } | 4357 } |
| 4358 |
| 4359 if (!persist_after_get_) { |
| 4360 cgen_->UnloadReference(this); |
| 4361 } |
| 4354 } | 4362 } |
| 4355 | 4363 |
| 4356 | 4364 |
| 4357 void Reference::SetValue(InitState init_state) { | 4365 void Reference::SetValue(InitState init_state) { |
| 4358 ASSERT(!is_illegal()); | 4366 ASSERT(!is_illegal()); |
| 4359 ASSERT(!cgen_->has_cc()); | 4367 ASSERT(!cgen_->has_cc()); |
| 4360 MacroAssembler* masm = cgen_->masm(); | 4368 MacroAssembler* masm = cgen_->masm(); |
| 4361 VirtualFrame* frame = cgen_->frame(); | 4369 VirtualFrame* frame = cgen_->frame(); |
| 4362 Property* property = expression_->AsProperty(); | 4370 Property* property = expression_->AsProperty(); |
| 4363 if (property != NULL) { | 4371 if (property != NULL) { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4405 Result value(r0); | 4413 Result value(r0); |
| 4406 frame->EmitPop(r0); // value | 4414 frame->EmitPop(r0); // value |
| 4407 frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, &value, 0); | 4415 frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, &value, 0); |
| 4408 frame->EmitPush(r0); | 4416 frame->EmitPush(r0); |
| 4409 break; | 4417 break; |
| 4410 } | 4418 } |
| 4411 | 4419 |
| 4412 default: | 4420 default: |
| 4413 UNREACHABLE(); | 4421 UNREACHABLE(); |
| 4414 } | 4422 } |
| 4423 cgen_->UnloadReference(this); |
| 4415 } | 4424 } |
| 4416 | 4425 |
| 4417 | 4426 |
| 4418 void FastNewClosureStub::Generate(MacroAssembler* masm) { | 4427 void FastNewClosureStub::Generate(MacroAssembler* masm) { |
| 4419 // Clone the boilerplate in new space. Set the context to the | 4428 // Clone the boilerplate in new space. Set the context to the |
| 4420 // current context in cp. | 4429 // current context in cp. |
| 4421 Label gc; | 4430 Label gc; |
| 4422 | 4431 |
| 4423 // Pop the boilerplate function from the stack. | 4432 // Pop the boilerplate function from the stack. |
| 4424 __ pop(r3); | 4433 __ pop(r3); |
| (...skipping 2461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6886 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) | 6895 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) |
| 6887 // tagged as a small integer. | 6896 // tagged as a small integer. |
| 6888 __ bind(&runtime); | 6897 __ bind(&runtime); |
| 6889 __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1); | 6898 __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1); |
| 6890 } | 6899 } |
| 6891 | 6900 |
| 6892 | 6901 |
| 6893 #undef __ | 6902 #undef __ |
| 6894 | 6903 |
| 6895 } } // namespace v8::internal | 6904 } } // namespace v8::internal |
| OLD | NEW |