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() const100 inline ArenaAllocator *Allocator() const 101 { 102 return allocator_; 103 } 104 Context() const105 inline CompilerContext *Context() const 106 { 107 return context_; 108 } 109 Strings() const110 const ArenaSet<util::StringView> &Strings() const 111 { 112 return strings_; 113 } 114 CatchList() const115 const ArenaVector<CatchTable *> &CatchList() const 116 { 117 return catchList_; 118 } 119 TopScope() const120 binder::FunctionScope *TopScope() const 121 { 122 return topScope_; 123 } 124 Scope() const125 binder::Scope *Scope() const 126 { 127 return scope_; 128 } 129 RootNode() const130 const ir::AstNode *RootNode() const 131 { 132 return rootNode_; 133 } 134 Insns()135 ArenaList<IRNode *> &Insns() 136 { 137 return insns_; 138 } 139 Insns() const140 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() const158 VReg NextReg() const 159 { 160 return usedRegs_; 161 } 162 TotalRegsNum() const163 uint32_t TotalRegsNum() const 164 { 165 return totalRegs_; 166 } 167 LabelCount() const168 size_t LabelCount() const 169 { 170 return labelId_; 171 } 172 Debuginfo() const173 const DebugInfo &Debuginfo() const 174 { 175 return debugInfo_; 176 } 177 FuncBuilder() const178 FunctionBuilder *FuncBuilder() const 179 { 180 return builder_; 181 } 182 GetEnvScope() const183 EnvScope *GetEnvScope() const 184 { 185 return envScope_; 186 } 187 BuffStorage() const188 const ArenaVector<compiler::LiteralBuffer *> &BuffStorage() const 189 { 190 return buffStorage_; 191 } 192 GetOptionalChain() const193 OptionalChain *GetOptionalChain() const 194 { 195 return optionalChain_; 196 } 197 IcSize() const198 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() const214 uint16_t GetSpillRegsCount() const 215 { 216 if (ra_.HasSpill()) { 217 return ra_.GetSpillRegsCount(); 218 } 219 return 0; 220 } 221 GetFunctionKind() const222 panda::panda_file::FunctionKind GetFunctionKind() const 223 { 224 return funcKind_; 225 } 226 IsConcurrent() const227 bool IsConcurrent() const 228 { 229 return funcKind_ == panda::panda_file::FunctionKind::CONCURRENT_FUNCTION; 230 } 231 IsSendable() const232 bool IsSendable() const 233 { 234 return (funcKind_ & panda::panda_file::FunctionKind::SENDABLE_FUNCTION) != 0; 235 } 236 237 void SetFunctionKind(); 238 void SetInSendable(); 239 240 bool IsDebug() const; 241 bool isDebuggerEvaluateExpressionMode() const; 242 std::string SourceFile() const; 243 uint32_t ParamCount() const; 244 uint32_t FormalParametersCount() const; 245 uint32_t InternalParamCount() const; 246 const util::StringView &InternalName() const; 247 const util::StringView &FunctionName() const; 248 binder::Binder *Binder() const; 249 250 Label *AllocLabel(); 251 252 bool FunctionHasFinalizer() const; 253 bool IsAsyncFunction() const; 254 void FunctionInit(CatchTable* catchTable); 255 void FunctionEnter(); 256 void FunctionExit(); 257 258 LiteralBuffer *NewLiteralBuffer(); 259 int32_t AddLiteralBuffer(LiteralBuffer *buf); 260 int32_t AddLexicalVarNamesForDebugInfo(ArenaMap<uint32_t, std::pair<util::StringView, int>> &lexicalVars); 261 262 void InitializeLexEnv(const ir::AstNode *node); 263 void CopyFunctionArguments(const ir::AstNode *node); 264 void GetFunctionObject(const ir::AstNode *node); 265 void GetNewTarget(const ir::AstNode *node); 266 void GetThis(const ir::AstNode *node); 267 void SetThis(const ir::AstNode *node); 268 void LoadVar(const ir::Identifier *node, const binder::ScopeFindResult &result); 269 void StoreVar(const ir::AstNode *node, const binder::ScopeFindResult &result, bool isDeclaration); 270 271 void StLetOrClassToGlobalRecord(const ir::AstNode *node, const util::StringView &name); 272 void StConstToGlobalRecord(const ir::AstNode *node, const util::StringView &name); 273 274 void StoreAccumulator(const ir::AstNode *node, VReg vreg); 275 void LoadAccFromArgs(const ir::AstNode *node); 276 void LoadObjProperty(const ir::AstNode *node, VReg obj, const Operand &prop); 277 278 void LoadObjByName(const ir::AstNode *node, VReg obj, const util::StringView &prop); 279 280 void StoreObjProperty(const ir::AstNode *node, VReg obj, const Operand &prop); 281 void DefineOwnProperty(const ir::AstNode *node, VReg obj, const Operand &prop); 282 void DefineClassPrivateField(const ir::AstNode *node, uint32_t level, uint32_t slot, VReg obj); 283 void StoreOwnProperty(const ir::AstNode *node, VReg obj, const Operand &prop, bool nameSetting = false); 284 void DeleteObjProperty(const ir::AstNode *node, VReg obj, const Operand &prop); 285 void LoadAccumulator(const ir::AstNode *node, VReg reg); 286 void LoadGlobalVar(const ir::AstNode *node, const util::StringView &name); 287 void StoreGlobalVar(const ir::AstNode *node, const util::StringView &name); 288 289 void LoadObjByNameViaDebugger(const ir::AstNode *node, const util::StringView &name, bool throwUndefinedIfHole); 290 void TryLoadGlobalByName(const ir::AstNode *node, const util::StringView &name); 291 void StoreObjByNameViaDebugger(const ir::AstNode *node, const util::StringView &name); 292 void TryStoreGlobalByName(const ir::AstNode *node, const util::StringView &name); 293 294 void LoadAccFromLexEnv(const ir::AstNode *node, const binder::ScopeFindResult &result); 295 void StoreAccToLexEnv(const ir::AstNode *node, const binder::ScopeFindResult &result, bool isDeclaration); 296 297 void LoadAccumulatorString(const ir::AstNode *node, const util::StringView &str); 298 void LoadAccumulatorFloat(const ir::AstNode *node, double num); 299 void LoadAccumulatorInt(const ir::AstNode *node, int32_t num); 300 void LoadAccumulatorInt(const ir::AstNode *node, size_t num); 301 void LoadAccumulatorBigInt(const ir::AstNode *node, const util::StringView &num); 302 303 void LoadConst(const ir::AstNode *node, Constant id); 304 void StoreConst(const ir::AstNode *node, VReg reg, Constant id); 305 void MoveVreg(const ir::AstNode *node, VReg vd, VReg vs); 306 307 void SetLabel(const ir::AstNode *node, Label *label); 308 void Branch(const ir::AstNode *node, class Label *label); 309 bool CheckControlFlowChange() const; 310 Label *ControlFlowChangeBreak(const ir::Identifier *label = nullptr); 311 Label *ControlFlowChangeContinue(const ir::Identifier *label); 312 void ControlFlowChangeReturn(); 313 314 void Condition(const ir::AstNode *node, lexer::TokenType op, VReg lhs, class Label *ifFalse); 315 void Unary(const ir::AstNode *node, lexer::TokenType op, VReg operand); 316 void Binary(const ir::AstNode *node, lexer::TokenType op, VReg lhs); 317 void Equal(const ir::AstNode *node, VReg lhs); 318 void NotEqual(const ir::AstNode *node, VReg lhs); 319 void StrictEqual(const ir::AstNode *node, VReg lhs); 320 void StrictNotEqual(const ir::AstNode *node, VReg lhs); 321 void LessThan(const ir::AstNode *node, VReg lhs); 322 void LessEqual(const ir::AstNode *node, VReg lhs); 323 void GreaterThan(const ir::AstNode *node, VReg lhs); 324 void GreaterEqual(const ir::AstNode *node, VReg lhs); 325 void IsTrue(const ir::AstNode *node); 326 327 void BranchIfUndefined(const ir::AstNode *node, class Label *target); 328 void BranchIfStrictUndefined(const ir::AstNode *node, class Label *target); 329 void BranchIfStrictNotUndefined(const ir::AstNode *node, class Label *target); 330 void BranchIfNotUndefined(const ir::AstNode *node, class Label *target); 331 void BranchIfHole(const ir::AstNode *node, class Label *target); 332 void BranchIfTrue(const ir::AstNode *node, class Label *target); 333 void BranchIfNotTrue(const ir::AstNode *node, class Label *target); 334 void BranchIfFalse(const ir::AstNode *node, class Label *target); 335 void BranchIfNotFalse(const ir::AstNode *node, class Label *target); 336 void BranchIfStrictNull(const ir::AstNode *node, class Label *target); 337 338 void EmitThrow(const ir::AstNode *node); 339 void EmitRethrow(const ir::AstNode *node); 340 void EmitReturn(const ir::AstNode *node); 341 void EmitReturnUndefined(const ir::AstNode *node); 342 void ValidateClassDirectReturn(const ir::AstNode *node); 343 void DirectReturn(const ir::AstNode *node); 344 void ExplicitReturn(const ir::AstNode *node); 345 void ImplicitReturn(const ir::AstNode *node); 346 void EmitAwait(const ir::AstNode *node); 347 348 void CallThis(const ir::AstNode *node, VReg startReg, size_t argCount); 349 void Call(const ir::AstNode *node, VReg startReg, size_t argCount); 350 void CallSpread(const ir::AstNode *node, VReg func, VReg thisReg, VReg args); 351 void SuperCall(const ir::AstNode *node, VReg startReg, size_t argCount); 352 void SuperCallSpread(const ir::AstNode *node, VReg vs); 353 void SuperCallForwardAllArgs(const ir::AstNode *node, VReg funcObj); 354 void NotifyConcurrentResult(const ir::AstNode *node); 355 void CallInit(const ir::AstNode *node, VReg thisReg); 356 357 void NewObject(const ir::AstNode *node, VReg startReg, size_t argCount); 358 void DefineFunction(const ir::AstNode *node, const ir::ScriptFunction *realNode, const util::StringView &name); 359 360 void TypeOf(const ir::AstNode *node); 361 void NewObjSpread(const ir::AstNode *node, VReg obj); 362 void GetUnmappedArgs(const ir::AstNode *node); 363 364 void Negate(const ir::AstNode *node); 365 void ToNumber(const ir::AstNode *node, VReg arg); 366 void ToNumeric(const ir::AstNode *node, VReg arg); 367 368 void CreateGeneratorObj(const ir::AstNode *node, VReg funcObj); 369 void ResumeGenerator(const ir::AstNode *node, VReg genObj); 370 void GetResumeMode(const ir::AstNode *node, VReg genObj); 371 372 void AsyncFunctionEnter(const ir::AstNode *node); 373 void AsyncFunctionAwait(const ir::AstNode *node, VReg asyncFuncObj); 374 void AsyncFunctionResolve(const ir::AstNode *node, VReg asyncFuncObj); 375 void AsyncFunctionReject(const ir::AstNode *node, VReg asyncFuncObj); 376 377 void GeneratorYield(const ir::AstNode *node, VReg genObj); 378 void GeneratorComplete(const ir::AstNode *node, VReg genObj); 379 void CreateAsyncGeneratorObj(const ir::AstNode *node, VReg funcObj); 380 void CreateIterResultObject(const ir::AstNode *node, VReg value, VReg done); 381 void SuspendGenerator(const ir::AstNode *node, VReg genObj); 382 383 void AsyncGeneratorResolve(const ir::AstNode *node, VReg asyncGenObj, VReg value, VReg canSuspend); 384 void AsyncGeneratorReject(const ir::AstNode *node, VReg asyncGenObj); 385 386 void GetTemplateObject(const ir::AstNode *node, VReg value); 387 void CopyRestArgs(const ir::AstNode *node, uint32_t index); 388 389 void GetPropIterator(const ir::AstNode *node); 390 void GetNextPropName(const ir::AstNode *node, VReg iter); 391 void CreateEmptyObject(const ir::AstNode *node); 392 void CreateObjectWithBuffer(const ir::AstNode *node, uint32_t idx); 393 void SetObjectWithProto(const ir::AstNode *node, VReg proto, VReg obj); 394 void CopyDataProperties(const ir::AstNode *node, VReg dst); 395 void DefineGetterSetterByValue(const ir::AstNode *node, VReg obj, VReg name, VReg getter, VReg setter, 396 bool setName); 397 void CreateEmptyArray(const ir::AstNode *node); 398 void CreateArray(const ir::AstNode *node, const ArenaVector<ir::Expression *> &elements, VReg obj); 399 void CreateArrayWithBuffer(const ir::AstNode *node, uint32_t idx); 400 void StoreArraySpread(const ir::AstNode *node, VReg array, VReg index); 401 402 void ThrowIfNotObject(const ir::AstNode *node, VReg obj); 403 void ThrowThrowNotExist(const ir::AstNode *node); 404 void GetIterator(const ir::AstNode *node); 405 void GetAsyncIterator(const ir::AstNode *node); 406 407 void CreateObjectWithExcludedKeys(const ir::AstNode *node, VReg obj, VReg argStart, size_t argCount); 408 void ThrowObjectNonCoercible(const ir::AstNode *node); 409 void CloseIterator(const ir::AstNode *node, VReg iter); 410 void DefineClassWithBuffer(const ir::AstNode *node, const util::StringView &ctorId, int32_t litIdx, VReg base); 411 void DefineSendableClass(const ir::AstNode *node, const util::StringView &ctorId, 412 int32_t litIdx, VReg base); 413 void LoadSendableClass(const ir::AstNode *node, int32_t level); 414 415 void LoadLocalModuleVariable(const ir::AstNode *node, const binder::ModuleVariable *variable); 416 void LoadExternalModuleVariable(const ir::AstNode *node, const binder::ModuleVariable *variable); 417 void StoreModuleVariable(const ir::AstNode *node, const binder::ModuleVariable *variable); 418 void GetModuleNamespace(const ir::AstNode *node, uint32_t index); 419 void DynamicImportCall(const ir::AstNode *node); 420 421 void StSuperByName(const ir::AstNode *node, VReg obj, const util::StringView &key); 422 void LdSuperByName(const ir::AstNode *node, VReg obj, const util::StringView &key); 423 void StSuperByValue(const ir::AstNode *node, VReg obj, VReg prop); 424 void LdSuperByValue(const ir::AstNode *node, VReg obj); 425 void StoreSuperProperty(const ir::AstNode *node, VReg obj, const Operand &prop); 426 void LoadSuperProperty(const ir::AstNode *node, VReg obj, const Operand &prop); 427 428 void PopLexEnv(const ir::AstNode *node); 429 void GenDebugger(const ir::AstNode *node); 430 void NewLexicalEnv(const ir::AstNode *node, uint32_t num, binder::VariableScope *scope); 431 void NewLexEnv(const ir::AstNode *node, uint32_t num); 432 void NewSendableEnv(const ir::AstNode *node, uint32_t num); 433 void NewLexEnvWithScopeInfo(const ir::AstNode *node, uint32_t num, int32_t scopeInfoIdx); 434 void LoadLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot); 435 void LoadSendableVar(const ir::AstNode *node, uint32_t level, uint32_t slot); 436 void LoadLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot, const util::StringView &name); 437 void StoreLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot); 438 void StoreSendableVar(const ir::AstNode *node, uint32_t level, uint32_t slot); 439 void StoreLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot, const binder::LocalVariable *local); 440 void StoreLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot, VReg value); 441 442 void ThrowIfSuperNotCorrectCall(const ir::AstNode *node, int64_t num); 443 void ThrowUndefinedIfHole(const ir::AstNode *node, const util::StringView &name); 444 void ThrowConstAssignment(const ir::AstNode *node, const util::StringView &name); 445 446 uint32_t TryDepth() const; 447 CatchTable *CreateCatchTable(); 448 void SortCatchTables(); 449 450 void LoadObjByIndex(const ir::AstNode *node, VReg obj, int64_t index); 451 void LoadObjByValue(const ir::AstNode *node, VReg obj); 452 453 void StoreObjByName(const ir::AstNode *node, VReg obj, const util::StringView &prop); 454 void StoreObjByIndex(const ir::AstNode *node, VReg obj, int64_t index); 455 void StoreObjByValue(const ir::AstNode *node, VReg obj, VReg prop); 456 457 void DefineFieldByName(const ir::AstNode *node, VReg obj, const util::StringView &prop); 458 void DefineFieldByIndex(const ir::AstNode *node, VReg obj, int64_t index); 459 void DefineFieldByValue(const ir::AstNode *node, VReg obj, VReg prop); 460 461 void StOwnByName(const ir::AstNode *node, VReg obj, const util::StringView &prop, bool nameSetting = false); 462 void StOwnByValue(const ir::AstNode *node, VReg obj, VReg prop, bool nameSetting = false); 463 void StOwnByIndex(const ir::AstNode *node, VReg obj, int64_t index); 464 465 Operand ToNamedPropertyKey(const ir::Expression *prop, bool isComputed); 466 Operand ToPropertyKey(const ir::Expression *prop, bool isComputed); 467 VReg LoadPropertyKey(const ir::Expression *prop, bool isComputed); 468 void ToComputedPropertyKey(const ir::AstNode *node); 469 470 void ReArrangeIc(); 471 472 void CreatePrivateProperty(const ir::AstNode *node, uint32_t num, int32_t bufIdx); 473 void TestIn(const ir::AstNode *node, uint32_t level, uint32_t slot); 474 void LoadPrivateProperty(const ir::AstNode *node, uint32_t level, uint32_t slot); 475 void StorePrivateProperty(const ir::AstNode *node, uint32_t level, uint32_t slot, VReg obj); 476 void ThrowTypeErrorIfFalse(const ir::AstNode *node, util::StringView str); 477 void ThrowTypeError(const ir::AstNode *node, util::StringView str); 478 479 /* 480 * Since the [Function] is not implemented yet, We compile the test262's framework code 481 * which obtains the [global] Object as following into [LoadConst.Global] directly. 482 * ``` 483 * var __globalObject = Function("return this;")(); 484 * var __globalObject = new Function("return this;")(); 485 * ``` 486 */ 487 bool TryCompileFunctionCallOrNewExpression(const ir::Expression *expr); 488 SetFirstStmt(const ir::Statement *stmt)489 void SetFirstStmt(const ir::Statement *stmt) 490 { 491 debugInfo_.firstStmt = stmt; 492 } 493 Unimplemented()494 [[noreturn]] static void Unimplemented() 495 { 496 throw Error(ErrorType::GENERIC, "Unimplemented code path"); 497 } 498 GetCurrentSlot() const499 IcSizeType GetCurrentSlot() const 500 { 501 return currentSlot_; 502 } 503 IncreaseCurrentSlot(ICSlot inc)504 void IncreaseCurrentSlot(ICSlot inc) 505 { 506 currentSlot_ += inc; 507 } 508 ResetCurrentSlot(IcSizeType slotSize)509 void ResetCurrentSlot(IcSizeType slotSize) 510 { 511 currentSlot_ = slotSize; 512 } 513 SetIcOverFlow()514 void SetIcOverFlow() 515 { 516 icOverFlow_ = true; 517 } 518 IsIcOverFlow() const519 bool IsIcOverFlow() const 520 { 521 return icOverFlow_; 522 } 523 524 private: 525 ArenaAllocator *allocator_; 526 CompilerContext *context_; 527 FunctionBuilder *builder_; 528 DebugInfo debugInfo_; 529 binder::FunctionScope *topScope_; 530 binder::Scope *scope_; 531 const ir::AstNode *rootNode_; 532 ArenaList<IRNode *> insns_; 533 ArenaVector<CatchTable *> catchList_; 534 ArenaSet<util::StringView> strings_; 535 ArenaVector<LiteralBuffer *> buffStorage_; 536 EnvScope *envScope_ {}; 537 DynamicContext *dynamicContext_ {}; 538 OptionalChain *optionalChain_ {}; 539 InlineCache ic_; 540 RegAllocator ra_; 541 IcSizeType currentSlot_ {0}; 542 543 uint32_t usedRegs_ {0}; 544 uint32_t totalRegs_ {0}; 545 friend class ScopeContext; 546 friend class RegScope; 547 friend class LocalRegScope; 548 friend class LoopRegScope; 549 friend class ParamRegScope; 550 friend class FunctionRegScope; 551 friend class EnvScope; 552 friend class LoopEnvScope; 553 friend class DynamicContext; 554 friend class OptionalChain; 555 size_t labelId_ {0}; 556 panda::panda_file::FunctionKind funcKind_ {panda::panda_file::FunctionKind::NONE}; 557 bool icOverFlow_ {false}; 558 bool inSendable_ {false}; 559 }; 560 } // namespace panda::es2panda::compiler 561 562 #endif 563