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