@@ -423,7 +423,8 @@ struct SerializeDeserialize<'a> {
423423 host_objects : Option < v8:: Local < ' a , v8:: Array > > ,
424424 error_callback : Option < v8:: Local < ' a , v8:: Function > > ,
425425 for_storage : bool ,
426- host_object_brand : Option < v8:: Global < v8:: Symbol > > ,
426+ host_object_brand : Option < v8:: Local < ' a , v8:: Symbol > > ,
427+ deserializers : Option < v8:: Local < ' a , v8:: Object > > ,
427428}
428429
429430impl v8:: ValueSerializerImpl for SerializeDeserialize < ' _ > {
@@ -488,19 +489,16 @@ impl v8::ValueSerializerImpl for SerializeDeserialize<'_> {
488489 }
489490
490491 fn has_custom_host_object ( & self , _isolate : & v8:: Isolate ) -> bool {
491- true
492+ self . host_object_brand . is_some ( )
492493 }
493494
494495 fn is_host_object < ' s , ' i > (
495496 & self ,
496497 scope : & mut v8:: PinScope < ' s , ' i > ,
497498 object : v8:: Local < ' s , v8:: Object > ,
498499 ) -> Option < bool > {
499- match & self . host_object_brand {
500- Some ( symbol) => {
501- let key = v8:: Local :: new ( scope, symbol) ;
502- object. has_own_property ( scope, key. into ( ) )
503- }
500+ match self . host_object_brand {
501+ Some ( symbol) => object. has ( scope, symbol. into ( ) ) ,
504502 _ => Some ( false ) ,
505503 }
506504 }
@@ -511,6 +509,15 @@ impl v8::ValueSerializerImpl for SerializeDeserialize<'_> {
511509 object : v8:: Local < ' s , v8:: Object > ,
512510 value_serializer : & dyn v8:: ValueSerializerHelper ,
513511 ) -> Option < bool > {
512+ if let Some ( host_object_brand) = self . host_object_brand {
513+ let value = object. get ( scope, host_object_brand. into ( ) ) ?;
514+ if let Ok ( func) = value. try_cast :: < v8:: Function > ( ) {
515+ let result = func. call ( scope, object. into ( ) , & [ ] ) ?;
516+ value_serializer. write_uint32 ( u32:: MAX ) ;
517+ value_serializer. write_value ( scope. get_current_context ( ) , result) ;
518+ return Some ( true ) ;
519+ }
520+ }
514521 if let Some ( host_objects) = self . host_objects {
515522 for i in 0 ..host_objects. length ( ) {
516523 let value = host_objects. get_index ( scope, i) . unwrap ( ) ;
@@ -570,11 +577,29 @@ impl v8::ValueDeserializerImpl for SerializeDeserialize<'_> {
570577 scope : & mut v8:: PinScope < ' s , ' i > ,
571578 value_deserializer : & dyn v8:: ValueDeserializerHelper ,
572579 ) -> Option < v8:: Local < ' s , v8:: Object > > {
573- if let Some ( host_objects) = self . host_objects {
574- let mut i = 0 ;
575- if !value_deserializer. read_uint32 ( & mut i) {
576- return None ;
580+ let mut i = 0 ;
581+ if !value_deserializer. read_uint32 ( & mut i) {
582+ return None ;
583+ }
584+ if i == u32:: MAX {
585+ if let Some ( deserializers) = self . deserializers
586+ && let Some ( value) =
587+ value_deserializer. read_value ( scope. get_current_context ( ) )
588+ && let Some ( object) = value. to_object ( scope)
589+ {
590+ let key = crate :: runtime:: v8_static_strings:: TYPE
591+ . v8_string ( scope)
592+ . unwrap ( ) ;
593+ let ty = object. get ( scope, key. into ( ) ) ?;
594+ let func = deserializers. get ( scope, ty) ?;
595+ let recv = v8:: null ( scope) . into ( ) ;
596+ let scope =
597+ std:: pin:: pin!( v8:: AllowJavascriptExecutionScope :: new( scope) ) ;
598+ let scope = & mut scope. init ( ) ;
599+ let res = func. cast :: < v8:: Function > ( ) . call ( scope, recv, & [ value] ) ?;
600+ return res. to_object ( scope) ;
577601 }
602+ } else if let Some ( host_objects) = self . host_objects {
578603 let maybe_value = host_objects. get_index ( scope, i) ;
579604 if let Some ( value) = maybe_value {
580605 return value. to_object ( scope) ;
@@ -625,13 +650,14 @@ pub fn op_serialize<'s, 'i>(
625650
626651 let key = v8_static_strings:: HOST_OBJECT . v8_string ( scope) . unwrap ( ) ;
627652 let symbol = v8:: Symbol :: for_key ( scope, key) ;
628- let host_object_brand = Some ( v8 :: Global :: new ( scope , symbol) ) ;
653+ let host_object_brand = Some ( symbol) ;
629654
630655 let serialize_deserialize = Box :: new ( SerializeDeserialize {
631656 host_objects,
632657 error_callback,
633658 for_storage,
634659 host_object_brand,
660+ deserializers : None ,
635661 } ) ;
636662 let value_serializer = v8:: ValueSerializer :: new ( scope, serialize_deserialize) ;
637663 value_serializer. write_header ( ) ;
@@ -692,6 +718,7 @@ pub fn op_deserialize<'s, 'i>(
692718 #[ buffer] zero_copy : JsBuffer ,
693719 host_objects : Option < v8:: Local < ' s , v8:: Value > > ,
694720 transferred_array_buffers : Option < v8:: Local < ' s , v8:: Value > > ,
721+ deserializers : Option < v8:: Local < ' s , v8:: Value > > ,
695722 for_storage : bool ,
696723) -> Result < v8:: Local < ' s , v8:: Value > , JsErrorBox > {
697724 let host_objects = match host_objects {
@@ -709,12 +736,20 @@ pub fn op_deserialize<'s, 'i>(
709736 }
710737 None => None ,
711738 } ;
739+ let deserializers = match deserializers {
740+ Some ( value) => Some (
741+ v8:: Local :: < v8:: Object > :: try_from ( value)
742+ . map_err ( |_| JsErrorBox :: type_error ( "deserializers not an object" ) ) ?,
743+ ) ,
744+ None => None ,
745+ } ;
712746
713747 let serialize_deserialize = Box :: new ( SerializeDeserialize {
714748 host_objects,
715749 error_callback : None ,
716750 for_storage,
717751 host_object_brand : None ,
752+ deserializers,
718753 } ) ;
719754 let value_deserializer =
720755 v8:: ValueDeserializer :: new ( scope, serialize_deserialize, & zero_copy) ;
@@ -768,16 +803,18 @@ pub fn op_deserialize<'s, 'i>(
768803pub fn op_structured_clone < ' s , ' i > (
769804 scope : & mut v8:: PinScope < ' s , ' i > ,
770805 value : v8:: Local < ' s , v8:: Value > ,
806+ deserializers : Option < v8:: Local < ' s , v8:: Object > > ,
771807) -> Result < v8:: Local < ' s , v8:: Value > , JsErrorBox > {
772808 let key = v8_static_strings:: HOST_OBJECT . v8_string ( scope) . unwrap ( ) ;
773809 let symbol = v8:: Symbol :: for_key ( scope, key) ;
774- let host_object_brand = Some ( v8 :: Global :: new ( scope , symbol) ) ;
810+ let host_object_brand = Some ( symbol) ;
775811
776812 let serialize_deserialize = Box :: new ( SerializeDeserialize {
777813 host_objects : None ,
778814 error_callback : None ,
779815 for_storage : false ,
780- host_object_brand : host_object_brand. clone ( ) ,
816+ host_object_brand,
817+ deserializers : None ,
781818 } ) ;
782819 let value_serializer = v8:: ValueSerializer :: new ( scope, serialize_deserialize) ;
783820 value_serializer. write_header ( ) ;
@@ -802,7 +839,8 @@ pub fn op_structured_clone<'s, 'i>(
802839 host_objects : None ,
803840 error_callback : None ,
804841 for_storage : false ,
805- host_object_brand : host_object_brand. clone ( ) ,
842+ host_object_brand,
843+ deserializers,
806844 } ) ;
807845 let value_deserializer =
808846 v8:: ValueDeserializer :: new ( scope, serialize_deserialize, & vector) ;
0 commit comments