summaryrefslogtreecommitdiff
path: root/Taler
diff options
context:
space:
mode:
authorJonathan Buchanan <jonathan.russ.buchanan@gmail.com>2021-01-28 22:45:57 -0500
committerJonathan Buchanan <jonathan.russ.buchanan@gmail.com>2021-01-28 22:45:57 -0500
commit43a8d866a4703aac8c545562eb8e2d3a610c4f68 (patch)
tree2dcaf6be0cec33065860262f1cc209387de45ed0 /Taler
parent97b916f0c1baeb2d931bb9457b0f2e8b966c4964 (diff)
downloadtaler-ios-43a8d866a4703aac8c545562eb8e2d3a610c4f68.tar.gz
taler-ios-43a8d866a4703aac8c545562eb8e2d3a610c4f68.tar.bz2
taler-ios-43a8d866a4703aac8c545562eb8e2d3a610c4f68.zip
add node to swift/objc bridge
Diffstat (limited to 'Taler')
-rw-r--r--Taler/AppDelegate.swift6
-rw-r--r--Taler/NodeWrapper.swift49
-rw-r--r--Taler/Taler-Bridging-Header.h4
-rw-r--r--Taler/node_wrapper.cpp274
-rw-r--r--Taler/node_wrapper.h44
5 files changed, 374 insertions, 3 deletions
diff --git a/Taler/AppDelegate.swift b/Taler/AppDelegate.swift
index ab96d31..e5e6bcd 100644
--- a/Taler/AppDelegate.swift
+++ b/Taler/AppDelegate.swift
@@ -7,7 +7,6 @@
//
import UIKit
-import TalerWallet
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
@@ -16,8 +15,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
- let num = Amount.init(currency: "EUR", value: 1, fraction: 99)
- print(num)
+ var iono = Iono();
+ print(iono.evalJS(source: "1 + 1"))
+ iono.evalJS(source: "console.log(\"test!\");");
return true
}
diff --git a/Taler/NodeWrapper.swift b/Taler/NodeWrapper.swift
new file mode 100644
index 0000000..60ca92b
--- /dev/null
+++ b/Taler/NodeWrapper.swift
@@ -0,0 +1,49 @@
+//
+// NodeWrapper.swift
+// Taler
+//
+// Created by Jonathan Buchanan on 1/14/21.
+// Copyright © 2021 Taler. All rights reserved.
+//
+
+import Foundation
+
+class Iono {
+ var __instance: OpaquePointer
+ var messageHandler: ((String) -> ())?
+
+ init() {
+ __instance = __new_instance()
+ }
+
+ deinit {
+ __free_instance(__instance)
+ }
+
+ func notifyNative() {
+
+ }
+
+ func evalJS(source: String) -> String {
+ var result_cstr: UnsafeMutablePointer<Int8> = __eval_js(source.cString(using: .utf8), __instance)
+ var result = String(cString: result_cstr)
+ free(result_cstr)
+ return result
+ }
+
+ func evalNodeCode(source: String) {
+ __make_callback(source.cString(using: .utf8), __instance)
+ }
+
+ func sendMessage(message: String) {
+
+ }
+
+ func waitUntilStopped() {
+
+ }
+
+ func putModuleCode(moduleName: String, code: String) {
+ __put_module_code(moduleName.cString(using: .utf8), code.cString(using: .utf8), __instance)
+ }
+}
diff --git a/Taler/Taler-Bridging-Header.h b/Taler/Taler-Bridging-Header.h
new file mode 100644
index 0000000..f4a0414
--- /dev/null
+++ b/Taler/Taler-Bridging-Header.h
@@ -0,0 +1,4 @@
+//
+// Use this file to import your target's public headers that you would like to expose to Swift.
+//
+#import "node_wrapper.h"
diff --git a/Taler/node_wrapper.cpp b/Taler/node_wrapper.cpp
new file mode 100644
index 0000000..7899281
--- /dev/null
+++ b/Taler/node_wrapper.cpp
@@ -0,0 +1,274 @@
+//
+// node_wrapper.cpp
+// Taler
+//
+// Created by Jonathan Buchanan on 12/31/20.
+// Copyright © 2020 Taler. All rights reserved.
+//
+
+#include <map>
+#include <string>
+
+#include "node.h"
+#include "uv.h"
+
+struct __IonoInstance
+{
+ static std::unique_ptr<node::MultiIsolatePlatform> platform;
+ std::unique_ptr<node::CommonEnvironmentSetup> setup;
+ v8::Isolate *isolate;
+ node::Environment *env;
+ uv_async_t async_notify;
+ bool break_requested;
+ std::map<std::string, std::string> modmap;
+
+ __IonoInstance();
+
+ char *
+ eval_js(const char *js);
+
+ void
+ run_node();
+
+ void
+ make_callback(const char *callback);
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct __IonoInstance *
+__new_instance()
+{
+ __IonoInstance *instance = new __IonoInstance();
+ return instance;
+}
+
+void
+__free_instance(struct __IonoInstance *instance)
+{
+ delete instance;
+}
+
+char *
+__eval_js(const char *js, struct __IonoInstance *instance)
+{
+ return instance->eval_js(js);
+}
+
+void
+__notify_instance(struct __IonoInstance *instance)
+{
+ uv_async_send(&instance->async_notify);
+}
+
+void
+__run_node(struct __IonoInstance *instance)
+{
+ instance->run_node();
+}
+
+void
+__make_callback(const char *callback, struct __IonoInstance *instance)
+{
+ instance->make_callback(callback);
+}
+
+void
+__put_module_code(const char *module_name, const char *module_code, struct __IonoInstance *instance)
+{
+ instance->modmap[std::string(module_name)] = std::string(module_code);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+std::unique_ptr<node::MultiIsolatePlatform> __IonoInstance::platform = nullptr;
+
+static void
+notify_callback(uv_async_t *async);
+
+static void
+send_message_callback(const v8::FunctionCallbackInfo<v8::Value> &args);
+
+__IonoInstance::__IonoInstance() :
+ break_requested(false),
+ modmap()
+{
+ {
+ uv_loop_t *loop = uv_default_loop();
+ uv_async_init(loop, &async_notify, &notify_callback);
+ async_notify.data = this;
+ }
+
+ std::vector<std::string> args = { "node" };
+ std::vector<std::string> exec_args;
+ std::vector<std::string> errors;
+
+ if (nullptr == platform)
+ {
+ int exit_code = node::InitializeNodeWithArgs(&args, &exec_args, &errors);
+ for (const std::string &error : errors)
+ {
+ fprintf(stderr, "%s: %s\n", args[0].c_str(), error.c_str());
+ /*if (exit_code != 0) {
+ return exit_code;*/
+ }
+
+ platform = node::MultiIsolatePlatform::Create(4);
+ v8::V8::InitializePlatform(platform.get());
+ v8::V8::Initialize();
+ }
+
+ setup = node::CommonEnvironmentSetup::Create(platform.get(), &errors, args, exec_args);
+ if (!setup) {
+ for (const std::string &err : errors)
+ fprintf(stderr, "%s: %s\n", args[0].c_str(), err.c_str());
+ //return 1;
+ }
+
+ isolate = setup->isolate();
+ env = setup->env();
+
+ {
+ v8::Locker locker(isolate);
+ v8::Isolate::Scope isolate_scope(isolate);
+ v8::HandleScope handle_scope(isolate);
+ v8::Context::Scope context_scope(setup->context());
+
+ v8::MaybeLocal<v8::Value> loadenv_ret = node::LoadEnvironment(
+ env,
+ "const publicRequire ="
+ " require('module').createRequire(process.cwd() + '/');"
+ "globalThis.require = publicRequire;"
+ "global.__node_run = (x) => {"
+ " 0 && console.log('running code', x);"
+ " global.eval(x);"
+ "};");
+
+ v8::Local<v8::ObjectTemplate> data_template = v8::ObjectTemplate::New(isolate);
+ data_template->SetInternalFieldCount(1);
+ v8::Local<v8::Object> data_object = data_template->NewInstance(setup->context()).ToLocalChecked();
+ data_object->SetAlignedPointerInInternalField(0, this);
+
+ v8::Local<v8::Function> sendMessageFunction = v8::Function::New(setup->context(),
+ send_message_callback,
+ data_object).ToLocalChecked();
+
+ v8::Local<v8::Object> global = setup->context()->Global();
+
+ global->Set(setup->context(), v8::String::NewFromUtf8(isolate, "__iono_sendMessage",
+ v8::NewStringType::kNormal).ToLocalChecked(),
+ sendMessageFunction).Check();
+ }
+}
+
+char *
+__IonoInstance::eval_js(const char *js)
+{
+ v8::Locker locker(isolate);
+ v8::Isolate::Scope isolate_scope(isolate);
+ v8::HandleScope handle_scope(isolate);
+ v8::Context::Scope context_scope(setup->context());
+
+ {
+ // Create a string containing the JavaScript source code.
+ v8::Local<v8::String> source =
+ v8::String::NewFromUtf8(isolate, js, v8::NewStringType::kNormal).ToLocalChecked();
+
+ // Compile the source code.
+ v8::Local<v8::Script> script;
+
+ if (!v8::Script::Compile(setup->context(), source).ToLocal(&script)) {
+ return nullptr;
+ }
+
+ // Run the script to get the result.
+ v8::Local<v8::Value> result;
+ if (!script->Run(setup->context()).ToLocal(&result)) {
+ return nullptr;
+ }
+
+ // Convert the result to an UTF8 string and print it.
+ v8::String::Utf8Value utf8(isolate, result);
+
+ return strdup(*utf8);
+ }
+}
+
+void
+__IonoInstance::run_node() {
+ v8::Locker locker(isolate);
+ v8::Isolate::Scope isolate_scope(isolate);
+ v8::HandleScope handle_scope(isolate);
+ v8::Context::Scope context_scope(setup->context());
+ break_requested = false;
+ while (true) {
+ uv_run(uv_default_loop(), UV_RUN_ONCE);
+ platform->DrainTasks(isolate);
+ if (break_requested)
+ break;
+ }
+}
+
+void
+__IonoInstance::make_callback(const char *callback)
+{
+ v8::Locker locker(isolate);
+ v8::Isolate::Scope isolate_scope(isolate);
+ v8::HandleScope handle_scope(isolate);
+ v8::Context::Scope context_scope(setup->context());
+ v8::Local<v8::Object> global = setup->context()->Global();
+ v8::Local<v8::Value> argv[] = {
+ v8::String::NewFromUtf8(isolate, callback,
+ v8::NewStringType::kNormal).ToLocalChecked()
+ };
+ node::MakeCallback(isolate, global, "__node_run", 1, argv, {0, 0});
+}
+
+static void
+notify_callback(uv_async_t *async) {
+ __IonoInstance *instance = (__IonoInstance *)async->data;
+ instance->break_requested = true;
+}
+
+static void
+send_message_callback(const v8::FunctionCallbackInfo<v8::Value> &args) {
+ v8::Isolate *isolate = args.GetIsolate();
+ v8::Locker locker(isolate);
+ if (args.Length() < 1) return;
+ v8::HandleScope scope(isolate);
+ v8::Local<v8::Value> arg = args[0];
+ v8::String::Utf8Value value(isolate, arg);
+
+ v8::Local<v8::Object> data = v8::Local<v8::Object>::Cast(args.Data());
+
+ __IonoInstance *instance = (__IonoInstance *)data->GetAlignedPointerFromInternalField(0);
+
+ /*JNIEnv *env = myInstance->currentJniEnv;
+
+ if (env == nullptr) {
+ mylog("FATAL: JNI env is nullptr");
+ return;
+ }
+
+ jclass clazz = env->FindClass("akono/AkonoJni");
+
+ if (clazz == nullptr) {
+ mylog("FATAL: class not found");
+ return;
+ }
+
+ jstring payloadStr = env->NewStringUTF(*value);
+
+ jmethodID meth = env->GetMethodID(clazz, "internalOnNotify", "(Ljava/lang/String;)V");
+
+ if (meth == nullptr) {
+ mylog("FATAL: method not found");
+ return;
+ }
+
+ env->CallVoidMethod(myInstance->currentJniThiz, meth, payloadStr);*/
+}
diff --git a/Taler/node_wrapper.h b/Taler/node_wrapper.h
new file mode 100644
index 0000000..164b95e
--- /dev/null
+++ b/Taler/node_wrapper.h
@@ -0,0 +1,44 @@
+//
+// node_wrapper.h
+// Taler
+//
+// Created by Jonathan Buchanan on 12/31/20.
+// Copyright © 2020 Taler. All rights reserved.
+//
+
+#ifndef node_wrapper_h
+#define node_wrapper_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct __IonoInstance;
+
+struct __IonoInstance *
+__new_instance();
+
+void
+__free_instance(struct __IonoInstance *instance);
+
+// result must be freed!
+char *
+__eval_js(const char *js, struct __IonoInstance *instance);
+
+void
+__notify_instance(struct __IonoInstance *instance);
+
+void
+__run_node(struct __IonoInstance *instance);
+
+void
+__make_callback(const char *callback, struct __IonoInstance *instance);
+
+void
+__put_module_code(const char *module_name, const char *module_code, struct IonoInstance *instance);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* node_wrapper_h */