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