Correct SIGSEGV with forwarders.
[SquirrelJME.git] / emulators / emulator-base / src / main / c / mle_runtime.c
blob4ad64771f8c0ef5d28c9383dc7e655d0e38f1f74
1 /* -*- Mode: C++; indent-tabs-mode: t; tab-width: 4 -*-
2 // ---------------------------------------------------------------------------
3 // SquirrelJME
4 // Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
5 // ---------------------------------------------------------------------------
6 // SquirrelJME is under the Mozilla Public License Version 2.0.
7 // See license.mkd for licensing and copyright information.
8 // -------------------------------------------------------------------------*/
10 #include <string.h>
11 #include <stdlib.h>
13 #if defined(_WIN32) || defined(_WIN64)
14 #include <windows.h>
15 #include <libloaderapi.h>
16 #elif defined(__APPLE__)
17 #include <mach-o/dyld.h>
18 #include <stdint.h>
19 #elif defined(__linux__) || defined(__linux)
20 #include <unistd.h>
21 #include <stdint.h>
22 #elif defined(__FreeBSD__)
23 #include <sys/stat.h>
24 #include <sys/sysctl.h>
25 #include <unistd.h>
26 #include <stdint.h>
27 #endif
29 #include "squirreljme.h"
31 #define RUNTIME_CLASSNAME "cc/squirreljme/emulator/EmulatedRuntimeShelf"
33 #define RUNTIME_MEMORYPROFILE_DESC "()I"
34 #define RUNTIME_SYSTEMENV_DESC "(Ljava/lang/String;)Ljava/lang/String;"
35 #define RUNTIME_VMDESCRIPTION_DESC "(I)Ljava/lang/String;"
36 #define RUNTIME_VMSTATISTIC_DESC "(I)J"
38 JNIEXPORT void JNICALL Impl_mle_RuntimeShelf_garbageCollect(
39 JNIEnv* env, jclass classy)
41 // Does nothing
44 JNIEXPORT jint JNICALL Impl_mle_RuntimeShelf_lineEnding(JNIEnv*, jclass)
46 #if defined(_WIN32)
47 return 3;
48 #else
49 return 1;
50 #endif
53 JNIEXPORT jstring JNICALL Impl_mle_RuntimeShelf_vmDescription(
54 JNIEnv* env, jclass classy, jint id)
56 #define NATIVE_EXEC_PATH_LEN 768
57 char fileName[NATIVE_EXEC_PATH_LEN];
59 #if defined(__APPLE__)
60 uint32_t fileNameLen;
61 #elif defined(__FreeBSD__)
62 struct stat* statBuf;
63 int sysCtlInput[4];
64 size_t fileNameLen;
65 #elif defined(__sun) || defined(__illumos__)
66 const char* bip;
67 #endif
69 // Executable path of the VM binary (EXECUTABLE_PATH)
70 if (id == 6)
72 // Clear buffer
73 memset(fileName, 0, sizeof(fileName));
75 // Use native system APIs to get this information
76 #if defined(_WIN32) || defined(_WIN64)
77 GetModuleFileNameA(NULL, fileName, NATIVE_EXEC_PATH_LEN);
78 #elif defined(__APPLE__)
79 fileNameLen = NATIVE_EXEC_PATH_LEN;
80 _NSGetExecutablePath(fileName, &fileNameLen);
81 #elif defined(__linux__) || defined(__linux)
82 readlink("/proc/self/exe", fileName, NATIVE_EXEC_PATH_LEN);
83 #elif defined(__NetBSD__) || defined(__DragonFly__)
84 readlink("/proc/curproc/file", fileName, NATIVE_EXEC_PATH_LEN);
85 #elif defined(__FreeBSD__)
86 memset(&statBuf, 0, sizeof(statBuf));
87 if (stat("/proc/curproc/file", &statBuf) == 0)
88 readlink("/proc/curproc/file", fileName, NATIVE_EXEC_PATH_LEN);
89 else
91 // Setup systemctl input
92 sysCtlInput[0] = CTL_KERN;
93 sysCtlInput[1] = KERN_PROC;
94 sysCtlInput[2] = KERN_PROC_PATHNAME;
95 sysCtlInput[3] = -1;
97 // Perform the call
98 fileNameLen = NATIVE_EXEC_PATH_LEN;
99 sysctl(mib, 4, fileName, &fileNameLen, NULL, 0);
101 #elif defined(__sun) || defined(__illumos__)
102 bip = getexecname();
103 if (bip != NULL)
104 strncpy(fileName, bip, NATIVE_EXEC_PATH_LEN - 1);
105 #endif
107 // Convert to Java String if Valid
108 if (fileName[0] != 0)
110 fileName[NATIVE_EXEC_PATH_LEN - 1] = 0;
111 return (*env)->NewStringUTF(env, fileName);
115 return (jstring)forwardCallStaticObject(env, RUNTIME_CLASSNAME,
116 "vmDescription", RUNTIME_VMDESCRIPTION_DESC,
117 id);
118 #undef NATIVE_EXEC_PATH_LEN
121 JNIEXPORT jlong JNICALL Impl_mle_RuntimeShelf_vmStatistic(
122 JNIEnv* env, jclass classy, jint id)
124 return forwardCallStaticLong(env, RUNTIME_CLASSNAME,
125 "vmStatistic", RUNTIME_VMSTATISTIC_DESC,
126 id);
129 JNIEXPORT jint JNICALL Impl_mle_RuntimeShelf_memoryProfile(JNIEnv*, jclass)
131 // The value is normal
132 return 0;
135 JNIEXPORT jint JNICALL Impl_mle_RuntimeShelf_phoneModel(JNIEnv*, jclass)
137 // Just be a generic device here
138 return 0;
141 JNIEXPORT jobject JNICALL Impl_mle_RuntimeShelf_systemEnv(
142 JNIEnv* env, jclass classy, jstring key)
144 return forwardCallStaticObject(env, RUNTIME_CLASSNAME,
145 "systemEnv", RUNTIME_SYSTEMENV_DESC,
146 key);
149 JNIEXPORT jint JNICALL Impl_mle_RuntimeShelf_vmType(JNIEnv*, jclass)
151 // The value 1 is Java SE type
152 return 1;
155 static const JNINativeMethod mleRuntimeMethods[] =
157 {"garbageCollect", "()V", (void*)Impl_mle_RuntimeShelf_garbageCollect},
158 {"lineEnding", "()I", (void*)Impl_mle_RuntimeShelf_lineEnding},
159 {"memoryProfile", RUNTIME_MEMORYPROFILE_DESC, (void*)Impl_mle_RuntimeShelf_memoryProfile},
160 {"phoneModel", "()I", (void*)Impl_mle_RuntimeShelf_phoneModel},
161 {"systemEnv", RUNTIME_SYSTEMENV_DESC, (void*)Impl_mle_RuntimeShelf_systemEnv},
162 {"vmDescription", RUNTIME_VMDESCRIPTION_DESC, (void*)Impl_mle_RuntimeShelf_vmDescription},
163 {"vmStatistic", RUNTIME_VMSTATISTIC_DESC, (void*)Impl_mle_RuntimeShelf_vmStatistic},
164 {"vmType", "()I", (void*)Impl_mle_RuntimeShelf_vmType},
167 jint JNICALL mleRuntimeInit(JNIEnv* env, jclass classy)
169 return (*env)->RegisterNatives(env,
170 (*env)->FindClass(env, "cc/squirreljme/jvm/mle/RuntimeShelf"),
171 mleRuntimeMethods, sizeof(mleRuntimeMethods) /
172 sizeof(JNINativeMethod));