Skip to content

Commit b5c84dd

Browse files
committed
csjvm: initial commit
0 parents  commit b5c84dd

File tree

5 files changed

+350
-0
lines changed

5 files changed

+350
-0
lines changed

.gitignore

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Compiled Object files
2+
*.slo
3+
*.lo
4+
*.o
5+
*.obj
6+
7+
# Precompiled Headers
8+
*.gch
9+
*.pch
10+
11+
# Compiled Dynamic libraries
12+
*.so
13+
*.dylib
14+
*.dll
15+
16+
# Fortran module files
17+
*.mod
18+
*.smod
19+
20+
# Compiled Static libraries
21+
*.lai
22+
*.la
23+
*.a
24+
*.lib
25+
26+
# Executables
27+
*.exe
28+
*.out
29+
*.app
30+
31+
# Logs
32+
*.log
33+
34+
.idea/
35+
cmake-build-*/
36+
37+
.DS_Store
38+
39+
# built application files
40+
*.apk
41+
*.ap_
42+
43+
# files for the dex VM
44+
*.dex
45+
46+
# Java class files
47+
*.class
48+
49+
# generated files
50+
bin/
51+
gen/
52+
53+
# Local configuration file (sdk path, etc)
54+
local.properties
55+
56+
# Eclipse project files
57+
.classpath
58+
.project
59+
60+
# Proguard folder generated by Eclipse
61+
proguard/
62+
63+
# Intellij project files
64+
*.iml
65+
*.ipr
66+
*.iws
67+
.idea/
68+
69+
*.iml
70+
.gradle
71+
/local.properties
72+
/.idea/workspace.xml
73+
/.idea/libraries
74+
.DS_Store
75+
/build
76+
/captures
77+
.externalNativeBuild
78+

CMakeLists.txt

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
cmake_minimum_required(VERSION 3.4)
2+
project(covscript-jvm)
3+
include_directories(include)
4+
include_directories(../covscript/include)
5+
6+
set(CMAKE_CXX_STANDARD 11)
7+
set(CMAKE_CXX_FLAGS " -fPIC -O3")
8+
9+
if (NOT DEFINED ENV{JAVA_HOME})
10+
message(FATAL_ERROR "Environment variable required: JAVA_HOME")
11+
endif ()
12+
13+
set(JAVA_HOME $ENV{JAVA_HOME})
14+
LINK_DIRECTORIES(${JAVA_HOME}/jre/lib)
15+
LINK_DIRECTORIES(${JAVA_HOME}/jre/lib/server)
16+
INCLUDE_DIRECTORIES(${JAVA_HOME}/include)
17+
set(CMAKE_BUILD_RPATH ${JAVA_HOME}/jre/lib ${JAVA_HOME}/jre/lib/server)
18+
19+
IF (WIN32)
20+
message(FATAL_ERROR "Windows is not supported")
21+
ELSEIF (APPLE)
22+
INCLUDE_DIRECTORIES(${JAVA_HOME}/include/darwin)
23+
ELSEIF (UNIX)
24+
message(FATAL_ERROR "Unix is not supported.")
25+
ENDIF ()
26+
27+
add_library(csjvm SHARED jvm.cpp)
28+
target_link_libraries(csjvm jvm)
29+
set_target_properties(csjvm PROPERTIES PREFIX "")
30+
set_target_properties(csjvm PROPERTIES SUFFIX ".cse")
31+

HelloWorld.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
public class HelloWorld {
2+
public static void main(String[] args) {
3+
System.out.println("hello world");
4+
}
5+
}

hello-world.csc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import csjvm
2+
3+
var vm = csjvm.create_JavaVM({"-Djava.class.path=."})
4+
5+
var clazz = vm.find_class("HelloWorld")
6+
7+
var method = vm.get_static_method(clazz, "main", "([Ljava/lang/String;)V")
8+
9+
vm.call_static_void_method(clazz, method, {})
10+
11+
vm.destroy_JavaVM()

jvm.cpp

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
#include <covscript/cni.hpp>
2+
#include <covscript/extension.hpp>
3+
#include <jni.h>
4+
5+
static JavaVM *jvm;
6+
static JNIEnv *env;
7+
8+
static cs::extension jvm_ext;
9+
static cs::extension_t jvm_ext_shared = cs::make_shared_extension(jvm_ext);
10+
11+
namespace csjvm {
12+
using namespace cs;
13+
14+
struct jvm_instance {
15+
JavaVM *jvm = nullptr;
16+
JNIEnv *env = nullptr;
17+
JavaVMInitArgs args;
18+
19+
int options_count = 0;
20+
JavaVMOption *options = nullptr;
21+
};
22+
23+
struct jvm_holder {
24+
jvm_instance *instance;
25+
};
26+
27+
static void dealloc_instance(jvm_instance *instance) {
28+
for (int i = 0; i < instance->options_count; ++i) {
29+
free(instance->options[i].optionString);
30+
}
31+
delete[] instance->options;
32+
delete instance;
33+
}
34+
35+
jvm_holder create_JavaVM(const array &optionsArray) {
36+
jvm_holder holder{nullptr};
37+
holder.instance = new jvm_instance;
38+
holder.instance->args.version = JNI_VERSION_1_8;
39+
holder.instance->options_count = static_cast<int>(optionsArray.size());
40+
holder.instance->args.nOptions = static_cast<jint>(holder.instance->options_count);
41+
42+
holder.instance->options = new JavaVMOption[optionsArray.size()];
43+
for (int i = 0; i < holder.instance->options_count; ++i) {
44+
var optionString = optionsArray[i];
45+
holder.instance->options[i].optionString =
46+
strdup(optionString.to_string().c_str());
47+
}
48+
holder.instance->args.options = holder.instance->options;
49+
holder.instance->args.ignoreUnrecognized = JNI_FALSE;
50+
51+
JavaVM *javaVM;
52+
JNIEnv *env;
53+
jint result = JNI_CreateJavaVM(&javaVM, (void **) &env, &holder.instance->args);
54+
if (result == JNI_OK) {
55+
holder.instance->jvm = javaVM;
56+
holder.instance->env = env;
57+
} else {
58+
dealloc_instance(holder.instance);
59+
holder.instance = nullptr;
60+
}
61+
return holder;
62+
}
63+
64+
void destroy_JavaVM(jvm_holder &holder) {
65+
if (holder.instance != nullptr) {
66+
dealloc_instance(holder.instance);
67+
holder.instance = nullptr;
68+
}
69+
}
70+
71+
jclass find_class(const jvm_holder &holder, const cs::string &name) {
72+
if (holder.instance == nullptr) {
73+
return nullptr;
74+
}
75+
return holder.instance->env->FindClass(name.c_str());
76+
}
77+
78+
jmethodID get_static_method(const jvm_holder &holder,
79+
const jclass clazz,
80+
const cs::string &name,
81+
const cs::string &signature) {
82+
if (holder.instance == nullptr || clazz == nullptr) {
83+
return nullptr;
84+
}
85+
return holder.instance->env->GetStaticMethodID(clazz, name.c_str(), signature.c_str());
86+
}
87+
88+
void call_static_void_method(const jvm_holder &holder, jclass clazz,
89+
jmethodID method, array args) {
90+
if (holder.instance == nullptr || clazz == nullptr || method == nullptr) {
91+
return;
92+
}
93+
holder.instance->env->CallStaticVoidMethod(clazz, method);
94+
}
95+
96+
void init() {
97+
jvm_ext.add_var("create_JavaVM", var::make_protect<callable>(cni(create_JavaVM), true));
98+
jvm_ext.add_var("destroy_JavaVM", var::make_protect<callable>(cni(destroy_JavaVM), true));
99+
jvm_ext.add_var("find_class", var::make_protect<callable>(cni(find_class), true));
100+
jvm_ext.add_var("get_static_method", var::make_protect<callable>(cni(get_static_method), true));
101+
jvm_ext.add_var("call_static_void_method", var::make_protect<callable>(cni(call_static_void_method), true));
102+
}
103+
}
104+
105+
namespace cs_impl {
106+
template<>
107+
cs::extension_t &get_ext<csjvm::jvm_holder>() {
108+
return jvm_ext_shared;
109+
}
110+
111+
template<>
112+
constexpr const char *get_name_of_type<csjvm::jvm_holder>() {
113+
return "csjvm::JavaVM";
114+
}
115+
116+
template<>
117+
constexpr const char *get_name_of_type<jclass>() {
118+
return "csjvm::JavaClass";
119+
}
120+
121+
template<>
122+
constexpr const char *get_name_of_type<jmethodID>() {
123+
return "csjvm::JavaMethod";
124+
}
125+
126+
template<>
127+
constexpr const char *get_name_of_type<jfieldID>() {
128+
return "csjvm::JavaField";
129+
}
130+
131+
template<>
132+
constexpr const char *get_name_of_type<jobject>() {
133+
return "csjvm::JavaObject";
134+
}
135+
136+
template<>
137+
constexpr const char *get_name_of_type<jthrowable>() {
138+
return "csjvm::JavaThrowable";
139+
}
140+
141+
template<>
142+
constexpr const char *get_name_of_type<jstring>() {
143+
return "csjvm::JavaString";
144+
}
145+
146+
template<>
147+
constexpr const char *get_name_of_type<jarray>() {
148+
return "csjvm::JavaArray";
149+
}
150+
151+
template<>
152+
constexpr const char *get_name_of_type<jbooleanArray>() {
153+
return "csjvm::JavaBooleanArray";
154+
}
155+
156+
template<>
157+
constexpr const char *get_name_of_type<jintArray>() {
158+
return "csjvm::JavaIntegerArray";
159+
}
160+
161+
template<>
162+
constexpr const char *get_name_of_type<jfloatArray>() {
163+
return "csjvm::JavaFloatArray";
164+
}
165+
166+
template<>
167+
constexpr const char *get_name_of_type<jdoubleArray>() {
168+
return "csjvm::JavaDoubleArray";
169+
}
170+
171+
template<>
172+
constexpr const char *get_name_of_type<jcharArray>() {
173+
return "csjvm::JavaCharacterArray";
174+
}
175+
176+
template<>
177+
constexpr const char *get_name_of_type<jbyteArray>() {
178+
return "csjvm::JavaByteArray";
179+
}
180+
181+
template<>
182+
constexpr const char *get_name_of_type<jshortArray>() {
183+
return "csjvm::JavaShortArray";
184+
}
185+
186+
template<>
187+
constexpr const char *get_name_of_type<jboolean>() {
188+
return "csjvm::JavaBoolean";
189+
}
190+
191+
template<>
192+
constexpr const char *get_name_of_type<jint>() {
193+
return "csjvm::JavaInteger";
194+
}
195+
196+
template<>
197+
constexpr const char *get_name_of_type<jfloat>() {
198+
return "csjvm::JavaFloat";
199+
}
200+
201+
template<>
202+
constexpr const char *get_name_of_type<jdouble>() {
203+
return "csjvm::JavaDouble";
204+
}
205+
206+
template<>
207+
constexpr const char *get_name_of_type<jchar>() {
208+
return "csjvm::JavaCharacter";
209+
}
210+
211+
template<>
212+
constexpr const char *get_name_of_type<jbyte>() {
213+
return "csjvm::JavaByte";
214+
}
215+
216+
template<>
217+
constexpr const char *get_name_of_type<jshort>() {
218+
return "csjvm::JavaShort";
219+
}
220+
}
221+
222+
cs::extension *cs_extension() {
223+
csjvm::init();
224+
return &jvm_ext;
225+
}

0 commit comments

Comments
 (0)