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 #ifndef ECMASCRIPT_MODULE_JS_MODULE_SOURCE_TEXT_H 17 #define ECMASCRIPT_MODULE_JS_MODULE_SOURCE_TEXT_H 18 19 #include "ecmascript/base/string_helper.h" 20 #include "ecmascript/mem/c_containers.h" 21 #include "ecmascript/module/js_module_record.h" 22 #include "ecmascript/module/js_module_entry.h" 23 #include "ecmascript/tagged_array.h" 24 25 namespace panda::ecmascript { 26 enum class ModuleStatus : uint8_t { UNINSTANTIATED = 0x01, INSTANTIATING, INSTANTIATED, EVALUATING, EVALUATED }; 27 28 enum class ModuleTypes : uint8_t { 29 ECMA_MODULE = 0x01, 30 CJS_MODULE, 31 JSON_MODULE, 32 NATIVE_MODULE, 33 OHOS_MODULE, 34 APP_MODULE, 35 INTERNAL_MODULE, 36 UNKNOWN 37 }; 38 39 enum class LoadingTypes : uint8_t { 40 STABLE_MODULE = 0x01, 41 DYNAMITC_MODULE, 42 OTHERS 43 }; 44 45 class SourceTextModule final : public ModuleRecord { 46 public: 47 static constexpr int UNDEFINED_INDEX = -1; 48 static constexpr size_t DEFAULT_DICTIONART_CAPACITY = 2; 49 static constexpr size_t DEFAULT_ARRAY_CAPACITY = 2; 50 static constexpr uint8_t DEREGISTER_MODULE_TAG = 1; 51 52 CAST_CHECK(SourceTextModule, IsSourceTextModule); 53 54 // 15.2.1.17 Runtime Semantics: HostResolveImportedModule ( referencingModule, specifier ) 55 static JSHandle<JSTaggedValue> HostResolveImportedModule(JSThread *thread, 56 const JSHandle<SourceTextModule> &module, 57 const JSHandle<JSTaggedValue> &moduleRequest); 58 static JSHandle<JSTaggedValue> HostResolveImportedModuleWithMerge(JSThread *thread, 59 const JSHandle<SourceTextModule> &module, 60 const JSHandle<JSTaggedValue> &moduleRequest); 61 62 // 15.2.1.16.2 GetExportedNames(exportStarSet) 63 static CVector<std::string> GetExportedNames(JSThread *thread, const JSHandle<SourceTextModule> &module, 64 const JSHandle<TaggedArray> &exportStarSet); 65 66 // 15.2.1.16.3 ResolveExport(exportName, resolveVector) 67 static JSHandle<JSTaggedValue> ResolveExport(JSThread *thread, const JSHandle<SourceTextModule> &module, 68 const JSHandle<JSTaggedValue> &exportName, 69 CVector<std::pair<JSHandle<SourceTextModule>, JSHandle<JSTaggedValue>>> &resolveVector); 70 static JSHandle<JSTaggedValue> ResolveExportObject(JSThread *thread, const JSHandle<SourceTextModule> &module, 71 const JSHandle<JSTaggedValue> &exportObject, 72 const JSHandle<JSTaggedValue> &exportName); 73 // 15.2.1.16.4.1 InnerModuleInstantiation ( module, stack, index ) 74 static int InnerModuleInstantiation(JSThread *thread, 75 const JSHandle<ModuleRecord> &moduleRecord, CVector<JSHandle<SourceTextModule>> &stack, 76 int index, bool excuteFromJob = false); 77 78 // 15.2.1.16.4.2 ModuleDeclarationEnvironmentSetup ( module ) 79 static void ModuleDeclarationEnvironmentSetup(JSThread *thread, const JSHandle<SourceTextModule> &module); 80 static void ModuleDeclarationArrayEnvironmentSetup(JSThread *thread, const JSHandle<SourceTextModule> &module); 81 82 // 15.2.1.16.5.1 InnerModuleEvaluation ( module, stack, index ) 83 static int InnerModuleEvaluation(JSThread *thread, const JSHandle<ModuleRecord> &moduleRecord, 84 CVector<JSHandle<SourceTextModule>> &stack, int index, const void *buffer = nullptr, 85 size_t size = 0, bool excuteFromJob = false); 86 static int ModuleEvaluation(JSThread *thread, const JSHandle<ModuleRecord> &moduleRecord, 87 CVector<JSHandle<SourceTextModule>> &stack, int index); 88 89 // 15.2.1.16.5.2 ModuleExecution ( module ) 90 static void ModuleExecution(JSThread *thread, const JSHandle<SourceTextModule> &module, 91 const void *buffer = nullptr, size_t size = 0, bool excuteFromJob = false); 92 93 // 15.2.1.18 Runtime Semantics: GetModuleNamespace ( module ) 94 static JSHandle<JSTaggedValue> GetModuleNamespace(JSThread *thread, const JSHandle<SourceTextModule> &module); 95 96 static void AddImportEntry(JSThread *thread, const JSHandle<SourceTextModule> &module, 97 const JSHandle<ImportEntry> &importEntry, size_t idx, uint32_t len); 98 static void AddLocalExportEntry(JSThread *thread, const JSHandle<SourceTextModule> &module, 99 const JSHandle<LocalExportEntry> &exportEntry, size_t idx, uint32_t len); 100 static void AddIndirectExportEntry(JSThread *thread, const JSHandle<SourceTextModule> &module, 101 const JSHandle<IndirectExportEntry> &exportEntry, size_t idx, uint32_t len); 102 static void AddStarExportEntry(JSThread *thread, const JSHandle<SourceTextModule> &module, 103 const JSHandle<StarExportEntry> &exportEntry, size_t idx, uint32_t len); 104 static std::pair<bool, ModuleTypes> CheckNativeModule(const CString &moduleRequestName); 105 static Local<JSValueRef> GetRequireNativeModuleFunc(EcmaVM *vm, ModuleTypes moduleType); 106 static void MakeAppArgs(const EcmaVM *vm, std::vector<Local<JSValueRef>> &arguments, const CString &moduleName); 107 static void MakeInternalArgs(const EcmaVM *vm, std::vector<Local<JSValueRef>> &arguments, 108 const CString &moduleRequestName); 109 static bool LoadNativeModule(JSThread *thread, JSHandle<SourceTextModule> &requiredModule, 110 const JSHandle<JSTaggedValue> &moduleRequest, ModuleTypes moduleType); IsNativeModule(ModuleTypes moduleType)111 inline static bool IsNativeModule(ModuleTypes moduleType) 112 { 113 return moduleType == ModuleTypes::OHOS_MODULE || 114 moduleType == ModuleTypes::APP_MODULE || 115 moduleType == ModuleTypes::NATIVE_MODULE || 116 moduleType == ModuleTypes::INTERNAL_MODULE; 117 } 118 119 static constexpr size_t SOURCE_TEXT_MODULE_OFFSET = ModuleRecord::SIZE; 120 ACCESSORS(Environment, SOURCE_TEXT_MODULE_OFFSET, NAMESPACE_OFFSET); 121 ACCESSORS(Namespace, NAMESPACE_OFFSET, ECMA_MODULE_FILENAME); 122 ACCESSORS(EcmaModuleFilename, ECMA_MODULE_FILENAME, ECMA_MODULE_RECORDNAME); 123 ACCESSORS(EcmaModuleRecordName, ECMA_MODULE_RECORDNAME, REQUESTED_MODULES_OFFSET); 124 ACCESSORS(RequestedModules, REQUESTED_MODULES_OFFSET, IMPORT_ENTRIES_OFFSET); 125 ACCESSORS(ImportEntries, IMPORT_ENTRIES_OFFSET, LOCAL_EXPORT_ENTTRIES_OFFSET); 126 ACCESSORS(LocalExportEntries, LOCAL_EXPORT_ENTTRIES_OFFSET, INDIRECT_EXPORT_ENTTRIES_OFFSET); 127 ACCESSORS(IndirectExportEntries, INDIRECT_EXPORT_ENTTRIES_OFFSET, START_EXPORT_ENTTRIES_OFFSET); 128 ACCESSORS(StarExportEntries, START_EXPORT_ENTTRIES_OFFSET, NAME_DICTIONARY_OFFSET); 129 ACCESSORS(NameDictionary, NAME_DICTIONARY_OFFSET, EVALUATION_ERROR_OFFSET); 130 ACCESSORS_PRIMITIVE_FIELD(EvaluationError, int32_t, EVALUATION_ERROR_OFFSET, DFS_ANCESTOR_INDEX_OFFSET); 131 ACCESSORS_PRIMITIVE_FIELD(DFSAncestorIndex, int32_t, DFS_ANCESTOR_INDEX_OFFSET, DFS_INDEX_OFFSET); 132 ACCESSORS_PRIMITIVE_FIELD(DFSIndex, int32_t, DFS_INDEX_OFFSET, BIT_FIELD_OFFSET); 133 ACCESSORS_BIT_FIELD(BitField, BIT_FIELD_OFFSET, LAST_OFFSET) 134 135 DEFINE_ALIGN_SIZE(LAST_OFFSET); 136 137 // define BitField 138 static constexpr size_t STATUS_BITS = 3; 139 static constexpr size_t MODULE_TYPE_BITS = 4; 140 static constexpr size_t IS_NEW_BC_VERSION_BITS = 1; 141 static constexpr size_t LOADING_TYPE_BITS = 3; 142 static constexpr uint16_t REGISTER_COUNTS = 16; 143 144 FIRST_BIT_FIELD(BitField, Status, ModuleStatus, STATUS_BITS) 145 NEXT_BIT_FIELD(BitField, Types, ModuleTypes, MODULE_TYPE_BITS, Status) 146 NEXT_BIT_FIELD(BitField, IsNewBcVersion, bool, IS_NEW_BC_VERSION_BITS, Types) 147 NEXT_BIT_FIELD(BitField, LoadingTypes, LoadingTypes, LOADING_TYPE_BITS, IsNewBcVersion) 148 NEXT_BIT_FIELD(BitField, RegisterCounts, uint16_t, REGISTER_COUNTS, LoadingTypes) 149 150 DECL_DUMP() 151 DECL_VISIT_OBJECT(SOURCE_TEXT_MODULE_OFFSET, EVALUATION_ERROR_OFFSET) 152 153 // 15.2.1.16.5 Evaluate() 154 static int Evaluate(JSThread *thread, const JSHandle<SourceTextModule> &module, 155 const void *buffer = nullptr, size_t size = 0, bool excuteFromJob = false); 156 static int EvaluateForConcurrent(JSThread *thread, const JSHandle<SourceTextModule> &module); 157 158 // 15.2.1.16.4 Instantiate() 159 static int Instantiate(JSThread *thread, const JSHandle<JSTaggedValue> &moduleHdl, 160 bool excuteFromJob = false); 161 static void InstantiateCJS(JSThread *thread, const JSHandle<SourceTextModule> ¤tModule, 162 const JSHandle<SourceTextModule> &requiredModule); 163 static void InstantiateNativeModule(JSThread *thread, JSHandle<SourceTextModule> ¤tModule, 164 JSHandle<SourceTextModule> &requiredModule, 165 const JSHandle<JSTaggedValue> &moduleRequest, 166 ModuleTypes moduleType); 167 168 JSTaggedValue GetModuleValue(JSThread *thread, int32_t index, bool isThrow); 169 void StoreModuleValue(JSThread *thread, int32_t index, const JSHandle<JSTaggedValue> &value); 170 171 JSTaggedValue GetModuleValue(JSThread *thread, JSTaggedValue key, bool isThrow); 172 void StoreModuleValue(JSThread *thread, const JSHandle<JSTaggedValue> &key, const JSHandle<JSTaggedValue> &value); 173 static JSHandle<JSTaggedValue> ResolveIndirectExport(JSThread *thread, const JSHandle<JSTaggedValue> &exportEntry, 174 const JSHandle<JSTaggedValue> &exportName, 175 const JSHandle<SourceTextModule> &module, 176 CVector<std::pair<JSHandle<SourceTextModule>, 177 JSHandle<JSTaggedValue>>> &resolveVector); 178 static JSTaggedValue GetModuleName(JSTaggedValue currentModule); 179 180 static bool IsDynamicModule(LoadingTypes types); 181 private: 182 static void SetExportName(JSThread *thread, 183 const JSHandle<JSTaggedValue> &moduleRequest, const JSHandle<SourceTextModule> &module, 184 CVector<std::string> &exportedNames, JSHandle<TaggedArray> &newExportStarSet); 185 static JSHandle<JSTaggedValue> GetStarResolution(JSThread *thread, const JSHandle<JSTaggedValue> &exportName, 186 const JSHandle<JSTaggedValue> &moduleRequest, 187 const JSHandle<SourceTextModule> &module, 188 JSMutableHandle<JSTaggedValue> &starResolution, 189 CVector<std::pair<JSHandle<SourceTextModule>, 190 JSHandle<JSTaggedValue>>> &resolveVector); 191 template <typename T> 192 static void AddExportName(JSThread *thread, const JSTaggedValue &exportEntry, CVector<std::string> &exportedNames); 193 static JSHandle<JSTaggedValue> ResolveLocalExport(JSThread *thread, const JSHandle<JSTaggedValue> &exportEntry, 194 const JSHandle<JSTaggedValue> &exportName, 195 const JSHandle<SourceTextModule> &module); 196 static JSHandle<JSTaggedValue> ResolveElementOfObject(JSThread *thread, 197 const JSHandle<JSHClass> &hclass, 198 const JSHandle<JSTaggedValue> &exportName, 199 const JSHandle<SourceTextModule> &module); 200 static bool CheckCircularImport(const JSHandle<SourceTextModule> &module, 201 const JSHandle<JSTaggedValue> &exportName, 202 CVector<std::pair<JSHandle<SourceTextModule>, JSHandle<JSTaggedValue>>> &resolveVector); 203 static void InitializeEnvironment(JSThread *thread, const JSHandle<SourceTextModule> ¤tModule, 204 JSHandle<JSTaggedValue> &moduleName, JSHandle<JSTaggedValue> &exports, bool isBundle); 205 206 static void CheckResolvedBinding(JSThread *thread, const JSHandle<SourceTextModule> &module); 207 static void CheckResolvedIndexBinding(JSThread *thread, const JSHandle<SourceTextModule> &module); 208 static JSTaggedValue FindByExport(const JSTaggedValue &exportEntriesTv, const JSTaggedValue &key, 209 const JSTaggedValue &dictionary); 210 static JSHandle<SourceTextModule> GetModuleFromBinding(JSThread *thread, const JSTaggedValue &JSTaggedValue); 211 }; 212 213 class ResolvedBinding final : public Record { 214 public: 215 CAST_CHECK(ResolvedBinding, IsResolvedBinding); 216 217 static constexpr size_t MODULE_OFFSET = Record::SIZE; 218 ACCESSORS(Module, MODULE_OFFSET, BINDING_NAME_OFFSET); 219 ACCESSORS(BindingName, BINDING_NAME_OFFSET, SIZE); 220 221 DECL_DUMP() 222 DECL_VISIT_OBJECT(MODULE_OFFSET, SIZE) 223 }; 224 class ResolvedIndexBinding final : public Record { 225 public: 226 CAST_CHECK(ResolvedIndexBinding, IsResolvedIndexBinding); 227 228 static constexpr size_t MODULE_OFFSET = Record::SIZE; 229 ACCESSORS(Module, MODULE_OFFSET, INDEX_OFFSET); 230 ACCESSORS_PRIMITIVE_FIELD(Index, int32_t, INDEX_OFFSET, END_OFFSET); 231 DEFINE_ALIGN_SIZE(END_OFFSET); 232 233 DECL_DUMP() 234 DECL_VISIT_OBJECT(MODULE_OFFSET, INDEX_OFFSET) 235 }; 236 } // namespace panda::ecmascript 237 #endif // ECMASCRIPT_MODULE_JS_MODULE_SOURCE_TEXT_H 238