14514f5e3Sopenharmony_ci/*
24514f5e3Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License.
54514f5e3Sopenharmony_ci * You may obtain a copy of the License at
64514f5e3Sopenharmony_ci *
74514f5e3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
84514f5e3Sopenharmony_ci *
94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and
134514f5e3Sopenharmony_ci * limitations under the License.
144514f5e3Sopenharmony_ci */
154514f5e3Sopenharmony_ci
164514f5e3Sopenharmony_ci#ifndef ECMASCRIPT_MODULE_JS_MODULE_MANAGER_H
174514f5e3Sopenharmony_ci#define ECMASCRIPT_MODULE_JS_MODULE_MANAGER_H
184514f5e3Sopenharmony_ci
194514f5e3Sopenharmony_ci#include "ecmascript/js_tagged_value-inl.h"
204514f5e3Sopenharmony_ci#include "ecmascript/jspandafile/js_pandafile.h"
214514f5e3Sopenharmony_ci#include "ecmascript/module/js_module_source_text.h"
224514f5e3Sopenharmony_ci#include "ecmascript/napi/jsnapi_helper.h"
234514f5e3Sopenharmony_ci#include "ecmascript/tagged_dictionary.h"
244514f5e3Sopenharmony_ci
254514f5e3Sopenharmony_cinamespace panda::ecmascript {
264514f5e3Sopenharmony_cienum class ModuleExecuteMode {
274514f5e3Sopenharmony_ci    ExecuteZipMode,
284514f5e3Sopenharmony_ci    ExecuteBufferMode
294514f5e3Sopenharmony_ci};
304514f5e3Sopenharmony_ciclass ModuleManager {
314514f5e3Sopenharmony_cipublic:
324514f5e3Sopenharmony_ci    explicit ModuleManager(EcmaVM *vm);
334514f5e3Sopenharmony_ci    ~ModuleManager()
344514f5e3Sopenharmony_ci    {
354514f5e3Sopenharmony_ci        InstantiatingSModuleList_.clear();
364514f5e3Sopenharmony_ci        resolvedModules_.clear();
374514f5e3Sopenharmony_ci    }
384514f5e3Sopenharmony_ci
394514f5e3Sopenharmony_ci    JSTaggedValue GetModuleValueInner(int32_t index);
404514f5e3Sopenharmony_ci    JSTaggedValue GetModuleValueInner(int32_t index, JSTaggedValue jsFunc);
414514f5e3Sopenharmony_ci    JSTaggedValue GetModuleValueInner(int32_t index, JSHandle<JSTaggedValue> currentModule);
424514f5e3Sopenharmony_ci    JSTaggedValue GetModuleValueOutter(int32_t index);
434514f5e3Sopenharmony_ci    JSTaggedValue GetModuleValueOutter(int32_t index, JSTaggedValue jsFunc);
444514f5e3Sopenharmony_ci    JSTaggedValue GetModuleValueOutter(int32_t index, JSHandle<JSTaggedValue> currentModule);
454514f5e3Sopenharmony_ci    JSTaggedValue GetLazyModuleValueOutter(int32_t index, JSTaggedValue jsFunc);
464514f5e3Sopenharmony_ci    void StoreModuleValue(int32_t index, JSTaggedValue value);
474514f5e3Sopenharmony_ci    void StoreModuleValue(int32_t index, JSTaggedValue value, JSTaggedValue jsFunc);
484514f5e3Sopenharmony_ci    JSTaggedValue GetModuleNamespace(int32_t index);
494514f5e3Sopenharmony_ci    JSTaggedValue GetModuleNamespace(int32_t index, JSTaggedValue currentFunc);
504514f5e3Sopenharmony_ci    JSTaggedValue GetModuleNamespaceInternal(int32_t index, JSTaggedValue currentModule);
514514f5e3Sopenharmony_ci
524514f5e3Sopenharmony_ci    // deprecated begin
534514f5e3Sopenharmony_ci    JSTaggedValue GetModuleValueInner(JSTaggedValue key);
544514f5e3Sopenharmony_ci    JSTaggedValue GetModuleValueInner(JSTaggedValue key, JSTaggedValue jsFunc);
554514f5e3Sopenharmony_ci    JSTaggedValue GetModuleValueOutter(JSTaggedValue key);
564514f5e3Sopenharmony_ci    JSTaggedValue GetModuleValueOutter(JSTaggedValue key, JSTaggedValue jsFunc);
574514f5e3Sopenharmony_ci    void StoreModuleValue(JSTaggedValue key, JSTaggedValue value);
584514f5e3Sopenharmony_ci    void StoreModuleValue(JSTaggedValue key, JSTaggedValue value, JSTaggedValue jsFunc);
594514f5e3Sopenharmony_ci    JSTaggedValue GetModuleNamespace(JSTaggedValue localName);
604514f5e3Sopenharmony_ci    JSTaggedValue GetModuleNamespace(JSTaggedValue localName, JSTaggedValue currentFunc);
614514f5e3Sopenharmony_ci    JSTaggedValue GetModuleNamespaceInternal(JSTaggedValue localName, JSTaggedValue currentModule);
624514f5e3Sopenharmony_ci    // deprecated end
634514f5e3Sopenharmony_ci
644514f5e3Sopenharmony_ci    JSHandle<SourceTextModule> GetImportedModule(const CString &referencing);
654514f5e3Sopenharmony_ci    JSHandle<SourceTextModule> PUBLIC_API HostGetImportedModule(const CString &referencing);
664514f5e3Sopenharmony_ci    JSTaggedValue HostGetImportedModule(void *src);
674514f5e3Sopenharmony_ci    bool IsLocalModuleLoaded(const CString& referencing);
684514f5e3Sopenharmony_ci    bool IsSharedModuleLoaded(const CString &referencing);
694514f5e3Sopenharmony_ci    bool IsModuleLoaded(const CString &referencing);
704514f5e3Sopenharmony_ci
714514f5e3Sopenharmony_ci    bool IsEvaluatedModule(const CString &referencing);
724514f5e3Sopenharmony_ci    bool IsInstantiatedModule(const CString &referencing);
734514f5e3Sopenharmony_ci    bool IsLocalModuleInstantiated(const CString &referencing);
744514f5e3Sopenharmony_ci
754514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> ResolveNativeModule(const CString &moduleRequest, const CString &baseFileName,
764514f5e3Sopenharmony_ci        ModuleTypes moduleType);
774514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> HostResolveImportedModule(const void *buffer, size_t size, const CString &filename);
784514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> HostResolveImportedModule(const CString &referencingModule,
794514f5e3Sopenharmony_ci        bool executeFromJob = false);
804514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> PUBLIC_API HostResolveImportedModuleWithMerge(const CString &referencingModule,
814514f5e3Sopenharmony_ci        const CString &recordName, bool executeFromJob = false);
824514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> PUBLIC_API HostResolveImportedModuleWithMergeForHotReload(const CString &referencingModule,
834514f5e3Sopenharmony_ci        const CString &recordName, bool executeFromJob = false);
844514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> HostResolveImportedModule(const JSPandaFile *jsPandaFile, const CString &filename);
854514f5e3Sopenharmony_ci
864514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> LoadNativeModule(JSThread *thread, const CString &key);
874514f5e3Sopenharmony_ci
884514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> ExecuteNativeModuleMayThrowError(JSThread *thread, const CString &recordName);
894514f5e3Sopenharmony_ci
904514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> ExecuteNativeModule(JSThread *thread, const CString &recordName);
914514f5e3Sopenharmony_ci
924514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> ExecuteJsonModule(JSThread *thread, const CString &recordName,
934514f5e3Sopenharmony_ci                                              const CString &filename, const JSPandaFile *jsPandaFile);
944514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> ExecuteCjsModule(JSThread *thread, const CString &recordName,
954514f5e3Sopenharmony_ci                                             const JSPandaFile *jsPandaFile);
964514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> GetModuleNameSpaceFromFile(
974514f5e3Sopenharmony_ci        JSThread *thread, const CString &recordNameStr, const CString &baseFileName);
984514f5e3Sopenharmony_ci
994514f5e3Sopenharmony_ci    JSTaggedValue GetCurrentModule();
1004514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> GenerateSendableFuncModule(const JSHandle<JSTaggedValue> &module);
1014514f5e3Sopenharmony_ci
1024514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> TryGetImportedModule(const CString& referencing);
1034514f5e3Sopenharmony_ci    void Iterate(const RootVisitor &v);
1044514f5e3Sopenharmony_ci
1054514f5e3Sopenharmony_ci    ModuleExecuteMode GetExecuteMode() const
1064514f5e3Sopenharmony_ci    {
1074514f5e3Sopenharmony_ci        return isExecuteBuffer_.load(std::memory_order_acquire);
1084514f5e3Sopenharmony_ci    }
1094514f5e3Sopenharmony_ci    void SetExecuteMode(ModuleExecuteMode mode)
1104514f5e3Sopenharmony_ci    {
1114514f5e3Sopenharmony_ci        isExecuteBuffer_.store(mode, std::memory_order_release);
1124514f5e3Sopenharmony_ci    }
1134514f5e3Sopenharmony_ci
1144514f5e3Sopenharmony_ci    static CString PUBLIC_API GetRecordName(JSTaggedValue module);
1154514f5e3Sopenharmony_ci    static int GetExportObjectIndex(EcmaVM *vm, JSHandle<SourceTextModule> ecmaModule, const CString &key);
1164514f5e3Sopenharmony_ci
1174514f5e3Sopenharmony_ci    uint32_t NextModuleAsyncEvaluatingOrdinal()
1184514f5e3Sopenharmony_ci    {
1194514f5e3Sopenharmony_ci        uint32_t ordinal = nextModuleAsyncEvaluatingOrdinal_++;
1204514f5e3Sopenharmony_ci        return ordinal;
1214514f5e3Sopenharmony_ci    }
1224514f5e3Sopenharmony_ci    inline void AddResolveImportedModule(const CString &recordName, JSTaggedValue module)
1234514f5e3Sopenharmony_ci    {
1244514f5e3Sopenharmony_ci        resolvedModules_.emplace(recordName, module);
1254514f5e3Sopenharmony_ci    }
1264514f5e3Sopenharmony_ci
1274514f5e3Sopenharmony_ci    inline void UpdateResolveImportedModule(const CString &recordName, JSTaggedValue module)
1284514f5e3Sopenharmony_ci    {
1294514f5e3Sopenharmony_ci        resolvedModules_[recordName] = module;
1304514f5e3Sopenharmony_ci    }
1314514f5e3Sopenharmony_ci
1324514f5e3Sopenharmony_ci    void NativeObjDestory()
1334514f5e3Sopenharmony_ci    {
1344514f5e3Sopenharmony_ci        for (auto it = resolvedModules_.begin(); it != resolvedModules_.end(); it++) {
1354514f5e3Sopenharmony_ci            CString key = it->first;
1364514f5e3Sopenharmony_ci            ASSERT(!key.empty());
1374514f5e3Sopenharmony_ci            JSTaggedValue module = it->second;
1384514f5e3Sopenharmony_ci            SourceTextModule::Cast(module)->DestoryLazyImportArray();
1394514f5e3Sopenharmony_ci            SourceTextModule::Cast(module)->DestoryEcmaModuleFilenameString();
1404514f5e3Sopenharmony_ci            SourceTextModule::Cast(module)->DestoryEcmaModuleRecordNameString();
1414514f5e3Sopenharmony_ci        }
1424514f5e3Sopenharmony_ci    }
1434514f5e3Sopenharmony_ci
1444514f5e3Sopenharmony_ciprivate:
1454514f5e3Sopenharmony_ci    NO_COPY_SEMANTIC(ModuleManager);
1464514f5e3Sopenharmony_ci    NO_MOVE_SEMANTIC(ModuleManager);
1474514f5e3Sopenharmony_ci
1484514f5e3Sopenharmony_ci    JSTaggedValue GetModuleValueOutterInternal(int32_t index, JSTaggedValue currentModule);
1494514f5e3Sopenharmony_ci    void StoreModuleValueInternal(JSHandle<SourceTextModule> &currentModule,
1504514f5e3Sopenharmony_ci                                  int32_t index, JSTaggedValue value);
1514514f5e3Sopenharmony_ci
1524514f5e3Sopenharmony_ci    JSTaggedValue GetLazyModuleValueOutterInternal(int32_t index, JSTaggedValue currentModule);
1534514f5e3Sopenharmony_ci
1544514f5e3Sopenharmony_ci    // deprecated begin
1554514f5e3Sopenharmony_ci    JSTaggedValue GetModuleValueOutterInternal(JSTaggedValue key, JSTaggedValue currentModule);
1564514f5e3Sopenharmony_ci    void StoreModuleValueInternal(JSHandle<SourceTextModule> &currentModule,
1574514f5e3Sopenharmony_ci                                  JSTaggedValue key, JSTaggedValue value);
1584514f5e3Sopenharmony_ci    // deprecated end
1594514f5e3Sopenharmony_ci
1604514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> ResolveModule(JSThread *thread, const JSPandaFile *jsPandaFile,
1614514f5e3Sopenharmony_ci        bool executeFromJob = false);
1624514f5e3Sopenharmony_ci
1634514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> ResolveModuleWithMerge(JSThread *thread, const JSPandaFile *jsPandaFile,
1644514f5e3Sopenharmony_ci        const CString &recordName, bool executeFromJob = false);
1654514f5e3Sopenharmony_ci
1664514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> CommonResolveImportedModuleWithMerge(const CString &moduleFileName,
1674514f5e3Sopenharmony_ci        const CString &recordName, bool executeFromJob = false);
1684514f5e3Sopenharmony_ci
1694514f5e3Sopenharmony_ci    void AddToInstantiatingSModuleList(const CString &record);
1704514f5e3Sopenharmony_ci
1714514f5e3Sopenharmony_ci    CVector<CString> GetInstantiatingSModuleList();
1724514f5e3Sopenharmony_ci
1734514f5e3Sopenharmony_ci    void ClearInstantiatingSModuleList();
1744514f5e3Sopenharmony_ci
1754514f5e3Sopenharmony_ci    void RemoveModuleFromCache(const CString &recordName);
1764514f5e3Sopenharmony_ci
1774514f5e3Sopenharmony_ci    void RemoveModuleNameFromList(const CString &recordName);
1784514f5e3Sopenharmony_ci
1794514f5e3Sopenharmony_ci    static constexpr uint32_t DEAULT_DICTIONART_CAPACITY = 4;
1804514f5e3Sopenharmony_ci
1814514f5e3Sopenharmony_ci    uint32_t nextModuleAsyncEvaluatingOrdinal_{SourceTextModule::FIRST_ASYNC_EVALUATING_ORDINAL};
1824514f5e3Sopenharmony_ci
1834514f5e3Sopenharmony_ci    EcmaVM *vm_ {nullptr};
1844514f5e3Sopenharmony_ci    CUnorderedMap<CString, JSTaggedValue> resolvedModules_;
1854514f5e3Sopenharmony_ci    std::atomic<ModuleExecuteMode> isExecuteBuffer_ {ModuleExecuteMode::ExecuteZipMode};
1864514f5e3Sopenharmony_ci    CVector<CString> InstantiatingSModuleList_;
1874514f5e3Sopenharmony_ci
1884514f5e3Sopenharmony_ci    friend class EcmaVM;
1894514f5e3Sopenharmony_ci    friend class PatchLoader;
1904514f5e3Sopenharmony_ci    friend class ModuleDeregister;
1914514f5e3Sopenharmony_ci    friend class SharedModuleManager;
1924514f5e3Sopenharmony_ci};
1934514f5e3Sopenharmony_ci} // namespace panda::ecmascript
1944514f5e3Sopenharmony_ci#endif // ECMASCRIPT_MODULE_JS_MODULE_MANAGER_H
195