@@ -213,14 +213,18 @@ impl<'de> de::Deserializer<'de> for &mut Deserializer<'de> {
213213 return result;
214214 }
215215
216- // FIXME: Replace type_of when https://github.com/DelSkayn/rquickjs/pull/458 is merged.
217- if ( get_class_id ( & self . value ) == ClassId :: BigInt as u32
218- || self . value . type_of ( ) == rquickjs:: Type :: BigInt )
219- && let Some ( f) = get_to_json ( & self . value )
220- {
221- let v: Value = f. call ( ( This ( self . value . clone ( ) ) , ) ) . map_err ( Error :: new) ?;
222- self . value = v;
223- return self . deserialize_any ( visitor) ;
216+ if get_class_id ( & self . value ) == ClassId :: BigInt as u32 || self . value . is_big_int ( ) {
217+ if let Some ( f) = get_to_json ( & self . value ) {
218+ let v: Value = f. call ( ( This ( self . value . clone ( ) ) , ) ) . map_err ( Error :: new) ?;
219+ self . value = v;
220+ return self . deserialize_any ( visitor) ;
221+ }
222+
223+ if let Some ( f) = get_to_string ( & self . value ) {
224+ let v: Value = f. call ( ( This ( self . value . clone ( ) ) , ) ) . map_err ( Error :: new) ?;
225+ self . value = v;
226+ return self . deserialize_any ( visitor) ;
227+ }
224228 }
225229
226230 Err ( Error :: new ( Exception :: throw_type (
@@ -482,39 +486,26 @@ impl<'de> de::SeqAccess<'de> for SeqAccess<'_, 'de> {
482486
483487/// Checks if the value is an object and contains a single `toJSON` function.
484488pub ( crate ) fn get_to_json < ' a > ( value : & Value < ' a > ) -> Option < Function < ' a > > {
485- let f = unsafe {
486- JS_GetProperty (
487- value. ctx ( ) . as_raw ( ) . as_ptr ( ) ,
488- value. as_raw ( ) ,
489- PredefinedAtom :: ToJSON as u32 ,
490- )
491- } ;
492- let f = unsafe { Value :: from_raw ( value. ctx ( ) . clone ( ) , f) } ;
493-
494- if f. is_function ( )
495- && let Some ( f) = f. into_function ( )
496- {
497- Some ( f)
498- } else {
499- None
500- }
489+ get_function ( value, PredefinedAtom :: ToJSON )
501490}
502491
503492/// Checks if the value is an object and contains a `valueOf` function.
504493fn get_valueof < ' a > ( value : & Value < ' a > ) -> Option < Function < ' a > > {
505- if let Some ( o) = value. as_object ( ) {
506- let value_of = o. get ( "valueOf" ) . ok ( ) ;
507- value_of. clone ( )
508- } else {
509- None
510- }
494+ get_function ( value, PredefinedAtom :: ValueOf )
511495}
512496
513- /// Checks if the value is an object and contains a `valueOf ` function.
497+ /// Checks if the value is an object and contains a `toString ` function.
514498fn get_to_string < ' a > ( value : & Value < ' a > ) -> Option < Function < ' a > > {
515- if let Some ( o) = value. as_object ( ) {
516- let value_of = o. get ( "toString" ) . ok ( ) ;
517- value_of. clone ( )
499+ get_function ( value, PredefinedAtom :: ToString )
500+ }
501+
502+ fn get_function < ' a > ( value : & Value < ' a > , atom : PredefinedAtom ) -> Option < Function < ' a > > {
503+ let f = unsafe { JS_GetProperty ( value. ctx ( ) . as_raw ( ) . as_ptr ( ) , value. as_raw ( ) , atom as u32 ) } ;
504+ let f = unsafe { Value :: from_raw ( value. ctx ( ) . clone ( ) , f) } ;
505+ if f. is_function ( )
506+ && let Some ( f) = f. into_function ( )
507+ {
508+ Some ( f)
518509 } else {
519510 None
520511 }
@@ -553,15 +544,18 @@ fn is_array_or_proxy_of_array(val: &Value) -> bool {
553544 if val. is_array ( ) {
554545 return true ;
555546 }
556- let ctx = val. ctx ( ) . as_raw ( ) . as_ptr ( ) ;
557- let mut val = val. as_raw ( ) ;
547+ let ctx = val. ctx ( ) . clone ( ) ;
548+ let mut val = val. clone ( ) ;
558549 loop {
559- let is_proxy = unsafe { JS_IsProxy ( val) } ;
550+ let is_proxy = unsafe { JS_IsProxy ( val. as_raw ( ) ) } ;
560551 if !is_proxy {
561552 return false ;
562553 }
563- val = unsafe { JS_GetProxyTarget ( ctx, val) } ;
564- if unsafe { JS_IsArray ( val) } {
554+ val = unsafe {
555+ let target = JS_GetProxyTarget ( ctx. as_raw ( ) . as_ptr ( ) , val. as_raw ( ) ) ;
556+ Value :: from_raw ( ctx. clone ( ) , target)
557+ } ;
558+ if unsafe { JS_IsArray ( val. as_raw ( ) ) } {
565559 return true ;
566560 }
567561 }
@@ -652,8 +646,12 @@ mod tests {
652646 where
653647 T : DeserializeOwned ,
654648 {
649+ let ctx = v. ctx ( ) . clone ( ) ;
655650 let mut deserializer = ValueDeserializer :: from ( v) ;
656- T :: deserialize ( & mut deserializer) . unwrap ( )
651+ match T :: deserialize ( & mut deserializer) {
652+ Ok ( val) => val,
653+ Err ( e) => panic ! ( "{}" , e. catch( & ctx) ) ,
654+ }
657655 }
658656
659657 #[ test]
@@ -806,6 +804,23 @@ mod tests {
806804 } ) ;
807805 }
808806
807+ #[ test]
808+ fn test_array_proxy ( ) {
809+ let rt = Runtime :: default ( ) ;
810+ rt. context ( ) . with ( |cx| {
811+ cx. eval :: < Value < ' _ > , _ > (
812+ r#"
813+ var arr = [1, 2, 3];
814+ var a = new Proxy(arr, {});
815+ "# ,
816+ )
817+ . unwrap ( ) ;
818+ let v = cx. globals ( ) . get ( "a" ) . unwrap ( ) ;
819+ let val = deserialize_value :: < Vec < u8 > > ( v) ;
820+ assert_eq ! ( vec![ 1 , 2 , 3 ] , val) ;
821+ } ) ;
822+ }
823+
809824 #[ test]
810825 fn test_non_json_object_values_are_dropped ( ) {
811826 let rt = Runtime :: default ( ) ;
@@ -870,4 +885,33 @@ mod tests {
870885 assert_eq ! ( left, right) ;
871886 } ) ;
872887 }
888+
889+ #[ test]
890+ fn test_short_bigint ( ) {
891+ let rt = Runtime :: default ( ) ;
892+ rt. context ( ) . with ( |cx| {
893+ cx. eval :: < Value < ' _ > , _ > ( "var a = BigInt(1);" ) . unwrap ( ) ;
894+ let v = cx. globals ( ) . get ( "a" ) . unwrap ( ) ;
895+ let val = deserialize_value :: < String > ( v) ;
896+ assert_eq ! ( val, "1" ) ;
897+ } ) ;
898+ }
899+
900+ #[ test]
901+ fn test_bigint ( ) {
902+ let rt = Runtime :: default ( ) ;
903+ rt. context ( ) . with ( |cx| {
904+ cx. eval :: < Value < ' _ > , _ > (
905+ r#"
906+ const left = 12345678901234567890n;
907+ const right = 98765432109876543210n;
908+ var a = left * right;
909+ "# ,
910+ )
911+ . unwrap ( ) ;
912+ let v = cx. globals ( ) . get ( "a" ) . unwrap ( ) ;
913+ let val = deserialize_value :: < String > ( v) ;
914+ assert_eq ! ( val, "1219326311370217952237463801111263526900" ) ;
915+ } ) ;
916+ }
873917}
0 commit comments