Init
This commit is contained in:
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user