• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2025 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 #ifndef ES2PANDA_COMPILER_CORE_PANDAGEN_H
17 #define ES2PANDA_COMPILER_CORE_PANDAGEN_H
18 
19 #include "compiler/core/codeGen.h"
20 #include "compiler/base/optionalChain.h"
21 #include "compiler/core/envScope.h"
22 #include "compiler/core/function.h"
23 
24 #include "compiler/core/regAllocator.h"
25 #include "compiler/core/regScope.h"
26 #include "ir/irnode.h"
27 #include "generated/tokenType.h"
28 #include "util/es2pandaMacros.h"
29 
30 #include <unordered_map>
31 
32 namespace ark::es2panda::varbinder {
33 class FunctionScope;
34 class Scope;
35 }  // namespace ark::es2panda::varbinder
36 
37 namespace ark::es2panda::ir {
38 class AstNode;
39 class ScriptFunction;
40 class Statement;
41 class Expression;
42 class Identifier;
43 }  // namespace ark::es2panda::ir
44 
45 namespace ark::es2panda::compiler {
46 class FunctionBuilder;
47 class DynamicContext;
48 
49 class PandaGen final : public CodeGen {
50 public:
51     explicit PandaGen(ArenaAllocator *allocator, RegSpiller *spiller, public_lib::Context *context,
52                       std::tuple<varbinder::FunctionScope *, ProgramElement *, AstCompiler *> toCompile);
53 
54     ~PandaGen() override = default;
55     NO_COPY_SEMANTIC(PandaGen);
56     NO_MOVE_SEMANTIC(PandaGen);
57 
58     [[nodiscard]] FunctionBuilder *FuncBuilder() const noexcept;
59     [[nodiscard]] EnvScope *GetEnvScope() const noexcept;
60 
61     void OptionalChainCheck(bool optional, VReg obj) const;
62 
63     [[nodiscard]] VReg LexEnv() const noexcept;
64 
65     bool FunctionHasFinalizer() const;
66     void FunctionInit(CatchTable *catchTable);
67     void FunctionEnter();
68     void FunctionExit();
69 
70     void StoreAccumulator(const ir::AstNode *node, VReg vreg);
71     void LoadAccumulator(const ir::AstNode *node, VReg reg);
72 
73     [[nodiscard]] IRNode *AllocMov(const ir::AstNode *node, VReg vd, VReg vs) override;
74     [[nodiscard]] IRNode *AllocMov(const ir::AstNode *node, OutVReg vd, VReg vs) override;
75     void MoveVreg(const ir::AstNode *node, VReg vd, VReg vs);
76 
77     void LoadAccumulatorDouble(const ir::AstNode *node, double num);
78     void LoadAccumulatorInt(const ir::AstNode *node, size_t num);
79 
80     void LoadConst(const ir::AstNode *node, Constant id);
81     void StoreConst(const ir::AstNode *node, VReg reg, Constant id);
82 
83     void GetFunctionObject(const ir::AstNode *node);
84     void GetNewTarget(const ir::AstNode *node);
85     void GetThis(const ir::AstNode *node);
86     void SetThis(const ir::AstNode *node);
87     void LoadVar(const ir::Identifier *node, const varbinder::ConstScopeFindResult &result);
88     void StoreVar(const ir::AstNode *node, const varbinder::ConstScopeFindResult &result, bool isDeclaration);
89 
90     void LoadAccFromArgs(const ir::AstNode *node);
91     void LoadObjProperty(const ir::AstNode *node, const Operand &prop);
92 
93     void LoadObjByName(const ir::AstNode *node, const util::StringView &prop);
94 
95     void StoreObjProperty(const ir::AstNode *node, VReg obj, const Operand &prop);
96     void StoreOwnProperty(const ir::AstNode *node, VReg obj, const Operand &prop);
97     void DeleteObjProperty(const ir::AstNode *node, VReg obj, VReg prop);
98     void LoadGlobalVar(const ir::AstNode *node, const util::StringView &name);
99     void StoreGlobalVar(const ir::AstNode *node, const util::StringView &name);
100     void StoreGlobalLet(const ir::AstNode *node, const util::StringView &name);
101 
102     void TryLoadGlobalByName(const ir::AstNode *node, const util::StringView &name);
103     void TryStoreGlobalByName(const ir::AstNode *node, const util::StringView &name);
104 
105     void LoadAccFromLexEnv(const ir::AstNode *node, const varbinder::ConstScopeFindResult &result);
106     void StoreAccToLexEnv(const ir::AstNode *node, const varbinder::ConstScopeFindResult &result, bool isDeclaration);
107 
108     void LoadAccumulatorBigInt(const ir::AstNode *node, const util::StringView &bigInt);
109 
110     void Condition(const ir::AstNode *node, lexer::TokenType op, VReg lhs, class Label *ifFalse);
111     void Unary(const ir::AstNode *node, lexer::TokenType op, VReg operand);
112     void Binary(const ir::AstNode *node, lexer::TokenType op, VReg lhs);
113 
114     void BranchIfUndefined(const ir::AstNode *node, class Label *target);
115     void BranchIfNotUndefined(const ir::AstNode *node, class Label *target);
116     void BranchIfHole(const ir::AstNode *node, class Label *target);
117 
118     void BranchIfTrue(const ir::AstNode *node, class Label *target);
119     void BranchIfNotTrue(const ir::AstNode *node, class Label *target);
120     void BranchIfFalse(const ir::AstNode *node, class Label *target);
121     void BranchIfCoercible(const ir::AstNode *node, class Label *target);
122 
123     void EmitThrow(const ir::AstNode *node);
124     void EmitRethrow(const ir::AstNode *node);
125     void EmitReturn(const ir::AstNode *node);
126     void EmitReturnUndefined(const ir::AstNode *node);
127     void ValidateClassDirectReturn(const ir::AstNode *node);
128     void DirectReturn(const ir::AstNode *node);
129     void ImplicitReturn(const ir::AstNode *node);
130     void EmitAwait(const ir::AstNode *node);
131 
132     static constexpr auto MAX_RANGE_CALL_ARG = 128;
133     void CallTagged(const ir::AstNode *node, VReg callee, VReg thisReg, const ArenaVector<ir::Expression *> &arguments);
134     void Call(const ir::AstNode *node, VReg callee, VReg thisReg, const ArenaVector<ir::Expression *> &arguments);
135     void Call0This(const ir::AstNode *node, VReg callee, VReg thisReg);
136     void Call1This(const ir::AstNode *node, VReg callee, VReg thisReg, VReg arg0);
137 
138     void CallSpread(const ir::AstNode *node, VReg func, VReg thisReg, VReg args);
139     void SuperCall(const ir::AstNode *node, VReg startReg, size_t argCount);
140     void SuperCallSpread(const ir::AstNode *node, VReg vs);
141 
142     void LoadHomeObject(const ir::AstNode *node);
143     void NewObject(const ir::AstNode *node, VReg startReg, size_t argCount);
144     void DefineMethod(const ir::AstNode *node, const util::StringView &name);
145     void DefineFunction(const ir::AstNode *node, const ir::ScriptFunction *realNode, const util::StringView &name);
146 
147     void TypeOf(const ir::AstNode *node);
148     void NewObjSpread(const ir::AstNode *node, VReg obj, VReg target);
149     void GetUnmappedArgs(const ir::AstNode *node);
150 
151     void Negate(const ir::AstNode *node);
152     void ToBoolean(const ir::AstNode *node);
153     void ToNumber(const ir::AstNode *node, VReg arg);
154 
155     void CreateGeneratorObj(const ir::AstNode *node, VReg funcObj);
156     void ResumeGenerator(const ir::AstNode *node, VReg genObj);
157     void GetResumeMode(const ir::AstNode *node, VReg genObj);
158 
159     void AsyncFunctionEnter(const ir::AstNode *node);
160     void AsyncFunctionAwait(const ir::AstNode *node, VReg asyncFuncObj);
161     void AsyncFunctionResolve(const ir::AstNode *node, VReg asyncFuncObj);
162     void AsyncFunctionReject(const ir::AstNode *node, VReg asyncFuncObj);
163 
164     void GetMethod(const ir::AstNode *node, VReg obj, const util::StringView &name);
165     void GeneratorYield(const ir::AstNode *node, VReg genObj);
166     void GeneratorComplete(const ir::AstNode *node, VReg genObj);
167     void CreateAsyncGeneratorObj(const ir::AstNode *node, VReg funcObj);
168     void CreateIterResultObject(const ir::AstNode *node, bool done);
169     void SuspendGenerator(const ir::AstNode *node, VReg genObj);
170     void SuspendAsyncGenerator(const ir::AstNode *node, VReg asyncGenObj);
171 
172     void AsyncGeneratorResolve(const ir::AstNode *node, VReg asyncGenObj);
173     void AsyncGeneratorReject(const ir::AstNode *node, VReg asyncGenObj);
174 
175     void GetTemplateObject(const ir::AstNode *node, VReg value);
176     void CopyRestArgs(const ir::AstNode *node, uint32_t index);
177 
178     void GetPropIterator(const ir::AstNode *node);
179     void GetNextPropName(const ir::AstNode *node, VReg iter);
180     void CreateEmptyObject(const ir::AstNode *node);
181     void CreateObjectWithBuffer(const ir::AstNode *node, uint32_t idx);
182     void CreateObjectHavingMethod(const ir::AstNode *node, uint32_t idx);
183     void SetObjectWithProto(const ir::AstNode *node, VReg proto, VReg obj);
184     void CopyDataProperties(const ir::AstNode *node, VReg dst, VReg src);
185     void DefineGetterSetterByValue(const ir::AstNode *node, std::tuple<VReg, VReg, VReg, VReg> registers, bool setName);
186     void CreateEmptyArray(const ir::AstNode *node);
187     size_t HandleArrayLiterals(const ir::AstNode *node, const ArenaVector<ir::Expression *> &elements);
188     void HandleArraySpread(const ir::AstNode *node, const ArenaVector<ir::Expression *> &elements, VReg obj);
189     void CreateArray(const ir::AstNode *node, const ArenaVector<ir::Expression *> &elements, VReg obj);
190     void CreateArrayWithBuffer(const ir::AstNode *node, uint32_t idx);
191     void StoreArraySpread(const ir::AstNode *node, VReg array, VReg index);
192 
193     void CreateRegExpWithLiteral(const ir::AstNode *node, const util::StringView &pattern, uint8_t flags);
194 
195     void ThrowIfNotObject(const ir::AstNode *node);
196     void ThrowThrowNotExist(const ir::AstNode *node);
197     void GetIterator(const ir::AstNode *node);
198     void GetAsyncIterator(const ir::AstNode *node);
199 
200     void CreateObjectWithExcludedKeys(const ir::AstNode *node, VReg obj, VReg argStart, size_t argCount);
201     void ThrowObjectNonCoercible(const ir::AstNode *node);
202     void CloseIterator(const ir::AstNode *node, VReg iter);
203     void SetClassComputedFields(const ir::AstNode *node, VReg classReg, VReg computedInstanceFieldArray);
204     void DefineClassWithBuffer(const ir::AstNode *node, const util::StringView &ctorId, uint32_t litIdx, VReg lexenv,
205                                VReg base);
206     void LoadClassComputedInstanceFields(const ir::AstNode *node, VReg ctor);
207     void DefineClassPrivateFields(const ir::AstNode *node, uint32_t privateBufIdx);
208     void ClassFieldAdd(const ir::AstNode *node, VReg obj, VReg prop);
209     void ClassPrivateFieldAdd(const ir::AstNode *node, VReg ctor, VReg obj, const util::StringView &prop);
210     void ClassPrivateMethodOrAccessorAdd(const ir::AstNode *node, VReg ctor, VReg obj);
211     void ClassPrivateFieldGet(const ir::AstNode *node, VReg ctor, VReg obj, const util::StringView &prop);
212     void ClassPrivateFieldSet(const ir::AstNode *node, VReg ctor, VReg obj, const util::StringView &prop);
213     void ClassPrivateFieldIn(const ir::AstNode *node, VReg ctor, const util::StringView &prop);
214 
215     void ImportModule(const ir::AstNode *node, const util::StringView &name);
216     void LoadModuleVariable(const ir::AstNode *node, VReg module, const util::StringView &name);
217     void StoreModuleVar(const ir::AstNode *node, const util::StringView &name);
218     void CopyModule(const ir::AstNode *node, VReg module);
219 
220     void StSuperByName(const ir::AstNode *node, VReg obj, const util::StringView &key);
221     void LdSuperByName(const ir::AstNode *node, const util::StringView &key);
222     void StSuperByValue(const ir::AstNode *node, VReg obj, VReg prop);
223     void LdSuperByValue(const ir::AstNode *node, VReg obj);
224     void StoreSuperProperty(const ir::AstNode *node, VReg obj, const Operand &prop);
225     void LoadSuperProperty(const ir::AstNode *node, const Operand &prop);
226 
227     void LdLexEnv(const ir::AstNode *node);
228     void PopLexEnv(const ir::AstNode *node);
229     void CopyLexEnv(const ir::AstNode *node);
230     void NewLexEnv(const ir::AstNode *node, uint32_t num);
231     void LoadLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot);
232     void LoadLexical(const ir::AstNode *node, const util::StringView &name, uint32_t level, uint32_t slot);
233     void StoreLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot);
234     void StoreLexical(const ir::AstNode *node, const util::StringView &name, uint32_t level, uint32_t slot);
235 
236     void ThrowIfSuperNotCorrectCall(const ir::AstNode *node, int64_t num);
237     void ThrowTdz(const ir::AstNode *node, const util::StringView &name);
238     void ThrowConstAssignment(const ir::AstNode *node, const util::StringView &name);
239 
240     void LoadObjByIndex(const ir::AstNode *node, int64_t index);
241     void LoadObjByValue(const ir::AstNode *node, VReg obj);
242 
243     void StoreObjByName(const ir::AstNode *node, VReg obj, const util::StringView &prop);
244     void StoreObjByIndex(const ir::AstNode *node, VReg obj, int64_t index);
245     void StoreObjByValue(const ir::AstNode *node, VReg obj, VReg prop);
246 
247     void StOwnByName(const ir::AstNode *node, VReg obj, const util::StringView &prop);
248     void StOwnByValue(const ir::AstNode *node, VReg obj, VReg prop);
249     void StOwnByIndex(const ir::AstNode *node, VReg obj, int64_t index);
250 
251     static Operand ToNamedPropertyKey(const ir::Expression *prop, bool isComputed);
252     void LoadPropertyKeyAcc(const ir::Expression *prop, bool isComputed);
253     Operand ToPropertyKey(const ir::Expression *prop, bool isComputed, bool isSuperExpression = false);
254     Operand ToOwnPropertyKey(const ir::Expression *prop, bool isComputed);
255     VReg LoadPropertyKey(const ir::Expression *prop, bool isComputed);
256 
257     void LoadEvalVariable(const ir::AstNode *node, const util::StringView &name);
258     void StoreEvalVariable(const ir::AstNode *node, const util::StringView &name);
259     void DirectEval(const ir::AstNode *node, uint32_t parserStatus);
260     void LoadLexicalContext(const ir::AstNode *node);
261     bool IsDirectEval() const;
262     bool IsEval() const;
263 
264     const checker::Type *GetVRegType(VReg vreg) const override;
265 
266 private:
267     void LoadEvalBindings(const ir::AstNode *node);
268     void Call0Args(const ir::AstNode *n, VReg c, VReg thisR, bool hasThis);
269     void Call1Arg(const ir::AstNode *n, VReg c, VReg thisR, const ArenaVector<ir::Expression *> &args, bool hasThis);
270     void Call2Args(const ir::AstNode *n, VReg c, VReg thisR, const ArenaVector<ir::Expression *> &args, bool hasThis);
271     void Call3Args(const ir::AstNode *n, VReg c, VReg thisR, const ArenaVector<ir::Expression *> &args, bool hasThis);
272     bool CallArgsTagged(const ir::AstNode *node, VReg callee, VReg thisReg,
273                         const ArenaVector<ir::Expression *> &arguments, bool hasThis);
274     FunctionBuilder *builder_ {};
275     EnvScope *envScope_ {};
276     OptionalChain *optionalChain_ {};
277 
278     friend class EnvScope;
279     friend class LoopEnvScope;
280     friend class DynamicContext;
281     friend class OptionalChain;
282 };
283 }  // namespace ark::es2panda::compiler
284 
285 #endif
286