summaryrefslogtreecommitdiff
path: root/core/bindings.rs
diff options
context:
space:
mode:
Diffstat (limited to 'core/bindings.rs')
-rw-r--r--core/bindings.rs112
1 files changed, 97 insertions, 15 deletions
diff --git a/core/bindings.rs b/core/bindings.rs
index 0703117c7..08f244166 100644
--- a/core/bindings.rs
+++ b/core/bindings.rs
@@ -47,6 +47,12 @@ lazy_static! {
function: decode.map_fn_to()
},
v8::ExternalReference {
+ function: serialize.map_fn_to()
+ },
+ v8::ExternalReference {
+ function: deserialize.map_fn_to()
+ },
+ v8::ExternalReference {
function: get_promise_details.map_fn_to()
},
v8::ExternalReference {
@@ -124,6 +130,8 @@ pub fn initialize_context<'s>(
set_func(scope, core_val, "evalContext", eval_context);
set_func(scope, core_val, "encode", encode);
set_func(scope, core_val, "decode", decode);
+ set_func(scope, core_val, "serialize", serialize);
+ set_func(scope, core_val, "deserialize", deserialize);
set_func(scope, core_val, "getPromiseDetails", get_promise_details);
set_func(scope, core_val, "getProxyDetails", get_proxy_details);
@@ -427,9 +435,7 @@ fn eval_context(
let source = match v8::Local::<v8::String>::try_from(args.get(0)) {
Ok(s) => s,
Err(_) => {
- let msg = v8::String::new(scope, "Invalid argument").unwrap();
- let exception = v8::Exception::type_error(scope, msg);
- scope.throw_exception(exception);
+ throw_type_error(scope, "Invalid argument");
return;
}
};
@@ -550,9 +556,7 @@ fn encode(
let text = match v8::Local::<v8::String>::try_from(args.get(0)) {
Ok(s) => s,
Err(_) => {
- let msg = v8::String::new(scope, "Invalid argument").unwrap();
- let exception = v8::Exception::type_error(scope, msg);
- scope.throw_exception(exception);
+ throw_type_error(scope, "Invalid argument");
return;
}
};
@@ -583,9 +587,7 @@ fn decode(
let view = match v8::Local::<v8::ArrayBufferView>::try_from(args.get(0)) {
Ok(view) => view,
Err(_) => {
- let msg = v8::String::new(scope, "Invalid argument").unwrap();
- let exception = v8::Exception::type_error(scope, msg);
- scope.throw_exception(exception);
+ throw_type_error(scope, "Invalid argument");
return;
}
};
@@ -625,6 +627,90 @@ fn decode(
};
}
+struct SerializeDeserialize {}
+
+impl v8::ValueSerializerImpl for SerializeDeserialize {
+ #[allow(unused_variables)]
+ fn throw_data_clone_error<'s>(
+ &mut self,
+ scope: &mut v8::HandleScope<'s>,
+ message: v8::Local<'s, v8::String>,
+ ) {
+ let error = v8::Exception::error(scope, message);
+ scope.throw_exception(error);
+ }
+}
+
+impl v8::ValueDeserializerImpl for SerializeDeserialize {}
+
+fn serialize(
+ scope: &mut v8::HandleScope,
+ args: v8::FunctionCallbackArguments,
+ mut rv: v8::ReturnValue,
+) {
+ let serialize_deserialize = Box::new(SerializeDeserialize {});
+ let mut value_serializer =
+ v8::ValueSerializer::new(scope, serialize_deserialize);
+ match value_serializer.write_value(scope.get_current_context(), args.get(0)) {
+ Some(true) => {
+ let vector = value_serializer.release();
+ let buf = {
+ let buf_len = vector.len();
+ let backing_store = v8::ArrayBuffer::new_backing_store_from_boxed_slice(
+ vector.into_boxed_slice(),
+ );
+ let backing_store_shared = backing_store.make_shared();
+ let ab =
+ v8::ArrayBuffer::with_backing_store(scope, &backing_store_shared);
+ v8::Uint8Array::new(scope, ab, 0, buf_len)
+ .expect("Failed to create UintArray8")
+ };
+
+ rv.set(buf.into());
+ }
+ _ => {
+ throw_type_error(scope, "Invalid argument");
+ }
+ }
+}
+
+fn deserialize(
+ scope: &mut v8::HandleScope,
+ args: v8::FunctionCallbackArguments,
+ mut rv: v8::ReturnValue,
+) {
+ let view = match v8::Local::<v8::ArrayBufferView>::try_from(args.get(0)) {
+ Ok(view) => view,
+ Err(_) => {
+ throw_type_error(scope, "Invalid argument");
+ return;
+ }
+ };
+
+ let backing_store = view.buffer(scope).unwrap().get_backing_store();
+ let buf = unsafe {
+ get_backing_store_slice(
+ &backing_store,
+ view.byte_offset(),
+ view.byte_length(),
+ )
+ };
+
+ let serialize_deserialize = Box::new(SerializeDeserialize {});
+ let mut value_deserializer =
+ v8::ValueDeserializer::new(scope, serialize_deserialize, buf);
+ let value = value_deserializer.read_value(scope.get_current_context());
+
+ match value {
+ Some(deserialized) => rv.set(deserialized),
+ None => {
+ let msg = v8::String::new(scope, "string too long").unwrap();
+ let exception = v8::Exception::range_error(scope, msg);
+ scope.throw_exception(exception);
+ }
+ };
+}
+
fn queue_microtask(
scope: &mut v8::HandleScope,
args: v8::FunctionCallbackArguments,
@@ -633,9 +719,7 @@ fn queue_microtask(
match v8::Local::<v8::Function>::try_from(args.get(0)) {
Ok(f) => scope.enqueue_microtask(f),
Err(_) => {
- let msg = v8::String::new(scope, "Invalid argument").unwrap();
- let exception = v8::Exception::type_error(scope, msg);
- scope.throw_exception(exception);
+ throw_type_error(scope, "Invalid argument");
}
};
}
@@ -725,9 +809,7 @@ fn get_promise_details(
let promise = match v8::Local::<v8::Promise>::try_from(args.get(0)) {
Ok(val) => val,
Err(_) => {
- let msg = v8::String::new(scope, "Invalid argument").unwrap();
- let exception = v8::Exception::type_error(scope, msg);
- scope.throw_exception(exception);
+ throw_type_error(scope, "Invalid argument");
return;
}
};