| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/runtime/runtime-utils.h" | 5 #include "src/runtime/runtime-utils.h" |
| 6 | 6 |
| 7 #include "src/arguments.h" | 7 #include "src/arguments.h" |
| 8 #include "src/factory.h" | 8 #include "src/factory.h" |
| 9 #include "src/frames-inl.h" | 9 #include "src/frames-inl.h" |
| 10 #include "src/objects-inl.h" | 10 #include "src/objects-inl.h" |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 } else { | 65 } else { |
| 66 Handle<FixedArray> operand_stack = | 66 Handle<FixedArray> operand_stack = |
| 67 isolate->factory()->NewFixedArray(operands_count); | 67 isolate->factory()->NewFixedArray(operands_count); |
| 68 frame->SaveOperandStack(*operand_stack); | 68 frame->SaveOperandStack(*operand_stack); |
| 69 generator_object->set_operand_stack(*operand_stack); | 69 generator_object->set_operand_stack(*operand_stack); |
| 70 } | 70 } |
| 71 | 71 |
| 72 return isolate->heap()->undefined_value(); | 72 return isolate->heap()->undefined_value(); |
| 73 } | 73 } |
| 74 | 74 |
| 75 | |
| 76 // Note that this function is the slow path for resuming generators. It is only | |
| 77 // called if the suspended activation had operands on the stack, stack handlers | |
| 78 // needing rewinding, or if the resume should throw an exception. The fast path | |
| 79 // is handled directly in FullCodeGenerator::EmitGeneratorResume(), which is | |
| 80 // inlined into GeneratorNext, GeneratorReturn, and GeneratorThrow. | |
| 81 // EmitGeneratorResume is called in any case, as it needs to reconstruct the | |
| 82 // stack frame and make space for arguments and operands. | |
| 83 RUNTIME_FUNCTION(Runtime_ResumeJSGeneratorObject) { | |
| 84 SealHandleScope shs(isolate); | |
| 85 DCHECK(args.length() == 3); | |
| 86 CONVERT_ARG_CHECKED(JSGeneratorObject, generator_object, 0); | |
| 87 CONVERT_ARG_CHECKED(Object, value, 1); | |
| 88 CONVERT_SMI_ARG_CHECKED(resume_mode_int, 2); | |
| 89 JavaScriptFrameIterator stack_iterator(isolate); | |
| 90 JavaScriptFrame* frame = stack_iterator.frame(); | |
| 91 | |
| 92 DCHECK_EQ(frame->function(), generator_object->function()); | |
| 93 DCHECK(frame->function()->shared()->is_compiled()); | |
| 94 DCHECK(!frame->function()->IsOptimized()); | |
| 95 | |
| 96 STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0); | |
| 97 STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0); | |
| 98 | |
| 99 Code* code = generator_object->function()->shared()->code(); | |
| 100 int offset = generator_object->continuation(); | |
| 101 DCHECK_GT(offset, 0); | |
| 102 frame->set_pc(code->instruction_start() + offset); | |
| 103 if (FLAG_enable_embedded_constant_pool) { | |
| 104 frame->set_constant_pool(code->constant_pool()); | |
| 105 } | |
| 106 generator_object->set_continuation(JSGeneratorObject::kGeneratorExecuting); | |
| 107 | |
| 108 FixedArray* operand_stack = generator_object->operand_stack(); | |
| 109 int operands_count = operand_stack->length(); | |
| 110 if (operands_count != 0) { | |
| 111 frame->RestoreOperandStack(operand_stack); | |
| 112 generator_object->set_operand_stack(isolate->heap()->empty_fixed_array()); | |
| 113 } | |
| 114 | |
| 115 JSGeneratorObject::ResumeMode resume_mode = | |
| 116 static_cast<JSGeneratorObject::ResumeMode>(resume_mode_int); | |
| 117 switch (resume_mode) { | |
| 118 // Note: this looks like NEXT and RETURN are the same but RETURN receives | |
| 119 // special treatment in the generator code (to which we return here). | |
| 120 case JSGeneratorObject::NEXT: | |
| 121 case JSGeneratorObject::RETURN: | |
| 122 return value; | |
| 123 case JSGeneratorObject::THROW: | |
| 124 return isolate->Throw(value); | |
| 125 } | |
| 126 | |
| 127 UNREACHABLE(); | |
| 128 return isolate->ThrowIllegalOperation(); | |
| 129 } | |
| 130 | |
| 131 | |
| 132 RUNTIME_FUNCTION(Runtime_GeneratorClose) { | 75 RUNTIME_FUNCTION(Runtime_GeneratorClose) { |
| 133 HandleScope scope(isolate); | 76 HandleScope scope(isolate); |
| 134 DCHECK(args.length() == 1); | 77 DCHECK(args.length() == 1); |
| 135 CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0); | 78 CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0); |
| 136 | 79 |
| 137 generator->set_continuation(JSGeneratorObject::kGeneratorClosed); | 80 generator->set_continuation(JSGeneratorObject::kGeneratorClosed); |
| 138 | 81 |
| 139 return isolate->heap()->undefined_value(); | 82 return isolate->heap()->undefined_value(); |
| 140 } | 83 } |
| 141 | 84 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 188 if (generator->is_suspended()) { | 131 if (generator->is_suspended()) { |
| 189 Handle<Code> code(generator->function()->code(), isolate); | 132 Handle<Code> code(generator->function()->code(), isolate); |
| 190 int offset = generator->continuation(); | 133 int offset = generator->continuation(); |
| 191 RUNTIME_ASSERT(0 <= offset && offset < code->instruction_size()); | 134 RUNTIME_ASSERT(0 <= offset && offset < code->instruction_size()); |
| 192 return Smi::FromInt(code->SourcePosition(offset)); | 135 return Smi::FromInt(code->SourcePosition(offset)); |
| 193 } | 136 } |
| 194 | 137 |
| 195 return isolate->heap()->undefined_value(); | 138 return isolate->heap()->undefined_value(); |
| 196 } | 139 } |
| 197 | 140 |
| 198 // Optimization for builtins calling any of the following three functions is | |
| 199 // disabled in js/generator.js and compiler.cc, hence they are unreachable. | |
| 200 | |
| 201 RUNTIME_FUNCTION(Runtime_GeneratorNext) { | |
| 202 UNREACHABLE(); | |
| 203 return nullptr; | |
| 204 } | |
| 205 | |
| 206 RUNTIME_FUNCTION(Runtime_GeneratorReturn) { | |
| 207 UNREACHABLE(); | |
| 208 return nullptr; | |
| 209 } | |
| 210 | |
| 211 RUNTIME_FUNCTION(Runtime_GeneratorThrow) { | |
| 212 UNREACHABLE(); | |
| 213 return nullptr; | |
| 214 } | |
| 215 | |
| 216 } // namespace internal | 141 } // namespace internal |
| 217 } // namespace v8 | 142 } // namespace v8 |
| OLD | NEW |