1/** 2 * Copyright (c) 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_UTIL_COMMON_H 17#define ES2PANDA_UTIL_COMMON_H 18 19#include <functional> 20#include <iostream> 21#include <vector> 22#include <set> 23#include <string> 24#include <string_view> 25 26#include "assembler/assembly-function.h" 27#include "assembler/assembly-literals.h" 28#include "assembler/assembly-program.h" 29#include "assembler/assembly-record.h" 30 31namespace panda::es2panda { 32struct CompileContextInfo; 33struct PkgInfo; 34}; 35 36namespace panda::es2panda::util { 37const std::string NPM_ENTRIES = "npmEntries.txt"; 38const std::string IS_COMMONJS = "isCommonjs"; 39// The format of ohmurl for non-SO files are start with '@normalized:N'. 40const std::string NORMALIZED_OHMURL_NOT_SO = "@normalized:N"; 41const std::string MODULE_RECORD_IDX = "moduleRecordIdx"; 42const std::string GLOBAL_TYPE_NAME = "_GLOBAL"; 43 44constexpr char NORMALIZED_OHMURL_SEPARATOR = '&'; 45constexpr char NORMALIZED_OHMURL_PREFIX = '@'; 46constexpr char SLASH_TAG = '/'; 47constexpr char CHAR_VERTICAL_LINE = '|'; 48 49constexpr size_t BUNDLE_NAME_POS = 2U; 50constexpr size_t NORMALIZED_IMPORT_POS = 3U; 51constexpr size_t VERSION_POS = 4U; 52 53std::vector<std::string> Split(const std::string &str, const char delimiter); 54bool IsExternalPkgNames(const std::string &ohmurl, const std::set<std::string> &externalPkgNames); 55std::string GetRecordNameFromNormalizedOhmurl(const std::string &ohmurl); 56std::string GetPkgNameFromNormalizedOhmurl(const std::string &ohmurl); 57std::string GetPkgNameFromNormalizedImport(const std::string &normalizedImport); 58std::string UpdatePackageVersionIfNeeded(const std::string &ohmurl, 59 const std::unordered_map<std::string, PkgInfo> &pkgContextInfo); 60bool RecordNotGeneratedFromBytecode(std::string recordName); 61 62template<bool isConst, typename T> 63using ConstReferenceIf = typename std::conditional<isConst, const T &, T &>::type; 64 65template<bool isConst> 66using ImportTraverser = std::function<void(ConstReferenceIf<isConst, std::string>)>; 67 68template <bool isConst> 69void VisitStaticImports(ConstReferenceIf<isConst, pandasm::Program> program, 70 ConstReferenceIf<isConst, pandasm::Record> record, 71 const ImportTraverser<isConst> &cb) 72{ 73 for (const pandasm::Field &field : record.field_list) { 74 if (field.name == util::MODULE_RECORD_IDX) { 75 auto moduleLiteralKey = field.metadata->GetValue().value().GetValue<std::string>(); 76 auto iter = program.literalarray_table.find(moduleLiteralKey); 77 ASSERT(iter != program.literalarray_table.end()); 78 auto &array = iter->second; 79 uint32_t importSize = std::get<uint32_t>(iter->second.literals_[0].value_); 80 for (size_t idx = 1; idx < importSize + 1; ++idx) { 81 cb(std::get<std::string>(array.literals_[idx].value_)); 82 } 83 } 84 } 85} 86 87// Only visit dynamic imports for import("xxxx") expression 88template <bool isConst> 89void VisitDyanmicImports(ConstReferenceIf<isConst, pandasm::Function> function, const ImportTraverser<isConst> &cb) 90{ 91 for (auto iter = function.ins.begin(); iter != function.ins.end(); iter++) { 92 // Only visit dynamic imports for import("xxxx") expression, whose bytecode always is: 93 // lda.str -> dynamicimport 94 // The dynamicimport bytecode should not have label, otherwise the dyanmicimport might be a jump 95 // target and its parameter is a variable instead of a constant string expression (Check 96 // AbcCodeProcessor::AddJumpLabels for more details). 97 if (iter->opcode != pandasm::Opcode::DYNAMICIMPORT || iter->set_label) { 98 continue; 99 } 100 auto prevIns = iter - 1; 101 if (prevIns->opcode != pandasm::Opcode::LDA_STR) { 102 continue; 103 } 104 ASSERT(prevIns->ids.size() == 1); 105 cb(prevIns->ids[0]); // 0: index of the string in lda.str bytecode 106 } 107} 108} // namespace panda::es2panda::util 109 110#endif