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