Refactoring ConcatFileNameWithMerge

issues:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I6BAYD

Signed-off-by: changjiaxing <changjiaxing2@huawei.com>
Change-Id: If11dc13131ef60d4760b31b68d2f7a6ce50c9597
This commit is contained in:
changjiaxing 2023-02-01 11:27:49 +08:00
parent 6dd7d9c0de
commit ac226d6806
15 changed files with 622 additions and 481 deletions

View File

@ -26,6 +26,33 @@
namespace panda::ecmascript::base {
class PathHelper {
public:
static constexpr char EXT_NAME_ABC[] = ".abc";
static constexpr char EXT_NAME_ETS[] = ".ets";
static constexpr char EXT_NAME_TS[] = ".ts";
static constexpr char EXT_NAME_JS[] = ".js";
static constexpr char EXT_NAME_JSON[] = ".json";
static constexpr char PREFIX_BUNDLE[] = "@bundle:";
static constexpr char PREFIX_MODULE[] = "@module:";
static constexpr char PREFIX_PACKAGE[] = "@package:";
static constexpr char NPM_PATH_SEGMENT[] = "node_modules";
static constexpr char NPM_ENTRY_FILE[] = "/index";
static constexpr char BUNDLE_INSTALL_PATH[] = "/data/storage/el1/bundle/";
static constexpr char MERGE_ABC_ETS_MODULES[] = "/ets/modules.abc";
static constexpr char MODULE_DEFAULE_ETS[] = "/ets/";
static constexpr char BUNDLE_SUB_INSTALL_PATH[] = "/data/storage/el1/";
static constexpr char PREVIEW_OF_ACROSS_HAP_FLAG[] = "[preview]";
static constexpr size_t MAX_PACKGE_LEVEL = 1;
static constexpr size_t SEGMENTS_LIMIT_TWO = 2;
static constexpr size_t EXT_NAME_ABC_LEN = 4;
static constexpr size_t EXT_NAME_ETS_LEN = 4;
static constexpr size_t EXT_NAME_TS_LEN = 3;
static constexpr size_t EXT_NAME_JS_LEN = 3;
static constexpr size_t EXT_NAME_JSON_LEN = 5;
static constexpr size_t PREFIX_BUNDLE_LEN = 8;
static constexpr size_t PREFIX_MODULE_LEN = 8;
static constexpr size_t PREFIX_PACKAGE_LEN = 9;
static void ResolveCurrentPath(JSThread *thread,
JSMutableHandle<JSTaggedValue> &dirPath,
JSMutableHandle<JSTaggedValue> &fileName,
@ -60,6 +87,337 @@ public:
CString dirPathStr = fullName.substr(0, foundPos + 1);
return factory->NewFromUtf8(dirPathStr);
}
static CString NormalizePath(const CString &fileName)
{
if (fileName.find("//") == CString::npos && fileName.find("../") == CString::npos) {
return fileName;
}
const char delim = '/';
CString res = "";
size_t prev = 0;
size_t curr = fileName.find(delim);
CVector<CString> elems;
while (curr != CString::npos) {
if (curr > prev) {
CString elem = fileName.substr(prev, curr - prev);
if (elem.compare("..") == 0 && !elems.empty()) {
elems.pop_back();
prev = curr + 1;
curr = fileName.find(delim, prev);
continue;
}
elems.push_back(elem);
}
prev = curr + 1;
curr = fileName.find(delim, prev);
}
if (prev != fileName.size()) {
elems.push_back(fileName.substr(prev));
}
for (auto e : elems) {
if (res.size() == 0 && fileName.at(0) != delim) {
res.append(e);
continue;
}
res.append(1, delim).append(e);
}
return res;
}
static CString ParseOhmUrl(EcmaVM *vm, const CString &inputFileName, CString &outFileName)
{
CString bundleInstallName(BUNDLE_INSTALL_PATH);
size_t startStrLen = bundleInstallName.length();
size_t pos = CString::npos;
if (inputFileName.length() > startStrLen && inputFileName.compare(0, startStrLen, bundleInstallName) == 0) {
pos = startStrLen;
}
CString entryPoint;
if (pos != CString::npos) {
pos = inputFileName.find('/', startStrLen);
ASSERT(pos != CString::npos);
CString moduleName = inputFileName.substr(startStrLen, pos - startStrLen);
if (moduleName != vm->GetModuleName()) {
outFileName = CString(BUNDLE_INSTALL_PATH) + moduleName + CString(MERGE_ABC_ETS_MODULES);
}
entryPoint = vm->GetBundleName() + "/" + inputFileName.substr(startStrLen);
} else {
// Temporarily handle the relative path sent by arkui
if (inputFileName.find("@bundle:") != CString::npos) {
entryPoint = inputFileName.substr(PREFIX_BUNDLE_LEN);
outFileName = ParseNewPagesUrl(vm, entryPoint);
} else {
entryPoint = vm->GetBundleName() + "/" + vm->GetModuleName() + MODULE_DEFAULE_ETS + inputFileName;
}
}
if (StringEndWith(entryPoint, EXT_NAME_ABC, EXT_NAME_ABC_LEN)) {
entryPoint.erase(entryPoint.length() - EXT_NAME_ABC_LEN, EXT_NAME_ABC_LEN);
}
return entryPoint;
}
static CString ParseNewPagesUrl(EcmaVM *vm, const CString &entryPoint)
{
auto errorFun = [entryPoint](const size_t &pos) {
if (pos == CString::npos) {
LOG_ECMA(FATAL) << "ParseNewPagesUrl failed, please check Url " << entryPoint;
}
};
size_t bundleEndPos = entryPoint.find('/');
errorFun(bundleEndPos);
CString bundleName = entryPoint.substr(0, bundleEndPos);
size_t moduleStartPos = bundleEndPos + 1;
size_t moduleEndPos = entryPoint.find('/', moduleStartPos);
errorFun(moduleEndPos);
CString moduleName = entryPoint.substr(moduleStartPos, moduleEndPos - moduleStartPos);
CString baseFileName;
if (bundleName != vm->GetBundleName()) {
// Cross-application
baseFileName =
BUNDLE_INSTALL_PATH + bundleName + "/" + moduleName + "/" + moduleName + MERGE_ABC_ETS_MODULES;
} else if (moduleName != vm->GetModuleName()) {
// Intra-application cross hap
baseFileName = BUNDLE_INSTALL_PATH + moduleName + MERGE_ABC_ETS_MODULES;
} else {
baseFileName = "";
}
return baseFileName;
}
static std::string ParseHapPath(const CString &fileName)
{
CString bundleSubInstallName(BUNDLE_SUB_INSTALL_PATH);
size_t startStrLen = bundleSubInstallName.length();
if (fileName.length() > startStrLen && fileName.compare(0, startStrLen, bundleSubInstallName) == 0) {
CString hapPath = fileName.substr(startStrLen);
size_t pos = hapPath.find(MERGE_ABC_ETS_MODULES);
if (pos != CString::npos) {
return hapPath.substr(0, pos).c_str();
}
}
return "";
}
static void CroppingRecord(CString &recordName)
{
size_t pos = recordName.find('/');
if (pos != CString::npos) {
pos = recordName.find('/', pos + 1);
if (pos != CString::npos) {
recordName = recordName.substr(pos + 1);
}
}
}
static bool StringStartWith(const CString& str, const CString& startStr, size_t startStrLen)
{
return ((str.length() >= startStrLen) && (str.compare(0, startStrLen, startStr) == 0));
}
static bool StringEndWith(const CString& str, const CString& endStr, size_t endStrLen)
{
size_t len = str.length();
return ((len >= endStrLen) && (str.compare(len - endStrLen, endStrLen, endStr) == 0));
}
static void SplitString(const CString& str, CVector<CString>& out, size_t startPos, size_t times, char c = '/')
{
size_t left = startPos;
size_t pos = 0;
size_t index = 0;
while ((pos = str.find(c, left)) != CString::npos) {
if (index >= times) {
return;
}
out.emplace_back(str.substr(left, pos - left));
left = pos + 1;
index++;
}
if (index < times && left < str.length()) {
out.emplace_back(str.substr(left));
}
}
static CString ParsePreixBundle(const JSPandaFile *jsPandaFile, CString &baseFilename, CString moduleRecordName,
CString moduleRequestName)
{
CString entryPoint;
moduleRequestName = moduleRequestName.substr(PREFIX_BUNDLE_LEN);
entryPoint = moduleRequestName;
if (jsPandaFile->IsNewRecord()) {
CVector<CString> vec;
size_t index = 0;
SplitString(moduleRequestName, vec, 0, SEGMENTS_LIMIT_TWO);
if (vec.size() < SEGMENTS_LIMIT_TWO) {
LOG_ECMA(ERROR) << "SplitString filed, please check moduleRequestName";
return CString();
}
CString bundleName = vec[index++];
if (!StringStartWith(moduleRecordName, bundleName, bundleName.size())) {
CString moduleName = vec[index];
baseFilename = BUNDLE_INSTALL_PATH + bundleName + '/' + moduleName + '/' + moduleName +
MERGE_ABC_ETS_MODULES;
}
} else {
CroppingRecord(entryPoint);
}
return entryPoint;
}
static CString ParsePreixModule([[maybe_unused]] CString &baseFilename, [[maybe_unused]] CString moduleRecordName,
[[maybe_unused]] CString moduleRequestName)
{
CString entryPoint;
#if !defined(PANDA_TARGET_WINDOWS) && !defined(PANDA_TARGET_MACOS)
moduleRequestName = moduleRequestName.substr(PREFIX_MODULE_LEN);
CVector<CString> vec;
SplitString(moduleRecordName, vec, 0, 1);
SplitString(moduleRequestName, vec, 0, 1);
if (vec.size() < SEGMENTS_LIMIT_TWO) {
LOG_ECMA(ERROR) << "SplitString filed, please check moduleRequestName and moduleRecordName";
return CString();
}
size_t index = 0;
CString bundleName = vec[index++];
CString moduleName = vec[index];
baseFilename = BUNDLE_INSTALL_PATH + moduleName + MERGE_ABC_ETS_MODULES;
entryPoint = bundleName + '/' + moduleRequestName;
#else
entryPoint = PREVIEW_OF_ACROSS_HAP_FLAG;
LOG_NO_TAG(ERROR) << "[ArkRuntime Log] Importing shared package is not supported in the Previewer.";
#endif
return entryPoint;
}
static CString MakeNewRecord(const JSPandaFile *jsPandaFile, CString &baseFilename, CString &moduleRecordName,
CString &moduleRequestName)
{
CString entryPoint;
size_t pos = moduleRequestName.find("./");
if (pos == 0) {
moduleRequestName = moduleRequestName.substr(2); // 2 means jump "./"
}
pos = moduleRecordName.rfind('/');
if (pos != CString::npos) {
entryPoint = moduleRecordName.substr(0, pos + 1) + moduleRequestName;
} else {
entryPoint = moduleRequestName;
}
entryPoint = NormalizePath(entryPoint);
if (jsPandaFile->HasRecord(entryPoint)) {
return entryPoint;
}
// Possible import directory
entryPoint += NPM_ENTRY_FILE;
if (jsPandaFile->HasRecord(entryPoint)) {
return entryPoint;
}
// Execute abc locally
pos = baseFilename.rfind('/');
if (pos != CString::npos) {
baseFilename = baseFilename.substr(0, pos + 1) + moduleRequestName + EXT_NAME_ABC;
} else {
baseFilename = moduleRequestName + EXT_NAME_ABC;
}
pos = moduleRequestName.rfind('/');
if (pos != CString::npos) {
entryPoint = moduleRequestName.substr(pos + 1);
} else {
entryPoint = moduleRequestName;
}
return entryPoint;
}
static CString FindNpmEntryPoint(const JSPandaFile *jsPandaFile, CString &npmPackage)
{
CString entryPoint = jsPandaFile->FindNpmEntryPoint(npmPackage);
if (!entryPoint.empty()) {
return entryPoint;
}
npmPackage += NPM_ENTRY_FILE;
entryPoint = jsPandaFile->FindNpmEntryPoint(npmPackage);
if (!entryPoint.empty()) {
return entryPoint;
}
return CString();
}
static CString FindPackageInTopLevel(const JSPandaFile *jsPandaFile, const CString& requestName,
const CString &packagePath)
{
CString entryPoint;
for (size_t level = 0; level <= MAX_PACKGE_LEVEL; ++level) {
CString levelStr = std::to_string(level).c_str();
CString key = packagePath + "/" + levelStr + '/' + requestName;
entryPoint = FindNpmEntryPoint(jsPandaFile, key);
if (!entryPoint.empty()) {
return entryPoint;
}
}
return CString();
}
static CString ParseThirdPartyPackge(const JSPandaFile *jsPandaFile, CString &moduleRecordName,
CString &moduleRequestName, const CString &packagePath)
{
CString entryPoint;
size_t pos = moduleRecordName.find(packagePath);
CString key = "";
if (pos != CString::npos) {
auto info = const_cast<JSPandaFile *>(jsPandaFile)->FindRecordInfo(moduleRecordName);
CString PackageName = info.npmPackageName;
while ((pos = PackageName.rfind(packagePath)) != CString::npos) {
key = PackageName + '/' + packagePath + "/" + moduleRequestName;
entryPoint = FindNpmEntryPoint(jsPandaFile, key);
if (!entryPoint.empty()) {
return entryPoint;
}
PackageName = PackageName.substr(0, pos > 0 ? pos - 1 : 0);
}
}
entryPoint = FindPackageInTopLevel(jsPandaFile, moduleRequestName, packagePath);
if (entryPoint.empty()) {
LOG_ECMA(ERROR) << "find entryPoint failed\n"
<< "moduleRequestName : " << moduleRequestName << "\n"
<< "moduleRecordName : " << moduleRecordName << "\n";
}
return entryPoint;
}
static bool CheckAndRemoveSuffix(CString &moduleRequestName)
{
size_t pos = moduleRequestName.rfind('.');
if (pos != CString::npos) {
CString suffix = moduleRequestName.substr(pos);
if (suffix == EXT_NAME_ETS || suffix == EXT_NAME_TS || suffix == EXT_NAME_JS || suffix == EXT_NAME_JSON) {
moduleRequestName.erase(pos, suffix.length());
return true;
}
}
return moduleRequestName.find("./") == 0 || moduleRequestName.find("../") == 0;
}
static CString ConcatFileNameWithMerge(const JSPandaFile *jsPandaFile, CString &baseFilename,
CString moduleRecordName, CString moduleRequestName)
{
CString entryPoint;
if (StringStartWith(moduleRequestName, PREFIX_BUNDLE, PREFIX_BUNDLE_LEN)) {
entryPoint = ParsePreixBundle(jsPandaFile, baseFilename, moduleRecordName, moduleRequestName);
} else if (StringStartWith(moduleRequestName, PREFIX_MODULE, PREFIX_MODULE_LEN)) {
entryPoint = ParsePreixModule(baseFilename, moduleRecordName, moduleRequestName);
} else if (StringStartWith(moduleRequestName, PREFIX_PACKAGE, PREFIX_PACKAGE_LEN)) {
entryPoint = moduleRequestName.substr(PREFIX_PACKAGE_LEN);
} else if (CheckAndRemoveSuffix(moduleRequestName)) {
entryPoint = MakeNewRecord(jsPandaFile, baseFilename, moduleRecordName, moduleRequestName);
} else {
entryPoint = ParseThirdPartyPackge(jsPandaFile, moduleRecordName, moduleRequestName, NPM_PATH_SEGMENT);
}
return entryPoint;
}
};
} // namespace panda::ecmascript::base
#endif // ECMASCRIPT_BASE_PATH_HELPER_H

View File

@ -168,8 +168,7 @@ JSTaggedValue BuiltinsPromiseJob::DynamicImportJob(EcmaRuntimeCallInfo *argv)
THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
}
entryPoint =
ModuleManager::ConcatFileNameWithMerge(jsPandaFile, baseFilename, recordNameStr, requestModule);
entryPoint = PathHelper::ConcatFileNameWithMerge(jsPandaFile, baseFilename, recordNameStr, requestModule);
fileNameStr = baseFilename;
moduleName = vm->GetFactory()->NewFromUtf8(entryPoint);

View File

@ -65,7 +65,7 @@ void JSPandaFile::CheckIsNewRecord(EcmaVM *vm)
}
for (auto info : jsRecordInfo_) {
if (info.first.find(NODE_MODULES) != CString::npos) {
if (info.first.find(NPM_PATH_SEGMENT) != CString::npos) {
continue;
}
CString recordName = info.first;
@ -290,92 +290,6 @@ CString JSPandaFile::FindNpmEntryPoint(const CString &recordName) const
return entryPoint;
}
CString JSPandaFile::ParseOhmUrl(EcmaVM *vm, const CString &inputFileName, CString &outFileName)
{
CString bundleInstallName(BUNDLE_INSTALL_PATH);
size_t startStrLen = bundleInstallName.length();
size_t pos = CString::npos;
if (inputFileName.length() > startStrLen && inputFileName.compare(0, startStrLen, bundleInstallName) == 0) {
pos = startStrLen;
}
CString entryPoint;
if (pos != CString::npos) {
pos = inputFileName.find('/', startStrLen);
ASSERT(pos != CString::npos);
CString moduleName = inputFileName.substr(startStrLen, pos - startStrLen);
if (moduleName != vm->GetModuleName()) {
outFileName = CString(BUNDLE_INSTALL_PATH) + moduleName + CString(MERGE_ABC_ETS_MODULES);
}
entryPoint = vm->GetBundleName() + "/" + inputFileName.substr(startStrLen);
} else {
// Temporarily handle the relative path sent by arkui
if (inputFileName.find("@bundle:") != CString::npos) {
entryPoint = inputFileName.substr(MODULE_OR_BUNDLE_PREFIX_LEN);
outFileName = ParseNewPagesUrl(vm, entryPoint);
} else {
entryPoint = vm->GetBundleName() + "/" + vm->GetModuleName() + MODULE_DEFAULE_ETS + inputFileName;
}
}
pos = entryPoint.rfind(".abc");
if (pos != CString::npos) {
entryPoint = entryPoint.substr(0, pos);
}
return entryPoint;
}
CString JSPandaFile::ParseNewPagesUrl(EcmaVM *vm, const CString &entryPoint)
{
auto errorFun = [entryPoint](const size_t &pos) {
if (pos == CString::npos) {
LOG_ECMA(FATAL) << "ParseNewPagesUrl failed, please check Url " << entryPoint;
}
};
size_t bundleEndPos = entryPoint.find('/');
errorFun(bundleEndPos);
CString bundleName = entryPoint.substr(0, bundleEndPos);
size_t moduleStartPos = bundleEndPos + 1;
size_t moduleEndPos = entryPoint.find('/', moduleStartPos);
errorFun(moduleEndPos);
CString moduleName = entryPoint.substr(moduleStartPos, moduleEndPos - moduleStartPos);
CString baseFileName;
if (bundleName != vm->GetBundleName()) {
// Cross-application
baseFileName = BUNDLE_INSTALL_PATH + bundleName + "/" + moduleName + "/" + moduleName + MERGE_ABC_ETS_MODULES;
} else if (moduleName != vm->GetModuleName()) {
// Intra-application cross hap
baseFileName = BUNDLE_INSTALL_PATH + moduleName + MERGE_ABC_ETS_MODULES;
} else {
baseFileName = "";
}
return baseFileName;
}
std::string JSPandaFile::ParseHapPath(const CString &fileName)
{
CString bundleSubInstallName(BUNDLE_SUB_INSTALL_PATH);
size_t startStrLen = bundleSubInstallName.length();
if (fileName.length() > startStrLen && fileName.compare(0, startStrLen, bundleSubInstallName) == 0) {
CString hapPath = fileName.substr(startStrLen);
size_t pos = hapPath.find(MERGE_ABC_ETS_MODULES);
if (pos != CString::npos) {
return hapPath.substr(0, pos).c_str();
}
}
return "";
}
void JSPandaFile::CroppingRecord(CString &recordName)
{
size_t pos = recordName.find('/');
if (pos != CString::npos) {
pos = recordName.find('/', pos + 1);
if (pos != CString::npos) {
recordName = recordName.substr(pos + 1);
}
}
}
FunctionKind JSPandaFile::GetFunctionKind(panda_file::FunctionKind funcKind)
{
FunctionKind kind;

View File

@ -69,20 +69,12 @@ public:
static constexpr char IS_COMMON_JS[] = "isCommonjs";
static constexpr char IS_JSON_CONTENT[] = "jsonFileContent";
static constexpr char MODULE_RECORD_IDX[] = "moduleRecordIdx";
static constexpr char MODULE_DEFAULE_ETS[] = "/ets/";
static constexpr char BUNDLE_INSTALL_PATH[] = "/data/storage/el1/bundle/";
static constexpr char BUNDLE_SUB_INSTALL_PATH[] = "/data/storage/el1/";
static constexpr char NODE_MODULES[] = "node_modules/";
static constexpr char NODE_MODULES_ZERO[] = "node_modules/0/";
static constexpr char NODE_MODULES_ONE[] = "node_modules/1/";
static constexpr char MERGE_ABC_NAME[] = "modules.abc";
static constexpr char MERGE_ABC_ETS_MODULES[] = "/ets/modules.abc";
static constexpr char PACKAGE_NAME[] = "pkgName@";
static constexpr char PREVIEW_OF_ACROSS_HAP_FLAG[] = "[preview]";
static constexpr char MERGE_ABC_NAME[] = "modules.abc";
static constexpr char NPM_PATH_SEGMENT[] = "node_modules";
static constexpr char BUNDLE_INSTALL_PATH[] = "/data/storage/el1/bundle/";
static constexpr int PACKAGE_NAME_LEN = 8;
static constexpr int MODULE_OR_BUNDLE_PREFIX_LEN = 8;
static constexpr int DEFAULT_TYPE_SUMMARY_OFFSET = 0;
static constexpr int PACKAGE_PREFIX_LEN = 9;
JSPandaFile(const panda_file::File *pf, const CString &descriptor);
~JSPandaFile();
@ -301,11 +293,6 @@ public:
CString FindNpmEntryPoint(const CString &record) const;
static CString ParseOhmUrl(EcmaVM *vm, const CString &inputFileName, CString &outFileName);
static CString ParseNewPagesUrl(EcmaVM *vm, const CString &entryPoint);
static std::string ParseHapPath(const CString &fileName);
static void CroppingRecord(CString &recordName);
uint32_t GetAOTFileInfoIndex() const
{
return anFileInfoIndex_;

View File

@ -15,6 +15,7 @@
#include "ecmascript/jspandafile/js_pandafile_executor.h"
#include "ecmascript/base/path_helper.h"
#include "ecmascript/ecma_vm.h"
#include "ecmascript/jspandafile/js_pandafile_manager.h"
#include "ecmascript/jspandafile/program_object.h"
@ -24,13 +25,14 @@
#include "ecmascript/patch/quick_fix_manager.h"
namespace panda::ecmascript {
using PathHelper = base::PathHelper;
Expected<JSTaggedValue, bool> JSPandaFileExecutor::ExecuteFromFile(JSThread *thread, const CString &filename,
std::string_view entryPoint, bool needUpdate, bool excuteFromJob)
{
LOG_ECMA(DEBUG) << "JSPandaFileExecutor::ExecuteFromFile filename " << filename;
CString entry;
CString name;
CString normalName = NormalizePath(filename);
CString normalName = PathHelper::NormalizePath(filename);
EcmaVM *vm = thread->GetEcmaVM();
if (!vm->IsBundlePack()) {
#if defined(PANDA_TARGET_LINUX) || defined(OHOS_UNIT_TEST)
@ -40,7 +42,7 @@ Expected<JSTaggedValue, bool> JSPandaFileExecutor::ExecuteFromFile(JSThread *thr
if (excuteFromJob) {
entry = entryPoint.data();
} else {
entry = JSPandaFile::ParseOhmUrl(vm, normalName, name);
entry = PathHelper::ParseOhmUrl(vm, normalName, name);
}
#if !WIN_OR_MAC_OR_IOS_PLATFORM
if (name.empty()) {
@ -67,7 +69,7 @@ Expected<JSTaggedValue, bool> JSPandaFileExecutor::ExecuteFromFile(JSThread *thr
if (!jsPandaFile->IsBundlePack() && !excuteFromJob && !vm->GetBundleName().empty()) {
const_cast<JSPandaFile *>(jsPandaFile)->CheckIsNewRecord(vm);
if (!jsPandaFile->IsNewRecord()) {
JSPandaFile::CroppingRecord(entry);
PathHelper::CroppingRecord(entry);
}
}
bool isModule = jsPandaFile->IsModule(thread, entry.c_str());
@ -103,7 +105,7 @@ Expected<JSTaggedValue, bool> JSPandaFileExecutor::ExecuteFromBuffer(JSThread *t
const void *buffer, size_t size, std::string_view entryPoint, const CString &filename, bool needUpdate)
{
LOG_ECMA(DEBUG) << "JSPandaFileExecutor::ExecuteFromBuffer filename " << filename;
CString normalName = NormalizePath(filename);
CString normalName = PathHelper::NormalizePath(filename);
const JSPandaFile *jsPandaFile =
JSPandaFileManager::GetInstance()->LoadJSPandaFile(thread, normalName, entryPoint, buffer, size, needUpdate);
if (jsPandaFile == nullptr) {
@ -134,8 +136,8 @@ Expected<JSTaggedValue, bool> JSPandaFileExecutor::ExecuteModuleBuffer(
CString assetPath = vm->GetAssetPath();
name = assetPath + "/" + JSPandaFile::MERGE_ABC_NAME;
#endif
CString normalName = NormalizePath(filename);
CString entry = JSPandaFile::ParseOhmUrl(vm, normalName, name);
CString normalName = PathHelper::NormalizePath(filename);
CString entry = PathHelper::ParseOhmUrl(vm, normalName, name);
const JSPandaFile *jsPandaFile =
JSPandaFileManager::GetInstance()->LoadJSPandaFile(thread, name, entry.c_str(), buffer, size);
if (jsPandaFile == nullptr) {
@ -153,7 +155,7 @@ Expected<JSTaggedValue, bool> JSPandaFileExecutor::ExecuteModuleBuffer(
if (!isBundle) {
const_cast<JSPandaFile *>(jsPandaFile)->CheckIsNewRecord(vm);
if (!jsPandaFile->IsNewRecord()) {
JSPandaFile::CroppingRecord(entry);
PathHelper::CroppingRecord(entry);
}
}
ASSERT(jsPandaFile->IsModule(thread, entry.c_str()));
@ -184,43 +186,6 @@ Expected<JSTaggedValue, bool> JSPandaFileExecutor::CommonExecuteBuffer(JSThread
return JSTaggedValue::Undefined();
}
CString JSPandaFileExecutor::NormalizePath(const CString &fileName)
{
if (fileName.find("//") == CString::npos && fileName.find("../") == CString::npos) {
return fileName;
}
const char delim = '/';
CString res = "";
size_t prev = 0;
size_t curr = fileName.find(delim);
CVector<CString> elems;
while (curr != CString::npos) {
if (curr > prev) {
CString elem = fileName.substr(prev, curr - prev);
if (elem.compare("..") == 0 && !elems.empty()) {
elems.pop_back();
prev = curr + 1;
curr = fileName.find(delim, prev);
continue;
}
elems.push_back(elem);
}
prev = curr + 1;
curr = fileName.find(delim, prev);
}
if (prev != fileName.size()) {
elems.push_back(fileName.substr(prev));
}
for (auto e : elems) {
if (res.size() == 0 && fileName.at(0) != delim) {
res.append(e);
continue;
}
res.append(1, delim).append(e);
}
return res;
}
Expected<JSTaggedValue, bool> JSPandaFileExecutor::Execute(JSThread *thread, const JSPandaFile *jsPandaFile,
std::string_view entryPoint, bool excuteFromJob)
{

View File

@ -36,7 +36,6 @@ public:
const CString &entry, const void *buffer, size_t size);
static Expected<JSTaggedValue, bool> Execute(JSThread *thread, const JSPandaFile *jsPandaFile,
std::string_view entryPoint, bool excuteFromJob = false);
static CString NormalizePath(const CString &fileName);
};
} // namespace panda::ecmascript
#endif // ECMASCRIPT_JSPANDAFILE_JS_PANDAFILE_EXECUTOR_H

View File

@ -16,6 +16,7 @@
#include "ecmascript/jspandafile/js_pandafile_manager.h"
#include "ecmascript/aot_file_manager.h"
#include "ecmascript/base/path_helper.h"
#include "ecmascript/jspandafile/program_object.h"
#include "ecmascript/js_file_path.h"
@ -80,7 +81,7 @@ const JSPandaFile *JSPandaFileManager::LoadJSPandaFile(JSThread *thread, const C
LOG_ECMA(ERROR) << "JSPandaFileExecutor::ExecuteFromFile resolveBufferCallback is nullptr";
return nullptr;
}
std::vector<uint8_t> data = resolveBufferCallback(JSPandaFile::ParseHapPath(filename));
std::vector<uint8_t> data = resolveBufferCallback(base::PathHelper::ParseHapPath(filename));
if (data.empty()) {
LOG_ECMA(ERROR) << "JSPandaFileExecutor::ExecuteFromFile resolveBufferCallback get buffer failed";
return nullptr;

View File

@ -166,29 +166,4 @@ HWTEST_F_L0(JSPandaFileExecutorTest, ExecuteFromBuffer)
const JSPandaFile *foundPf = pfManager->FindJSPandaFile(fileName);
pfManager->RemoveJSPandaFile((void *)foundPf);
}
HWTEST_F_L0(JSPandaFileExecutorTest, NormalizePath)
{
CString res1 = "node_modules/0/moduleTest/index";
CString moduleRecordName1 = "node_modules///0//moduleTest/index";
CString res2 = "./node_modules/0/moduleTest/index";
CString moduleRecordName2 = "./node_modules///0//moduleTest/index";
CString res3 = "../node_modules/0/moduleTest/index";
CString moduleRecordName3 = "../node_modules/0/moduleTest///index";
CString res4 = "./moduleTest/index";
CString moduleRecordName4 = "./node_modules/..//moduleTest////index";
CString normalName1 = JSPandaFileExecutor::NormalizePath(moduleRecordName1);
CString normalName2 = JSPandaFileExecutor::NormalizePath(moduleRecordName2);
CString normalName3 = JSPandaFileExecutor::NormalizePath(moduleRecordName3);
CString normalName4 = JSPandaFileExecutor::NormalizePath(moduleRecordName4);
EXPECT_EQ(res1, normalName1);
EXPECT_EQ(res2, normalName2);
EXPECT_EQ(res3, normalName3);
EXPECT_EQ(res4, normalName4);
}
} // namespace panda::test

View File

@ -15,6 +15,7 @@
#include "ecmascript/module/js_module_manager.h"
#include "ecmascript/aot_file_manager.h"
#include "ecmascript/base/path_helper.h"
#include "ecmascript/builtins/builtins_json.h"
#include "ecmascript/global_env.h"
#include "ecmascript/interpreter/frame_handler.h"
@ -34,6 +35,7 @@
namespace panda::ecmascript {
using BuiltinsJson = builtins::BuiltinsJson;
using PathHelper = base::PathHelper;
namespace {
constexpr size_t NATIVE_PREFIX_SIZE = 8;
@ -535,136 +537,6 @@ void ModuleManager::Iterate(const RootVisitor &v)
v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&resolvedModules_)));
}
CString ModuleManager::ConcatFileNameWithMerge(const JSPandaFile *jsPandaFile, CString &baseFilename,
CString moduleRecordName, CString moduleRequestName)
{
CString entryPoint;
size_t pos = 0;
size_t typePos = CString::npos;
if (moduleRequestName.find("@bundle:") != CString::npos) {
moduleRequestName = moduleRequestName.substr(JSPandaFile::MODULE_OR_BUNDLE_PREFIX_LEN);
pos = moduleRequestName.find('/');
CString bundleName = moduleRequestName.substr(0, pos);
size_t bundleNameLen = bundleName.length();
entryPoint = moduleRequestName;
if (jsPandaFile->IsNewRecord()) {
bool isDifferentBundle = (moduleRecordName.length() > bundleNameLen) &&
(moduleRecordName.compare(0, bundleNameLen, bundleName) != 0);
pos = moduleRequestName.find('/', bundleNameLen + 1);
if (isDifferentBundle && CString::npos != pos) {
CString moduleName = moduleRequestName.substr(bundleNameLen + 1, pos - bundleNameLen - 1);
baseFilename = JSPandaFile::BUNDLE_INSTALL_PATH + moduleRequestName.substr(0, pos) + '/' + moduleName +
JSPandaFile::MERGE_ABC_ETS_MODULES;
}
} else {
JSPandaFile::CroppingRecord(entryPoint);
}
} else if (moduleRequestName.find("@module:") != CString::npos) {
#if !defined(PANDA_TARGET_WINDOWS) && !defined(PANDA_TARGET_MACOS)
moduleRequestName = moduleRequestName.substr(JSPandaFile::MODULE_OR_BUNDLE_PREFIX_LEN);
pos = moduleRequestName.find('/');
ASSERT(pos != CString::npos);
baseFilename =
JSPandaFile::BUNDLE_INSTALL_PATH + moduleRequestName.substr(0, pos) + JSPandaFile::MERGE_ABC_ETS_MODULES;
pos = moduleRecordName.find('/');
entryPoint = moduleRecordName.substr(0, pos + 1) + moduleRequestName;
#else
entryPoint = JSPandaFile::PREVIEW_OF_ACROSS_HAP_FLAG;
LOG_NO_TAG(ERROR) << "[ArkRuntime Log] Importing shared package is not supported in the Previewer.";
#endif
} else if (IsImportedPath(moduleRequestName, typePos)) {
if (typePos != CString::npos) {
moduleRequestName = moduleRequestName.substr(0, typePos);
}
pos = moduleRequestName.find("./");
if (pos == 0) {
moduleRequestName = moduleRequestName.substr(2); // 2 means jump "./"
}
pos = moduleRecordName.rfind('/');
if (pos != CString::npos) {
entryPoint = moduleRecordName.substr(0, pos + 1) + moduleRequestName;
} else {
entryPoint = moduleRequestName;
}
entryPoint = JSPandaFileExecutor::NormalizePath(entryPoint);
if (!jsPandaFile->HasRecord(entryPoint)) {
entryPoint += "/index";
}
if (!jsPandaFile->HasRecord(entryPoint)) {
pos = baseFilename.rfind('/');
if (pos != CString::npos) {
baseFilename = baseFilename.substr(0, pos + 1) + moduleRequestName + ".abc";
} else {
baseFilename = moduleRequestName + ".abc";
}
pos = moduleRequestName.rfind('/');
if (pos != CString::npos) {
entryPoint = moduleRequestName.substr(pos + 1);
} else {
entryPoint = moduleRequestName;
}
}
} else if (moduleRequestName.find("@package:") != CString::npos) {
entryPoint = moduleRequestName.substr(JSPandaFile::PACKAGE_PREFIX_LEN);
} else {
pos = moduleRecordName.find(JSPandaFile::NODE_MODULES);
CString key = "";
if (pos != CString::npos) {
auto info = const_cast<JSPandaFile *>(jsPandaFile)->FindRecordInfo(moduleRecordName);
CString PackageName = info.npmPackageName;
while ((pos = PackageName.rfind(JSPandaFile::NODE_MODULES)) != CString::npos) {
key = PackageName + "/" + JSPandaFile::NODE_MODULES + moduleRequestName;
AddIndexToEntryPoint(jsPandaFile, entryPoint, key);
if (entryPoint.empty()) {
break;
}
PackageName = PackageName.substr(0, pos > 0 ? pos - 1 : 0);
}
}
if (entryPoint.empty()) {
key = JSPandaFile::NODE_MODULES_ZERO + moduleRequestName;
AddIndexToEntryPoint(jsPandaFile, entryPoint, key);
}
if (entryPoint.empty()) {
key = JSPandaFile::NODE_MODULES_ONE + moduleRequestName;
AddIndexToEntryPoint(jsPandaFile, entryPoint, key);
}
if (entryPoint.empty()) {
LOG_ECMA(ERROR) << "find entryPoint failed\n"
<< "moduleRequestName : " << moduleRequestName << "\n"
<< "moduleRecordName : " << moduleRecordName << "\n";
}
}
return entryPoint;
}
bool ModuleManager::IsImportedPath(const CString &moduleRequestName, size_t &typePos)
{
if (moduleRequestName.rfind(".js") != CString::npos) {
typePos = moduleRequestName.rfind(".js");
return true;
} else if (moduleRequestName.rfind(".ts") != CString::npos) {
typePos = moduleRequestName.rfind(".ts");
return true;
} else if (moduleRequestName.rfind(".ets") != CString::npos) {
typePos = moduleRequestName.rfind(".ets");
return true;
}
return moduleRequestName.find("./") == 0 || moduleRequestName.find("../") == 0;
}
void ModuleManager::AddIndexToEntryPoint(const JSPandaFile *jsPandaFile, CString &entryPoint, CString &key)
{
entryPoint = jsPandaFile->FindNpmEntryPoint(key);
if (entryPoint.empty()) {
key += "/index";
entryPoint = jsPandaFile->FindNpmEntryPoint(key);
}
}
CString ModuleManager::GetRecordName(JSTaggedValue module)
{
CString entry = "";

View File

@ -66,9 +66,6 @@ public:
void AddResolveImportedModule(const CString &referencingModule, JSHandle<JSTaggedValue> moduleRecord);
void Iterate(const RootVisitor &v);
static CString ConcatFileNameWithMerge(const JSPandaFile *jsPandaFile, CString &baseFilename,
CString moduleRecordName, CString moduleRequestName);
bool GetCurrentMode() const
{
return isExecuteBuffer_;
@ -80,8 +77,6 @@ public:
static CString GetRecordName(JSTaggedValue module);
static int GetExportObjectIndex(EcmaVM *vm, JSHandle<SourceTextModule> ecmaModule, const std::string &key);
static bool IsImportedPath(const CString &moduleRequestName, size_t &typePos);
static void AddIndexToEntryPoint(const JSPandaFile *jsPandaFile, CString &entryPoint, CString &key);
static JSTaggedValue JsonParse(JSThread *thread, const JSPandaFile *jsPandaFile, CString entryPoint);
inline static bool IsNativeModule(ModuleTypes moduleType)

View File

@ -28,6 +28,7 @@
#include "ecmascript/tagged_dictionary.h"
namespace panda::ecmascript {
using PathHelper = base::PathHelper;
CVector<std::string> SourceTextModule::GetExportedNames(JSThread *thread, const JSHandle<SourceTextModule> &module,
const JSHandle<TaggedArray> &exportStarSet)
{
@ -96,9 +97,9 @@ JSHandle<JSTaggedValue> SourceTextModule::HostResolveImportedModuleWithMerge(
JSPandaFileManager::GetInstance()->LoadJSPandaFile(thread, baseFilename, moduleRecordName);
CString entryPoint =
ModuleManager::ConcatFileNameWithMerge(jsPandaFile, baseFilename, moduleRecordName, moduleRequestName);
PathHelper::ConcatFileNameWithMerge(jsPandaFile, baseFilename, moduleRecordName, moduleRequestName);
#if defined(PANDA_TARGET_WINDOWS) || defined(PANDA_TARGET_MACOS)
if (entryPoint == JSPandaFile::PREVIEW_OF_ACROSS_HAP_FLAG) {
if (entryPoint == PathHelper::PREVIEW_OF_ACROSS_HAP_FLAG) {
THROW_SYNTAX_ERROR_AND_RETURN(thread, "", thread->GlobalConstants()->GetHandledUndefined());
}
#endif

View File

@ -17,6 +17,7 @@
#include "assembler/assembly-parser.h"
#include "libpandafile/class_data_accessor-inl.h"
#include "ecmascript/base/path_helper.h"
#include "ecmascript/global_env.h"
#include "ecmascript/jspandafile/js_pandafile.h"
#include "ecmascript/jspandafile/js_pandafile_manager.h"
@ -31,7 +32,7 @@
using namespace panda::ecmascript;
using namespace panda::panda_file;
using namespace panda::pandasm;
using PathHelper = panda::ecmascript::base::PathHelper;
namespace panda::test {
class EcmaModuleTest : public testing::Test {
public:
@ -198,163 +199,6 @@ HWTEST_F_L0(EcmaModuleTest, GetModuleValue)
EXPECT_EQ(exportValueHandle.GetTaggedValue(), importDefaultValue);
}
HWTEST_F_L0(EcmaModuleTest, ConcatFileNameWithMerge1)
{
CString baseFilename = "merge.abc";
const char *data = R"(
.language ECMAScript
.function any func_main_0(any a0, any a1, any a2) {
ldai 1
return
}
)";
JSPandaFileManager *pfManager = JSPandaFileManager::GetInstance();
Parser parser;
auto res = parser.Parse(data);
std::unique_ptr<const File> pfPtr = pandasm::AsmEmitter::Emit(res.Value());
JSPandaFile *pf = pfManager->NewJSPandaFile(pfPtr.release(), baseFilename);
// Test moduleRequestName start with "@bundle"
CString moduleRecordName = "moduleTest1";
CString moduleRequestName = "@bundle:com.bundleName.test/moduleName/requestModuleName1";
CString result = "com.bundleName.test/moduleName/requestModuleName1";
CString entryPoint = ModuleManager::ConcatFileNameWithMerge(pf, baseFilename, moduleRecordName, moduleRequestName);
EXPECT_EQ(result, entryPoint);
// Test cross application
moduleRecordName = "@bundle:com.bundleName1.test/moduleName/requestModuleName1";
CString newBaseFileName = "/data/storage/el1/bundle/com.bundleName.test/moduleName/moduleName/ets/modules.abc";
ModuleManager::ConcatFileNameWithMerge(pf, baseFilename, moduleRecordName, moduleRequestName);
EXPECT_EQ(baseFilename, newBaseFileName);
}
HWTEST_F_L0(EcmaModuleTest, ConcatFileNameWithMerge2)
{
CString baseFilename = "merge.abc";
const char *data = R"(
.language ECMAScript
.function any func_main_0(any a0, any a1, any a2) {
ldai 1
return
}
)";
JSPandaFileManager *pfManager = JSPandaFileManager::GetInstance();
Parser parser;
auto res = parser.Parse(data);
std::unique_ptr<const File> pfPtr = pandasm::AsmEmitter::Emit(res.Value());
JSPandaFile *pf = pfManager->NewJSPandaFile(pfPtr.release(), baseFilename);
// Test moduleRequestName start with "./"
CString moduleRecordName = "moduleTest2";
CString moduleRequestName = "./requestModule.js";
CString result = "requestModule";
pf->InsertJSRecordInfo(result);
CString entryPoint = ModuleManager::ConcatFileNameWithMerge(pf, baseFilename, moduleRecordName, moduleRequestName);
EXPECT_EQ(result, entryPoint);
// Test moduleRecordName with "/"
moduleRecordName = "moduleName/moduleTest2";
moduleRequestName = "./requestModule.js";
result = "moduleName/requestModule";
pf->InsertJSRecordInfo(result);
entryPoint = ModuleManager::ConcatFileNameWithMerge(pf, baseFilename, moduleRecordName, moduleRequestName);
EXPECT_EQ(result, entryPoint);
}
HWTEST_F_L0(EcmaModuleTest, ConcatFileNameWithMerge3)
{
CString baseFilename = "merge.abc";
const char *data = R"(
.language ECMAScript
.function any func_main_0(any a0, any a1, any a2) {
ldai 1
return
}
)";
JSPandaFileManager *pfManager = JSPandaFileManager::GetInstance();
Parser parser;
auto res = parser.Parse(data);
std::unique_ptr<const File> pfPtr = pandasm::AsmEmitter::Emit(res.Value());
JSPandaFile *pf = pfManager->NewJSPandaFile(pfPtr.release(), baseFilename);
// Test RecordName is not in JSPandaFile
CString moduleRecordName = "moduleTest3";
CString moduleRequestName = "./secord.js";
CString result = "secord";
CString requestFileName = "secord.abc";
CString entryPoint =
ModuleManager::ConcatFileNameWithMerge(pf, baseFilename, moduleRecordName, moduleRequestName);
EXPECT_EQ(baseFilename, requestFileName);
EXPECT_EQ(result, entryPoint);
// Test RecordName is not in JSPandaFile and baseFilename with "/" and moduleRequestName with "/"
baseFilename = "test/merge.abc";
std::unique_ptr<const File> pfPtr2 = pandasm::AsmEmitter::Emit(res.Value());
JSPandaFile *pf2 = pfManager->NewJSPandaFile(pfPtr2.release(), baseFilename);
moduleRecordName = "moduleTest3";
moduleRequestName = "./test/secord.js";
result = "secord";
requestFileName = "test/test/secord.abc";
entryPoint = ModuleManager::ConcatFileNameWithMerge(pf2, baseFilename, moduleRecordName, moduleRequestName);
EXPECT_EQ(baseFilename, requestFileName);
EXPECT_EQ(result, entryPoint);
}
HWTEST_F_L0(EcmaModuleTest, ConcatFileNameWithMerge4)
{
CString baseFilename = "merge.abc";
const char *data = R"(
.language ECMAScript
.function any func_main_0(any a0, any a1, any a2) {
ldai 1
return
}
)";
JSPandaFileManager *pfManager = JSPandaFileManager::GetInstance();
Parser parser;
auto res = parser.Parse(data);
std::unique_ptr<const File> pfPtr = pandasm::AsmEmitter::Emit(res.Value());
JSPandaFile *pf = pfManager->NewJSPandaFile(pfPtr.release(), baseFilename);
const CUnorderedMap<CString, JSPandaFile::JSRecordInfo> &recordInfo = pf->GetJSRecordInfo();
// Test moduleRequestName is npm package
CString moduleRecordName = "node_modules/0/moduleTest4/index";
CString moduleRequestName = "json/index";
CString result = "node_modules/0/moduleTest4/node_modules/json/index";
JSPandaFile::JSRecordInfo info;
info.npmPackageName = "node_modules/0/moduleTest4";
const_cast<CUnorderedMap<CString, JSPandaFile::JSRecordInfo> &>(recordInfo).insert({moduleRecordName, info});
const_cast<CUnorderedMap<CString, JSPandaFile::JSRecordInfo> &>(recordInfo).insert({result, info});
CString entryPoint = ModuleManager::ConcatFileNameWithMerge(pf, baseFilename, moduleRecordName, moduleRequestName);
EXPECT_EQ(result, entryPoint);
}
HWTEST_F_L0(EcmaModuleTest, ConcatFileNameWithMerge5)
{
CString baseFilename = "merge.abc";
const char *data = R"(
.language ECMAScript
.function any func_main_0(any a0, any a1, any a2) {
ldai 1
return
}
)";
JSPandaFileManager *pfManager = JSPandaFileManager::GetInstance();
Parser parser;
auto res = parser.Parse(data);
std::unique_ptr<const File> pfPtr = pandasm::AsmEmitter::Emit(res.Value());
JSPandaFile *pf = pfManager->NewJSPandaFile(pfPtr.release(), baseFilename);
// Test moduleRequestName start with "@module"
CString moduleRecordName = "com.bundleName.test/moduleName1/moduleTest1";
CString moduleRequestName = "@module:moduleName/requestModuleName1";
CString result = "com.bundleName.test/moduleName/requestModuleName1";
CString newBaseFileName = "/data/storage/el1/bundle/moduleName/ets/modules.abc";
CString entryPoint = ModuleManager::ConcatFileNameWithMerge(pf, baseFilename, moduleRecordName, moduleRequestName);
EXPECT_EQ(result, entryPoint);
EXPECT_EQ(baseFilename, newBaseFileName);
}
HWTEST_F_L0(EcmaModuleTest, GetRecordName1)
{
std::string baseFileName = MODULE_ABC_PATH "module_test_module_test_module_base.abc";
@ -434,4 +278,237 @@ HWTEST_F_L0(EcmaModuleTest, Instantiate_Evaluate_GetNamespace_SetNamespace)
ModuleRecord::SetNamespace(thread, module.GetTaggedValue(), JSTaggedValue::Undefined());
EXPECT_TRUE(res == SourceTextModule::UNDEFINED_INDEX);
}
HWTEST_F_L0(EcmaModuleTest, ConcatFileNameWithMerge1)
{
CString baseFilename = "merge.abc";
const char *data = R"(
.language ECMAScript
.function any func_main_0(any a0, any a1, any a2) {
ldai 1
return
}
)";
JSPandaFileManager *pfManager = JSPandaFileManager::GetInstance();
Parser parser;
auto res = parser.Parse(data);
std::unique_ptr<const File> pfPtr = pandasm::AsmEmitter::Emit(res.Value());
JSPandaFile *pf = pfManager->NewJSPandaFile(pfPtr.release(), baseFilename);
// Test moduleRequestName start with "@bundle"
CString moduleRecordName = "moduleTest1";
CString moduleRequestName = "@bundle:com.bundleName.test/moduleName/requestModuleName1";
CString result = "com.bundleName.test/moduleName/requestModuleName1";
CString entryPoint = PathHelper::ConcatFileNameWithMerge(pf, baseFilename, moduleRecordName, moduleRequestName);
EXPECT_EQ(result, entryPoint);
// Test cross application
moduleRecordName = "@bundle:com.bundleName1.test/moduleName/requestModuleName1";
CString newBaseFileName = "/data/storage/el1/bundle/com.bundleName.test/moduleName/moduleName/ets/modules.abc";
PathHelper::ConcatFileNameWithMerge(pf, baseFilename, moduleRecordName, moduleRequestName);
EXPECT_EQ(baseFilename, newBaseFileName);
}
HWTEST_F_L0(EcmaModuleTest, ConcatFileNameWithMerge2)
{
CString baseFilename = "merge.abc";
const char *data = R"(
.language ECMAScript
.function any func_main_0(any a0, any a1, any a2) {
ldai 1
return
}
)";
JSPandaFileManager *pfManager = JSPandaFileManager::GetInstance();
Parser parser;
auto res = parser.Parse(data);
std::unique_ptr<const File> pfPtr = pandasm::AsmEmitter::Emit(res.Value());
JSPandaFile *pf = pfManager->NewJSPandaFile(pfPtr.release(), baseFilename);
// Test moduleRequestName start with "./"
CString moduleRecordName = "moduleTest2";
CString moduleRequestName = "./requestModule.js";
CString result = "requestModule";
pf->InsertJSRecordInfo(result);
CString entryPoint = PathHelper::ConcatFileNameWithMerge(pf, baseFilename, moduleRecordName, moduleRequestName);
EXPECT_EQ(result, entryPoint);
// Test moduleRecordName with "/"
moduleRecordName = "moduleName/moduleTest2";
moduleRequestName = "./requestModule.js";
result = "moduleName/requestModule";
pf->InsertJSRecordInfo(result);
entryPoint = PathHelper::ConcatFileNameWithMerge(pf, baseFilename, moduleRecordName, moduleRequestName);
EXPECT_EQ(result, entryPoint);
}
HWTEST_F_L0(EcmaModuleTest, ConcatFileNameWithMerge3)
{
CString baseFilename = "merge.abc";
const char *data = R"(
.language ECMAScript
.function any func_main_0(any a0, any a1, any a2) {
ldai 1
return
}
)";
JSPandaFileManager *pfManager = JSPandaFileManager::GetInstance();
Parser parser;
auto res = parser.Parse(data);
std::unique_ptr<const File> pfPtr = pandasm::AsmEmitter::Emit(res.Value());
JSPandaFile *pf = pfManager->NewJSPandaFile(pfPtr.release(), baseFilename);
// Test RecordName is not in JSPandaFile
CString moduleRecordName = "moduleTest3";
CString moduleRequestName = "./secord.js";
CString result = "secord";
CString requestFileName = "secord.abc";
CString entryPoint =
PathHelper::ConcatFileNameWithMerge(pf, baseFilename, moduleRecordName, moduleRequestName);
EXPECT_EQ(baseFilename, requestFileName);
EXPECT_EQ(result, entryPoint);
// Test RecordName is not in JSPandaFile and baseFilename with "/" and moduleRequestName with "/"
baseFilename = "test/merge.abc";
std::unique_ptr<const File> pfPtr2 = pandasm::AsmEmitter::Emit(res.Value());
JSPandaFile *pf2 = pfManager->NewJSPandaFile(pfPtr2.release(), baseFilename);
moduleRecordName = "moduleTest3";
moduleRequestName = "./test/secord.js";
result = "secord";
requestFileName = "test/test/secord.abc";
entryPoint = PathHelper::ConcatFileNameWithMerge(pf2, baseFilename, moduleRecordName, moduleRequestName);
EXPECT_EQ(baseFilename, requestFileName);
EXPECT_EQ(result, entryPoint);
}
HWTEST_F_L0(EcmaModuleTest, ConcatFileNameWithMerge4)
{
CString baseFilename = "merge.abc";
const char *data = R"(
.language ECMAScript
.function any func_main_0(any a0, any a1, any a2) {
ldai 1
return
}
)";
JSPandaFileManager *pfManager = JSPandaFileManager::GetInstance();
Parser parser;
auto res = parser.Parse(data);
std::unique_ptr<const File> pfPtr = pandasm::AsmEmitter::Emit(res.Value());
JSPandaFile *pf = pfManager->NewJSPandaFile(pfPtr.release(), baseFilename);
const CUnorderedMap<CString, JSPandaFile::JSRecordInfo> &recordInfo = pf->GetJSRecordInfo();
// Test moduleRequestName is npm package
CString moduleRecordName = "node_modules/0/moduleTest4/index";
CString moduleRequestName = "json/index";
CString result = "node_modules/0/moduleTest4/node_modules/json/index";
JSPandaFile::JSRecordInfo info;
info.npmPackageName = "node_modules/0/moduleTest4";
const_cast<CUnorderedMap<CString, JSPandaFile::JSRecordInfo> &>(recordInfo).insert({moduleRecordName, info});
const_cast<CUnorderedMap<CString, JSPandaFile::JSRecordInfo> &>(recordInfo).insert({result, info});
CString entryPoint = PathHelper::ConcatFileNameWithMerge(pf, baseFilename, moduleRecordName, moduleRequestName);
EXPECT_EQ(result, entryPoint);
}
HWTEST_F_L0(EcmaModuleTest, ConcatFileNameWithMerge5)
{
CString baseFilename = "merge.abc";
const char *data = R"(
.language ECMAScript
.function any func_main_0(any a0, any a1, any a2) {
ldai 1
return
}
)";
JSPandaFileManager *pfManager = JSPandaFileManager::GetInstance();
Parser parser;
auto res = parser.Parse(data);
std::unique_ptr<const File> pfPtr = pandasm::AsmEmitter::Emit(res.Value());
JSPandaFile *pf = pfManager->NewJSPandaFile(pfPtr.release(), baseFilename);
// Test moduleRequestName start with "@module"
CString moduleRecordName = "com.bundleName.test/moduleName1/moduleTest1";
CString moduleRequestName = "@module:moduleName/requestModuleName1";
CString result = "com.bundleName.test/moduleName/requestModuleName1";
CString newBaseFileName = "/data/storage/el1/bundle/moduleName/ets/modules.abc";
CString entryPoint = PathHelper::ConcatFileNameWithMerge(pf, baseFilename, moduleRecordName, moduleRequestName);
EXPECT_EQ(result, entryPoint);
EXPECT_EQ(baseFilename, newBaseFileName);
}
HWTEST_F_L0(EcmaModuleTest, NormalizePath)
{
CString res1 = "node_modules/0/moduleTest/index";
CString moduleRecordName1 = "node_modules///0//moduleTest/index";
CString res2 = "./node_modules/0/moduleTest/index";
CString moduleRecordName2 = "./node_modules///0//moduleTest/index";
CString res3 = "../node_modules/0/moduleTest/index";
CString moduleRecordName3 = "../node_modules/0/moduleTest///index";
CString res4 = "./moduleTest/index";
CString moduleRecordName4 = "./node_modules/..//moduleTest////index";
CString normalName1 = PathHelper::NormalizePath(moduleRecordName1);
CString normalName2 = PathHelper::NormalizePath(moduleRecordName2);
CString normalName3 = PathHelper::NormalizePath(moduleRecordName3);
CString normalName4 = PathHelper::NormalizePath(moduleRecordName4);
EXPECT_EQ(res1, normalName1);
EXPECT_EQ(res2, normalName2);
EXPECT_EQ(res3, normalName3);
EXPECT_EQ(res4, normalName4);
}
HWTEST_F_L0(EcmaModuleTest, ParseOhmUrl)
{
// old pages url
instance->SetBundleName("com.bundleName.test");
instance->SetModuleName("moduleName");
CString inputFileName = "pages/index.abc";
CString outFileName = "";
CString res1 = "com.bundleName.test/moduleName/ets/pages/index";
CString entryPoint = PathHelper::ParseOhmUrl(instance, inputFileName, outFileName);
EXPECT_EQ(entryPoint, res1);
EXPECT_EQ(outFileName, "");
// new pages url
inputFileName = "@bundle:com.bundleName.test/moduleName/ets/pages/index.abc";
entryPoint = PathHelper::ParseOhmUrl(instance, inputFileName, outFileName);
EXPECT_EQ(entryPoint, res1);
EXPECT_EQ(outFileName, "");
// new pages url Intra-application cross hap
inputFileName = "@bundle:com.bundleName.test/moduleName1/ets/pages/index.abc";
CString outRes = "/data/storage/el1/bundle/moduleName1/ets/modules.abc";
CString res2 = "com.bundleName.test/moduleName1/ets/pages/index";
entryPoint = PathHelper::ParseOhmUrl(instance, inputFileName, outFileName);
EXPECT_EQ(entryPoint, res2);
EXPECT_EQ(outFileName, outRes);
// new pages url Cross-application
inputFileName = "@bundle:com.bundleName.test1/moduleName1/ets/pages/index.abc";
CString outRes1 = "/data/storage/el1/bundle/com.bundleName.test1/moduleName1/moduleName1/ets/modules.abc";
CString res3 = "com.bundleName.test1/moduleName1/ets/pages/index";
entryPoint = PathHelper::ParseOhmUrl(instance, inputFileName, outFileName);
EXPECT_EQ(entryPoint, res3);
EXPECT_EQ(outFileName, outRes1);
// worker url Intra-application cross hap
inputFileName = "/data/storage/el1/bundle/entry/ets/mainAbility.abc";
CString outRes2 = "/data/storage/el1/bundle/entry/ets/modules.abc";
CString res4 = "com.bundleName.test/entry/ets/mainAbility";
entryPoint = PathHelper::ParseOhmUrl(instance, inputFileName, outFileName);
EXPECT_EQ(entryPoint, res4);
EXPECT_EQ(outFileName, outRes2);
// worker url
outFileName = "";
inputFileName = "/data/storage/el1/bundle/moduleName/ets/mainAbility.abc";
CString res5 = "com.bundleName.test/moduleName/ets/mainAbility";
entryPoint = PathHelper::ParseOhmUrl(instance, inputFileName, outFileName);
EXPECT_EQ(entryPoint, res5);
EXPECT_EQ(outFileName, "");
}
} // namespace panda::test

View File

@ -21,6 +21,7 @@
#include "ecmascript/base/builtins_base.h"
#include "ecmascript/base/json_parser.h"
#include "ecmascript/base/json_stringifier.h"
#include "ecmascript/base/path_helper.h"
#include "ecmascript/base/string_helper.h"
#include "ecmascript/base/typed_array_helper-inl.h"
#if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
@ -164,11 +165,11 @@ using JSHandle = ecmascript::JSHandle<T>;
template<typename T>
using JSMutableHandle = ecmascript::JSMutableHandle<T>;
using PathHelper = ecmascript::base::PathHelper;
namespace {
// NOLINTNEXTLINE(fuchsia-statically-constructed-objects)
constexpr std::string_view ENTRY_POINTER = "_GLOBAL::func_main_0";
}
int JSNApi::vmCount_ = 0;
bool JSNApi::initialize_ = false;
static os::memory::Mutex mutex;
@ -641,7 +642,7 @@ Local<ObjectRef> JSNApi::GetExportObject(EcmaVM *vm, const std::string &file, co
JSThread *thread = vm->GetJSThread();
ecmascript::CString name = vm->GetAssetPath();
if (!vm->IsBundlePack()) {
entry = ecmascript::JSPandaFile::ParseOhmUrl(vm, entry, name);
entry = PathHelper::ParseOhmUrl(vm, entry, name);
const JSPandaFile *jsPandaFile =
JSPandaFileManager::GetInstance()->LoadJSPandaFile(thread, name, entry.c_str(), false);
if (jsPandaFile == nullptr) {
@ -649,7 +650,7 @@ Local<ObjectRef> JSNApi::GetExportObject(EcmaVM *vm, const std::string &file, co
return JSNApiHelper::ToLocal<ObjectRef>(exportObj);
}
if (!jsPandaFile->IsNewRecord()) {
JSPandaFile::CroppingRecord(entry);
PathHelper::CroppingRecord(entry);
}
}
ecmascript::ModuleManager *moduleManager = vm->GetModuleManager();

View File

@ -113,8 +113,8 @@ JSHandle<JSTaggedValue> CjsModule::Load(JSThread *thread, JSHandle<EcmaString> &
} else {
CString currentEntryPoint = ConvertToString(entrypointVal.GetTaggedValue());
CString requestStr = ConvertToString(request.GetTaggedValue());
requestEntryPoint = ModuleManager::ConcatFileNameWithMerge(jsPandaFile, mergedFilename,
currentEntryPoint, requestStr);
requestEntryPoint = PathHelper::ConcatFileNameWithMerge(jsPandaFile, mergedFilename,
currentEntryPoint, requestStr);
filename.Update(factory->NewFromUtf8(requestEntryPoint));
}

View File

@ -15,9 +15,9 @@
#include "ecmascript/ts_types/ts_type_parser.h"
#include "ecmascript/base/path_helper.h"
#include "ecmascript/jspandafile/js_pandafile_manager.h"
#include "ecmascript/jspandafile/literal_data_extractor.h"
#include "ecmascript/module/js_module_manager.h"
#include "libpandafile/annotation_data_accessor.h"
#include "libpandafile/class_data_accessor-inl.h"
@ -84,10 +84,7 @@ GlobalTSTypeRef TSTypeParser::ResolveImportType(const JSPandaFile *jsPandaFile,
CString cstringRelativePath = ConvertToString(*relativePath);
CString baseFileName = jsPandaFile->GetJSPandaFileDesc();
CString entryPoint =
ModuleManager::ConcatFileNameWithMerge(jsPandaFile,
baseFileName,
recordName,
cstringRelativePath);
base::PathHelper::ConcatFileNameWithMerge(jsPandaFile, baseFileName, recordName, cstringRelativePath);
JSHandle<EcmaString> targetVarName = GenerateImportVar(importVarNamePath);
JSHandle<TaggedArray> arrayWithGT = GenerateExportTableFromRecord(jsPandaFile, entryPoint);
GlobalTSTypeRef importedGT = GetExportGTByName(targetVarName, arrayWithGT);