Skip to content

Commit

Permalink
[unity]ExecuteModuleJSCode.h的代码移动到js文件,统一用loader加载,并且移除plugin的GetModu…
Browse files Browse the repository at this point in the history
…leExecutor
  • Loading branch information
chexiongsheng committed Oct 14, 2024
1 parent 10657a5 commit b55d23c
Show file tree
Hide file tree
Showing 6 changed files with 230 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1806,17 +1806,26 @@ void SetObjectToGlobal(pesapi_env_ref envRef, Il2CppString* __key, RuntimeObject
}
}

#define EXECUTEMODULEGLOBANAME "__puertsExecuteModule"

Il2CppObject* GetModuleExecutor(intptr_t ptr, Il2CppReflectionType* rtype)
{
pesapi_env_ref envRef = reinterpret_cast<pesapi_env_ref>(ptr);

AutoValueScope ValueScope(envRef);
auto env = pesapi_get_env_from_ref(envRef);

pesapi_value func = g_unityExports.GetModuleExecutor(env);
if (pesapi_has_caught(ValueScope.scope))
pesapi_value global = pesapi_global(env);
if (!global)
{
Exception::Raise(Exception::GetInvalidOperationException(pesapi_get_exception_as_string(ValueScope.scope, true)));
Exception::Raise(Exception::GetInvalidOperationException("can not get global for env"));
return nullptr;
}

pesapi_value func = pesapi_get_property(env, global, EXECUTEMODULEGLOBANAME);
if (!func)
{
Exception::Raise(Exception::GetInvalidOperationException("can not find ExecuteModule for env"));
return nullptr;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,12 @@ typedef void* (*GetJsClassInfoFunc)(const void* TypeId, bool TryLazyLoad);

typedef const void* (*CSharpTypeToTypeIdFunc)(const void *type);

typedef v8::Value* (*GetModuleExecutorFunc)(v8::Context* env);

#else

typedef struct JsClassInfoHeader* (*GetJsClassInfoFunc)(const void* TypeId, bool TryLazyLoad);

typedef const void* (*CSharpTypeToTypeIdFunc)(Il2CppObject *type);

typedef pesapi_value (*GetModuleExecutorFunc)(pesapi_env env);

#endif

typedef void(*LogCallbackFunc)(const char* value);
Expand All @@ -42,8 +38,6 @@ struct UnityExports

//plugin api
GetJsClassInfoFunc GetJsClassInfo = nullptr;

GetModuleExecutorFunc GetModuleExecutor = nullptr;

LogCallbackFunc LogCallback = nullptr;
};
Expand Down
215 changes: 215 additions & 0 deletions unity/Assets/core/upm/Runtime/Resources/puerts/esm_resolve.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
/*
* 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.
*/

//begin move from ExecuteModuleJSCode.h
var global = global || globalThis || (function () { return this; }());
/* eslint-disable max-depth, max-statements, complexity, max-lines-per-function */
const SLASH = 47
const DOT = 46

const assertPath = (path) => {
const t = typeof path
if (t !== 'string') {
throw new TypeError(`Expected a string, got a ${t}`)
}
}

// this function is directly from node source
const posixNormalize = (path, allowAboveRoot) => {
let res = ''
let lastSegmentLength = 0
let lastSlash = -1
let dots = 0
let code

for (let i = 0; i <= path.length; ++i) {
if (i < path.length) {
code = path.charCodeAt(i)
} else if (code === SLASH) {
break
} else {
code = SLASH
}
if (code === SLASH) {
if (lastSlash === i - 1 || dots === 1) {
// NOOP
} else if (lastSlash !== i - 1 && dots === 2) {
if (
res.length < 2 ||
lastSegmentLength !== 2 ||
res.charCodeAt(res.length - 1) !== DOT ||
res.charCodeAt(res.length - 2) !== DOT
) {
if (res.length > 2) {
const lastSlashIndex = res.lastIndexOf('/')
if (lastSlashIndex !== res.length - 1) {
if (lastSlashIndex === -1) {
res = ''
lastSegmentLength = 0
} else {
res = res.slice(0, lastSlashIndex)
lastSegmentLength = res.length - 1 - res.lastIndexOf('/')
}
lastSlash = i
dots = 0
continue
}
} else if (res.length === 2 || res.length === 1) {
res = ''
lastSegmentLength = 0
lastSlash = i
dots = 0
continue
}
}
if (allowAboveRoot) {
if (res.length > 0) {
res += '/..'
} else {
res = '..'
}
lastSegmentLength = 2
}
} else {
if (res.length > 0) {
res += '/' + path.slice(lastSlash + 1, i)
} else {
res = path.slice(lastSlash + 1, i)
}
lastSegmentLength = i - lastSlash - 1
}
lastSlash = i
dots = 0
} else if (code === DOT && dots !== -1) {
++dots
} else {
dots = -1
}
}

return res
}

const decode = (s) => {
try {
return decodeURIComponent(s)
} catch {
return s
}
}

const normalize = (p) => {
assertPath(p)

let path = p
if (path.length === 0) {
return '.'
}

const isAbsolute = path.charCodeAt(0) === SLASH
const trailingSeparator = path.charCodeAt(path.length - 1) === SLASH

path = decode(path)
path = posixNormalize(path, !isAbsolute)

if (path.length === 0 && !isAbsolute) {
path = '.'
}
if (path.length > 0 && trailingSeparator) {
path += '/'
}
if (isAbsolute) {
return '/' + path
}

return path
}

global.__puer_path__ = {
normalize: normalize,
isAbsolute(filepath) {
return !(
!/^[\\\\\\/]{2,}[^\\\\\\/]+[\\\\\\/]+[^\\\\\\/]+/.test(filepath) &&
!/^([a-z]:)?[\\\\\\/]/i.test(filepath)
)
},
isRelative(filepath) {
if (filepath[0] == '.') {
if (filepath.length == 1 || filepath[1] == '/') return true;
if (filepath[1] == '.') {
if (filepath.length == 2 || filepath[2] == '/') return true;
}
}
return false;
},
dirname: function dirname(path) {
if (path.length === 0) return '.';
var code = path.charCodeAt(0);
var hasRoot = code === 47 /*/*/;
var end = -1;
var matchedSlash = true;
for (var i = path.length - 1; i >= 1; --i) {
code = path.charCodeAt(i);
if (code === 47 /*/*/) {
if (!matchedSlash) {
end = i;
break;
}
} else {
// We saw the first non-path separator
matchedSlash = false;
}
}

if (end === -1) return hasRoot ? '/' : '.';
if (hasRoot && end === 1) return '//';
return path.slice(0, end);
}
}

var __loader = undefined;
const getLoader = () => {
if (!__loader) {
__loader = typeof jsEnv != 'undefined' ? jsEnv.GetLoader() : __tgjsGetLoader();
}
return __loader;
}

global.__puer_resolve_module_url__ = function(specifier, referer) {
const originSp = specifier;
const loader = getLoader();
if (!loader.Resolve) {
let s = !__puer_path__.isRelative(specifier) ? specifier :
__puer_path__.normalize(__puer_path__.dirname(referer) + '/' + specifier)
if (loader.FileExists(s)) {
return s
} else {
throw new Error(`[Puer002]import ${originSp} failed: module not found`);
}

} else {
let p = loader.Resolve(specifier, referer)
if (!p) {
throw new Error(`[Puer002]import ${originSp} failed: module not found`);
}
return p;
}
}

global.__puer_resolve_module_content__ = function(specifier, debugpathRef = []) {
const originSp = specifier;
const loader = getLoader();
let isESM = true;
if (loader.IsESM) isESM = specifier.startsWith('puerts/') || loader.IsESM(specifier)
if (!isESM && puer.require) return `export default puer.require('${specifier}')['default']`
const content = loader.ReadFile(specifier, debugpathRef);
if (content === undefined) {
throw new Error(`[Puer003]import ${originSp} failed: module not found`);
}
return content
}
//end move from ExecuteModuleJSCode.h
3 changes: 3 additions & 0 deletions unity/Assets/core/upm/Runtime/Src/IL2Cpp/JsEnv.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ public JsEnv(ILoader loader, int debugPort = -1)
if (debugPort != -1) {
PuertsIl2cpp.NativeAPI.CreateInspector(nativeJsEnv, debugPort);
}
string debugpath;
string context = loader.ReadFile("puerts/esm_resolve.mjs", out debugpath);
Eval(context, debugpath);
ExecuteModule("puerts/init_il2cpp.mjs");
ExecuteModule("puerts/log.mjs");
ExecuteModule("puerts/csharp.mjs");
Expand Down
6 changes: 0 additions & 6 deletions unity/cli/UnityExports4Puerts.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,12 @@ typedef void* (*GetJsClassInfoFunc)(const void* TypeId, bool TryLazyLoad);

typedef const void* (*CSharpTypeToTypeIdFunc)(const void *type);

typedef v8::Value* (*GetModuleExecutorFunc)(v8::Context* env);

#else

typedef struct JsClassInfoHeader* (*GetJsClassInfoFunc)(const void* TypeId, bool TryLazyLoad);

typedef const void* (*CSharpTypeToTypeIdFunc)(Il2CppObject *type);

typedef pesapi_value (*GetModuleExecutorFunc)(pesapi_env env);

#endif

typedef void(*LogCallbackFunc)(const char* value);
Expand All @@ -42,8 +38,6 @@ struct UnityExports

//plugin api
GetJsClassInfoFunc GetJsClassInfo = nullptr;

GetModuleExecutorFunc GetModuleExecutor = nullptr;

LogCallbackFunc LogCallback = nullptr;
};
Expand Down
21 changes: 0 additions & 21 deletions unity/native_src_il2cpp/Src/Puerts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,26 +83,6 @@ static void* GetJsClassInfo(const void* TypeId, bool TryLazyLoad)
return ClassDefinition->Data;
}

static v8::Value* GetModuleExecutor(v8::Context* env)
{
//TODO: pesapi 数据到v8的转换应该交给pesapi实现来提供
v8::Local<v8::Context> Context;
memcpy(static_cast<void*>(&Context), &env, sizeof(env));

auto ret = pesapi_eval((pesapi_env) env, (const uint8_t*) ExecuteModuleJSCode, strlen(ExecuteModuleJSCode), "__puer_execute__.mjs");

auto Isolate = Context->GetIsolate();
v8::Local<v8::Object> Global = Context->Global();
auto Ret = Global->Get(Context, v8::String::NewFromUtf8(Isolate, EXECUTEMODULEGLOBANAME).ToLocalChecked());
v8::Local<v8::Value> Func;
if (Ret.ToLocal(&Func) && Func->IsFunction())
{
return *Func;
}

return nullptr;
}

struct JSEnv
{
JSEnv()
Expand Down Expand Up @@ -251,7 +231,6 @@ V8_EXPORT pesapi_env_ref GetPapiEnvRef(puerts::JSEnv* jsEnv)
V8_EXPORT void ExchangeAPI(puerts::UnityExports * exports)
{
exports->GetJsClassInfo = &puerts::GetJsClassInfo;
exports->GetModuleExecutor = &puerts::GetModuleExecutor;
exports->LogCallback = puerts::GLogCallback;
puerts::GUnityExports = *exports;
}
Expand Down

0 comments on commit b55d23c

Please sign in to comment.