1 /** 2 * Copyright (c) 2021-2024 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/base/optionalChain.h> 20 #include <compiler/core/envScope.h> 21 #include <compiler/core/inlineCache.h> 22 #include <compiler/core/regAllocator.h> 23 #include <compiler/core/regScope.h> 24 #include <ir/irnode.h> 25 #include <lexer/token/tokenType.h> 26 #include <libpandafile/file_items.h> 27 #include <macros.h> 28 #include <util/enumbitops.h> 29 30 #include <regex> 31 32 namespace panda::es2panda::binder { 33 class FunctionScope; 34 class ModuleVaribale; 35 class ScopeFindResult; 36 class Scope; 37 } // namespace panda::es2panda::binder 38 39 namespace panda::es2panda::ir { 40 class AstNode; 41 class ScriptFunction; 42 class Statement; 43 class Expression; 44 class Identifier; 45 } // namespace panda::es2panda::ir 46 47 DEFINE_BITOPS(panda::panda_file::FunctionKind); 48 49 namespace panda::es2panda::compiler { 50 class FunctionBuilder; 51 class CompilerContext; 52 class LiteralBuffer; 53 class DynamicContext; 54 class CatchTable; 55 56 enum class Constant { 57 JS_NAN, 58 JS_HOLE, 59 JS_INFINITY, 60 JS_UNDEFINED, 61 JS_NULL, 62 JS_TRUE, 63 JS_FALSE, 64 JS_SYMBOL, 65 JS_GLOBAL, 66 }; 67 68 class DebugInfo { 69 public: DebugInfo(ArenaAllocator * allocator)70 explicit DebugInfo(ArenaAllocator *allocator) : variableDebugInfo(allocator->Adapter()) {}; 71 DEFAULT_COPY_SEMANTIC(DebugInfo); 72 DEFAULT_MOVE_SEMANTIC(DebugInfo); 73 ~DebugInfo() = default; 74 75 ArenaVector<const binder::Scope *> variableDebugInfo; 76 const ir::Statement *firstStmt {}; 77 }; 78 79 class PandaGen { 80 public: PandaGen(ArenaAllocator * allocator,CompilerContext * context,binder::FunctionScope * scope)81 explicit PandaGen(ArenaAllocator *allocator, CompilerContext *context, binder::FunctionScope *scope) 82 : allocator_(allocator), 83 context_(context), 84 builder_(nullptr), 85 debugInfo_(allocator_), 86 topScope_(scope), 87 scope_(topScope_), 88 rootNode_(scope->Node()), 89 insns_(allocator_->Adapter()), 90 catchList_(allocator_->Adapter()), 91 strings_(allocator_->Adapter()), 92 buffStorage_(allocator_->Adapter()), 93 ra_(this) 94 { 95 } 96 ~PandaGen() = default; 97 NO_COPY_SEMANTIC(PandaGen); 98 NO_MOVE_SEMANTIC(PandaGen); 99 Allocator()100 inline ArenaAllocator *Allocator() const 101 { 102 return allocator_; 103 } 104 Context()105 inline CompilerContext *Context() const 106 { 107 return context_; 108 } 109 Strings()110 const ArenaSet<util::StringView> &Strings() const 111 { 112 return strings_; 113 } 114 CatchList()115 const ArenaVector<CatchTable *> &CatchList() const 116 { 117 return catchList_; 118 } 119 TopScope()120 binder::FunctionScope *TopScope() const 121 { 122 return topScope_; 123 } 124 Scope()125 binder::Scope *Scope() const 126 { 127 return scope_; 128 } 129 RootNode()130 const ir::AstNode *RootNode() const 131 { 132 return rootNode_; 133 } 134 Insns()135 ArenaList<IRNode *> &Insns() 136 { 137 return insns_; 138 } 139 Insns()140 const ArenaList<IRNode *> &Insns() const 141 { 142 return insns_; 143 } 144 SetInsns(ArenaList<IRNode * > & newInsns)145 void SetInsns(ArenaList<IRNode *> &newInsns) 146 { 147 insns_.assign(newInsns.begin(), newInsns.end()); 148 } 149 AllocReg()150 VReg AllocReg() 151 { 152 if (usedRegs_ > UINT16_MAX) { 153 throw Error(ErrorType::GENERIC, "Can't alloc new reg because all regs ran out"); 154 } 155 return usedRegs_++; 156 } 157 NextReg()158 VReg NextReg() const 159 { 160 return usedRegs_; 161 } 162 TotalRegsNum()163 uint32_t TotalRegsNum() const 164 { 165 return totalRegs_; 166 } 167 LabelCount()168 size_t LabelCount() const 169 { 170 return labelId_; 171 } 172 Debuginfo()173 const DebugInfo &Debuginfo() const 174 { 175 return debugInfo_; 176 } 177 FuncBuilder()178 FunctionBuilder *FuncBuilder() const 179 { 180 return builder_; 181 } 182 GetEnvScope()183 EnvScope *GetEnvScope() const 184 { 185 return envScope_; 186 } 187 BuffStorage()188 const ArenaVector<compiler::LiteralBuffer *> &BuffStorage() const 189 { 190 return buffStorage_; 191 } 192 GetOptionalChain()193 OptionalChain *GetOptionalChain() const 194 { 195 return optionalChain_; 196 } 197 IcSize()198 uint32_t IcSize() const 199 { 200 return ic_.Size(); 201 } 202 SetSourceLocationFlag(lexer::SourceLocationFlag flag)203 void SetSourceLocationFlag(lexer::SourceLocationFlag flag) 204 { 205 ra_.SetSourceLocationFlag(flag); 206 } 207 AdjustSpillInsns()208 void AdjustSpillInsns() 209 { 210 ra_.AdjustInsRegWhenHasSpill(); 211 totalRegs_ += ra_.GetSpillRegsCount(); 212 } 213 GetSpillRegsCount()214 uint16_t GetSpillRegsCount() const 215 { 216 if (ra_.HasSpill()) { 217 return ra_.GetSpillRegsCount(); 218 } 219 return 0; 220 } 221 GetFunctionKind()222 panda::panda_file::FunctionKind GetFunctionKind() const 223 { 224 return funcKind_; 225 } 226 IsConcurrent()227 bool IsConcurrent() const 228 { 229 return funcKind_ == panda::panda_file::FunctionKind::CONCURRENT_FUNCTION; 230 } 231 IsSendable()232 bool IsSendable() const 233 { 234 return (funcKind_ & panda::panda_file::FunctionKind::SENDABLE_FUNCTION) != 0; 235 } 236 237 void SetFunctionKind(); 238 void SetInSendable(); 239 size_t GetExpectedPropertyCount() const; 240 241 bool IsDebug() const; 242 bool isDebuggerEvaluateExpressionMode() const; 243 std::string SourceFile() const; 244 uint32_t ParamCount() const; 245 uint32_t FormalParametersCount() const; 246 uint32_t InternalParamCount() const; 247 const util::StringView &InternalName() const; 248 const util::StringView &FunctionName() const; 249 binder::Binder *Binder() const; 250 pandasm::extensions::Language SourceLang() const; 251 252 Label *AllocLabel(); 253 254 bool FunctionHasFinalizer() const; 255 bool IsAsyncFunction() const; 256 void FunctionInit(CatchTable* catchTable); 257 void FunctionEnter(); 258 void FunctionExit(); 259 260 LiteralBuffer *NewLiteralBuffer(); 261 int32_t AddLiteralBuffer(LiteralBuffer *buf); 262 int32_t AddLexicalVarNamesForDebugInfo(ArenaMap<uint32_t, std::pair<util::StringView, int>> &lexicalVars); 263 264 void InitializeLexEnv(const ir::AstNode *node); 265 void CopyFunctionArguments(const ir::AstNode *node); 266 void GetFunctionObject(const ir::AstNode *node); 267 void GetNewTarget(const ir::AstNode *node); 268 void GetThis(const ir::AstNode *node); 269 void SetThis(const ir::AstNode *node); 270 void LoadVar(const ir::Identifier *node, const binder::ScopeFindResult &result); 271 void StoreVar(const ir::AstNode *node, const binder::ScopeFindResult &result, bool isDeclaration); 272 273 void StLetOrClassToGlobalRecord(const ir::AstNode *node, const util::StringView &name); 274 void StConstToGlobalRecord(const ir::AstNode *node, const util::StringView &name); 275 276 void StoreAccumulator(const ir::AstNode *node, VReg vreg); 277 void LoadAccFromArgs(const ir::AstNode *node); 278 void LoadObjProperty(const ir::AstNode *node, VReg obj, const Operand &prop); 279 280 void LoadObjByName(const ir::AstNode *node, VReg obj, const util::StringView &prop); 281 282 void StoreObjProperty(const ir::AstNode *node, VReg obj, const Operand &prop); 283 void DefineOwnProperty(const ir::AstNode *node, VReg obj, const Operand &prop); 284 void DefineClassPrivateField(const ir::AstNode *node, uint32_t level, uint32_t slot, VReg obj); 285 void StoreOwnProperty(const ir::AstNode *node, VReg obj, const Operand &prop, bool nameSetting = false); 286 void DeleteObjProperty(const ir::AstNode *node, VReg obj, const Operand &prop); 287 void LoadAccumulator(const ir::AstNode *node, VReg reg); 288 void LoadGlobalVar(const ir::AstNode *node, const util::StringView &name); 289 void StoreGlobalVar(const ir::AstNode *node, const util::StringView &name); 290 291 void LoadObjByNameViaDebugger(const ir::AstNode *node, const util::StringView &name, bool throwUndefinedIfHole); 292 void TryLoadGlobalByName(const ir::AstNode *node, const util::StringView &name); 293 void StoreObjByNameViaDebugger(const ir::AstNode *node, const util::StringView &name); 294 void TryStoreGlobalByName(const ir::AstNode *node, const util::StringView &name); 295 296 void LoadAccFromLexEnv(const ir::AstNode *node, const binder::ScopeFindResult &result); 297 void StoreAccToLexEnv(const ir::AstNode *node, const binder::ScopeFindResult &result, bool isDeclaration); 298 299 void LoadAccumulatorString(const ir::AstNode *node, const util::StringView &str); 300 void LoadAccumulatorFloat(const ir::AstNode *node, double num); 301 void LoadAccumulatorInt(const ir::AstNode *node, int32_t num); 302 void LoadAccumulatorInt(const ir::AstNode *node, size_t num); 303 void LoadAccumulatorBigInt(const ir::AstNode *node, const util::StringView &num); 304 305 void LoadConst(const ir::AstNode *node, Constant id); 306 void StoreConst(const ir::AstNode *node, VReg reg, Constant id); 307 void MoveVreg(const ir::AstNode *node, VReg vd, VReg vs); 308 309 void SetLabel(const ir::AstNode *node, Label *label); 310 void Branch(const ir::AstNode *node, class Label *label); 311 bool CheckControlFlowChange() const; 312 Label *ControlFlowChangeBreak(const ir::Identifier *label = nullptr); 313 Label *ControlFlowChangeContinue(const ir::Identifier *label); 314 void ControlFlowChangeReturn(); 315 316 void Condition(const ir::AstNode *node, lexer::TokenType op, VReg lhs, class Label *ifFalse); 317 void Unary(const ir::AstNode *node, lexer::TokenType op, VReg operand); 318 void Binary(const ir::AstNode *node, lexer::TokenType op, VReg lhs); 319 void Equal(const ir::AstNode *node, VReg lhs); 320 void NotEqual(const ir::AstNode *node, VReg lhs); 321 void StrictEqual(const ir::AstNode *node, VReg lhs); 322 void StrictNotEqual(const ir::AstNode *node, VReg lhs); 323 void LessThan(const ir::AstNode *node, VReg lhs); 324 void LessEqual(const ir::AstNode *node, VReg lhs); 325 void GreaterThan(const ir::AstNode *node, VReg lhs); 326 void GreaterEqual(const ir::AstNode *node, VReg lhs); 327 void IsTrue(const ir::AstNode *node); 328 329 void BranchIfUndefined(const ir::AstNode *node, class Label *target); 330 void BranchIfStrictUndefined(const ir::AstNode *node, class Label *target); 331 void BranchIfStrictNotUndefined(const ir::AstNode *node, class Label *target); 332 void BranchIfNotUndefined(const ir::AstNode *node, class Label *target); 333 void BranchIfHole(const ir::AstNode *node, class Label *target); 334 void BranchIfTrue(const ir::AstNode *node, class Label *target); 335 void BranchIfNotTrue(const ir::AstNode *node, class Label *target); 336 void BranchIfFalse(const ir::AstNode *node, class Label *target); 337 void BranchIfNotFalse(const ir::AstNode *node, class Label *target); 338 void BranchIfStrictNull(const ir::AstNode *node, class Label *target); 339 340 void EmitThrow(const ir::AstNode *node); 341 void EmitRethrow(const ir::AstNode *node); 342 void EmitReturn(const ir::AstNode *node); 343 void EmitReturnUndefined(const ir::AstNode *node); 344 void ValidateClassDirectReturn(const ir::AstNode *node); 345 void DirectReturn(const ir::AstNode *node); 346 void ExplicitReturn(const ir::AstNode *node); 347 void ImplicitReturn(const ir::AstNode *node); 348 void EmitAwait(const ir::AstNode *node); 349 350 void CallThis(const ir::AstNode *node, VReg startReg, size_t argCount); 351 void Call(const ir::AstNode *node, VReg startReg, size_t argCount); 352 void CallSpread(const ir::AstNode *node, VReg func, VReg thisReg, VReg args); 353 void SuperCall(const ir::AstNode *node, VReg startReg, size_t argCount); 354 void SuperCallSpread(const ir::AstNode *node, VReg vs); 355 void SuperCallForwardAllArgs(const ir::AstNode *node, VReg funcObj); 356 void NotifyConcurrentResult(const ir::AstNode *node); 357 void CallInit(const ir::AstNode *node, VReg thisReg); 358 359 void NewObject(const ir::AstNode *node, VReg startReg, size_t argCount); 360 void DefineFunction(const ir::AstNode *node, const ir::ScriptFunction *realNode, const util::StringView &name); 361 362 void TypeOf(const ir::AstNode *node); 363 void NewObjSpread(const ir::AstNode *node, VReg obj); 364 void GetUnmappedArgs(const ir::AstNode *node); 365 366 void Negate(const ir::AstNode *node); 367 void ToNumber(const ir::AstNode *node, VReg arg); 368 void ToNumeric(const ir::AstNode *node, VReg arg); 369 370 void CreateGeneratorObj(const ir::AstNode *node, VReg funcObj); 371 void ResumeGenerator(const ir::AstNode *node, VReg genObj); 372 void GetResumeMode(const ir::AstNode *node, VReg genObj); 373 374 void AsyncFunctionEnter(const ir::AstNode *node); 375 void AsyncFunctionAwait(const ir::AstNode *node, VReg asyncFuncObj); 376 void AsyncFunctionResolve(const ir::AstNode *node, VReg asyncFuncObj); 377 void AsyncFunctionReject(const ir::AstNode *node, VReg asyncFuncObj); 378 379 void GeneratorYield(const ir::AstNode *node, VReg genObj); 380 void GeneratorComplete(const ir::AstNode *node, VReg genObj); 381 void CreateAsyncGeneratorObj(const ir::AstNode *node, VReg funcObj); 382 void CreateIterResultObject(const ir::AstNode *node, VReg value, VReg done); 383 void SuspendGenerator(const ir::AstNode *node, VReg genObj); 384 385 void AsyncGeneratorResolve(const ir::AstNode *node, VReg asyncGenObj, VReg value, VReg canSuspend); 386 void AsyncGeneratorReject(const ir::AstNode *node, VReg asyncGenObj); 387 388 void GetTemplateObject(const ir::AstNode *node, VReg value); 389 void CopyRestArgs(const ir::AstNode *node, uint32_t index); 390 391 void GetPropIterator(const ir::AstNode *node); 392 void GetNextPropName(const ir::AstNode *node, VReg iter); 393 void CreateEmptyObject(const ir::AstNode *node); 394 void CreateObjectWithBuffer(const ir::AstNode *node, uint32_t idx); 395 void SetObjectWithProto(const ir::AstNode *node, VReg proto, VReg obj); 396 void CopyDataProperties(const ir::AstNode *node, VReg dst); 397 void DefineGetterSetterByValue(const ir::AstNode *node, VReg obj, VReg name, VReg getter, VReg setter, 398 bool setName); 399 void CreateEmptyArray(const ir::AstNode *node); 400 void CreateArray(const ir::AstNode *node, const ArenaVector<ir::Expression *> &elements, VReg obj); 401 void CreateArrayWithBuffer(const ir::AstNode *node, uint32_t idx); 402 void StoreArraySpread(const ir::AstNode *node, VReg array, VReg index); 403 404 void ThrowIfNotObject(const ir::AstNode *node, VReg obj); 405 void ThrowThrowNotExist(const ir::AstNode *node); 406 void GetIterator(const ir::AstNode *node); 407 void GetAsyncIterator(const ir::AstNode *node); 408 409 void CreateObjectWithExcludedKeys(const ir::AstNode *node, VReg obj, VReg argStart, size_t argCount); 410 void ThrowObjectNonCoercible(const ir::AstNode *node); 411 void CloseIterator(const ir::AstNode *node, VReg iter); 412 void DefineClassWithBuffer(const ir::AstNode *node, const util::StringView &ctorId, int32_t litIdx, VReg base); 413 void DefineSendableClass(const ir::AstNode *node, const util::StringView &ctorId, 414 int32_t litIdx, VReg base); 415 void LoadSendableClass(const ir::AstNode *node, int32_t level); 416 417 void LoadLocalModuleVariable(const ir::AstNode *node, const binder::ModuleVariable *variable); 418 void LoadExternalModuleVariable(const ir::AstNode *node, const binder::ModuleVariable *variable); 419 void StoreModuleVariable(const ir::AstNode *node, const binder::ModuleVariable *variable); 420 void GetModuleNamespace(const ir::AstNode *node, uint32_t index); 421 void DynamicImportCall(const ir::AstNode *node); 422 423 void StSuperByName(const ir::AstNode *node, VReg obj, const util::StringView &key); 424 void LdSuperByName(const ir::AstNode *node, VReg obj, const util::StringView &key); 425 void StSuperByValue(const ir::AstNode *node, VReg obj, VReg prop); 426 void LdSuperByValue(const ir::AstNode *node, VReg obj); 427 void StoreSuperProperty(const ir::AstNode *node, VReg obj, const Operand &prop); 428 void LoadSuperProperty(const ir::AstNode *node, VReg obj, const Operand &prop); 429 430 void PopLexEnv(const ir::AstNode *node); 431 void GenDebugger(const ir::AstNode *node); 432 void NewLexicalEnv(const ir::AstNode *node, uint32_t num, binder::VariableScope *scope); 433 void NewLexEnv(const ir::AstNode *node, uint32_t num); 434 void NewSendableEnv(const ir::AstNode *node, uint32_t num); 435 void NewLexEnvWithScopeInfo(const ir::AstNode *node, uint32_t num, int32_t scopeInfoIdx); 436 void LoadLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot); 437 void LoadSendableVar(const ir::AstNode *node, uint32_t level, uint32_t slot); 438 void LoadLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot, const util::StringView &name); 439 void StoreLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot); 440 void StoreSendableVar(const ir::AstNode *node, uint32_t level, uint32_t slot); 441 void StoreLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot, const binder::LocalVariable *local); 442 void StoreLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot, VReg value); 443 444 void ThrowIfSuperNotCorrectCall(const ir::AstNode *node, int64_t num); 445 void ThrowUndefinedIfHole(const ir::AstNode *node, const util::StringView &name); 446 void ThrowConstAssignment(const ir::AstNode *node, const util::StringView &name); 447 448 uint32_t TryDepth() const; 449 CatchTable *CreateCatchTable(); 450 void SortCatchTables(); 451 452 void LoadObjByIndex(const ir::AstNode *node, VReg obj, int64_t index); 453 void LoadObjByValue(const ir::AstNode *node, VReg obj); 454 455 void StoreObjByName(const ir::AstNode *node, VReg obj, const util::StringView &prop); 456 void StoreObjByIndex(const ir::AstNode *node, VReg obj, int64_t index); 457 void StoreObjByValue(const ir::AstNode *node, VReg obj, VReg prop); 458 459 void DefineFieldByName(const ir::AstNode *node, VReg obj, const util::StringView &prop); 460 void DefineFieldByIndex(const ir::AstNode *node, VReg obj, int64_t index); 461 void DefineFieldByValue(const ir::AstNode *node, VReg obj, VReg prop); 462 463 void StOwnByName(const ir::AstNode *node, VReg obj, const util::StringView &prop, bool nameSetting = false); 464 void StOwnByValue(const ir::AstNode *node, VReg obj, VReg prop, bool nameSetting = false); 465 void StOwnByIndex(const ir::AstNode *node, VReg obj, int64_t index); 466 467 Operand ToNamedPropertyKey(const ir::Expression *prop, bool isComputed); 468 Operand ToPropertyKey(const ir::Expression *prop, bool isComputed); 469 VReg LoadPropertyKey(const ir::Expression *prop, bool isComputed); 470 void ToComputedPropertyKey(const ir::AstNode *node); 471 472 void ReArrangeIc(); 473 474 void CreatePrivateProperty(const ir::AstNode *node, uint32_t num, int32_t bufIdx); 475 void TestIn(const ir::AstNode *node, uint32_t level, uint32_t slot); 476 void LoadPrivateProperty(const ir::AstNode *node, uint32_t level, uint32_t slot); 477 void StorePrivateProperty(const ir::AstNode *node, uint32_t level, uint32_t slot, VReg obj); 478 void ThrowTypeErrorIfFalse(const ir::AstNode *node, util::StringView str); 479 void ThrowTypeError(const ir::AstNode *node, util::StringView str); 480 481 /* 482 * Since the [Function] is not implemented yet, We compile the test262's framework code 483 * which obtains the [global] Object as following into [LoadConst.Global] directly. 484 * ``` 485 * var __globalObject = Function("return this;")(); 486 * var __globalObject = new Function("return this;")(); 487 * ``` 488 */ 489 bool TryCompileFunctionCallOrNewExpression(const ir::Expression *expr); 490 SetFirstStmt(const ir::Statement * stmt)491 void SetFirstStmt(const ir::Statement *stmt) 492 { 493 debugInfo_.firstStmt = stmt; 494 } 495 Unimplemented()496 [[noreturn]] static void Unimplemented() 497 { 498 throw Error(ErrorType::GENERIC, "Unimplemented code path"); 499 } 500 GetCurrentSlot()501 IcSizeType GetCurrentSlot() const 502 { 503 return currentSlot_; 504 } 505 IncreaseCurrentSlot(ICSlot inc)506 void IncreaseCurrentSlot(ICSlot inc) 507 { 508 currentSlot_ += inc; 509 } 510 ResetCurrentSlot(IcSizeType slotSize)511 void ResetCurrentSlot(IcSizeType slotSize) 512 { 513 currentSlot_ = slotSize; 514 } 515 SetIcOverFlow()516 void SetIcOverFlow() 517 { 518 icOverFlow_ = true; 519 } 520 IsIcOverFlow()521 bool IsIcOverFlow() const 522 { 523 return icOverFlow_; 524 } 525 526 private: 527 ArenaAllocator *allocator_; 528 CompilerContext *context_; 529 FunctionBuilder *builder_; 530 DebugInfo debugInfo_; 531 binder::FunctionScope *topScope_; 532 binder::Scope *scope_; 533 const ir::AstNode *rootNode_; 534 ArenaList<IRNode *> insns_; 535 ArenaVector<CatchTable *> catchList_; 536 ArenaSet<util::StringView> strings_; 537 ArenaVector<LiteralBuffer *> buffStorage_; 538 EnvScope *envScope_ {}; 539 DynamicContext *dynamicContext_ {}; 540 OptionalChain *optionalChain_ {}; 541 InlineCache ic_; 542 RegAllocator ra_; 543 IcSizeType currentSlot_ {0}; 544 545 uint32_t usedRegs_ {0}; 546 uint32_t totalRegs_ {0}; 547 friend class ScopeContext; 548 friend class RegScope; 549 friend class LocalRegScope; 550 friend class LoopRegScope; 551 friend class ParamRegScope; 552 friend class FunctionRegScope; 553 friend class EnvScope; 554 friend class LoopEnvScope; 555 friend class DynamicContext; 556 friend class OptionalChain; 557 size_t labelId_ {0}; 558 panda::panda_file::FunctionKind funcKind_ {panda::panda_file::FunctionKind::NONE}; 559 bool icOverFlow_ {false}; 560 bool inSendable_ {false}; 561 }; 562 } // namespace panda::es2panda::compiler 563 564 #endif 565