summaryrefslogtreecommitdiff
path: root/core/core_isolate.rs
diff options
context:
space:
mode:
Diffstat (limited to 'core/core_isolate.rs')
-rw-r--r--core/core_isolate.rs63
1 files changed, 63 insertions, 0 deletions
diff --git a/core/core_isolate.rs b/core/core_isolate.rs
index 18539395f..160e37f1d 100644
--- a/core/core_isolate.rs
+++ b/core/core_isolate.rs
@@ -20,6 +20,8 @@ use futures::stream::FuturesUnordered;
use futures::stream::StreamExt;
use futures::task::AtomicWaker;
use futures::Future;
+use serde_json::json;
+use serde_json::Value;
use std::any::Any;
use std::cell::RefCell;
use std::collections::HashMap;
@@ -429,6 +431,50 @@ impl CoreIsolate {
state.op_registry.register(name, op)
}
+ pub fn register_op_json_sync<F>(&mut self, name: &str, op: F) -> OpId
+ where
+ F: 'static
+ + Fn(
+ &mut CoreIsolateState,
+ serde_json::Value,
+ &mut [ZeroCopyBuf],
+ ) -> Result<serde_json::Value, ErrBox>,
+ {
+ let core_op =
+ move |state: &mut CoreIsolateState, bufs: &mut [ZeroCopyBuf]| -> Op {
+ let value = serde_json::from_slice(&bufs[0]).unwrap();
+ let result = op(state, value, &mut bufs[1..]);
+ let buf = serialize_result(None, result);
+ Op::Sync(buf)
+ };
+
+ let state_rc = Self::state(self);
+ let mut state = state_rc.borrow_mut();
+ state.op_registry.register(name, core_op)
+ }
+
+ pub fn register_op_json_async<F, Fut>(&mut self, name: &str, op: F) -> OpId
+ where
+ Fut: 'static + Future<Output = Result<serde_json::Value, ErrBox>>,
+ F: 'static
+ + Fn(&mut CoreIsolateState, serde_json::Value, &mut [ZeroCopyBuf]) -> Fut,
+ {
+ let core_op = move |state: &mut CoreIsolateState,
+ bufs: &mut [ZeroCopyBuf]|
+ -> Op {
+ let value: serde_json::Value = serde_json::from_slice(&bufs[0]).unwrap();
+ let promise_id = value.get("promiseId").unwrap().as_u64().unwrap();
+ let fut = op(state, value, &mut bufs[1..]);
+ let fut2 =
+ fut.map(move |result| serialize_result(Some(promise_id), result));
+ Op::Async(Box::pin(fut2))
+ };
+
+ let state_rc = Self::state(self);
+ let mut state = state_rc.borrow_mut();
+ state.op_registry.register(name, core_op)
+ }
+
/// Registers a callback on the isolate when the memory limits are approached.
/// Use this to prevent V8 from crashing the process when reaching the limit.
///
@@ -484,6 +530,23 @@ where
callback(current_heap_limit, initial_heap_limit)
}
+fn serialize_result(
+ promise_id: Option<u64>,
+ result: Result<Value, ErrBox>,
+) -> Buf {
+ let value = match result {
+ Ok(v) => json!({ "ok": v, "promiseId": promise_id }),
+ Err(err) => json!({
+ "promiseId": promise_id ,
+ "err": {
+ "message": err.to_string(),
+ "kind": "Other", // TODO(ry) Figure out how to propagate errors.
+ }
+ }),
+ };
+ serde_json::to_vec(&value).unwrap().into_boxed_slice()
+}
+
impl Future for CoreIsolate {
type Output = Result<(), ErrBox>;