summaryrefslogtreecommitdiff
path: root/akono/src/main/cpp/akono-jni.cpp
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2019-12-06 02:00:34 +0100
committerFlorian Dold <florian.dold@gmail.com>2019-12-06 02:00:34 +0100
commitcb3eb410fbf79cb2bb9ddb969b771259ea9acf6e (patch)
tree0fcc0e7f3703735330b9432f3df1fa2f2b33f22a /akono/src/main/cpp/akono-jni.cpp
parent307baaf5eb716f8ea327374c09cb328305e29c51 (diff)
downloadakono-cb3eb410fbf79cb2bb9ddb969b771259ea9acf6e.tar.gz
akono-cb3eb410fbf79cb2bb9ddb969b771259ea9acf6e.tar.bz2
akono-cb3eb410fbf79cb2bb9ddb969b771259ea9acf6e.zip
simplifications / threading
Diffstat (limited to 'akono/src/main/cpp/akono-jni.cpp')
-rw-r--r--akono/src/main/cpp/akono-jni.cpp253
1 files changed, 23 insertions, 230 deletions
diff --git a/akono/src/main/cpp/akono-jni.cpp b/akono/src/main/cpp/akono-jni.cpp
index 0480eea5..1d0f7512 100644
--- a/akono/src/main/cpp/akono-jni.cpp
+++ b/akono/src/main/cpp/akono-jni.cpp
@@ -1,9 +1,11 @@
-#include <string.h>
+#include <sys/types.h>
+#include <sys/syscall.h>
+#include <cstring>
#include <jni.h>
#include <libplatform/libplatform.h>
#include <v8.h>
-#define NODE_WANT_INTERNALS 1
+#define NODE_WANT_INTERNALS 1 // NOLINT(cppcoreguidelines-macro-usage)
#include <node.h>
@@ -11,10 +13,9 @@
#include <unistd.h>
#include <android/log.h>
#include <node_main_instance.h>
+#include <node_binding.h>
#include <node_native_module_env.h>
-
-
// Provide stubs so that libnode.so links properly
namespace node {
namespace native_module {
@@ -40,7 +41,7 @@ static const char *tag = "myapp";
static void *thread_func(void *) {
ssize_t rdsz;
- char buf[128];
+ char buf[1024];
while ((rdsz = read(pfd[0], buf, sizeof buf - 1)) > 0) {
if (buf[rdsz - 1] == '\n') --rdsz;
buf[rdsz] = 0; /* add null-terminator */
@@ -83,7 +84,7 @@ private:
JNIEnv *m_env;
public:
JStringValue(JNIEnv *env, jstring s) : m_env(env), m_jstr(s) {
- m_cstr = env->GetStringUTFChars(s, NULL);
+ m_cstr = env->GetStringUTFChars(s, nullptr);
}
~JStringValue() {
@@ -111,82 +112,21 @@ static void InitNode(std::vector<const char *> argv) {
void notifyCb(uv_async_t *async);
static void sendMessageCallback(const v8::FunctionCallbackInfo<v8::Value> &args);
-static void loadModuleCallback(const v8::FunctionCallbackInfo<v8::Value> &args);
-static void getDataCallback(const v8::FunctionCallbackInfo<v8::Value> &args);
static const char *main_code = "global.__akono_run = (x) => {"
- " console.log('running code', x);"
+ " 0 && console.log('running code', x);"
" global.eval(x);"
"};"
""
"global.__akono_onMessage = (x) => {"
- " console.log('got __akono_onMessage', x);"
- "};"
- ""
- "mod = require('module');"
- "mod._saved_findPath = mod._findPath;"
- "mod._akonoMods = {};"
- "mod._findPath = (request, paths, isMain) => {"
- " console.log('in _findPath');"
- " const res = mod._saved_findPath(request, paths, isMain);"
- " if (res !== false) return res;"
- " const args = JSON.stringify({ request, paths});"
- " const loadResult = JSON.parse(global.__akono_loadModule(args));"
- " console.log('got loadModule result');"
- " if (!loadResult) return false;"
- " console.log('loadModule path is', loadResult.path);"
- " mod._akonoMods[loadResult.path] = loadResult;"
- " console.log('returning path', loadResult.path);"
- " return loadResult.path;"
- "};"
- ""
- "function stripBOM(content) {"
- " if (content.charCodeAt(0) === 0xFEFF) {"
- " content = content.slice(1);"
- " }"
- " return content;"
- "}"
- ""
- "mod._saved_js_extension = mod._extensions[\".js\"];"
- "mod._extensions[\".js\"] = (module, filename) => {"
- " console.log('handling js extension', [module, filename]);"
- " if (mod._akonoMods.hasOwnProperty(filename)) {"
- " const akmod = mod._akonoMods[filename];"
- " console.log('found mod');"
- " const content = akmod.content;"
- " module._compile(stripBOM(content), filename);"
- " return;"
- " }"
- " console.log('falling back');"
- " return mod._saved_js_extension(module, filename);"
- "};"
- ""
- "mod._saved_json_extension = mod._extensions[\".json\"];"
- "mod._extensions[\".json\"] = (module, filename) => {"
- " console.log('handling json extension', [module, filename]);"
- " if (mod._akonoMods.hasOwnProperty(filename)) {"
- " const akmod = mod._akonoMods[filename];"
- " console.log('found mod');"
- " const content = akmod.content;"
- " try {"
- " module.exports = JSON.parse(stripBOM(content));"
- " return;"
- " } catch (err) {"
- " err.message = filename + ': ' + err.message;"
- " throw err;"
- " }"
- " }"
- " console.log('falling back');"
- " return mod._saved_json_extension(module, filename);"
- "};"
- "";
+ " 0 && console.log('got __akono_onMessage', x);"
+ "};";
class NativeAkonoInstance {
private:
static bool logInitialized;
static bool v8Initialized;
- //static std::unique_ptr<v8::Platform> platform;
static node::MultiIsolatePlatform *platform;
public:
v8::Isolate *isolate;
@@ -245,12 +185,8 @@ public:
// Arguments for the script run by node
std::vector<const char *> nodeExecArgv{};
- mylog("entering global scope");
-
v8::Context::Scope context_scope(globalContext.Get(isolate));
- mylog("creating environment");
-
node::Environment *environment = node::CreateEnvironment(
isolateData,
globalContext.Get(isolate),
@@ -259,12 +195,8 @@ public:
nodeExecArgv.size(),
&nodeExecArgv[0]);
- mylog("loading environment");
-
node::LoadEnvironment(environment);
- mylog("finished loading environment");
-
v8::Local<v8::ObjectTemplate> dataTemplate = v8::ObjectTemplate::New(isolate);
dataTemplate->SetInternalFieldCount(1);
v8::Local<v8::Object> dataObject = dataTemplate->NewInstance(context).ToLocalChecked();
@@ -274,29 +206,12 @@ public:
sendMessageCallback,
dataObject).ToLocalChecked();
- v8::Local<v8::Function> loadModuleFunction = v8::Function::New(context,
- loadModuleCallback,
- dataObject).ToLocalChecked();
-
- v8::Local<v8::Function> getDataFunction = v8::Function::New(context,
- getDataCallback,
- dataObject).ToLocalChecked();
-
v8::Local<v8::Object> global = context->Global();
global->Set(v8::String::NewFromUtf8(isolate, "__akono_sendMessage",
v8::NewStringType::kNormal).ToLocalChecked(),
sendMessageFunction);
- global->Set(v8::String::NewFromUtf8(isolate, "__akono_loadModule",
- v8::NewStringType::kNormal).ToLocalChecked(),
- loadModuleFunction);
-
- // Get data synchronously (!) from the embedder
- global->Set(v8::String::NewFromUtf8(isolate, "__akono_getData",
- v8::NewStringType::kNormal).ToLocalChecked(),
- getDataFunction);
-
}
/**
@@ -305,12 +220,14 @@ public:
* @param env JNI env of the thread we're running in.
*/
void runNode() {
+ //printf("running node loop, tid=%llu\n", (unsigned long long) syscall(__NR_gettid));
+ v8::Locker locker(isolate);
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = globalContext.Get(isolate);
v8::Context::Scope context_scope(context);
this->breakRequested = false;
- while (1) {
+ while (true) {
uv_run(uv_default_loop(), UV_RUN_ONCE);
platform->DrainTasks(isolate);
if (this->breakRequested)
@@ -324,7 +241,7 @@ public:
* Must not be called from a different thread.
*/
void makeCallback(const char *code) {
- mylog("in makeCallback");
+ v8::Locker locker(isolate);
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = globalContext.Get(isolate);
@@ -334,7 +251,6 @@ public:
v8::String::NewFromUtf8(isolate, code,
v8::NewStringType::kNormal).ToLocalChecked()
};
- mylog("calling node::MakeCallback");
node::MakeCallback(isolate, global, "__akono_run", 1, argv, {0, 0});
}
@@ -343,8 +259,6 @@ public:
}
jstring evalJs(JNIEnv *env, jstring sourceString) {
- mylog("begin evalJs");
-
JStringValue jsv(env, sourceString);
v8::Isolate::Scope isolate_scope(isolate);
@@ -370,28 +284,19 @@ public:
// Compile the source code.
v8::Local<v8::Script> script;
- mylog("about to compile script");
-
if (!v8::Script::Compile(context, source).ToLocal(&script)) {
return nullptr;
}
- mylog("about to run script");
-
// Run the script to get the result.
v8::Local<v8::Value> result;
if (!script->Run(context).ToLocal(&result)) {
- mylog("running script failed");
return nullptr;
}
- mylog("converting script result value");
-
// Convert the result to an UTF8 string and print it.
v8::String::Utf8Value utf8(isolate, result);
- mylog("about to return value");
-
return env->NewStringUTF(*utf8);
}
}
@@ -404,8 +309,7 @@ node::MultiIsolatePlatform *NativeAkonoInstance::platform = nullptr;
void notifyCb(uv_async_t *async) {
- NativeAkonoInstance *akono = (NativeAkonoInstance *) async->data;
- mylog("async notifyCb called!");
+ auto akono = (NativeAkonoInstance *) async->data;
akono->breakRequested = true;
}
@@ -415,11 +319,9 @@ static void sendMessageCallback(const v8::FunctionCallbackInfo<v8::Value> &args)
v8::HandleScope scope(isolate);
v8::Local<v8::Value> arg = args[0];
v8::String::Utf8Value value(isolate, arg);
- mylog("sendMessageCallback called, yay!");
v8::Local<v8::Object> data = v8::Local<v8::Object>::Cast(args.Data());
- mylog("getting instance");
NativeAkonoInstance *myInstance = (NativeAkonoInstance *) data->GetAlignedPointerFromInternalField(0);
JNIEnv *env = myInstance->currentJniEnv;
@@ -429,7 +331,6 @@ static void sendMessageCallback(const v8::FunctionCallbackInfo<v8::Value> &args)
return;
}
- mylog("finding class");
jclass clazz = env->FindClass("akono/AkonoJni");
if (clazz == nullptr) {
@@ -437,12 +338,9 @@ static void sendMessageCallback(const v8::FunctionCallbackInfo<v8::Value> &args)
return;
}
- mylog("creating strings");
jstring jstr1 = env->NewStringUTF("message");
jstring jstr2 = env->NewStringUTF(*value);
- mylog("getting method");
-
jmethodID meth = env->GetMethodID(clazz, "internalOnNotify", "(Ljava/lang/String;Ljava/lang/String;)V");
if (meth == nullptr) {
@@ -450,122 +348,9 @@ static void sendMessageCallback(const v8::FunctionCallbackInfo<v8::Value> &args)
return;
}
- mylog("calling method");
-
env->CallVoidMethod(myInstance->currentJniThiz, meth, jstr1, jstr2);
}
-
-static void loadModuleCallback(const v8::FunctionCallbackInfo<v8::Value> &args) {
- if (args.Length() < 1) return;
- v8::Isolate *isolate = args.GetIsolate();
- v8::HandleScope scope(isolate);
- v8::Local<v8::Value> arg = args[0];
- v8::String::Utf8Value value(isolate, arg);
- mylog("sendMessageCallback called, yay!");
-
- v8::Local<v8::Object> data = v8::Local<v8::Object>::Cast(args.Data());
-
- mylog("getting instance");
- NativeAkonoInstance *myInstance = (NativeAkonoInstance *) data->GetAlignedPointerFromInternalField(0);
-
- JNIEnv *env = myInstance->currentJniEnv;
-
- if (env == nullptr) {
- mylog("FATAL: JNI env is nullptr");
- return;
- }
-
- mylog("finding class");
- jclass clazz = env->FindClass("akono/AkonoJni");
-
- if (clazz == nullptr) {
- mylog("FATAL: class not found");
- return;
- }
-
- mylog("creating strings");
- jstring jstr1 = env->NewStringUTF(*value);
-
- mylog("getting method");
-
- jmethodID meth = env->GetMethodID(clazz, "internalOnModuleLoad", "(Ljava/lang/String;)Ljava/lang/String;");
-
- if (meth == nullptr) {
- mylog("FATAL: method not found");
- return;
- }
-
- mylog("calling method");
-
- jstring jresult = (jstring) env->CallObjectMethod(myInstance->currentJniThiz, meth, jstr1);
-
- JStringValue resultStringValue(env, jresult);
-
- // Create a string containing the JavaScript source code.
- v8::Local<v8::String> rs =
- v8::String::NewFromUtf8(isolate, *resultStringValue,
- v8::NewStringType::kNormal)
- .ToLocalChecked();
-
- args.GetReturnValue().Set(rs);
-}
-
-
-static void getDataCallback(const v8::FunctionCallbackInfo<v8::Value> &args) {
- if (args.Length() < 1) return;
- v8::Isolate *isolate = args.GetIsolate();
- v8::HandleScope scope(isolate);
- v8::Local<v8::Value> arg = args[0];
- v8::String::Utf8Value value(isolate, arg);
- mylog("getDataCallback called");
-
- v8::Local<v8::Object> data = v8::Local<v8::Object>::Cast(args.Data());
- mylog("getting instance");
- NativeAkonoInstance *myInstance = (NativeAkonoInstance *) data->GetAlignedPointerFromInternalField(0);
-
- JNIEnv *env = myInstance->currentJniEnv;
- if (env == nullptr) {
- mylog("FATAL: JNI env is nullptr");
- return;
- }
-
- mylog("finding class");
- jclass clazz = env->FindClass("akono/AkonoJni");
-
- if (clazz == nullptr) {
- mylog("FATAL: class not found");
- return;
- }
-
- mylog("creating strings");
- jstring jstr1 = env->NewStringUTF(*value);
-
- mylog("getting method");
-
- jmethodID meth = env->GetMethodID(clazz, "internalOnGetData", "(Ljava/lang/String;)Ljava/lang/String;");
-
- if (meth == nullptr) {
- mylog("FATAL: method not found");
- return;
- }
-
- mylog("calling method");
-
- jstring jresult = (jstring) env->CallObjectMethod(myInstance->currentJniThiz, meth, jstr1);
-
- JStringValue resultStringValue(env, jresult);
-
- // Create a string containing the JavaScript source code.
- v8::Local<v8::String> rs =
- v8::String::NewFromUtf8(isolate, *resultStringValue,
- v8::NewStringType::kNormal)
- .ToLocalChecked();
-
- args.GetReturnValue().Set(rs);
-}
-
-
extern "C" JNIEXPORT jobject JNICALL
Java_akono_AkonoJni_initNative(JNIEnv *env, jobject thiz) {
NativeAkonoInstance *myInstance = new NativeAkonoInstance();
@@ -608,3 +393,11 @@ Java_akono_AkonoJni_makeCallbackNative(JNIEnv *env, jobject thiz, jstring source
myInstance->currentJniThiz = thiz;
return myInstance->makeCallback(*jsv);
}
+
+void InitializeAkono(v8::Local<v8::Object> target,
+ v8::Local<v8::Value> unused,
+ v8::Local<v8::Context> context,
+ void* priv) {
+}
+
+NODE_MODULE_CONTEXT_AWARE_INTERNAL(akono, InitializeAkono)