OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_ARM64 | 7 #if V8_TARGET_ARCH_ARM64 |
8 | 8 |
9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 4915 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4926 break; | 4926 break; |
4927 } | 4927 } |
4928 } | 4928 } |
4929 } | 4929 } |
4930 | 4930 |
4931 | 4931 |
4932 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, | 4932 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, |
4933 Expression *value, | 4933 Expression *value, |
4934 JSGeneratorObject::ResumeMode resume_mode) { | 4934 JSGeneratorObject::ResumeMode resume_mode) { |
4935 ASM_LOCATION("FullCodeGenerator::EmitGeneratorResume"); | 4935 ASM_LOCATION("FullCodeGenerator::EmitGeneratorResume"); |
4936 Register value_reg = x0; | |
4937 Register generator_object = x1; | 4936 Register generator_object = x1; |
4938 Register the_hole = x2; | 4937 Register the_hole = x2; |
4939 Register operand_stack_size = w3; | 4938 Register operand_stack_size = w3; |
4940 Register function = x4; | 4939 Register function = x4; |
4941 | 4940 |
4942 // The value stays in x0, and is ultimately read by the resumed generator, as | 4941 // The value stays in x0, and is ultimately read by the resumed generator, as |
4943 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it | 4942 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it |
4944 // is read to throw the value when the resumed generator is already closed. x1 | 4943 // is read to throw the value when the resumed generator is already closed. x1 |
4945 // will hold the generator object until the activation has been resumed. | 4944 // will hold the generator object until the activation has been resumed. |
4946 VisitForStackValue(generator); | 4945 VisitForStackValue(generator); |
4947 VisitForAccumulatorValue(value); | 4946 VisitForAccumulatorValue(value); |
4948 __ Pop(generator_object); | 4947 __ Pop(generator_object); |
4949 | 4948 |
4950 // Check generator state. | |
4951 Label wrong_state, closed_state, done; | |
4952 __ Ldr(x10, FieldMemOperand(generator_object, | |
4953 JSGeneratorObject::kContinuationOffset)); | |
4954 STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0); | |
4955 STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0); | |
4956 __ CompareAndBranch(x10, Smi::FromInt(0), eq, &closed_state); | |
4957 __ CompareAndBranch(x10, Smi::FromInt(0), lt, &wrong_state); | |
4958 | |
4959 // Load suspended function and context. | 4949 // Load suspended function and context. |
4960 __ Ldr(cp, FieldMemOperand(generator_object, | 4950 __ Ldr(cp, FieldMemOperand(generator_object, |
4961 JSGeneratorObject::kContextOffset)); | 4951 JSGeneratorObject::kContextOffset)); |
4962 __ Ldr(function, FieldMemOperand(generator_object, | 4952 __ Ldr(function, FieldMemOperand(generator_object, |
4963 JSGeneratorObject::kFunctionOffset)); | 4953 JSGeneratorObject::kFunctionOffset)); |
4964 | 4954 |
4965 // Load receiver and store as the first argument. | 4955 // Load receiver and store as the first argument. |
4966 __ Ldr(x10, FieldMemOperand(generator_object, | 4956 __ Ldr(x10, FieldMemOperand(generator_object, |
4967 JSGeneratorObject::kReceiverOffset)); | 4957 JSGeneratorObject::kReceiverOffset)); |
4968 __ Push(x10); | 4958 __ Push(x10); |
4969 | 4959 |
4970 // Push holes for the rest of the arguments to the generator function. | 4960 // Push holes for the rest of the arguments to the generator function. |
4971 __ Ldr(x10, FieldMemOperand(function, JSFunction::kSharedFunctionInfoOffset)); | 4961 __ Ldr(x10, FieldMemOperand(function, JSFunction::kSharedFunctionInfoOffset)); |
4972 | 4962 |
4973 // The number of arguments is stored as an int32_t, and -1 is a marker | 4963 // The number of arguments is stored as an int32_t, and -1 is a marker |
4974 // (SharedFunctionInfo::kDontAdaptArgumentsSentinel), so we need sign | 4964 // (SharedFunctionInfo::kDontAdaptArgumentsSentinel), so we need sign |
4975 // extension to correctly handle it. However, in this case, we operate on | 4965 // extension to correctly handle it. However, in this case, we operate on |
4976 // 32-bit W registers, so extension isn't required. | 4966 // 32-bit W registers, so extension isn't required. |
4977 __ Ldr(w10, FieldMemOperand(x10, | 4967 __ Ldr(w10, FieldMemOperand(x10, |
4978 SharedFunctionInfo::kFormalParameterCountOffset)); | 4968 SharedFunctionInfo::kFormalParameterCountOffset)); |
4979 __ LoadRoot(the_hole, Heap::kTheHoleValueRootIndex); | 4969 __ LoadRoot(the_hole, Heap::kTheHoleValueRootIndex); |
4980 __ PushMultipleTimes(the_hole, w10); | 4970 __ PushMultipleTimes(the_hole, w10); |
4981 | 4971 |
4982 // Enter a new JavaScript frame, and initialize its slots as they were when | 4972 // Enter a new JavaScript frame, and initialize its slots as they were when |
4983 // the generator was suspended. | 4973 // the generator was suspended. |
4984 Label resume_frame; | 4974 Label resume_frame, done; |
4985 __ Bl(&resume_frame); | 4975 __ Bl(&resume_frame); |
4986 __ B(&done); | 4976 __ B(&done); |
4987 | 4977 |
4988 __ Bind(&resume_frame); | 4978 __ Bind(&resume_frame); |
4989 __ Push(lr, // Return address. | 4979 __ Push(lr, // Return address. |
4990 fp, // Caller's frame pointer. | 4980 fp, // Caller's frame pointer. |
4991 cp, // Callee's context. | 4981 cp, // Callee's context. |
4992 function); // Callee's JS Function. | 4982 function); // Callee's JS Function. |
4993 __ Add(fp, __ StackPointer(), kPointerSize * 2); | 4983 __ Add(fp, __ StackPointer(), kPointerSize * 2); |
4994 | 4984 |
(...skipping 24 matching lines...) Expand all Loading... |
5019 // Otherwise, we push holes for the operand stack and call the runtime to fix | 5009 // Otherwise, we push holes for the operand stack and call the runtime to fix |
5020 // up the stack and the handlers. | 5010 // up the stack and the handlers. |
5021 __ PushMultipleTimes(the_hole, operand_stack_size); | 5011 __ PushMultipleTimes(the_hole, operand_stack_size); |
5022 | 5012 |
5023 __ Mov(x10, Smi::FromInt(resume_mode)); | 5013 __ Mov(x10, Smi::FromInt(resume_mode)); |
5024 __ Push(generator_object, result_register(), x10); | 5014 __ Push(generator_object, result_register(), x10); |
5025 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3); | 5015 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3); |
5026 // Not reached: the runtime call returns elsewhere. | 5016 // Not reached: the runtime call returns elsewhere. |
5027 __ Unreachable(); | 5017 __ Unreachable(); |
5028 | 5018 |
5029 // Reach here when generator is closed. | |
5030 __ Bind(&closed_state); | |
5031 if (resume_mode == JSGeneratorObject::NEXT) { | |
5032 // Return completed iterator result when generator is closed. | |
5033 __ LoadRoot(x10, Heap::kUndefinedValueRootIndex); | |
5034 __ Push(x10); | |
5035 // Pop value from top-of-stack slot; box result into result register. | |
5036 EmitCreateIteratorResult(true); | |
5037 } else { | |
5038 // Throw the provided value. | |
5039 __ Push(value_reg); | |
5040 __ CallRuntime(Runtime::kThrow, 1); | |
5041 } | |
5042 __ B(&done); | |
5043 | |
5044 // Throw error if we attempt to operate on a running generator. | |
5045 __ Bind(&wrong_state); | |
5046 __ Push(generator_object); | |
5047 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1); | |
5048 | |
5049 __ Bind(&done); | 5019 __ Bind(&done); |
5050 context()->Plug(result_register()); | 5020 context()->Plug(result_register()); |
5051 } | 5021 } |
5052 | 5022 |
5053 | 5023 |
5054 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { | 5024 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { |
5055 Label gc_required; | 5025 Label gc_required; |
5056 Label allocated; | 5026 Label allocated; |
5057 | 5027 |
5058 const int instance_size = 5 * kPointerSize; | 5028 const int instance_size = 5 * kPointerSize; |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5347 return previous_; | 5317 return previous_; |
5348 } | 5318 } |
5349 | 5319 |
5350 | 5320 |
5351 #undef __ | 5321 #undef __ |
5352 | 5322 |
5353 | 5323 |
5354 } } // namespace v8::internal | 5324 } } // namespace v8::internal |
5355 | 5325 |
5356 #endif // V8_TARGET_ARCH_ARM64 | 5326 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |