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