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 |