diff options
Diffstat (limited to 'core/core_isolate.rs')
-rw-r--r-- | core/core_isolate.rs | 63 |
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>; |