OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 613 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
624 __ bind(&done); | 624 __ bind(&done); |
625 } | 625 } |
626 | 626 |
627 | 627 |
628 void FullCodeGenerator::StackValueContext::Plug( | 628 void FullCodeGenerator::StackValueContext::Plug( |
629 Label* materialize_true, | 629 Label* materialize_true, |
630 Label* materialize_false) const { | 630 Label* materialize_false) const { |
631 Label done; | 631 Label done; |
632 __ bind(materialize_true); | 632 __ bind(materialize_true); |
633 __ LoadRoot(at, Heap::kTrueValueRootIndex); | 633 __ LoadRoot(at, Heap::kTrueValueRootIndex); |
634 __ push(at); | |
635 __ Branch(&done); | 634 __ Branch(&done); |
636 __ bind(materialize_false); | 635 __ bind(materialize_false); |
637 __ LoadRoot(at, Heap::kFalseValueRootIndex); | 636 __ LoadRoot(at, Heap::kFalseValueRootIndex); |
| 637 __ bind(&done); |
638 __ push(at); | 638 __ push(at); |
639 __ bind(&done); | |
640 } | 639 } |
641 | 640 |
642 | 641 |
643 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, | 642 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, |
644 Label* materialize_false) const { | 643 Label* materialize_false) const { |
645 ASSERT(materialize_true == true_label_); | 644 ASSERT(materialize_true == true_label_); |
646 ASSERT(materialize_false == false_label_); | 645 ASSERT(materialize_false == false_label_); |
647 } | 646 } |
648 | 647 |
649 | 648 |
(...skipping 960 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1610 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); | 1609 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); |
1611 __ mov(t1, v0); | 1610 __ mov(t1, v0); |
1612 | 1611 |
1613 __ bind(&materialized); | 1612 __ bind(&materialized); |
1614 int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize; | 1613 int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize; |
1615 Label allocated, runtime_allocate; | 1614 Label allocated, runtime_allocate; |
1616 __ Allocate(size, v0, a2, a3, &runtime_allocate, TAG_OBJECT); | 1615 __ Allocate(size, v0, a2, a3, &runtime_allocate, TAG_OBJECT); |
1617 __ jmp(&allocated); | 1616 __ jmp(&allocated); |
1618 | 1617 |
1619 __ bind(&runtime_allocate); | 1618 __ bind(&runtime_allocate); |
1620 __ push(t1); | |
1621 __ li(a0, Operand(Smi::FromInt(size))); | 1619 __ li(a0, Operand(Smi::FromInt(size))); |
1622 __ push(a0); | 1620 __ Push(t1, a0); |
1623 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); | 1621 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); |
1624 __ pop(t1); | 1622 __ pop(t1); |
1625 | 1623 |
1626 __ bind(&allocated); | 1624 __ bind(&allocated); |
1627 | 1625 |
1628 // After this, registers are used as follows: | 1626 // After this, registers are used as follows: |
1629 // v0: Newly allocated regexp. | 1627 // v0: Newly allocated regexp. |
1630 // t1: Materialized regexp. | 1628 // t1: Materialized regexp. |
1631 // a2: temp. | 1629 // a2: temp. |
1632 __ CopyFields(v0, t1, a2.bit(), size / kPointerSize); | 1630 __ CopyFields(v0, t1, a2.bit(), size / kPointerSize); |
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2053 // Initial send value is undefined. | 2051 // Initial send value is undefined. |
2054 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex); | 2052 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex); |
2055 __ Branch(&l_next); | 2053 __ Branch(&l_next); |
2056 | 2054 |
2057 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } | 2055 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } |
2058 __ bind(&l_catch); | 2056 __ bind(&l_catch); |
2059 __ mov(a0, v0); | 2057 __ mov(a0, v0); |
2060 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); | 2058 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); |
2061 __ LoadRoot(a2, Heap::kthrow_stringRootIndex); // "throw" | 2059 __ LoadRoot(a2, Heap::kthrow_stringRootIndex); // "throw" |
2062 __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter | 2060 __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter |
2063 __ push(a3); // iter | 2061 __ Push(a3, a0); // iter, exception |
2064 __ push(a0); // exception | |
2065 __ jmp(&l_call); | 2062 __ jmp(&l_call); |
2066 | 2063 |
2067 // try { received = %yield result } | 2064 // try { received = %yield result } |
2068 // Shuffle the received result above a try handler and yield it without | 2065 // Shuffle the received result above a try handler and yield it without |
2069 // re-boxing. | 2066 // re-boxing. |
2070 __ bind(&l_try); | 2067 __ bind(&l_try); |
2071 __ pop(a0); // result | 2068 __ pop(a0); // result |
2072 __ PushTryHandler(StackHandler::CATCH, expr->index()); | 2069 __ PushTryHandler(StackHandler::CATCH, expr->index()); |
2073 const int handler_size = StackHandlerConstants::kSize; | 2070 const int handler_size = StackHandlerConstants::kSize; |
2074 __ push(a0); // result | 2071 __ push(a0); // result |
(...skipping 17 matching lines...) Expand all Loading... |
2092 __ pop(v0); // result | 2089 __ pop(v0); // result |
2093 EmitReturnSequence(); | 2090 EmitReturnSequence(); |
2094 __ mov(a0, v0); | 2091 __ mov(a0, v0); |
2095 __ bind(&l_resume); // received in a0 | 2092 __ bind(&l_resume); // received in a0 |
2096 __ PopTryHandler(); | 2093 __ PopTryHandler(); |
2097 | 2094 |
2098 // receiver = iter; f = 'next'; arg = received; | 2095 // receiver = iter; f = 'next'; arg = received; |
2099 __ bind(&l_next); | 2096 __ bind(&l_next); |
2100 __ LoadRoot(a2, Heap::knext_stringRootIndex); // "next" | 2097 __ LoadRoot(a2, Heap::knext_stringRootIndex); // "next" |
2101 __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter | 2098 __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter |
2102 __ push(a3); // iter | 2099 __ Push(a3, a0); // iter, received |
2103 __ push(a0); // received | |
2104 | 2100 |
2105 // result = receiver[f](arg); | 2101 // result = receiver[f](arg); |
2106 __ bind(&l_call); | 2102 __ bind(&l_call); |
2107 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(1); | 2103 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(1); |
2108 CallIC(ic); | 2104 CallIC(ic); |
2109 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2105 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2110 | 2106 |
2111 // if (!result.done) goto l_try; | 2107 // if (!result.done) goto l_try; |
2112 __ bind(&l_loop); | 2108 __ bind(&l_loop); |
2113 __ mov(a0, v0); | 2109 __ mov(a0, v0); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2169 __ push(a2); | 2165 __ push(a2); |
2170 __ jmp(&push_argument_holes); | 2166 __ jmp(&push_argument_holes); |
2171 | 2167 |
2172 // Enter a new JavaScript frame, and initialize its slots as they were when | 2168 // Enter a new JavaScript frame, and initialize its slots as they were when |
2173 // the generator was suspended. | 2169 // the generator was suspended. |
2174 Label resume_frame; | 2170 Label resume_frame; |
2175 __ bind(&push_frame); | 2171 __ bind(&push_frame); |
2176 __ Call(&resume_frame); | 2172 __ Call(&resume_frame); |
2177 __ jmp(&done); | 2173 __ jmp(&done); |
2178 __ bind(&resume_frame); | 2174 __ bind(&resume_frame); |
2179 __ push(ra); // Return address. | 2175 // ra = return address. |
2180 __ push(fp); // Caller's frame pointer. | 2176 // fp = caller's frame pointer. |
2181 __ mov(fp, sp); | 2177 // cp = callee's context, |
2182 __ push(cp); // Callee's context. | 2178 // t0 = callee's JS function. |
2183 __ push(t0); // Callee's JS Function. | 2179 __ Push(ra, fp, cp, t0); |
| 2180 // Adjust FP to point to saved FP. |
| 2181 __ Addu(fp, sp, 2 * kPointerSize); |
2184 | 2182 |
2185 // Load the operand stack size. | 2183 // Load the operand stack size. |
2186 __ lw(a3, FieldMemOperand(a1, JSGeneratorObject::kOperandStackOffset)); | 2184 __ lw(a3, FieldMemOperand(a1, JSGeneratorObject::kOperandStackOffset)); |
2187 __ lw(a3, FieldMemOperand(a3, FixedArray::kLengthOffset)); | 2185 __ lw(a3, FieldMemOperand(a3, FixedArray::kLengthOffset)); |
2188 __ SmiUntag(a3); | 2186 __ SmiUntag(a3); |
2189 | 2187 |
2190 // If we are sending a value and there is no operand stack, we can jump back | 2188 // If we are sending a value and there is no operand stack, we can jump back |
2191 // in directly. | 2189 // in directly. |
2192 if (resume_mode == JSGeneratorObject::NEXT) { | 2190 if (resume_mode == JSGeneratorObject::NEXT) { |
2193 Label slow_resume; | 2191 Label slow_resume; |
(...skipping 10 matching lines...) Expand all Loading... |
2204 | 2202 |
2205 // Otherwise, we push holes for the operand stack and call the runtime to fix | 2203 // Otherwise, we push holes for the operand stack and call the runtime to fix |
2206 // up the stack and the handlers. | 2204 // up the stack and the handlers. |
2207 Label push_operand_holes, call_resume; | 2205 Label push_operand_holes, call_resume; |
2208 __ bind(&push_operand_holes); | 2206 __ bind(&push_operand_holes); |
2209 __ Subu(a3, a3, Operand(1)); | 2207 __ Subu(a3, a3, Operand(1)); |
2210 __ Branch(&call_resume, lt, a3, Operand(zero_reg)); | 2208 __ Branch(&call_resume, lt, a3, Operand(zero_reg)); |
2211 __ push(a2); | 2209 __ push(a2); |
2212 __ Branch(&push_operand_holes); | 2210 __ Branch(&push_operand_holes); |
2213 __ bind(&call_resume); | 2211 __ bind(&call_resume); |
2214 __ push(a1); | 2212 ASSERT(!result_register().is(a1)); |
2215 __ push(result_register()); | 2213 __ Push(a1, result_register()); |
2216 __ Push(Smi::FromInt(resume_mode)); | 2214 __ Push(Smi::FromInt(resume_mode)); |
2217 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3); | 2215 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3); |
2218 // Not reached: the runtime call returns elsewhere. | 2216 // Not reached: the runtime call returns elsewhere. |
2219 __ stop("not-reached"); | 2217 __ stop("not-reached"); |
2220 | 2218 |
2221 // Throw error if we attempt to operate on a running generator. | 2219 // Throw error if we attempt to operate on a running generator. |
2222 __ bind(&wrong_state); | 2220 __ bind(&wrong_state); |
2223 __ push(a1); | 2221 __ push(a1); |
2224 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1); | 2222 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1); |
2225 | 2223 |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2435 ? isolate()->builtins()->StoreIC_Initialize() | 2433 ? isolate()->builtins()->StoreIC_Initialize() |
2436 : isolate()->builtins()->StoreIC_Initialize_Strict(); | 2434 : isolate()->builtins()->StoreIC_Initialize_Strict(); |
2437 CallIC(ic); | 2435 CallIC(ic); |
2438 break; | 2436 break; |
2439 } | 2437 } |
2440 case KEYED_PROPERTY: { | 2438 case KEYED_PROPERTY: { |
2441 __ push(result_register()); // Preserve value. | 2439 __ push(result_register()); // Preserve value. |
2442 VisitForStackValue(prop->obj()); | 2440 VisitForStackValue(prop->obj()); |
2443 VisitForAccumulatorValue(prop->key()); | 2441 VisitForAccumulatorValue(prop->key()); |
2444 __ mov(a1, result_register()); | 2442 __ mov(a1, result_register()); |
2445 __ pop(a2); | 2443 __ Pop(a0, a2); // a0 = restored value. |
2446 __ pop(a0); // Restore value. | |
2447 Handle<Code> ic = is_classic_mode() | 2444 Handle<Code> ic = is_classic_mode() |
2448 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 2445 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
2449 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 2446 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
2450 CallIC(ic); | 2447 CallIC(ic); |
2451 break; | 2448 break; |
2452 } | 2449 } |
2453 } | 2450 } |
2454 context()->Plug(v0); | 2451 context()->Plug(v0); |
2455 } | 2452 } |
2456 | 2453 |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2578 // Assignment to a property, using a keyed store IC. | 2575 // Assignment to a property, using a keyed store IC. |
2579 | 2576 |
2580 // Record source code position before IC call. | 2577 // Record source code position before IC call. |
2581 SetSourcePosition(expr->position()); | 2578 SetSourcePosition(expr->position()); |
2582 // Call keyed store IC. | 2579 // Call keyed store IC. |
2583 // The arguments are: | 2580 // The arguments are: |
2584 // - a0 is the value, | 2581 // - a0 is the value, |
2585 // - a1 is the key, | 2582 // - a1 is the key, |
2586 // - a2 is the receiver. | 2583 // - a2 is the receiver. |
2587 __ mov(a0, result_register()); | 2584 __ mov(a0, result_register()); |
2588 __ pop(a1); // Key. | 2585 __ Pop(a2, a1); // a1 = key. |
2589 __ pop(a2); | |
2590 | 2586 |
2591 Handle<Code> ic = is_classic_mode() | 2587 Handle<Code> ic = is_classic_mode() |
2592 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 2588 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
2593 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 2589 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
2594 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId()); | 2590 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId()); |
2595 | 2591 |
2596 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2592 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2597 context()->Plug(v0); | 2593 context()->Plug(v0); |
2598 } | 2594 } |
2599 | 2595 |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2707 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 2703 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
2708 __ CallStub(&stub, expr->CallFeedbackId()); | 2704 __ CallStub(&stub, expr->CallFeedbackId()); |
2709 RecordJSReturnSite(expr); | 2705 RecordJSReturnSite(expr); |
2710 // Restore context register. | 2706 // Restore context register. |
2711 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2707 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2712 context()->DropAndPlug(1, v0); | 2708 context()->DropAndPlug(1, v0); |
2713 } | 2709 } |
2714 | 2710 |
2715 | 2711 |
2716 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { | 2712 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { |
2717 // Push copy of the first argument or undefined if it doesn't exist. | 2713 // t2: copy of the first argument or undefined if it doesn't exist. |
2718 if (arg_count > 0) { | 2714 if (arg_count > 0) { |
2719 __ lw(a1, MemOperand(sp, arg_count * kPointerSize)); | 2715 __ lw(t2, MemOperand(sp, arg_count * kPointerSize)); |
2720 } else { | 2716 } else { |
2721 __ LoadRoot(a1, Heap::kUndefinedValueRootIndex); | 2717 __ LoadRoot(t2, Heap::kUndefinedValueRootIndex); |
2722 } | 2718 } |
2723 __ push(a1); | |
2724 | 2719 |
2725 // Push the receiver of the enclosing function. | 2720 // t1: the receiver of the enclosing function. |
2726 int receiver_offset = 2 + info_->scope()->num_parameters(); | 2721 int receiver_offset = 2 + info_->scope()->num_parameters(); |
2727 __ lw(a1, MemOperand(fp, receiver_offset * kPointerSize)); | 2722 __ lw(t1, MemOperand(fp, receiver_offset * kPointerSize)); |
2728 __ push(a1); | |
2729 // Push the language mode. | |
2730 __ li(a1, Operand(Smi::FromInt(language_mode()))); | |
2731 __ push(a1); | |
2732 | 2723 |
2733 // Push the start position of the scope the calls resides in. | 2724 // t0: the language mode. |
| 2725 __ li(t0, Operand(Smi::FromInt(language_mode()))); |
| 2726 |
| 2727 // a1: the start position of the scope the calls resides in. |
2734 __ li(a1, Operand(Smi::FromInt(scope()->start_position()))); | 2728 __ li(a1, Operand(Smi::FromInt(scope()->start_position()))); |
2735 __ push(a1); | |
2736 | 2729 |
2737 // Do the runtime call. | 2730 // Do the runtime call. |
| 2731 __ Push(t2, t1, t0, a1); |
2738 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); | 2732 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); |
2739 } | 2733 } |
2740 | 2734 |
2741 | 2735 |
2742 void FullCodeGenerator::VisitCall(Call* expr) { | 2736 void FullCodeGenerator::VisitCall(Call* expr) { |
2743 #ifdef DEBUG | 2737 #ifdef DEBUG |
2744 // We want to verify that RecordJSReturnSite gets called on all paths | 2738 // We want to verify that RecordJSReturnSite gets called on all paths |
2745 // through this function. Avoid early returns. | 2739 // through this function. Avoid early returns. |
2746 expr->return_is_recorded_ = false; | 2740 expr->return_is_recorded_ = false; |
2747 #endif | 2741 #endif |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2800 | 2794 |
2801 { PreservePositionScope scope(masm()->positions_recorder()); | 2795 { PreservePositionScope scope(masm()->positions_recorder()); |
2802 // Generate code for loading from variables potentially shadowed | 2796 // Generate code for loading from variables potentially shadowed |
2803 // by eval-introduced variables. | 2797 // by eval-introduced variables. |
2804 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); | 2798 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); |
2805 } | 2799 } |
2806 | 2800 |
2807 __ bind(&slow); | 2801 __ bind(&slow); |
2808 // Call the runtime to find the function to call (returned in v0) | 2802 // Call the runtime to find the function to call (returned in v0) |
2809 // and the object holding it (returned in v1). | 2803 // and the object holding it (returned in v1). |
2810 __ push(context_register()); | 2804 ASSERT(!context_register().is(a2)); |
2811 __ li(a2, Operand(proxy->name())); | 2805 __ li(a2, Operand(proxy->name())); |
2812 __ push(a2); | 2806 __ Push(context_register(), a2); |
2813 __ CallRuntime(Runtime::kLoadContextSlot, 2); | 2807 __ CallRuntime(Runtime::kLoadContextSlot, 2); |
2814 __ Push(v0, v1); // Function, receiver. | 2808 __ Push(v0, v1); // Function, receiver. |
2815 | 2809 |
2816 // If fast case code has been generated, emit code to push the | 2810 // If fast case code has been generated, emit code to push the |
2817 // function and receiver and have the slow path jump around this | 2811 // function and receiver and have the slow path jump around this |
2818 // code. | 2812 // code. |
2819 if (done.is_linked()) { | 2813 if (done.is_linked()) { |
2820 Label call; | 2814 Label call; |
2821 __ Branch(&call); | 2815 __ Branch(&call); |
2822 __ bind(&done); | 2816 __ bind(&done); |
(...skipping 691 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3514 void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) { | 3508 void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) { |
3515 ZoneList<Expression*>* args = expr->arguments(); | 3509 ZoneList<Expression*>* args = expr->arguments(); |
3516 ASSERT_EQ(3, args->length()); | 3510 ASSERT_EQ(3, args->length()); |
3517 | 3511 |
3518 Register string = v0; | 3512 Register string = v0; |
3519 Register index = a1; | 3513 Register index = a1; |
3520 Register value = a2; | 3514 Register value = a2; |
3521 | 3515 |
3522 VisitForStackValue(args->at(1)); // index | 3516 VisitForStackValue(args->at(1)); // index |
3523 VisitForStackValue(args->at(2)); // value | 3517 VisitForStackValue(args->at(2)); // value |
3524 __ pop(value); | 3518 __ Pop(index, value); |
3525 __ pop(index); | |
3526 VisitForAccumulatorValue(args->at(0)); // string | 3519 VisitForAccumulatorValue(args->at(0)); // string |
3527 | 3520 |
3528 if (FLAG_debug_code) { | 3521 if (FLAG_debug_code) { |
3529 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; | 3522 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; |
3530 EmitSeqStringSetCharCheck(string, index, value, one_byte_seq_type); | 3523 EmitSeqStringSetCharCheck(string, index, value, one_byte_seq_type); |
3531 } | 3524 } |
3532 | 3525 |
3533 __ SmiUntag(value, value); | 3526 __ SmiUntag(value, value); |
3534 __ Addu(at, | 3527 __ Addu(at, |
3535 string, | 3528 string, |
3536 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); | 3529 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); |
3537 __ SmiUntag(index); | 3530 __ SmiUntag(index); |
3538 __ Addu(at, at, index); | 3531 __ Addu(at, at, index); |
3539 __ sb(value, MemOperand(at)); | 3532 __ sb(value, MemOperand(at)); |
3540 context()->Plug(string); | 3533 context()->Plug(string); |
3541 } | 3534 } |
3542 | 3535 |
3543 | 3536 |
3544 void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) { | 3537 void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) { |
3545 ZoneList<Expression*>* args = expr->arguments(); | 3538 ZoneList<Expression*>* args = expr->arguments(); |
3546 ASSERT_EQ(3, args->length()); | 3539 ASSERT_EQ(3, args->length()); |
3547 | 3540 |
3548 Register string = v0; | 3541 Register string = v0; |
3549 Register index = a1; | 3542 Register index = a1; |
3550 Register value = a2; | 3543 Register value = a2; |
3551 | 3544 |
3552 VisitForStackValue(args->at(1)); // index | 3545 VisitForStackValue(args->at(1)); // index |
3553 VisitForStackValue(args->at(2)); // value | 3546 VisitForStackValue(args->at(2)); // value |
3554 __ pop(value); | 3547 __ Pop(index, value); |
3555 __ pop(index); | |
3556 VisitForAccumulatorValue(args->at(0)); // string | 3548 VisitForAccumulatorValue(args->at(0)); // string |
3557 | 3549 |
3558 if (FLAG_debug_code) { | 3550 if (FLAG_debug_code) { |
3559 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; | 3551 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; |
3560 EmitSeqStringSetCharCheck(string, index, value, two_byte_seq_type); | 3552 EmitSeqStringSetCharCheck(string, index, value, two_byte_seq_type); |
3561 } | 3553 } |
3562 | 3554 |
3563 __ SmiUntag(value, value); | 3555 __ SmiUntag(value, value); |
3564 __ Addu(at, | 3556 __ Addu(at, |
3565 string, | 3557 string, |
(...skipping 740 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4306 __ Push(a2, a1, a0); | 4298 __ Push(a2, a1, a0); |
4307 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); | 4299 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); |
4308 context()->Plug(v0); | 4300 context()->Plug(v0); |
4309 } else if (var->IsStackAllocated() || var->IsContextSlot()) { | 4301 } else if (var->IsStackAllocated() || var->IsContextSlot()) { |
4310 // Result of deleting non-global, non-dynamic variables is false. | 4302 // Result of deleting non-global, non-dynamic variables is false. |
4311 // The subexpression does not have side effects. | 4303 // The subexpression does not have side effects. |
4312 context()->Plug(var->is_this()); | 4304 context()->Plug(var->is_this()); |
4313 } else { | 4305 } else { |
4314 // Non-global variable. Call the runtime to try to delete from the | 4306 // Non-global variable. Call the runtime to try to delete from the |
4315 // context where the variable was introduced. | 4307 // context where the variable was introduced. |
4316 __ push(context_register()); | 4308 ASSERT(!context_register().is(a2)); |
4317 __ li(a2, Operand(var->name())); | 4309 __ li(a2, Operand(var->name())); |
4318 __ push(a2); | 4310 __ Push(context_register(), a2); |
4319 __ CallRuntime(Runtime::kDeleteContextSlot, 2); | 4311 __ CallRuntime(Runtime::kDeleteContextSlot, 2); |
4320 context()->Plug(v0); | 4312 context()->Plug(v0); |
4321 } | 4313 } |
4322 } else { | 4314 } else { |
4323 // Result of deleting non-property, non-variable reference is true. | 4315 // Result of deleting non-property, non-variable reference is true. |
4324 // The subexpression may have side effects. | 4316 // The subexpression may have side effects. |
4325 VisitForEffect(expr->expression()); | 4317 VisitForEffect(expr->expression()); |
4326 context()->Plug(true); | 4318 context()->Plug(true); |
4327 } | 4319 } |
4328 break; | 4320 break; |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4540 if (!context()->IsEffect()) { | 4532 if (!context()->IsEffect()) { |
4541 context()->PlugTOS(); | 4533 context()->PlugTOS(); |
4542 } | 4534 } |
4543 } else { | 4535 } else { |
4544 context()->Plug(v0); | 4536 context()->Plug(v0); |
4545 } | 4537 } |
4546 break; | 4538 break; |
4547 } | 4539 } |
4548 case KEYED_PROPERTY: { | 4540 case KEYED_PROPERTY: { |
4549 __ mov(a0, result_register()); // Value. | 4541 __ mov(a0, result_register()); // Value. |
4550 __ pop(a1); // Key. | 4542 __ Pop(a2, a1); // a1 = key, a2 = receiver. |
4551 __ pop(a2); // Receiver. | |
4552 Handle<Code> ic = is_classic_mode() | 4543 Handle<Code> ic = is_classic_mode() |
4553 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 4544 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
4554 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 4545 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
4555 CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId()); | 4546 CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId()); |
4556 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4547 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
4557 if (expr->is_postfix()) { | 4548 if (expr->is_postfix()) { |
4558 if (!context()->IsEffect()) { | 4549 if (!context()->IsEffect()) { |
4559 context()->PlugTOS(); | 4550 context()->PlugTOS(); |
4560 } | 4551 } |
4561 } else { | 4552 } else { |
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5003 Assembler::target_address_at(pc_immediate_load_address)) == | 4994 Assembler::target_address_at(pc_immediate_load_address)) == |
5004 reinterpret_cast<uint32_t>( | 4995 reinterpret_cast<uint32_t>( |
5005 isolate->builtins()->OsrAfterStackCheck()->entry())); | 4996 isolate->builtins()->OsrAfterStackCheck()->entry())); |
5006 return OSR_AFTER_STACK_CHECK; | 4997 return OSR_AFTER_STACK_CHECK; |
5007 } | 4998 } |
5008 | 4999 |
5009 | 5000 |
5010 } } // namespace v8::internal | 5001 } } // namespace v8::internal |
5011 | 5002 |
5012 #endif // V8_TARGET_ARCH_MIPS | 5003 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |