| 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 |