65
65
66
66
{[
67
67
var u = caml_obj_dup (x)
68
- var new_record = u.slice ()
68
+ var new_record = u.slice ()
69
69
70
70
]}
71
71
*)
@@ -99,19 +99,19 @@ let caml_obj_truncate (x : Obj.t) (new_size : int) =
99
99
let caml_lazy_make_forward x = lazy x
100
100
101
101
(* *
102
- For the empty dummy object, whether it's
103
- `[]` or `{}` depends on how
104
- runtime encoding works, and will affect
105
- js polymorphic comparison(Js.(=)) (fine with caml polymoprhic comparison (Pervasives.equal))
106
- In most cases, rec value comes from record/modules,
107
- whose tag is 0, we optimize that case
108
- *)
102
+ For the empty dummy object, whether it's
103
+ `[]` or `{}` depends on how
104
+ runtime encoding works, and will affect
105
+ js polymorphic comparison(Js.(=)) (fine with caml polymoprhic comparison (Pervasives.equal))
106
+ In most cases, rec value comes from record/modules,
107
+ whose tag is 0, we optimize that case
108
+ *)
109
109
let caml_update_dummy x y =
110
110
(* let len = Bs_obj.length y in
111
- for i = 0 to len - 1 do
112
- Array.unsafe_set x i (Obj.field y i)
113
- done;
114
- Obj.set_tag (Obj.magic x) (Obj.tag y)
111
+ for i = 0 to len - 1 do
112
+ Array.unsafe_set x i (Obj.field y i)
113
+ done;
114
+ Obj.set_tag (Obj.magic x) (Obj.tag y)
115
115
*)
116
116
let len = Bs_obj. length y in
117
117
for i = 0 to len - 1 do
@@ -120,10 +120,10 @@ let caml_update_dummy x y =
120
120
let y_tag = Obj. tag y in
121
121
if y_tag <> 0 then
122
122
Obj. set_tag x y_tag
123
-
124
- (* Bs_obj.set_length x (Bs_obj.length y) *)
125
- (* [set_length] seems redundant here given that it is initialized as an array
126
- *)
123
+
124
+ (* Bs_obj.set_length x (Bs_obj.length y) *)
125
+ (* [set_length] seems redundant here given that it is initialized as an array
126
+ *)
127
127
let caml_int_compare (x : int ) (y : int ) : int =
128
128
if x < y then - 1 else if x = y then 0 else 1
129
129
@@ -153,45 +153,54 @@ let unsafe_js_compare x y =
153
153
*)
154
154
let rec caml_compare (a : Obj.t ) (b : Obj.t ) : int =
155
155
(* front and formoest, we do not compare function values*)
156
- if Js. typeof a = " string" then
156
+ let a_type = Js. typeof a in
157
+ let b_type = Js. typeof b in
158
+ if a_type = " string" then
157
159
caml_string_compare (Obj. magic a) (Obj. magic b )
158
- else if Js. typeof a = " number" then
159
- caml_int_compare (Obj. magic a) (Obj. magic b )
160
- else if Js. typeof a = " boolean"
161
- || Js. typeof a = " null"
162
- || Js. typeof a = " undefined"
163
- then
164
- unsafe_js_compare a b
165
- else if Js. typeof a = " function" || Js. typeof b = " function"
166
- then raise (Invalid_argument " compare: functional value" )
167
- else
168
- (* if js_is_instance_array a then *)
169
- (* 0 *)
170
- (* else *)
171
- let tag_a = Bs_obj. tag a in
172
- let tag_b = Bs_obj. tag b in
173
- (* double_array_tag: 254
174
- forward_tag:250
175
- *)
176
- if tag_a = 250 then
177
- caml_compare (Obj. field a 0 ) b
178
- else if tag_b = 250 then
179
- caml_compare a (Obj. field b 0 )
180
- else if tag_a = 248 (* object/exception *) then
181
- caml_int_compare (Obj. magic @@ Obj. field a 1 ) (Obj. magic @@ Obj. field b 1 )
182
- else if tag_a = 251 (* abstract_tag *) then
183
- raise (Invalid_argument " equal: abstract value" )
184
- else if tag_a <> tag_b then
185
- if tag_a < tag_b then (- 1 ) else 1
186
- else
187
- let len_a = Bs_obj. length a in
188
- let len_b = Bs_obj. length b in
189
- if len_a = len_b then
190
- aux_same_length a b 0 len_a
191
- else if len_a < len_b then
192
- aux_length_a_short a b 0 len_a
160
+ else
161
+ let is_a_number = a_type = " number" in
162
+ let is_b_number = b_type = " number" in
163
+ match is_a_number , is_b_number with
164
+ | true , true ->
165
+ caml_int_compare (Obj. magic a) (Obj. magic b )
166
+ | true , false -> - 1 (* Integer < Block in OCaml runtime GPR #1195 *)
167
+ | false , true -> 1
168
+ | false , false ->
169
+ if a_type = " boolean"
170
+ || a_type = " null"
171
+ || a_type = " undefined"
172
+ then
173
+ unsafe_js_compare a b
174
+ else if a_type = " function" || b_type = " function"
175
+ then raise (Invalid_argument " compare: functional value" )
193
176
else
194
- aux_length_b_short a b 0 len_b
177
+ (* if js_is_instance_array a then *)
178
+ (* 0 *)
179
+ (* else *)
180
+ let tag_a = Bs_obj. tag a in
181
+ let tag_b = Bs_obj. tag b in
182
+ (* double_array_tag: 254
183
+ forward_tag:250
184
+ *)
185
+ if tag_a = 250 then
186
+ caml_compare (Obj. field a 0 ) b
187
+ else if tag_b = 250 then
188
+ caml_compare a (Obj. field b 0 )
189
+ else if tag_a = 248 (* object/exception *) then
190
+ caml_int_compare (Obj. magic @@ Obj. field a 1 ) (Obj. magic @@ Obj. field b 1 )
191
+ else if tag_a = 251 (* abstract_tag *) then
192
+ raise (Invalid_argument " equal: abstract value" )
193
+ else if tag_a <> tag_b then
194
+ if tag_a < tag_b then (- 1 ) else 1
195
+ else
196
+ let len_a = Bs_obj. length a in
197
+ let len_b = Bs_obj. length b in
198
+ if len_a = len_b then
199
+ aux_same_length a b 0 len_a
200
+ else if len_a < len_b then
201
+ aux_length_a_short a b 0 len_a
202
+ else
203
+ aux_length_b_short a b 0 len_b
195
204
and aux_same_length (a : Obj.t ) (b : Obj.t ) i same_length =
196
205
if i = same_length then
197
206
0
@@ -218,10 +227,10 @@ let rec caml_equal (a : Obj.t) (b : Obj.t) : bool =
218
227
(* front and formoest, we do not compare function values*)
219
228
if a == b then true
220
229
else if Js. typeof a = " string"
221
- || Js. typeof a = " number"
222
- || Js. typeof a = " boolean"
223
- || Js. typeof a = " undefined"
224
- || Js. typeof a = " null"
230
+ || Js. typeof a = " number"
231
+ || Js. typeof a = " boolean"
232
+ || Js. typeof a = " undefined"
233
+ || Js. typeof a = " null"
225
234
then false
226
235
else if Js. typeof a = " function" || Js. typeof b = " function"
227
236
then raise (Invalid_argument " equal: functional value" )
0 commit comments