2020open Js
2121open ! Import
2222
23+ (* ***)
24+
25+ let write_string buffer s =
26+ Buffer. add_char buffer '\"' ;
27+ for i = 0 to String. length s - 1 do
28+ match s.[i] with
29+ | '\"' -> Buffer. add_string buffer " \\\" "
30+ | '\\' -> Buffer. add_string buffer " \\\\ "
31+ | '\b' -> Buffer. add_string buffer " \\ b"
32+ | '\x0C' -> Buffer. add_string buffer " \\ f"
33+ | '\n' -> Buffer. add_string buffer " \\ n"
34+ | '\r' -> Buffer. add_string buffer " \\ r"
35+ | '\t' -> Buffer. add_string buffer " \\ t"
36+ | c when Poly. (c < = '\x1F' ) ->
37+ (* Other control characters are escaped. *)
38+ Printf. bprintf buffer " \\ u%04X" (int_of_char c)
39+ | c when Poly. (c < '\x80' ) -> Buffer. add_char buffer s.[i]
40+ | _c (* >= '\x80' *) ->
41+ (* Bytes greater than 127 are embedded in a UTF-8 sequence. *)
42+ Buffer. add_char buffer (Char. chr (0xC2 lor (Char. code s.[i] lsr 6 )));
43+ Buffer. add_char buffer (Char. chr (0x80 lor (Char. code s.[i] land 0x3F )))
44+ done ;
45+ Buffer. add_char buffer '\"'
46+
47+ let write_float buffer f =
48+ (* "%.15g" can be (much) shorter; "%.17g" is round-trippable *)
49+ let s = Printf. sprintf " %.15g" f in
50+ if Poly. (float_of_string s = f)
51+ then Buffer. add_string buffer s
52+ else Printf. bprintf buffer " %.17g" f
53+
54+ external custom_identifier : Obj .t -> string = " caml_custom_identifier"
55+
56+ let rec write b v =
57+ if Obj. is_int v
58+ then Printf. bprintf b " %d" (Obj. obj v : int )
59+ else
60+ let t = Obj. tag v in
61+ if t < = Obj. last_non_constant_constructor_tag
62+ then (
63+ Printf. bprintf b " [%d" t;
64+ for i = 0 to Obj. size v - 1 do
65+ Buffer. add_char b ',' ;
66+ write b (Obj. field v i)
67+ done ;
68+ Buffer. add_char b ']' )
69+ else if t = Obj. string_tag
70+ then write_string b (Obj. obj v : string )
71+ else if t = Obj. double_tag
72+ then write_float b (Obj. obj v : float )
73+ else if t = Obj. double_array_tag
74+ then (
75+ Printf. bprintf b " [%d" t;
76+ for i = 0 to Obj. size v - 1 do
77+ Buffer. add_char b ',' ;
78+ write_float b (Obj. double_field v i)
79+ done ;
80+ Buffer. add_char b ']' )
81+ else if t = Obj. custom_tag
82+ then
83+ match custom_identifier v with
84+ | "_i" -> Printf. bprintf b " %ld" (Obj. obj v : int32 )
85+ | "_j" ->
86+ let i : int64 = Obj. obj v in
87+ let mask16 = Int64. of_int 0xffff in
88+ let mask24 = Int64. of_int 0xffffff in
89+ Printf. bprintf
90+ b
91+ " [255,%Ld,%Ld,%Ld]"
92+ (Int64. logand i mask24)
93+ (Int64. logand (Int64. shift_right i 24 ) mask24)
94+ (Int64. logand (Int64. shift_right i 48 ) mask16)
95+ | id -> failwith (Printf. sprintf " Json.output: unsupported custom value %s " id)
96+ else failwith (Printf. sprintf " Json.output: unsupported tag %d " t)
97+
98+ let to_json v =
99+ let buf = Buffer. create 50 in
100+ write buf v;
101+ Buffer. contents buf
102+
103+ (* ***)
104+
23105class type json = object
24106 method parse : 'a. js_string t -> 'a meth
25107
@@ -51,13 +133,18 @@ let input_reviver =
51133 in
52134 wrap_meth_callback reviver
53135
54- let unsafe_input s = json##parse_ s input_reviver
136+ let unsafe_input s =
137+ match Sys. backend_type with
138+ | Other "wasm_of_ocaml" -> failwith " Json.unsafe_input: not implemented"
139+ | _ -> json##parse_ s input_reviver
55140
56141class type obj = object
57142 method constructor : 'a. 'a constr Js. readonly_prop
58143end
59144
60145let mlInt64_constr =
146+ Js.Unsafe. pure_expr
147+ @@ fun () ->
61148 let dummy_int64 = 1L in
62149 let dummy_obj : obj t = Obj. magic dummy_int64 in
63150 dummy_obj##.constructor
@@ -71,4 +158,7 @@ let output_reviver _key (value : Unsafe.any) : Obj.t =
71158 Obj. repr (array [| 255 ; value##.lo; value##.mi; value##.hi |])
72159 else Obj. repr value
73160
74- let output obj = json##stringify_ obj (Js. wrap_callback output_reviver)
161+ let output obj =
162+ match Sys. backend_type with
163+ | Other "wasm_of_ocaml" -> Js. string (to_json (Obj. repr obj))
164+ | _ -> json##stringify_ obj (Js. wrap_callback output_reviver)
0 commit comments