Skip to content

Commit 3710094

Browse files
committed
v0.1.0
0 parents  commit 3710094

32 files changed

Lines changed: 623 additions & 0 deletions

Runtime.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
126 KB
Binary file not shown.

Runtime/Microsoft.JavaScript.NodeApi.DotNetHost.dll.meta

Lines changed: 29 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
147 KB
Binary file not shown.

Runtime/Microsoft.JavaScript.NodeApi.Generator.dll.meta

Lines changed: 53 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
460 KB
Binary file not shown.

Runtime/Microsoft.JavaScript.NodeApi.dll.meta

Lines changed: 29 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Runtime/Unity.NodeApi.Native.cpp

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
#include <codegen/il2cpp-codegen-metadata.h>
2+
#include <utils/Exception.h>
3+
#include <os/Image.h>
4+
#include <Cpp/Baselib_DynamicLibrary.h>
5+
#include <fcontext.h>
6+
7+
extern "C" char *GC_approx_sp(void);
8+
extern "C" char *GC_get_main_stack_base(void);
9+
extern "C" char *GC_stackbottom;
10+
typedef void (* GC_push_other_roots_proc)(void);
11+
extern "C" void GC_set_push_other_roots(GC_push_other_roots_proc);
12+
extern "C" GC_push_other_roots_proc GC_get_push_other_roots(void);
13+
extern "C" void GC_push_all_stack_sections(char *lo, char *hi, void *);
14+
typedef void *(* GC_fn_type)(void *);
15+
extern "C" void *GC_call_with_alloc_lock(GC_fn_type fn, void *client_data);
16+
17+
typedef struct uv_loop_s { void* data; } uv_loop_t;
18+
typedef struct uv_idle_s { void* data; uv_loop_t* loop; } uv_idle_t;
19+
typedef void (*uv_idle_cb)(uv_idle_t* handle);
20+
static int (*uv_idle_init)(uv_loop_t*, uv_idle_t* idle);
21+
static int (*uv_idle_start)(uv_idle_t* idle, uv_idle_cb cb);
22+
23+
typedef struct napi_env__* napi_env;
24+
typedef enum { napi_ok } napi_status;
25+
static napi_status (*napi_get_uv_event_loop)(napi_env env, struct uv_loop_s** loop);
26+
27+
using namespace il2cpp;
28+
29+
extern "C" void UnityFiberProc()
30+
{
31+
std::string imagePath = os::Image::GetImageName();
32+
imagePath = imagePath.substr(0, imagePath.find_last_of(IL2CPP_DIR_SEPARATOR));
33+
#if defined(__APPLE__)
34+
imagePath += "/UnityPlayer.dylib";
35+
#elif defined(_WIN32)
36+
imagePath += "\\UnityPlayer.dll";
37+
#endif
38+
39+
auto errorState = Baselib_ErrorState_Create();
40+
auto playerLib = Baselib_DynamicLibrary_Open(imagePath.c_str(), &errorState);
41+
if (Baselib_ErrorState_ErrorRaised(&errorState))
42+
{
43+
printf("error: %s\n", utils::Exception::FormatBaselibErrorState(errorState).c_str());
44+
abort();
45+
}
46+
47+
#if defined(__APPLE__)
48+
extern int PlayerMain(int argc, const char *argv[]);
49+
auto playerProc = (decltype(&PlayerMain))Baselib_DynamicLibrary_GetFunction(playerLib, "_Z10PlayerMainiPPKc", &errorState);
50+
#elif defined(_WIN32)
51+
extern int UnityMain2(void *hInstance, const wchar_t *customDataFolder, wchar_t *lpCmdLine, int nShowCmd);
52+
auto playerProc = (decltype(&UnityMain2))Baselib_DynamicLibrary_GetFunction(playerLib, "UnityMain2", &errorState);
53+
#endif
54+
55+
if (!playerProc)
56+
{
57+
printf("error: %s\n", utils::Exception::FormatBaselibErrorState(errorState).c_str());
58+
abort();
59+
}
60+
61+
#if defined(__APPLE__)
62+
imagePath = imagePath.substr(0, imagePath.find_last_of(IL2CPP_DIR_SEPARATOR));
63+
imagePath = imagePath.substr(0, imagePath.find_last_of(IL2CPP_DIR_SEPARATOR));
64+
imagePath = imagePath.substr(0, imagePath.find_last_of(IL2CPP_DIR_SEPARATOR));
65+
extern void NSBundle_fixup(const char *path);
66+
NSBundle_fixup(imagePath.c_str());
67+
68+
const char *argv[] = { os::Image::GetImageName(), "-logfile", "-" };
69+
playerProc(1, argv);
70+
#elif defined(_WIN32)
71+
imagePath = imagePath.substr(0, imagePath.find_last_of(IL2CPP_DIR_SEPARATOR));
72+
imagePath += "\\unode-module_Data";
73+
auto dataPath = utils::StringUtils::Utf8ToNativeString(imagePath);
74+
75+
extern IMPORTED_SYMBOL int SetProcessDpiAwarenessContext(int);
76+
SetProcessDpiAwarenessContext(-4);
77+
78+
extern IMPORTED_SYMBOL void *GetModuleHandleW(wchar_t *);
79+
playerProc(GetModuleHandleW(nullptr), dataPath.c_str(), L"-logfile -", 5);
80+
#endif
81+
82+
Baselib_DynamicLibrary_Close(playerLib);
83+
}
84+
85+
static char *GC_stackbottom_alt;
86+
static char *GC_stacktop_alt;
87+
88+
static const auto GC_push_other_roots = GC_get_push_other_roots();
89+
static void MY_push_other_roots(void)
90+
{
91+
GC_push_all_stack_sections(GC_stacktop_alt, GC_stackbottom_alt, nullptr);
92+
GC_push_other_roots();
93+
}
94+
95+
static fcontext_t MY_fiber;
96+
static fcontext_t MY_fiber_alt;
97+
98+
static IL2CPP_NO_INLINE void node_jump(uv_idle_t *context)
99+
{
100+
auto ctx = (fcontext_t *)GC_call_with_alloc_lock([](void *context) -> void *
101+
{
102+
auto GC_stacktop = GC_approx_sp();
103+
std::swap(GC_stacktop, GC_stacktop_alt);
104+
std::swap(GC_stackbottom, GC_stackbottom_alt);
105+
std::swap(MY_fiber, MY_fiber_alt);
106+
return jump_fcontext(MY_fiber, nullptr).ctx;
107+
}, nullptr);
108+
109+
if (MY_fiber_alt)
110+
MY_fiber_alt = ctx;
111+
}
112+
113+
extern "C" EXPORTED_SYMBOL void *napi_register_module_v1(napi_env env, void *exports)
114+
{
115+
fcontext_stack_t s = create_fcontext_stack(1024 * 1024);
116+
MY_fiber_alt = make_fcontext(s.sptr, s.ssize, [](fcontext_transfer_t t)
117+
{
118+
MY_fiber_alt = t.ctx;
119+
UnityFiberProc();
120+
MY_fiber = nullptr;
121+
node_jump({});
122+
});
123+
124+
GC_stackbottom_alt = (char *)s.sptr;
125+
GC_stackbottom = GC_get_main_stack_base();
126+
GC_set_push_other_roots(MY_push_other_roots);
127+
128+
extern void display_link(void (*cb)(uv_idle_t *), uv_idle_t *data);
129+
display_link(&node_jump, nullptr);
130+
131+
atexit([]{ quick_exit(0); });
132+
node_jump({});
133+
134+
auto errorState = Baselib_ErrorState_Create();
135+
auto progHandle = Baselib_DynamicLibrary_OpenProgramHandle(&errorState);
136+
napi_get_uv_event_loop = (decltype(napi_get_uv_event_loop))Baselib_DynamicLibrary_GetFunction(progHandle, "napi_get_uv_event_loop", &errorState);
137+
uv_idle_init = (decltype(uv_idle_init))Baselib_DynamicLibrary_GetFunction(progHandle, "uv_idle_init", &errorState);
138+
uv_idle_start = (decltype(uv_idle_start))Baselib_DynamicLibrary_GetFunction(progHandle, "uv_idle_start", &errorState);
139+
if (Baselib_ErrorState_ErrorRaised(&errorState))
140+
{
141+
printf("error: %s\n", utils::Exception::FormatBaselibErrorState(errorState).c_str());
142+
return nullptr;
143+
}
144+
Baselib_DynamicLibrary_Close(progHandle);
145+
146+
uv_loop_t *loop;
147+
napi_get_uv_event_loop(env, &loop);
148+
149+
static uv_idle_t idler;
150+
uv_idle_init(loop, &idler);
151+
uv_idle_start(&idler, &node_jump);
152+
153+
extern const Il2CppMethodPointer g_ReversePInvokeWrapperPointers[];
154+
extern const Il2CppCodeGenModule g_Unity_NodeApi_CodeGenModule;
155+
156+
auto func = g_ReversePInvokeWrapperPointers[g_Unity_NodeApi_CodeGenModule.reversePInvokeWrapperIndices[0].index];
157+
return reinterpret_cast<decltype(&napi_register_module_v1)>(func)(env, exports);
158+
}

Runtime/Unity.NodeApi.Native.cpp.meta

Lines changed: 50 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Runtime/Unity.NodeApi.Native.mm

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#include <Foundation/NSBundle.h>
2+
#include <AppKit/NSApplication.h>
3+
#include <AppKit/NSScreen.h>
4+
#include <QuartzCore/CADisplayLink.h>
5+
#include <objc/runtime.h>
6+
7+
static NSBundle *mainBundleFix;
8+
9+
@implementation NSBundle(BundleFixup)
10+
11+
+(void)fixup
12+
{
13+
Method originalMethod = class_getClassMethod(self, @selector(mainBundle));
14+
Method extendedMethod = class_getClassMethod(self, @selector(mainBundleFix));
15+
method_exchangeImplementations(originalMethod, extendedMethod);
16+
}
17+
18+
+(NSBundle *)mainBundleFix
19+
{
20+
return mainBundleFix;
21+
}
22+
23+
@end
24+
25+
extern "C" void NSBundle_fixup(const char *path)
26+
{
27+
@autoreleasepool
28+
{
29+
mainBundleFix = [NSBundle bundleWithPath:[NSString stringWithUTF8String:path]];
30+
[NSBundle fixup];
31+
32+
[[NSClassFromString(@"NSApplication") sharedApplication] setActivationPolicy:NSApplicationActivationPolicyRegular];
33+
}
34+
}
35+
36+
extern "C" void display_link(void (*cb)(void *), void *data)
37+
{
38+
@autoreleasepool
39+
{
40+
id callback = [^{cb(data);} copy];
41+
CADisplayLink *link = [[NSClassFromString(@"NSScreen") mainScreen] displayLinkWithTarget:callback selector:@selector(invoke)];
42+
[link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
43+
}
44+
}

0 commit comments

Comments
 (0)