1 /*
2 * Copyright (c) 2021-2022 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 "generatorFunctionBuilder.h"
17
18 #include <compiler/core/pandagen.h>
19 #include <compiler/base/catchTable.h>
20 #include <ir/base/scriptFunction.h>
21
22 namespace panda::es2panda::compiler {
23
Prepare(const ir::ScriptFunction * node)24 void GeneratorFunctionBuilder::Prepare(const ir::ScriptFunction *node)
25 {
26 VReg callee = FunctionReg(node);
27 VReg completionType = pg_->AllocReg();
28 VReg completionValue = pg_->AllocReg();
29
30 pg_->CreateGeneratorObj(node, callee);
31 pg_->StoreAccumulator(node, funcObj_);
32 pg_->LoadConst(node, Constant::JS_UNDEFINED);
33 SuspendResumeExecution(node, completionType, completionValue);
34 HandleCompletion(node, completionType, completionValue);
35 }
36
CleanUp(const ir::ScriptFunction * node) const37 void GeneratorFunctionBuilder::CleanUp(const ir::ScriptFunction *node) const
38 {
39 const auto &labelSet = catchTable_->LabelSet();
40
41 pg_->SetLabel(node, labelSet.TryEnd());
42 pg_->SetLabel(node, labelSet.CatchBegin());
43 pg_->EmitThrow(node);
44 pg_->SetLabel(node, labelSet.CatchEnd());
45 }
46
DirectReturn(const ir::AstNode * node) const47 void GeneratorFunctionBuilder::DirectReturn(const ir::AstNode *node) const
48 {
49 pg_->EmitReturn(node);
50 }
51
ImplicitReturn(const ir::AstNode * node) const52 void GeneratorFunctionBuilder::ImplicitReturn(const ir::AstNode *node) const
53 {
54 pg_->SetSourceLocationFlag(lexer::SourceLocationFlag::INVALID_SOURCE_LOCATION);
55 pg_->LoadConst(node, Constant::JS_UNDEFINED);
56 pg_->SetSourceLocationFlag(lexer::SourceLocationFlag::VALID_SOURCE_LOCATION);
57 DirectReturn(node);
58 }
59
ExplicitReturn(const ir::AstNode * node) const60 void GeneratorFunctionBuilder::ExplicitReturn(const ir::AstNode *node) const
61 {
62 DirectReturn(node);
63 }
64
Yield(const ir::AstNode * node)65 void GeneratorFunctionBuilder::Yield(const ir::AstNode *node)
66 {
67 RegScope rs(pg_);
68 VReg value = pg_->AllocReg();
69 VReg done = pg_->AllocReg();
70 VReg completionType = pg_->AllocReg();
71 VReg completionValue = pg_->AllocReg();
72
73 pg_->StoreAccumulator(node, value);
74 pg_->LoadConst(node, Constant::JS_FALSE);
75 pg_->StoreAccumulator(node, done);
76 pg_->CreateIterResultObject(node, value, done);
77 SuspendResumeExecution(node, completionType, completionValue);
78
79 HandleCompletion(node, completionType, completionValue);
80 }
81
82 } // namespace panda::es2panda::compiler
83