1/* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "builtins_generator.h" 17 18#include "ecmascript/js_generator_object.h" 19 20namespace panda::ecmascript::builtins { 21// 26.2.1.1 GeneratorFunction(p1, p2, … , pn, body) 22JSTaggedValue BuiltinsGenerator::GeneratorFunctionConstructor(EcmaRuntimeCallInfo *argv) 23{ 24 BUILTINS_API_TRACE(argv->GetThread(), Generator, Constructor); 25 // not support 26 THROW_TYPE_ERROR_AND_RETURN(argv->GetThread(), "Not support eval. Forbidden using new GeneratorFunction().", 27 JSTaggedValue::Exception()); 28} 29 30// 26.4.1.2 Generator.prototype.next(value) 31JSTaggedValue BuiltinsGenerator::GeneratorPrototypeNext(EcmaRuntimeCallInfo *argv) 32{ 33 BUILTINS_API_TRACE(argv->GetThread(), Generator, PrototypeNext); 34 // 1.Let g be the this value. 35 JSThread *thread = argv->GetThread(); 36 [[maybe_unused]] EcmaHandleScope handleScope(thread); 37 JSHandle<JSTaggedValue> msg = GetThis(argv); 38 if (!msg->IsGeneratorObject()) { 39 THROW_TYPE_ERROR_AND_RETURN(thread, "Not a generator object.", JSTaggedValue::Exception()); 40 } 41 JSHandle<JSGeneratorObject> generator(thread, JSGeneratorObject::Cast(*JSTaggedValue::ToObject(thread, msg))); 42 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 43 JSHandle<JSTaggedValue> value = GetCallArg(argv, 0); 44 45 // 2.Return ? GeneratorResume(g, value). 46 JSHandle<JSObject> result = JSGeneratorObject::GeneratorResume(thread, generator, value.GetTaggedValue()); 47 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 48 return result.GetTaggedValue(); 49} 50 51// 26.4.1.3 Generator.prototype.return(value) 52JSTaggedValue BuiltinsGenerator::GeneratorPrototypeReturn(EcmaRuntimeCallInfo *argv) 53{ 54 BUILTINS_API_TRACE(argv->GetThread(), Generator, PrototypeReturn); 55 // 1.Let g be the this value. 56 JSThread *thread = argv->GetThread(); 57 [[maybe_unused]] EcmaHandleScope handleScope(thread); 58 JSHandle<JSTaggedValue> msg = GetThis(argv); 59 if (!msg->IsGeneratorObject()) { 60 THROW_TYPE_ERROR_AND_RETURN(thread, "Not a generator object.", JSTaggedValue::Exception()); 61 } 62 JSHandle<JSGeneratorObject> generator(thread, JSGeneratorObject::Cast(*JSTaggedValue::ToObject(thread, msg))); 63 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 64 // 2.Let C be Completion { [[Type]]: return, [[Value]]: value, [[Target]]: empty }. 65 JSHandle<JSTaggedValue> value = GetCallArg(argv, 0); 66 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 67 JSHandle<CompletionRecord> completionRecord = 68 factory->NewCompletionRecord(CompletionRecordType::RETURN, value); 69 70 // 3.Return ? GeneratorResumeAbrupt(g, C). 71 JSHandle<JSObject> result = JSGeneratorObject::GeneratorResumeAbrupt(thread, generator, completionRecord); 72 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 73 return result.GetTaggedValue(); 74} 75 76// 26.4.1.4 Generator.prototype.throw(exception) 77JSTaggedValue BuiltinsGenerator::GeneratorPrototypeThrow(EcmaRuntimeCallInfo *argv) 78{ 79 BUILTINS_API_TRACE(argv->GetThread(), Generator, PrototypeThrow); 80 // 1.Let g be the this value. 81 JSThread *thread = argv->GetThread(); 82 [[maybe_unused]] EcmaHandleScope handleScope(thread); 83 JSHandle<JSTaggedValue> msg = GetThis(argv); 84 if (!msg->IsGeneratorObject()) { 85 THROW_TYPE_ERROR_AND_RETURN(thread, "Not a generator object.", JSTaggedValue::Exception()); 86 } 87 JSHandle<JSGeneratorObject> generator(thread, JSGeneratorObject::Cast(*JSTaggedValue::ToObject(thread, msg))); 88 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 89 // 2.Let C be ThrowCompletion(exception). 90 JSHandle<JSTaggedValue> exception = GetCallArg(argv, 0); 91 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 92 JSHandle<CompletionRecord> completionRecord = 93 factory->NewCompletionRecord(CompletionRecordType::THROW, exception); 94 95 // 3.Return ? GeneratorResumeAbrupt(g, C). 96 JSHandle<JSObject> result = JSGeneratorObject::GeneratorResumeAbrupt(thread, generator, completionRecord); 97 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 98 return result.GetTaggedValue(); 99} 100} // namespace panda::ecmascript::builtins 101