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_MANAGER_H 17 #define ECMASCRIPT_MODULE_JS_MODULE_MANAGER_H 18 19 #include "ecmascript/js_tagged_value-inl.h" 20 #include "ecmascript/jspandafile/js_pandafile.h" 21 #include "ecmascript/module/js_module_source_text.h" 22 #include "ecmascript/napi/jsnapi_helper.h" 23 #include "ecmascript/tagged_dictionary.h" 24 #include "ecmascript/module/module_manager_map.h" 25 26 namespace panda::ecmascript { 27 enum class ModuleExecuteMode { 28 ExecuteZipMode, 29 ExecuteBufferMode 30 }; 31 class ModuleManager { 32 public: 33 explicit ModuleManager(EcmaVM *vm); ~ModuleManager()34 ~ModuleManager() 35 { 36 resolvedModules_.Clear(); 37 } 38 39 JSHandle<SourceTextModule> GetImportedModule(const CString &referencing); 40 JSHandle<SourceTextModule> PUBLIC_API HostGetImportedModule(const CString &referencing); 41 JSTaggedValue HostGetImportedModule(void *src); 42 bool IsLocalModuleLoaded(const CString& referencing); 43 bool IsSharedModuleLoaded(const CString &referencing); 44 bool IsModuleLoaded(const CString &referencing); 45 46 bool IsEvaluatedModule(const CString &referencing); 47 bool IsInstantiatedModule(const CString &referencing); 48 bool IsLocalModuleInstantiated(const CString &referencing); 49 bool NeedExecuteModule(const CString &referencing); 50 51 JSHandle<JSTaggedValue> LoadNativeModule(JSThread *thread, const CString &key); 52 53 JSHandle<JSTaggedValue> ExecuteNativeModuleMayThrowError(JSThread *thread, const CString &recordName); 54 55 JSHandle<JSTaggedValue> ExecuteNativeModule(JSThread *thread, const CString &recordName); 56 57 JSHandle<JSTaggedValue> ExecuteJsonModule(JSThread *thread, const CString &recordName, 58 const CString &filename, const JSPandaFile *jsPandaFile); 59 JSHandle<JSTaggedValue> ExecuteCjsModule(JSThread *thread, const CString &recordName, 60 const JSPandaFile *jsPandaFile); 61 62 JSHandle<JSTaggedValue> GenerateSendableFuncModule(const JSHandle<JSTaggedValue> &module); 63 64 JSHandle<JSTaggedValue> TryGetImportedModule(const CString& referencing); 65 void Iterate(RootVisitor &v); 66 GetExecuteMode()67 ModuleExecuteMode GetExecuteMode() const 68 { 69 return isExecuteBuffer_.load(std::memory_order_acquire); 70 } SetExecuteMode(ModuleExecuteMode mode)71 inline void SetExecuteMode(ModuleExecuteMode mode) 72 { 73 isExecuteBuffer_.store(mode, std::memory_order_release); 74 } 75 76 static CString PUBLIC_API GetRecordName(const JSThread *thread, JSTaggedValue module); 77 static int GetExportObjectIndex(EcmaVM *vm, JSHandle<SourceTextModule> ecmaModule, const CString &key); 78 NextModuleAsyncEvaluatingOrdinal()79 uint32_t NextModuleAsyncEvaluatingOrdinal() 80 { 81 uint32_t ordinal = nextModuleAsyncEvaluatingOrdinal_++; 82 return ordinal; 83 } 84 AddResolveImportedModule(const CString & recordName,JSTaggedValue module)85 inline void AddResolveImportedModule(const CString &recordName, JSTaggedValue module) 86 { 87 resolvedModules_.Emplace(recordName, module); 88 } 89 UpdateResolveImportedModule(const CString & recordName,JSTaggedValue module)90 inline void UpdateResolveImportedModule(const CString &recordName, JSTaggedValue module) 91 { 92 resolvedModules_.Insert(recordName, module); 93 } 94 NativeObjDestory()95 void NativeObjDestory() 96 { 97 resolvedModules_.ForEach([](auto it) { 98 CString key = it->first; 99 ASSERT(!key.empty()); 100 GCRoot &root = it->second; 101 JSTaggedValue module = root.Read(); 102 SourceTextModule::Cast(module)->DestoryLazyImportArray(); 103 SourceTextModule::Cast(module)->DestoryEcmaModuleFilenameString(); 104 SourceTextModule::Cast(module)->DestoryEcmaModuleRecordNameString(); 105 }); 106 } 107 GetResolvedModulesSize()108 inline uint32_t GetResolvedModulesSize() const 109 { 110 return resolvedModules_.Size(); 111 } 112 AddNormalSerializeModule(JSThread * thread,JSHandle<TaggedArray> serializerArray,uint32_t idx)113 inline void AddNormalSerializeModule(JSThread *thread, JSHandle<TaggedArray> serializerArray, uint32_t idx) 114 { 115 resolvedModules_.ForEach( 116 [thread, &idx, serializerArray](auto it) { serializerArray->Set(thread, idx++, it->second.Read()); }); 117 } 118 IsVMBundlePack()119 inline bool IsVMBundlePack() 120 { 121 return vm_->IsBundlePack(); 122 } 123 static JSTaggedValue CreateModuleManagerNativePointer(JSThread *thread); 124 void SyncModuleExecuteMode(JSThread *thread); 125 126 // fast path ldexternalmodulevar for jit 127 static bool CheckModuleValueOutterResolved(JSThread *thread, int32_t index, JSFunction *jsFunc); 128 static JSTaggedValue GetExternalModuleVarFastPathForJIT(JSThread *thread, int32_t index, JSFunction *jsFunc); 129 130 // for ut ClearResolvedModules()131 void ClearResolvedModules() 132 { 133 resolvedModules_.Clear(); 134 } 135 136 private: 137 NO_COPY_SEMANTIC(ModuleManager); 138 NO_MOVE_SEMANTIC(ModuleManager); 139 140 void RemoveModuleFromCache(const CString &recordName); 141 142 void RemoveModuleNameFromList(const CString &recordName); 143 144 static constexpr uint32_t DEAULT_DICTIONART_CAPACITY = 4; 145 146 uint32_t nextModuleAsyncEvaluatingOrdinal_{SourceTextModule::FIRST_ASYNC_EVALUATING_ORDINAL}; 147 148 EcmaVM *vm_ {nullptr}; 149 ModuleManagerMap<CString> resolvedModules_; 150 std::atomic<ModuleExecuteMode> isExecuteBuffer_ {ModuleExecuteMode::ExecuteZipMode}; 151 152 friend class EcmaVM; 153 friend class PatchLoader; 154 friend class ModuleDeregister; 155 friend class SharedModuleManager; 156 }; 157 } // namespace panda::ecmascript 158 #endif // ECMASCRIPT_MODULE_JS_MODULE_MANAGER_H 159