Skip to content

Commit

Permalink
Add more functions
Browse files Browse the repository at this point in the history
  • Loading branch information
CaiMuCheng committed Jan 25, 2024
1 parent e974a86 commit f384750
Show file tree
Hide file tree
Showing 27 changed files with 685 additions and 27 deletions.
26 changes: 26 additions & 0 deletions app/src/main/assets/nodeJava.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
(function() {
const $java = process._linkedBinding("java");
$java.constructors = {};
$java.prototypes = {};

$java.findClassOrNull = function (className) {
const cachedClass = $java.constructors[className];
if (typeof cachedClass !== "undefined") {
return cachedClass;
}

const classInfo = $java.getClassInfo(className);
if (!classInfo) {
return null;
}

return classInfo;
}

globalThis["$java"] = $java;
})();

$java.setUnsafeReflectionEnabled(true);

const clazz = $java.findClassOrNull("com.mucheng.nodejava.core.Context");
console.log(clazz);
Empty file added app/src/main/assets/test.js
Empty file.
4 changes: 4 additions & 0 deletions app/src/main/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,12 @@ add_library(${CMAKE_PROJECT_NAME} SHARED
# List C/C++ source files with relative paths to this CMakeLists.txt.
main.cpp
Util.cpp
embedding.cpp
Isolate.cpp
Context.cpp
Locker.cpp
Unlocker.cpp
javabridge/ClassInfo.cpp
)

target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC
Expand Down
17 changes: 15 additions & 2 deletions app/src/main/cpp/Context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "Util.h"
#include "main.h"
#include "log.h"
#include "embedding.h"
#include <jni.h>

Context::Context(Isolate *isolate) {
Expand All @@ -25,14 +26,14 @@ void Context::To(jobject instance, Context *self) {
}

Context *Context::From(jobject instance) {
return Util::GetPtrCast<Context *>(instance, "contextPtr");
return Util::GetPtrAs<Context *>(instance, "contextPtr");
}

extern "C"
JNIEXPORT void JNICALL
Java_com_mucheng_nodejava_core_Context_nativeCreateContext(JNIEnv *env, jobject thiz,
jlong isolatePtr) {
Isolate *isolate = Util::Cast<Isolate *>(isolatePtr);
Isolate *isolate = Util::As<Isolate *>(isolatePtr);
Context *context = new Context(isolate);
Context::To(thiz, context);
}
Expand Down Expand Up @@ -154,4 +155,16 @@ Java_com_mucheng_nodejava_core_Context_nativeEvaluateScript(JNIEnv *env, jobject
}
return;
}
}

extern "C"
JNIEXPORT void JNICALL
Java_com_mucheng_nodejava_core_Context_nativeInjectJavaBridge(JNIEnv *env, jobject thiz) {
Context *context = Context::From(thiz);
AddLinkedBinding(
context->environment,
"java",
JAVA_ACCESSOR_BINDING,
nullptr
);
}
2 changes: 1 addition & 1 deletion app/src/main/cpp/Isolate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ void Isolate::To(jobject instance, Isolate *self) {
}

Isolate *Isolate::From(jobject instance) {
return Util::GetPtrCast<Isolate *>(instance, "isolatePtr");
return Util::GetPtrAs<Isolate *>(instance, "isolatePtr");
}

extern "C"
Expand Down
60 changes: 60 additions & 0 deletions app/src/main/cpp/Locker.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#include "Locker.h"
#include "Util.h"
#include "Isolate.h"
#include <jni.h>

Locker::Locker(Isolate *isolate) {
this->isolate = isolate;

self = new v8::Locker(isolate->self);
}

void Locker::To(jobject instance, Locker *self) {
Util::SetPtr(instance, "lockerPtr", self);
}

Locker *Locker::From(jobject instance) {
return Util::GetPtrAs<Locker *>(instance, "lockerPtr");
}

bool Locker::isLocked(Isolate *isolate) {
return v8::Locker::IsLocked(isolate->self);
}

void Locker::release() {
delete this->self;
}

extern "C"
JNIEXPORT void JNICALL
Java_com_mucheng_nodejava_core_Locker_nativeCreateLocker(JNIEnv *env, jobject thiz,
jlong isolatePtr) {
Isolate *isolate = Util::As<Isolate *>(isolatePtr);
Locker *locker = new Locker(isolate);
Locker::To(thiz, locker);
}

extern "C"
JNIEXPORT jboolean JNICALL
Java_com_mucheng_nodejava_core_Locker_nativeIsLocked(JNIEnv *env, jclass clazz, jlong isolatePtr) {
Isolate *isolate = Util::As<Isolate *>(isolatePtr);
return Locker::isLocked(isolate);
}

extern "C"
JNIEXPORT jboolean JNICALL
Java_com_mucheng_nodejava_core_Locker_nativeIsActive(JNIEnv *env, jobject thiz) {
return Locker::From(thiz)->self->IsActive();
}

extern "C"
JNIEXPORT jboolean JNICALL
Java_com_mucheng_nodejava_core_Locker_nativeWasEverUsed(JNIEnv *env, jobject thiz) {
return Locker::From(thiz)->self->WasEverUsed();
}

extern "C"
JNIEXPORT void JNICALL
Java_com_mucheng_nodejava_core_Locker_nativeRelease(JNIEnv *env, jobject thiz) {
Locker::From(thiz)->release();
}
29 changes: 29 additions & 0 deletions app/src/main/cpp/Locker.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// Created by 35785 on 2024/1/25.
//

#ifndef NODEJAVA_LOCKER_H
#define NODEJAVA_LOCKER_H

#include <jni.h>
#include <v8.h>
#include "Isolate.h"

class Locker {
public:
Isolate *isolate;
v8::Locker *self;

Locker(Isolate *isolate);

static void To(jobject instance, Locker *self);

static Locker *From(jobject instance);

void release();

static bool isLocked(Isolate *isolate);
};


#endif //NODEJAVA_LOCKER_H
26 changes: 26 additions & 0 deletions app/src/main/cpp/Unlocker.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#include "Unlocker.h"
#include "Util.h"
#include <v8.h>

Unlocker::Unlocker(Isolate *isolate) {
this->isolate = isolate;

self = new v8::Unlocker(isolate->self);
}

void Unlocker::To(jobject instance, Unlocker *unlocker) {
Util::SetPtr(instance, "unlockerPtr", unlocker);
}

Unlocker *Unlocker::From(jobject instance) {
return Util::GetPtrAs<Unlocker *>(instance, "unlockerPtr");
}

extern "C"
JNIEXPORT void JNICALL
Java_com_mucheng_nodejava_core_Unlocker_nativeCreateUnlocker(JNIEnv *env, jobject thiz,
jlong isolatePtr) {
Isolate *isolate = Util::As<Isolate *>(isolatePtr);
Unlocker *unlocker = new Unlocker(isolate);
Unlocker::To(thiz, unlocker);
}
26 changes: 26 additions & 0 deletions app/src/main/cpp/Unlocker.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// Created by 35785 on 2024/1/25.
//

#ifndef NODEJAVA_UNLOCKER_H
#define NODEJAVA_UNLOCKER_H
#include <jni.h>
#include <v8.h>
#include "Isolate.h"

class Unlocker {
public:
Isolate *isolate;
v8::Unlocker *self;

Unlocker(Isolate *isolate);

static void To(jobject instance, Unlocker *unlocker);

static Unlocker *From(jobject instance);


};


#endif //NODEJAVA_UNLOCKER_H
6 changes: 3 additions & 3 deletions app/src/main/cpp/Util.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,17 @@ namespace Util {
void ThrowNodeException(const char *message);

template<typename Class>
inline Class Cast(long ptr) {
inline Class As(long ptr) {
return reinterpret_cast<Class>(ptr);
}

template<typename Class>
inline Class GetPtrCast(jclass javaClass, const char *fieldName) {
inline Class GetPtrAs(jclass javaClass, const char *fieldName) {
return static_cast<Class>(GetPtr(javaClass, fieldName));
}

template<typename Class>
inline Class GetPtrCast(jobject instance, const char *fieldName) {
inline Class GetPtrAs(jobject instance, const char *fieldName) {
return static_cast<Class>(GetPtr(instance, fieldName));
}

Expand Down
74 changes: 74 additions & 0 deletions app/src/main/cpp/embedding.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#include "embedding.h"
#include "main.h"
#include "log.h"
#include "javabridge/ClassInfo.h"

v8::Local<v8::Object> getClassInfo(
v8::Isolate *isolate,
v8::Local<v8::Context> context,
v8::Local<v8::String> className
) {
JNIEnv *env = Main::env();
jclass javaBridgeUtilClass = env->FindClass("com/mucheng/nodejava/javabridge/JavaBridgeUtil");
jmethodID findClassOrNull = env->GetStaticMethodID(javaBridgeUtilClass, "findClassOrNull",
"(Ljava/lang/String;)Lcom/mucheng/nodejava/javabridge/ClassInfo;");
jobject classInfoInstance = env->NewGlobalRef(
env->CallStaticObjectMethod(javaBridgeUtilClass, findClassOrNull,
env->NewStringUTF(
*v8::String::Utf8Value(isolate,
className))));


return ClassInfo::BuildObject(isolate, context, classInfoInstance);
}

void JAVA_ACCESSOR_BINDING(
v8::Local<v8::Object> exports,
v8::Local<v8::Value>,
v8::Local<v8::Context> context,
void *priv
) {
v8::Isolate *isolate = context->GetIsolate();

exports->Set(
context,
v8::String::NewFromUtf8Literal(isolate, "getClassInfo"),
v8::Function::New(context, [](const v8::FunctionCallbackInfo<v8::Value> &info) {
SETUP_CALLBACK_INFO();
info.GetReturnValue().Set(getClassInfo(isolate, context, info[0].As<v8::String>()));
}).ToLocalChecked()
).Check();

exports->Set(
context,
v8::String::NewFromUtf8Literal(isolate, "setUnsafeReflectionEnabled"),
v8::Function::New(context, [](const v8::FunctionCallbackInfo<v8::Value> &info) {
SETUP_CALLBACK_INFO();
JNIEnv *env = Main::env();
jclass javaBridgeUtilClass = env->FindClass(
"com/mucheng/nodejava/javabridge/JavaBridgeUtil");
jfieldID unsafeReflectionEnabledField = env->GetStaticFieldID(javaBridgeUtilClass,
"unsafeReflectionEnabled",
"Z");
env->SetStaticBooleanField(javaBridgeUtilClass, unsafeReflectionEnabledField,
info[0].As<v8::Boolean>()->Value());
}).ToLocalChecked()
).Check();

exports->Set(
context,
v8::String::NewFromUtf8Literal(isolate, "isUnsafeReflectionEnabled"),
v8::Function::New(context, [](const v8::FunctionCallbackInfo<v8::Value> &info) {
SETUP_CALLBACK_INFO();
JNIEnv *env = Main::env();
jclass javaBridgeUtilClass = env->FindClass(
"com/mucheng/nodejava/javabridge/JavaBridgeUtil");
jfieldID unsafeReflectionEnabledField = env->GetStaticFieldID(javaBridgeUtilClass,
"unsafeReflectionEnabled",
"Z");
info.GetReturnValue().Set(env->GetStaticBooleanField(javaBridgeUtilClass,
unsafeReflectionEnabledField));
}).ToLocalChecked()
).Check();

}
17 changes: 17 additions & 0 deletions app/src/main/cpp/embedding.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifndef NODEJAVA_EMBEDDING_H
#define NODEJAVA_EMBEDDING_H

#include <node.h>
#include <v8.h>

#define SETUP_CALLBACK_INFO() v8::Isolate *isolate = info.GetIsolate(); \
v8::Local<v8::Context> context = isolate->GetCurrentContext();

void JAVA_ACCESSOR_BINDING(
v8::Local<v8::Object> exports,
v8::Local<v8::Value> module,
v8::Local<v8::Context> context,
void *priv
);

#endif //NODEJAVA_EMBEDDING_H
2 changes: 1 addition & 1 deletion app/src/main/cpp/include/node/nan_object_wrap.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class ObjectWrap {
static inline T* Unwrap(v8::Local<v8::Object> object) {
assert(!object.IsEmpty());
assert(object->InternalFieldCount() > 0);
// Cast to ObjectWrap before casting to T. A direct cast from void
// As to ObjectWrap before casting to T. A direct cast from void
// to T won't work right when T has more than one base class.
void* ptr = GetInternalFieldPointer(object, 0);
ObjectWrap* wrap = static_cast<ObjectWrap*>(ptr);
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/cpp/include/node/nan_persistent_pre_12_inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ class Global : public PersistentBase<T> {
return *this;
}
/**
* Cast operator for moves.
* As operator for moves.
*/
inline operator RValue() { return RValue(this); }
/**
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/cpp/include/node/node_object_wrap.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class ObjectWrap {
static inline T* Unwrap(v8::Local<v8::Object> handle) {
assert(!handle.IsEmpty());
assert(handle->InternalFieldCount() > 0);
// Cast to ObjectWrap before casting to T. A direct cast from void
// As to ObjectWrap before casting to T. A direct cast from void
// to T won't work right when T has more than one base class.
void* ptr = handle->GetAlignedPointerFromInternalField(0);
ObjectWrap* wrap = static_cast<ObjectWrap*>(ptr);
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/cpp/include/node/v8-fast-api-calls.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@
* static void SlowMethod(
* const v8::FunctionCallbackInfo<v8::Value>& info) {
* v8::Local<v8::Object> instance =
* v8::Local<v8::Object>::Cast(info.Holder());
* v8::Local<v8::Object>::As(info.Holder());
* CustomEmbedderType* receiver = Unwrap(instance);
* // TODO: Do type checks and extract {param}.
* receiver->Method(param);
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/cpp/include/node/v8-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,7 @@ class Internals {
};

// Only perform cast check for types derived from v8::Data since
// other types do not implement the Cast method.
// other types do not implement the As method.
template <bool PerformCheck>
struct CastCheck {
template <class T>
Expand Down
Loading

0 comments on commit f384750

Please sign in to comment.