diff --git a/unity/Assets/core/upm/Editor/Resources/puerts/xil2cpp/Puerts_il2cpp.cpp.txt b/unity/Assets/core/upm/Editor/Resources/puerts/xil2cpp/Puerts_il2cpp.cpp.txt index df94d3bc4a..b06bf7ced4 100644 --- a/unity/Assets/core/upm/Editor/Resources/puerts/xil2cpp/Puerts_il2cpp.cpp.txt +++ b/unity/Assets/core/upm/Editor/Resources/puerts/xil2cpp/Puerts_il2cpp.cpp.txt @@ -1806,6 +1806,8 @@ 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(ptr); @@ -1813,10 +1815,17 @@ Il2CppObject* GetModuleExecutor(intptr_t ptr, Il2CppReflectionType* rtype) 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; } diff --git a/unity/Assets/core/upm/Editor/Resources/puerts/xil2cpp/UnityExports4Puerts.h.txt b/unity/Assets/core/upm/Editor/Resources/puerts/xil2cpp/UnityExports4Puerts.h.txt index 5a83fdc010..84c7ceee8c 100644 --- a/unity/Assets/core/upm/Editor/Resources/puerts/xil2cpp/UnityExports4Puerts.h.txt +++ b/unity/Assets/core/upm/Editor/Resources/puerts/xil2cpp/UnityExports4Puerts.h.txt @@ -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); @@ -42,8 +38,6 @@ struct UnityExports //plugin api GetJsClassInfoFunc GetJsClassInfo = nullptr; - - GetModuleExecutorFunc GetModuleExecutor = nullptr; LogCallbackFunc LogCallback = nullptr; }; diff --git a/unity/Assets/core/upm/Runtime/Resources/puerts/esm_resolve.mjs b/unity/Assets/core/upm/Runtime/Resources/puerts/esm_resolve.mjs new file mode 100644 index 0000000000..91b4651e2f --- /dev/null +++ b/unity/Assets/core/upm/Runtime/Resources/puerts/esm_resolve.mjs @@ -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 \ No newline at end of file diff --git a/unity/Assets/core/upm/Runtime/Src/IL2Cpp/JsEnv.cs b/unity/Assets/core/upm/Runtime/Src/IL2Cpp/JsEnv.cs index c54b4bd018..8a16dfd121 100644 --- a/unity/Assets/core/upm/Runtime/Src/IL2Cpp/JsEnv.cs +++ b/unity/Assets/core/upm/Runtime/Src/IL2Cpp/JsEnv.cs @@ -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"); diff --git a/unity/cli/UnityExports4Puerts.h b/unity/cli/UnityExports4Puerts.h index 19cfd60c44..dc3182b0fa 100644 --- a/unity/cli/UnityExports4Puerts.h +++ b/unity/cli/UnityExports4Puerts.h @@ -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); @@ -42,8 +38,6 @@ struct UnityExports //plugin api GetJsClassInfoFunc GetJsClassInfo = nullptr; - - GetModuleExecutorFunc GetModuleExecutor = nullptr; LogCallbackFunc LogCallback = nullptr; }; diff --git a/unity/native_src_il2cpp/Src/Puerts.cpp b/unity/native_src_il2cpp/Src/Puerts.cpp index de1ee078fd..0eec9b3ee0 100644 --- a/unity/native_src_il2cpp/Src/Puerts.cpp +++ b/unity/native_src_il2cpp/Src/Puerts.cpp @@ -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 Context; - memcpy(static_cast(&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 Global = Context->Global(); - auto Ret = Global->Get(Context, v8::String::NewFromUtf8(Isolate, EXECUTEMODULEGLOBANAME).ToLocalChecked()); - v8::Local Func; - if (Ret.ToLocal(&Func) && Func->IsFunction()) - { - return *Func; - } - - return nullptr; -} - struct JSEnv { JSEnv() @@ -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; }