1/** 2 * Copyright (c) 2021 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 "variable.h" 17 18#include <binder/scope.h> 19 20#include <utility> 21 22namespace panda::es2panda::binder { 23 24LocalVariable::LocalVariable(Decl *decl, VariableFlags flags) : Variable(decl, flags) 25{ 26 if (decl->IsConstDecl()) { 27 flags_ |= VariableFlags::READONLY; 28 } 29} 30 31const util::StringView &Variable::Name() const 32{ 33 return decl_->Name(); 34} 35 36LocalVariable *LocalVariable::Copy(ArenaAllocator *allocator, Decl *decl) const 37{ 38 auto *var = allocator->New<LocalVariable>(decl, flags_); 39 CHECK_NOT_NULL(var); 40 var->vreg_ = vreg_; 41 return var; 42} 43 44void LocalVariable::SetLexical(Scope *scope, util::PatchFix *patchFixHelper) 45{ 46 if (LexicalBound()) { 47 return; 48 } 49 50 VariableScope *varScope = scope->IsFunctionParamScope() ? 51 scope->AsFunctionParamScope()->GetFunctionScope() : scope->EnclosingVariableScope(); 52 CHECK_NOT_NULL(varScope); 53 uint32_t slot = 0; 54 auto name = Declaration()->Name(); 55 56 if (patchFixHelper && patchFixHelper->IsScopeValidToPatchLexical(varScope)) { 57 // get slot from symbol table for lexical variable, if not found, slot is set to UINT32_MAX 58 slot = patchFixHelper->GetSlotIdFromSymbolTable(std::string(name)); 59 // Store the additional lexical variable into PatchEnv 60 if (patchFixHelper->IsAdditionalVarInPatch(slot)) { 61 patchFixHelper->AllocSlotfromPatchEnv(std::string(name)); 62 } else { 63 // Just for restore 'newlexenv' instruction for func_main_0 in patch 64 varScope->RestoreFuncMain0LexEnv(patchFixHelper->GetEnvSizeOfFuncMain0()); 65 } 66 } else { 67 if (decl_ && decl_->NeedSetInSendableEnv(varScope)) { 68 AddFlag(VariableFlags::IN_SENDABLE_ENV); 69 slot = varScope->NextSendableSlot(); 70 } else { 71 slot = varScope->NextSlot(); 72 } 73 } 74 75 BindLexEnvSlot(slot); 76 // gather lexical variables for debuginfo 77 varScope->AddLexicalVarNameAndType(slot, name, 78 static_cast<typename std::underlying_type<binder::DeclType>::type>(Declaration()->Type())); 79} 80 81void GlobalVariable::SetLexical([[maybe_unused]] Scope *scope, [[maybe_unused]] util::PatchFix *patchFixHelper) {} 82void ModuleVariable::SetLexical([[maybe_unused]] Scope *scope, [[maybe_unused]] util::PatchFix *patchFixHelper) {} 83void EnumVariable::SetLexical([[maybe_unused]] Scope *scope, [[maybe_unused]] util::PatchFix *patchFixHelper) {} 84void NamespaceVariable::SetLexical([[maybe_unused]] Scope *scope, [[maybe_unused]] util::PatchFix *patchFixHelper) {} 85void ImportEqualsVariable::SetLexical([[maybe_unused]] Scope *scope, [[maybe_unused]] util::PatchFix *patchFixHelper) {} 86void EnumLiteralVariable::SetLexical([[maybe_unused]] Scope *scope, [[maybe_unused]] util::PatchFix *patchFixHelper) {} 87 88void EnumVariable::ResetDecl(Decl *decl) 89{ 90 decl_ = decl; 91} 92 93} // namespace panda::es2panda::binder 94