| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 110 }; | 110 }; |
| 111 | 111 |
| 112 | 112 |
| 113 // Generate code for a JS function. On entry to the function the receiver | 113 // Generate code for a JS function. On entry to the function the receiver |
| 114 // and arguments have been pushed on the stack left to right. The actual | 114 // and arguments have been pushed on the stack left to right. The actual |
| 115 // argument count matches the formal parameter count expected by the | 115 // argument count matches the formal parameter count expected by the |
| 116 // function. | 116 // function. |
| 117 // | 117 // |
| 118 // The live registers are: | 118 // The live registers are: |
| 119 // - x1: the JS function object being called (i.e. ourselves). | 119 // - x1: the JS function object being called (i.e. ourselves). |
| 120 // - x5: call kind or strict mode. | |
| 121 // - cp: our context. | 120 // - cp: our context. |
| 122 // - fp: our caller's frame pointer. | 121 // - fp: our caller's frame pointer. |
| 123 // - jssp: stack pointer. | 122 // - jssp: stack pointer. |
| 124 // - lr: return address. | 123 // - lr: return address. |
| 125 // | 124 // |
| 126 // The function builds a JS frame. See JavaScriptFrameConstants in | 125 // The function builds a JS frame. See JavaScriptFrameConstants in |
| 127 // frames-arm.h for its layout. | 126 // frames-arm.h for its layout. |
| 128 void FullCodeGenerator::Generate() { | 127 void FullCodeGenerator::Generate() { |
| 129 CompilationInfo* info = info_; | 128 CompilationInfo* info = info_; |
| 130 handler_table_ = | 129 handler_table_ = |
| (...skipping 10 matching lines...) Expand all Loading... |
| 141 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { | 140 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { |
| 142 __ Debug("stop-at", __LINE__, BREAK); | 141 __ Debug("stop-at", __LINE__, BREAK); |
| 143 } | 142 } |
| 144 #endif | 143 #endif |
| 145 | 144 |
| 146 // Classic mode functions and builtins need to replace the receiver with the | 145 // Classic mode functions and builtins need to replace the receiver with the |
| 147 // global proxy when called as functions (without an explicit receiver | 146 // global proxy when called as functions (without an explicit receiver |
| 148 // object). | 147 // object). |
| 149 if (info->is_classic_mode() && !info->is_native()) { | 148 if (info->is_classic_mode() && !info->is_native()) { |
| 150 Label ok; | 149 Label ok; |
| 151 __ Cbz(x5, &ok); | |
| 152 int receiver_offset = info->scope()->num_parameters() * kXRegSizeInBytes; | 150 int receiver_offset = info->scope()->num_parameters() * kXRegSizeInBytes; |
| 153 __ Peek(x10, receiver_offset); | 151 __ Peek(x10, receiver_offset); |
| 154 __ JumpIfNotRoot(x10, Heap::kUndefinedValueRootIndex, &ok); | 152 __ JumpIfNotRoot(x10, Heap::kUndefinedValueRootIndex, &ok); |
| 155 | 153 |
| 156 __ Ldr(x10, GlobalObjectMemOperand()); | 154 __ Ldr(x10, GlobalObjectMemOperand()); |
| 157 __ Ldr(x10, FieldMemOperand(x10, GlobalObject::kGlobalReceiverOffset)); | 155 __ Ldr(x10, FieldMemOperand(x10, GlobalObject::kGlobalReceiverOffset)); |
| 158 __ Poke(x10, receiver_offset); | 156 __ Poke(x10, receiver_offset); |
| 159 | 157 |
| 160 __ Bind(&ok); | 158 __ Bind(&ok); |
| 161 } | 159 } |
| (...skipping 2162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2324 int arg_count = args->length(); | 2322 int arg_count = args->length(); |
| 2325 { PreservePositionScope scope(masm()->positions_recorder()); | 2323 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2326 for (int i = 0; i < arg_count; i++) { | 2324 for (int i = 0; i < arg_count; i++) { |
| 2327 VisitForStackValue(args->at(i)); | 2325 VisitForStackValue(args->at(i)); |
| 2328 } | 2326 } |
| 2329 __ Mov(x2, Operand(name)); | 2327 __ Mov(x2, Operand(name)); |
| 2330 } | 2328 } |
| 2331 // Record source position for debugger. | 2329 // Record source position for debugger. |
| 2332 SetSourcePosition(expr->position()); | 2330 SetSourcePosition(expr->position()); |
| 2333 // Call the IC initialization code. | 2331 // Call the IC initialization code. |
| 2334 Handle<Code> ic = | 2332 Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize(arg_count); |
| 2335 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); | |
| 2336 TypeFeedbackId ast_id = mode == CONTEXTUAL | 2333 TypeFeedbackId ast_id = mode == CONTEXTUAL |
| 2337 ? TypeFeedbackId::None() | 2334 ? TypeFeedbackId::None() |
| 2338 : expr->CallFeedbackId(); | 2335 : expr->CallFeedbackId(); |
| 2339 CallIC(ic, mode, ast_id); | 2336 CallIC(ic, mode, ast_id); |
| 2340 RecordJSReturnSite(expr); | 2337 RecordJSReturnSite(expr); |
| 2341 // Restore context register. | 2338 // Restore context register. |
| 2342 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2339 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2343 context()->Plug(x0); | 2340 context()->Plug(x0); |
| 2344 } | 2341 } |
| 2345 | 2342 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 2370 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); | 2367 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); |
| 2371 __ Peek(x2, (arg_count + 1) * kXRegSizeInBytes); // Key. | 2368 __ Peek(x2, (arg_count + 1) * kXRegSizeInBytes); // Key. |
| 2372 CallIC(ic, NOT_CONTEXTUAL, expr->CallFeedbackId()); | 2369 CallIC(ic, NOT_CONTEXTUAL, expr->CallFeedbackId()); |
| 2373 RecordJSReturnSite(expr); | 2370 RecordJSReturnSite(expr); |
| 2374 // Restore context register. | 2371 // Restore context register. |
| 2375 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2372 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2376 context()->DropAndPlug(1, x0); // Drop the key still on the stack. | 2373 context()->DropAndPlug(1, x0); // Drop the key still on the stack. |
| 2377 } | 2374 } |
| 2378 | 2375 |
| 2379 | 2376 |
| 2380 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { | 2377 void FullCodeGenerator::EmitCallWithStub(Call* expr) { |
| 2381 // Code common for calls using the call stub. | 2378 // Code common for calls using the call stub. |
| 2382 ZoneList<Expression*>* args = expr->arguments(); | 2379 ZoneList<Expression*>* args = expr->arguments(); |
| 2383 int arg_count = args->length(); | 2380 int arg_count = args->length(); |
| 2384 { PreservePositionScope scope(masm()->positions_recorder()); | 2381 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2385 for (int i = 0; i < arg_count; i++) { | 2382 for (int i = 0; i < arg_count; i++) { |
| 2386 VisitForStackValue(args->at(i)); | 2383 VisitForStackValue(args->at(i)); |
| 2387 } | 2384 } |
| 2388 } | 2385 } |
| 2389 // Record source position for debugger. | 2386 // Record source position for debugger. |
| 2390 SetSourcePosition(expr->position()); | 2387 SetSourcePosition(expr->position()); |
| 2391 | 2388 |
| 2392 // Record call targets in unoptimized code. | |
| 2393 flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET); | |
| 2394 Handle<Object> uninitialized = | 2389 Handle<Object> uninitialized = |
| 2395 TypeFeedbackCells::UninitializedSentinel(isolate()); | 2390 TypeFeedbackCells::UninitializedSentinel(isolate()); |
| 2396 Handle<Cell> cell = | 2391 Handle<Cell> cell = |
| 2397 isolate()->factory()->NewCell(uninitialized); | 2392 isolate()->factory()->NewCell(uninitialized); |
| 2398 RecordTypeFeedbackCell(expr->CallFeedbackId(), cell); | 2393 RecordTypeFeedbackCell(expr->CallFeedbackId(), cell); |
| 2399 __ Mov(x2, Operand(cell)); | 2394 __ Mov(x2, Operand(cell)); |
| 2400 | 2395 |
| 2401 CallFunctionStub stub(arg_count, flags); | 2396 // Record call targets in unoptimized code. |
| 2397 CallFunctionStub stub(arg_count, RECORD_CALL_TARGET); |
| 2402 __ Peek(x1, (arg_count + 1) * kXRegSizeInBytes); | 2398 __ Peek(x1, (arg_count + 1) * kXRegSizeInBytes); |
| 2403 __ CallStub(&stub, expr->CallFeedbackId()); | 2399 __ CallStub(&stub, expr->CallFeedbackId()); |
| 2404 RecordJSReturnSite(expr); | 2400 RecordJSReturnSite(expr); |
| 2405 // Restore context register. | 2401 // Restore context register. |
| 2406 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2402 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2407 context()->DropAndPlug(1, x0); | 2403 context()->DropAndPlug(1, x0); |
| 2408 } | 2404 } |
| 2409 | 2405 |
| 2410 | 2406 |
| 2411 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { | 2407 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2528 __ Push(x0); | 2524 __ Push(x0); |
| 2529 // The receiver is implicitly the global receiver. Indicate this | 2525 // The receiver is implicitly the global receiver. Indicate this |
| 2530 // by passing the undefined to the call function stub. | 2526 // by passing the undefined to the call function stub. |
| 2531 __ LoadRoot(x1, Heap::kUndefinedValueRootIndex); | 2527 __ LoadRoot(x1, Heap::kUndefinedValueRootIndex); |
| 2532 __ Push(x1); | 2528 __ Push(x1); |
| 2533 __ Bind(&call); | 2529 __ Bind(&call); |
| 2534 } | 2530 } |
| 2535 | 2531 |
| 2536 // The receiver is either the global receiver or an object found | 2532 // The receiver is either the global receiver or an object found |
| 2537 // by LoadContextSlot. | 2533 // by LoadContextSlot. |
| 2538 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); | 2534 EmitCallWithStub(expr); |
| 2539 } else if (property != NULL) { | 2535 } else if (property != NULL) { |
| 2540 { PreservePositionScope scope(masm()->positions_recorder()); | 2536 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2541 VisitForStackValue(property->obj()); | 2537 VisitForStackValue(property->obj()); |
| 2542 } | 2538 } |
| 2543 if (property->key()->IsPropertyName()) { | 2539 if (property->key()->IsPropertyName()) { |
| 2544 EmitCallWithIC(expr, | 2540 EmitCallWithIC(expr, |
| 2545 property->key()->AsLiteral()->value(), | 2541 property->key()->AsLiteral()->value(), |
| 2546 NOT_CONTEXTUAL); | 2542 NOT_CONTEXTUAL); |
| 2547 } else { | 2543 } else { |
| 2548 EmitKeyedCallWithIC(expr, property->key()); | 2544 EmitKeyedCallWithIC(expr, property->key()); |
| 2549 } | 2545 } |
| 2550 | 2546 |
| 2551 } else { | 2547 } else { |
| 2552 // Call to an arbitrary expression not handled specially above. | 2548 // Call to an arbitrary expression not handled specially above. |
| 2553 { PreservePositionScope scope(masm()->positions_recorder()); | 2549 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2554 VisitForStackValue(callee); | 2550 VisitForStackValue(callee); |
| 2555 } | 2551 } |
| 2556 __ LoadRoot(x1, Heap::kUndefinedValueRootIndex); | 2552 __ LoadRoot(x1, Heap::kUndefinedValueRootIndex); |
| 2557 __ Push(x1); | 2553 __ Push(x1); |
| 2558 // Emit function call. | 2554 // Emit function call. |
| 2559 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); | 2555 EmitCallWithStub(expr); |
| 2560 } | 2556 } |
| 2561 | 2557 |
| 2562 #ifdef DEBUG | 2558 #ifdef DEBUG |
| 2563 // RecordJSReturnSite should have been called. | 2559 // RecordJSReturnSite should have been called. |
| 2564 ASSERT(expr->return_is_recorded_); | 2560 ASSERT(expr->return_is_recorded_); |
| 2565 #endif | 2561 #endif |
| 2566 } | 2562 } |
| 2567 | 2563 |
| 2568 | 2564 |
| 2569 void FullCodeGenerator::VisitCallNew(CallNew* expr) { | 2565 void FullCodeGenerator::VisitCallNew(CallNew* expr) { |
| (...skipping 922 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3492 VisitForAccumulatorValue(args->last()); // Function. | 3488 VisitForAccumulatorValue(args->last()); // Function. |
| 3493 | 3489 |
| 3494 Label runtime, done; | 3490 Label runtime, done; |
| 3495 // Check for non-function argument (including proxy). | 3491 // Check for non-function argument (including proxy). |
| 3496 __ JumpIfSmi(x0, &runtime); | 3492 __ JumpIfSmi(x0, &runtime); |
| 3497 __ JumpIfNotObjectType(x0, x1, x1, JS_FUNCTION_TYPE, &runtime); | 3493 __ JumpIfNotObjectType(x0, x1, x1, JS_FUNCTION_TYPE, &runtime); |
| 3498 | 3494 |
| 3499 // InvokeFunction requires the function in x1. Move it in there. | 3495 // InvokeFunction requires the function in x1. Move it in there. |
| 3500 __ Mov(x1, x0); | 3496 __ Mov(x1, x0); |
| 3501 ParameterCount count(arg_count); | 3497 ParameterCount count(arg_count); |
| 3502 __ InvokeFunction(x1, count, CALL_FUNCTION, | 3498 __ InvokeFunction(x1, count, CALL_FUNCTION, NullCallWrapper()); |
| 3503 NullCallWrapper(), CALL_AS_FUNCTION); | |
| 3504 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3499 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 3505 __ B(&done); | 3500 __ B(&done); |
| 3506 | 3501 |
| 3507 __ Bind(&runtime); | 3502 __ Bind(&runtime); |
| 3508 __ Push(x0); | 3503 __ Push(x0); |
| 3509 __ CallRuntime(Runtime::kCall, args->length()); | 3504 __ CallRuntime(Runtime::kCall, args->length()); |
| 3510 __ Bind(&done); | 3505 __ Bind(&done); |
| 3511 | 3506 |
| 3512 context()->Plug(x0); | 3507 context()->Plug(x0); |
| 3513 } | 3508 } |
| (...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3891 } | 3886 } |
| 3892 | 3887 |
| 3893 int arg_count = args->length(); | 3888 int arg_count = args->length(); |
| 3894 for (int i = 0; i < arg_count; i++) { | 3889 for (int i = 0; i < arg_count; i++) { |
| 3895 VisitForStackValue(args->at(i)); | 3890 VisitForStackValue(args->at(i)); |
| 3896 } | 3891 } |
| 3897 | 3892 |
| 3898 if (expr->is_jsruntime()) { | 3893 if (expr->is_jsruntime()) { |
| 3899 // Call the JS runtime function. | 3894 // Call the JS runtime function. |
| 3900 __ Mov(x2, Operand(expr->name())); | 3895 __ Mov(x2, Operand(expr->name())); |
| 3901 ContextualMode mode = NOT_CONTEXTUAL; | 3896 Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize(arg_count); |
| 3902 Handle<Code> ic = | 3897 CallIC(ic, NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); |
| 3903 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); | |
| 3904 CallIC(ic, mode, expr->CallRuntimeFeedbackId()); | |
| 3905 // Restore context register. | 3898 // Restore context register. |
| 3906 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3899 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 3907 } else { | 3900 } else { |
| 3908 // Call the C runtime function. | 3901 // Call the C runtime function. |
| 3909 __ CallRuntime(expr->function(), arg_count); | 3902 __ CallRuntime(expr->function(), arg_count); |
| 3910 } | 3903 } |
| 3911 | 3904 |
| 3912 context()->Plug(x0); | 3905 context()->Plug(x0); |
| 3913 } | 3906 } |
| 3914 | 3907 |
| (...skipping 679 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4594 break; | 4587 break; |
| 4595 } | 4588 } |
| 4596 } | 4589 } |
| 4597 } | 4590 } |
| 4598 | 4591 |
| 4599 | 4592 |
| 4600 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, | 4593 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, |
| 4601 Expression *value, | 4594 Expression *value, |
| 4602 JSGeneratorObject::ResumeMode resume_mode) { | 4595 JSGeneratorObject::ResumeMode resume_mode) { |
| 4603 ASM_LOCATION("FullCodeGenerator::EmitGeneratorResume"); | 4596 ASM_LOCATION("FullCodeGenerator::EmitGeneratorResume"); |
| 4597 Register value_reg = x0; |
| 4604 Register generator_object = x1; | 4598 Register generator_object = x1; |
| 4605 Register the_hole = x2; | 4599 Register the_hole = x2; |
| 4606 Register operand_stack_size = w3; | 4600 Register operand_stack_size = w3; |
| 4607 Register function = x4; | 4601 Register function = x4; |
| 4608 | 4602 |
| 4609 // The value stays in x0, and is ultimately read by the resumed generator, as | 4603 // The value stays in x0, and is ultimately read by the resumed generator, as |
| 4610 // if the CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. x1 | 4604 // if the CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it |
| 4605 // is read to throw the value when the resumed generator is already closed. r1 |
| 4611 // will hold the generator object until the activation has been resumed. | 4606 // will hold the generator object until the activation has been resumed. |
| 4612 VisitForStackValue(generator); | 4607 VisitForStackValue(generator); |
| 4613 VisitForAccumulatorValue(value); | 4608 VisitForAccumulatorValue(value); |
| 4614 __ Pop(generator_object); | 4609 __ Pop(generator_object); |
| 4615 | 4610 |
| 4616 // Check generator state. | 4611 // Check generator state. |
| 4617 Label wrong_state, done; | 4612 Label wrong_state, closed_state, done; |
| 4618 __ Ldr(x10, FieldMemOperand(generator_object, | 4613 __ Ldr(x10, FieldMemOperand(generator_object, |
| 4619 JSGeneratorObject::kContinuationOffset)); | 4614 JSGeneratorObject::kContinuationOffset)); |
| 4620 STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting <= 0); | 4615 STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0); |
| 4621 STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed <= 0); | 4616 STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0); |
| 4622 __ CompareAndBranch(x10, Operand(Smi::FromInt(0)), le, &wrong_state); | 4617 __ CompareAndBranch(x10, Operand(Smi::FromInt(0)), eq, &closed_state); |
| 4618 __ CompareAndBranch(x10, Operand(Smi::FromInt(0)), lt, &wrong_state); |
| 4623 | 4619 |
| 4624 // Load suspended function and context. | 4620 // Load suspended function and context. |
| 4625 __ Ldr(cp, FieldMemOperand(generator_object, | 4621 __ Ldr(cp, FieldMemOperand(generator_object, |
| 4626 JSGeneratorObject::kContextOffset)); | 4622 JSGeneratorObject::kContextOffset)); |
| 4627 __ Ldr(function, FieldMemOperand(generator_object, | 4623 __ Ldr(function, FieldMemOperand(generator_object, |
| 4628 JSGeneratorObject::kFunctionOffset)); | 4624 JSGeneratorObject::kFunctionOffset)); |
| 4629 | 4625 |
| 4630 // Load receiver and store as the first argument. | 4626 // Load receiver and store as the first argument. |
| 4631 __ Ldr(x10, FieldMemOperand(generator_object, | 4627 __ Ldr(x10, FieldMemOperand(generator_object, |
| 4632 JSGeneratorObject::kReceiverOffset)); | 4628 JSGeneratorObject::kReceiverOffset)); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4701 __ Push(the_hole); | 4697 __ Push(the_hole); |
| 4702 __ B(&push_operand_holes); | 4698 __ B(&push_operand_holes); |
| 4703 | 4699 |
| 4704 __ Bind(&call_resume); | 4700 __ Bind(&call_resume); |
| 4705 __ Mov(x10, Operand(Smi::FromInt(resume_mode))); | 4701 __ Mov(x10, Operand(Smi::FromInt(resume_mode))); |
| 4706 __ Push(generator_object, result_register(), x10); | 4702 __ Push(generator_object, result_register(), x10); |
| 4707 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3); | 4703 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3); |
| 4708 // Not reached: the runtime call returns elsewhere. | 4704 // Not reached: the runtime call returns elsewhere. |
| 4709 __ Unreachable(); | 4705 __ Unreachable(); |
| 4710 | 4706 |
| 4707 // Reach here when generator is closed. |
| 4708 __ Bind(&closed_state); |
| 4709 if (resume_mode == JSGeneratorObject::NEXT) { |
| 4710 // Return completed iterator result when generator is closed. |
| 4711 __ LoadRoot(x10, Heap::kUndefinedValueRootIndex); |
| 4712 __ Push(x10); |
| 4713 // Pop value from top-of-stack slot; box result into result register. |
| 4714 EmitCreateIteratorResult(true); |
| 4715 } else { |
| 4716 // Throw the provided value. |
| 4717 __ Push(value_reg); |
| 4718 __ CallRuntime(Runtime::kThrow, 1); |
| 4719 } |
| 4720 __ B(&done); |
| 4721 |
| 4711 // Throw error if we attempt to operate on a running generator. | 4722 // Throw error if we attempt to operate on a running generator. |
| 4712 __ Bind(&wrong_state); | 4723 __ Bind(&wrong_state); |
| 4713 __ Push(generator_object); | 4724 __ Push(generator_object); |
| 4714 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1); | 4725 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1); |
| 4715 | 4726 |
| 4716 __ Bind(&done); | 4727 __ Bind(&done); |
| 4717 context()->Plug(result_register()); | 4728 context()->Plug(result_register()); |
| 4718 } | 4729 } |
| 4719 | 4730 |
| 4720 | 4731 |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5006 return previous_; | 5017 return previous_; |
| 5007 } | 5018 } |
| 5008 | 5019 |
| 5009 | 5020 |
| 5010 #undef __ | 5021 #undef __ |
| 5011 | 5022 |
| 5012 | 5023 |
| 5013 } } // namespace v8::internal | 5024 } } // namespace v8::internal |
| 5014 | 5025 |
| 5015 #endif // V8_TARGET_ARCH_A64 | 5026 #endif // V8_TARGET_ARCH_A64 |
| OLD | NEW |