This commit is contained in:
2025-02-10 00:44:11 +08:00
parent ece733c0e5
commit 1e0c4b8d8c
1640 changed files with 1628924 additions and 0 deletions
@@ -0,0 +1,43 @@
/*
* Tencent is pleased to support the open source community by making Puerts available.
* Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
* Puerts is licensed under the BSD 3-Clause License, except for the third-party components listed in the file 'LICENSE' which may
* be subject to their corresponding license terms. This file is subject to the terms and conditions defined in file 'LICENSE',
* which is part of this source code package.
*/
#include "Wasm3ExportDef.h"
WASMCORE_API bool Export_m3_GetResults(IM3Function i_function, uint32_t i_retc, const void* o_retptrs[])
{
M3Result err = m3_GetResults(i_function, i_retc, o_retptrs);
if (err)
{
UE_LOG(LogTemp, Error, TEXT("get results error for %s: %s"), UTF8_TO_TCHAR(i_function->export_name), UTF8_TO_TCHAR(err));
return false;
}
return true;
}
WASMCORE_API bool Export_m3_Call(IM3Function i_function, uint32_t i_argc, const void* i_argptrs[])
{
M3Result err = m3_Call(i_function, i_argc, i_argptrs);
if (err)
{
UE_LOG(LogTemp, Error, TEXT("m3_Call error for %s: %s"), UTF8_TO_TCHAR(i_function->export_name), UTF8_TO_TCHAR(err));
return false;
}
return true;
}
WASMCORE_API bool Export_m3_LinkRawFunctionEx(IM3Module io_module, const char* const i_moduleName, const char* const i_functionName,
const char* const i_signature, M3RawCall i_function, const void* i_userdata)
{
M3Result err = m3_LinkRawFunctionEx(io_module, i_moduleName, i_functionName, i_signature, i_function, i_userdata);
if (err && err != m3Err_functionLookupFailed)
{
UE_LOG(LogTemp, Error, TEXT("link error for %s: %s"), UTF8_TO_TCHAR(i_functionName), UTF8_TO_TCHAR(err));
return false;
}
return true;
}
@@ -0,0 +1,62 @@
/*
* Tencent is pleased to support the open source community by making Puerts available.
* Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
* Puerts is licensed under the BSD 3-Clause License, except for the third-party components listed in the file 'LICENSE' which may
* be subject to their corresponding license terms. This file is subject to the terms and conditions defined in file 'LICENSE',
* which is part of this source code package.
*/
#include "WasmCore.h"
#include "WasmEnv.h"
#include "WasmRuntime.h"
#include "WasmModuleInstance.h"
#include "WasmFunction.h"
#define LOCTEXT_NAMESPACE "WasmCoreModule"
void WasmCoreModule::StartupModule()
{
/*if (false)
{
WasmEnv* Env = new WasmEnv();
WasmRuntime* Runtime = new WasmRuntime(Env);
{
TArray<uint8> Data;
if (FFileHelper::LoadFileToArray(Data, *(FPaths::ProjectContentDir() / TEXT("JavaScript/wasm/main.wasm"))))
{
WasmModuleInstance* Instance = new WasmModuleInstance(Data);
if (!Instance->ParseModule(Env) || !Instance->LoadModule(Runtime, 0))
{
delete Instance;
}
}
}
{
TArray<uint8> Data;
if (FFileHelper::LoadFileToArray(Data, *(FPaths::ProjectContentDir() / TEXT("JavaScript/wasm/testvector.wasm"))))
{
WasmModuleInstance* Instance = new WasmModuleInstance(Data);
if (Instance->ParseModule(Env) && Instance->LoadModule(Runtime, 0))
{
float a = Instance->GetAllExportFunctions()[TEXT("TestVector")]->Call<float, FVector>(FVector(1, 2, 3));
UE_LOG(LogTemp, Warning, TEXT("sss %f"), a);
}
else
{
delete Instance;
}
}
}
delete Runtime;
delete Env;
}*/
}
void WasmCoreModule::ShutdownModule()
{
}
#undef LOCTEXT_NAMESPACE
IMPLEMENT_MODULE(WasmCoreModule, WasmCore)
@@ -0,0 +1,23 @@
/*
* Tencent is pleased to support the open source community by making Puerts available.
* Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
* Puerts is licensed under the BSD 3-Clause License, except for the third-party components listed in the file 'LICENSE' which may
* be subject to their corresponding license terms. This file is subject to the terms and conditions defined in file 'LICENSE',
* which is part of this source code package.
*/
#include "WasmEnv.h"
WasmEnv::WasmEnv()
{
_Env = m3_NewEnvironment(); // m3_FreeEnvironment
}
WasmEnv::~WasmEnv()
{
if (_Env)
{
m3_FreeEnvironment(_Env);
_Env = nullptr;
}
}
@@ -0,0 +1,10 @@
/*
* Tencent is pleased to support the open source community by making Puerts available.
* Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
* Puerts is licensed under the BSD 3-Clause License, except for the third-party components listed in the file 'LICENSE' which may
* be subject to their corresponding license terms. This file is subject to the terms and conditions defined in file 'LICENSE',
* which is part of this source code package.
*/
#include "WasmFunction.h"
#include "WasmModule.h"
@@ -0,0 +1,13 @@
/*
* Tencent is pleased to support the open source community by making Puerts available.
* Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
* Puerts is licensed under the BSD 3-Clause License, except for the third-party components listed in the file 'LICENSE' which may
* be subject to their corresponding license terms. This file is subject to the terms and conditions defined in file 'LICENSE',
* which is part of this source code package.
*/
#include "WasmModule.h"
#include "Misc/FileHelper.h"
#include "WasmRuntime.h"
#include "WasmFunction.h"
#include "WasmStaticLink.h"
@@ -0,0 +1,162 @@
/*
* Tencent is pleased to support the open source community by making Puerts available.
* Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
* Puerts is licensed under the BSD 3-Clause License, except for the third-party components listed in the file 'LICENSE' which may
* be subject to their corresponding license terms. This file is subject to the terms and conditions defined in file 'LICENSE',
* which is part of this source code package.
*/
#include "WasmModuleInstance.h"
#include "Misc/FileHelper.h"
#include "WasmRuntime.h"
#include "WasmFunction.h"
#include "WasmStaticLink.h"
#include "WasmEnv.h"
WasmModuleInstance::WasmModuleInstance(TArray<uint8>& InData)
{
Data = std::move(InData);
}
bool WasmModuleInstance::ParseModule(WasmEnv* Env)
{
_Module = nullptr;
M3Result err = m3_ParseModule(Env->GetEnv(), &_Module, Data.GetData(), Data.Num()); // m3_FreeModule
if (err)
{
_Module = nullptr;
UE_LOG(LogTemp, Error, TEXT("m3_ParseModule:%s"), ANSI_TO_TCHAR(err));
Data.Empty();
return false;
}
return true;
}
bool WasmModuleInstance::LoadModule(WasmRuntime* Runtime, int LinkCategory, AdditionLinkFunc _Func /*= nullptr*/)
{
if (!_Module)
return false;
IM3Runtime m3Runtime = Runtime->GetRuntime();
//初始的page设置为已经分配的,否则runtime加载一个初始memory更小的module,会导致老的import memory的module被重置
if (_Module->memoryInfo.initPages < m3Runtime->memory.numPages)
{
_Module->memoryInfo.initPages = m3Runtime->memory.numPages;
}
M3Result err = m3_LoadModule(m3Runtime, _Module);
if (err)
{
UE_LOG(LogTemp, Error, TEXT("m3_LoadModule:%s"), ANSI_TO_TCHAR(err));
m3_FreeModule(_Module);
_Module = nullptr;
Data.Empty();
return false;
}
if (LinkCategory >= 0)
{
if (!WasmStaticLinkClass::Link(_Module, LinkCategory))
{
Data.Empty();
return false;
}
}
if (_Func)
{
if (!_Func(_Module))
{
UE_LOG(LogTemp, Error, TEXT("wasm module addition link function error"));
Data.Empty();
return false;
}
}
//这里需要把所有函数都compile掉,否则在函数调用的过程中如果触发compile,会有写越界
//这是因为compile需要读取wasm的原始数据(类似v8需要js原始代码一样)
//这里暂时不想保留wasm的源码,所以先全部compile
//未来如果有crash,就再考虑保留源码
err = m3_CompileModule(_Module);
if (err)
{
UE_LOG(LogTemp, Error, TEXT("m3_CompileModule: %s"), ANSI_TO_TCHAR(err));
Data.Empty();
return false;
}
for (u32 i = 0; i < _Module->numFunctions; ++i)
{
IM3Function f = &_Module->functions[i];
if (f->compiled && f->export_name && *(f->export_name))
{
_AllExportFunctions.Add(f->export_name, new WasmFunction(f));
}
}
//清理下data,如果有crash就不清理了吧
Data.Empty();
Runtime->OnModuleInstance(this);
return true;
// compile all function
/*for (u32 i = 0; i < _Module->numFunctions; ++i)
{
IM3Function f = &_Module->functions[i];
// if (f->export_name && *(f->export_name))
{
if (!f->compiled)
{
err = CompileFunction(f);
if (err)
{
UE_LOG(LogTemp, Error, TEXT("m3_ExportFunctions:%s %s"), ANSI_TO_TCHAR(err), ANSI_TO_TCHAR(f->export_name));
}
}
if (f->compiled && f->export_name && *(f->export_name))
{
_AllExportFunctions.Add(f->export_name, new WasmFunction(f));
}
}
}*/
}
size_t WasmModuleInstance::TableGrow(size_t N) const
{
size_t ret;
M3Result err = m3_GrowTable0(_Module, N, &ret);
if (err)
{
// TODO: do not log with LogTemp
UE_LOG(LogTemp, Error, TEXT("m3_GrowTable0: %s"), ANSI_TO_TCHAR(err));
return 0;
}
return ret;
}
void WasmModuleInstance::TableSet(size_t Idx, IM3Function Function) const
{
M3Result err = m3_SetTable0(_Module, Idx, Function);
if (err)
{
// TODO: do not log with LogTemp
UE_LOG(LogTemp, Error, TEXT("m3_SetTable0: %s"), ANSI_TO_TCHAR(err));
}
}
size_t WasmModuleInstance::TableLen() const
{
return m3_GetTable0Size(_Module);
}
WasmModuleInstance::~WasmModuleInstance()
{
for (auto Iter = _AllExportFunctions.CreateIterator(); Iter; ++Iter)
{
delete Iter->Value;
}
// module会在runtime的free的时候被free,所以这里不需要主动free了?
if (_Module)
{
// m3_FreeModule(_Module);
_Module = nullptr;
}
}
@@ -0,0 +1,99 @@
/*
* Tencent is pleased to support the open source community by making Puerts available.
* Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
* Puerts is licensed under the BSD 3-Clause License, except for the third-party components listed in the file 'LICENSE' which may
* be subject to their corresponding license terms. This file is subject to the terms and conditions defined in file 'LICENSE',
* which is part of this source code package.
*/
#include "WasmRuntime.h"
#include "WasmModule.h"
#include "WasmFunction.h"
#include "HAL/Platform.h"
#include "m3_exec_defs.h"
#include "m3_env.h"
#include "WasmModuleInstance.h"
static TArray<WasmRuntime*> _AllWasmRuntimes;
static uint16 WasmRuntime_Seq = 1;
WasmRuntime::WasmRuntime(WasmEnv* Env, int MaxPage /*= 10*/, int InitPage /*= 1*/, int StackSizeInBytes /*= 5 * 1024*/)
{
_RuntimeSeq = WasmRuntime_Seq;
WasmRuntime_Seq++;
if (!WasmRuntime_Seq)
WasmRuntime_Seq++;
_Env = Env;
_Runtime = m3_NewRuntime(_Env->GetEnv(), StackSizeInBytes, this);
_Runtime->memory.maxPages = MaxPage;
ResizeMemory(_Runtime, InitPage);
_AllWasmRuntimes.Add(this);
}
WasmRuntime::~WasmRuntime()
{
for (WasmModuleInstance*& Instance : _AllModuleInstances)
{
delete Instance;
}
if (_Runtime)
{
m3_FreeRuntime(_Runtime);
_Runtime = nullptr;
}
_AllWasmRuntimes.Remove(this);
}
int WasmRuntime::Grow(int number)
{
int Ret = _Runtime->memory.numPages;
ResizeMemory(_Runtime, _Runtime->memory.numPages + number);
return Ret;
}
uint8* WasmRuntime::GetBuffer(int& Length)
{
u8* base = m3MemData(_Runtime->memory.mallocated);
Length = _Runtime->memory.mallocated->length;
return base;
}
WasmModuleInstance* WasmRuntime::OnModuleInstance(WasmModuleInstance* InModuleInstance)
{
_AllModuleInstances.Add(InModuleInstance);
WasmModuleInstance* ret = _AllModuleInstances[_AllModuleInstances.Num() - 1];
ret->Index = _AllModuleInstances.Num() - 1;
if (MaxWasmStackAllocCount == 0)
{
if (ret->GetAllExportFunctions().Contains("GetStackParamBegin"))
{
WasmFunction* GetStackParamBegin = ret->GetAllExportFunctions()["GetStackParamBegin"];
WasmFunction* GetStackParamMaxSize = ret->GetAllExportFunctions()["GetStackParamMaxSize"];
MaxWasmStackAllocCount = GetStackParamMaxSize->Call<WASM_PTR>();
WASM_PTR BasePtr = GetStackParamBegin->Call<WASM_PTR>();
BaseStackAllocInfo.PtrInWasm = BasePtr;
BaseStackAllocInfo.RealPtr = (char*) GetPlatformAddress(BasePtr);
CurrentStackAllocInfo = BaseStackAllocInfo;
// 8字节对齐
while ((reinterpret_cast<UPTRINT>(CurrentStackAllocInfo.RealPtr) % 8) != 0)
{
CurrentStackAllocInfo.PtrInWasm++;
CurrentStackAllocInfo.RealPtr++;
}
}
}
return ret;
}
void* WasmRuntime::GetPlatformAddress(WASM_PTR ptr)
{
u8* base = m3MemData(_Runtime->memory.mallocated);
return base + ptr;
}
WasmRuntime* WasmRuntime::StaticGetWasmRuntime(IM3Runtime Runtime)
{
return (WasmRuntime*) (Runtime->userdata);
}
@@ -0,0 +1,42 @@
/*
* Tencent is pleased to support the open source community by making Puerts available.
* Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
* Puerts is licensed under the BSD 3-Clause License, except for the third-party components listed in the file 'LICENSE' which may
* be subject to their corresponding license terms. This file is subject to the terms and conditions defined in file 'LICENSE',
* which is part of this source code package.
*/
#include "WasmStaticLink.h"
static TArray<TArray<WasmStaticLinkClassFunction> >* StaticLinkFunctionList = nullptr;
WasmStaticLinkClass::WasmStaticLinkClass(WasmStaticLinkClassFunction func, int Category)
{
if (!StaticLinkFunctionList)
StaticLinkFunctionList = new TArray<TArray<WasmStaticLinkClassFunction> >();
if (StaticLinkFunctionList->Num() <= Category)
{
StaticLinkFunctionList->AddDefaulted(Category - StaticLinkFunctionList->Num() + 1);
}
TArray<TArray<WasmStaticLinkClassFunction> >& tmp = *StaticLinkFunctionList;
tmp[Category].Add(func);
}
bool WasmStaticLinkClass::Link(IM3Module _Module, int Category)
{
if (StaticLinkFunctionList)
{
TArray<TArray<WasmStaticLinkClassFunction> >& tmp = *StaticLinkFunctionList;
if (tmp.Num() > Category)
{
for (WasmStaticLinkClassFunction& func : tmp[Category])
{
if (!func(_Module))
{
return false;
}
}
}
}
return true;
}