Skip to content

Commit 9060aa0

Browse files
committed
add bitwise operations
1 parent a13c298 commit 9060aa0

24 files changed

+642
-476
lines changed

jscomp/core/lam_analysis.ml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,10 @@ let rec no_side_effects (lam : Lam.t) : bool =
7676
(* Float operations *)
7777
| Pintoffloat | Pfloatofint | Pnegfloat
7878
(* | Pabsfloat *)
79-
| Paddfloat | Psubfloat | Pmulfloat | Pdivfloat | Pfloatcomp _ | Pbigintcomp _ | Pjscomp _
79+
| Paddfloat | Psubfloat | Pmulfloat | Pdivfloat | Pfloatcomp _ | Pjscomp _
8080
| Pnegbigint | Paddbigint | Psubbigint | Pmulbigint | Ppowbigint
81+
| Pandbigint | Porbigint | Pxorbigint | Plslbigint | Pasrbigint
82+
| Pbigintcomp _
8183
(* String operations *)
8284
| Pstringlength | Pstringrefu | Pstringrefs | Pbyteslength | Pbytesrefu
8385
| Pbytesrefs | Pmakearray | Parraylength | Parrayrefu | Parrayrefs

jscomp/core/lam_compile_primitive.ml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,8 @@ let translate output_prefix loc (cxt : Lam_compile_context.t)
225225
| Plslint -> (
226226
match args with [ e1; e2 ] -> E.int32_lsl e1 e2 | _ -> assert false)
227227
| Plslint64 -> Js_long.lsl_ args
228+
| Plslbigint -> (
229+
match args with [ e1; e2 ] -> E.bigint_op Lsl e1 e2 | _ -> assert false)
228230
| Plsrint -> (
229231
match args with
230232
| [ e1; { J.expression_desc = Number (Int { i = 0l; _ } | Uint 0l); _ } ]
@@ -236,15 +238,23 @@ let translate output_prefix loc (cxt : Lam_compile_context.t)
236238
| Pasrint -> (
237239
match args with [ e1; e2 ] -> E.int32_asr e1 e2 | _ -> assert false)
238240
| Pasrint64 -> Js_long.asr_ args
241+
| Pasrbigint -> (
242+
match args with [ e1; e2 ] -> E.bigint_op Asr e1 e2 | _ -> assert false)
239243
| Pandint -> (
240244
match args with [ e1; e2 ] -> E.int32_band e1 e2 | _ -> assert false)
241245
| Pandint64 -> Js_long.and_ args
246+
| Pandbigint -> (
247+
match args with [ e1; e2 ] -> E.bigint_op Band e1 e2 | _ -> assert false)
242248
| Porint -> (
243249
match args with [ e1; e2 ] -> E.int32_bor e1 e2 | _ -> assert false)
244250
| Porint64 -> Js_long.or_ args
251+
| Porbigint -> (
252+
match args with [ e1; e2 ] -> E.bigint_op Bor e1 e2 | _ -> assert false)
245253
| Pxorint -> (
246254
match args with [ e1; e2 ] -> E.int32_bxor e1 e2 | _ -> assert false)
247255
| Pxorint64 -> Js_long.xor args
256+
| Pxorbigint -> (
257+
match args with [ e1; e2 ] -> E.bigint_op Bxor e1 e2 | _ -> assert false)
248258
| Pjscomp cmp -> (
249259
match args with [ l; r ] -> E.js_comp cmp l r | _ -> assert false)
250260
| Pfloatcomp cmp | Pintcomp cmp -> (

jscomp/core/lam_convert.ml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,11 @@ let lam_prim ~primitive:(p : Lambda.primitive) ~args loc : Lam.t =
261261
| Pdivbigint _is_safe (*FIXME*) -> prim ~primitive:Pdivbigint ~args loc
262262
| Pmodbigint _is_safe (*FIXME*) -> prim ~primitive:Pmodbigint ~args loc
263263
| Ppowbigint -> prim ~primitive:Ppowbigint ~args loc
264+
| Pandbigint -> prim ~primitive:Pandbigint ~args loc
265+
| Porbigint -> prim ~primitive:Porbigint ~args loc
266+
| Pxorbigint -> prim ~primitive:Pxorbigint ~args loc
267+
| Plslbigint -> prim ~primitive:Plslbigint ~args loc
268+
| Pasrbigint -> prim ~primitive:Pasrbigint ~args loc
264269
| Pbigintcomp x -> prim ~primitive:(Pbigintcomp x) ~args loc
265270
| Pintcomp x -> prim ~primitive:(Pintcomp x) ~args loc
266271
| Poffsetint x -> prim ~primitive:(Poffsetint x) ~args loc

jscomp/core/lam_primitive.ml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,11 @@ type t =
8787
| Pdivbigint
8888
| Pmodbigint
8989
| Ppowbigint
90+
| Pandbigint
91+
| Porbigint
92+
| Pxorbigint
93+
| Plslbigint
94+
| Pasrbigint
9095
| Pintcomp of Lam_compat.comparison
9196
| Pfloatcomp of Lam_compat.comparison
9297
| Pjscomp of Lam_compat.comparison
@@ -216,6 +221,11 @@ let eq_primitive_approx (lhs : t) (rhs : t) =
216221
| Pdivbigint -> rhs = Pdivbigint
217222
| Pmodbigint -> rhs = Pmodbigint
218223
| Ppowbigint -> rhs = Ppowbigint
224+
| Pandbigint -> rhs = Pandbigint
225+
| Porbigint -> rhs = Porbigint
226+
| Pxorbigint -> rhs = Pxorbigint
227+
| Plslbigint -> rhs = Plslbigint
228+
| Pasrbigint -> rhs = Pasrbigint
219229
| Pjs_apply -> rhs = Pjs_apply
220230
| Pjs_runtime_apply -> rhs = Pjs_runtime_apply
221231
| Pstringlength -> rhs = Pstringlength

jscomp/core/lam_primitive.mli

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ type t =
7777
| Pdivbigint
7878
| Pmodbigint
7979
| Ppowbigint
80+
| Pandbigint
81+
| Porbigint
82+
| Pxorbigint
83+
| Plslbigint
84+
| Pasrbigint
8085
| Pintcomp of Lam_compat.comparison
8186
| Pfloatcomp of Lam_compat.comparison
8287
| Pjscomp of Lam_compat.comparison

jscomp/core/lam_print.ml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,11 @@ let primitive ppf (prim : Lam_primitive.t) =
141141
| Pdivbigint -> fprintf ppf "/,"
142142
| Pmodbigint -> fprintf ppf "modn"
143143
| Ppowbigint -> fprintf ppf "**,"
144+
| Pandbigint -> fprintf ppf "and,"
145+
| Porbigint -> fprintf ppf "or,"
146+
| Pxorbigint -> fprintf ppf "xor,"
147+
| Plslbigint -> fprintf ppf "lsl,"
148+
| Pasrbigint -> fprintf ppf "asr,"
144149
| Pbigintcomp Ceq -> fprintf ppf "==,"
145150
| Pbigintcomp Cneq -> fprintf ppf "!=,"
146151
| Pbigintcomp Clt -> fprintf ppf "<,"

jscomp/ml/lambda.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,8 @@ type primitive =
232232
(* Bigint operations *)
233233
| Pnegbigint | Paddbigint | Psubbigint | Ppowbigint
234234
| Pmulbigint | Pdivbigint of is_safe | Pmodbigint of is_safe
235+
| Pandbigint | Porbigint | Pxorbigint
236+
| Plslbigint | Pasrbigint
235237
| Pbigintcomp of comparison
236238
(* String operations *)
237239
| Pstringlength | Pstringrefu | Pstringrefs

jscomp/ml/lambda.mli

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,8 @@ type primitive =
198198
(* Bigint operations *)
199199
| Pnegbigint | Paddbigint | Psubbigint | Ppowbigint
200200
| Pmulbigint | Pdivbigint of is_safe | Pmodbigint of is_safe
201+
| Pandbigint | Porbigint | Pxorbigint
202+
| Plslbigint | Pasrbigint
201203
| Pbigintcomp of comparison
202204
(* String operations *)
203205
| Pstringlength | Pstringrefu | Pstringrefs

jscomp/ml/printlambda.ml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,11 @@ let primitive ppf = function
182182
| Psubbigint -> fprintf ppf "-,"
183183
| Pmulbigint -> fprintf ppf "*,"
184184
| Ppowbigint -> fprintf ppf "**,"
185+
| Pandbigint -> fprintf ppf "and,"
186+
| Porbigint -> fprintf ppf "or,"
187+
| Pxorbigint -> fprintf ppf "xor,"
188+
| Plslbigint -> fprintf ppf "lsl,"
189+
| Pasrbigint -> fprintf ppf "asr,"
185190
| Pdivbigint Safe -> fprintf ppf "/n"
186191
| Pdivbigint Unsafe -> fprintf ppf "/nu"
187192
| Pmodbigint Safe -> fprintf ppf "mod"
@@ -300,6 +305,11 @@ let name_of_primitive = function
300305
| Pdivbigint _ -> "Pdivbigint"
301306
| Pmodbigint _ -> "Pmodbigint"
302307
| Ppowbigint -> "Ppowbigint"
308+
| Pandbigint -> "Pandbigint"
309+
| Porbigint -> "Porbigint"
310+
| Pxorbigint -> "Pxorbigint"
311+
| Plslbigint -> "Plslbigint"
312+
| Pasrbigint -> "Pasrbigint"
303313
| Pbigintcomp _ -> "Pbigintcomp"
304314
| Pstringlength -> "Pstringlength"
305315
| Pstringrefu -> "Pstringrefu"

jscomp/ml/translcore.ml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,11 @@ let primitives_table =
345345
("%lslint", Plslint);
346346
("%lsrint", Plsrint);
347347
("%asrint", Pasrint);
348+
("%andbigint", Pandbigint);
349+
("%orbigint", Porbigint);
350+
("%xorbigint", Pxorbigint);
351+
("%lslbigint", Plslbigint);
352+
("%asrbigint", Pasrbigint);
348353
("%eq", Pintcomp Ceq);
349354
("%noteq", Pintcomp Cneq);
350355
("%ltint", Pintcomp Clt);

jscomp/stdlib-406/pervasives.res

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,15 @@ external \"/,": (bigint, bigint) => bigint = "%divbigint"
190190
external modn: (bigint, bigint) => bigint = "%modbigint"
191191
external \"**,": (bigint, bigint) => bigint = "%powbigint"
192192

193+
external landn: (bigint, bigint) => bigint = "%andbigint"
194+
external lorn: (bigint, bigint) => bigint = "%orbigint"
195+
external lxorn: (bigint, bigint) => bigint = "%xorbigint"
196+
197+
let lnotn = x => lxorn(x, -1n)
198+
199+
external lsln: (bigint, bigint) => bigint = "%lslbigint"
200+
external asrn: (bigint, bigint) => bigint = "%asrbigint"
201+
193202
/* String and byte sequence operations -- more in modules String and Bytes */
194203

195204
external string_length: string => int = "%string_length"

jscomp/stdlib-406/pervasives.resi

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,33 @@ external modn: (bigint, bigint) => bigint = "%modbigint"
568568
Left-associative operator at precedence level 7/9. */
569569
external \"**,": (bigint, bigint) => bigint = "%powbigint"
570570

571+
/** Bigint Bitwise logical and.
572+
Left-associative operator at precedence level 7/11. */
573+
external landn: (bigint, bigint) => bigint = "%andbigint"
574+
575+
/** Bigint Bitwise logical or.
576+
Left-associative operator at precedence level 7/11. */
577+
external lorn: (bigint, bigint) => bigint = "%orbigint"
578+
579+
/** Bigint Bitwise logical exclusive or.
580+
Left-associative operator at precedence level 7/11. */
581+
external lxorn: (bigint, bigint) => bigint = "%xorbigint"
582+
583+
/** Bigint Bitwise logical negation. */
584+
let lnotn: bigint => bigint
585+
586+
/** [n lsln m] shifts [n] to the left by [m] bits.
587+
The result is unspecified if [m < 0n] or [m >= bitsize],
588+
where the both operands are bigints.
589+
Right-associative operator at precedence level 8/11. */
590+
external lsln: (bigint, bigint) => bigint = "%lslbigint"
591+
592+
/** [n asrn m] shifts [n] to the right by [m] bits.
593+
This is an arithmetic shift: the sign bit of [n] is replicated.
594+
The result is unspecified if [m < 0n] or [m >= bitsize].
595+
Right-associative operator at precedence level 8/11. */
596+
external asrn: (bigint, bigint) => bigint = "%asrbigint"
597+
571598
@val
572599
@scope("Number")
573600
/** A special floating-point value denoting the result of an

jscomp/stdlib-406/pervasivesU.res

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,15 @@ external \"/,": (bigint, bigint) => bigint = "%divbigint"
191191
external modn: (bigint, bigint) => bigint = "%modbigint"
192192
external \"**,": (bigint, bigint) => bigint = "%powbigint"
193193

194+
external landn: (bigint, bigint) => bigint = "%andbigint"
195+
external lorn: (bigint, bigint) => bigint = "%orbigint"
196+
external lxorn: (bigint, bigint) => bigint = "%xorbigint"
197+
198+
let lnotn = x => lxorn(x, -1n)
199+
200+
external lsln: (bigint, bigint) => bigint = "%lslbigint"
201+
external asrn: (bigint, bigint) => bigint = "%asrbigint"
202+
194203
/* String and byte sequence operations -- more in modules String and Bytes */
195204

196205
external string_length: string => int = "%string_length"

jscomp/stdlib-406/pervasivesU.resi

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,33 @@ external modn: (bigint, bigint) => bigint = "%modbigint"
571571
Left-associative operator at precedence level 7/9. */
572572
external \"**,": (bigint, bigint) => bigint = "%powbigint"
573573

574+
/** Bigint Bitwise logical and.
575+
Left-associative operator at precedence level 7/11. */
576+
external landn: (bigint, bigint) => bigint = "%andbigint"
577+
578+
/** Bigint Bitwise logical or.
579+
Left-associative operator at precedence level 7/11. */
580+
external lorn: (bigint, bigint) => bigint = "%orbigint"
581+
582+
/** Bigint Bitwise logical exclusive or.
583+
Left-associative operator at precedence level 7/11. */
584+
external lxorn: (bigint, bigint) => bigint = "%xorbigint"
585+
586+
/** Bigint Bitwise logical negation. */
587+
let lnotn: bigint => bigint
588+
589+
/** [n lsln m] shifts [n] to the left by [m] bits.
590+
The result is unspecified if [m < 0n] or [m >= bitsize],
591+
where the both operands are bigints.
592+
Right-associative operator at precedence level 8/11. */
593+
external lsln: (bigint, bigint) => bigint = "%lslbigint"
594+
595+
/** [n asrn m] shifts [n] to the right by [m] bits.
596+
This is an arithmetic shift: the sign bit of [n] is replicated.
597+
The result is unspecified if [m < 0n] or [m >= bitsize].
598+
Right-associative operator at precedence level 8/11. */
599+
external asrn: (bigint, bigint) => bigint = "%asrbigint"
600+
574601
@val
575602
@scope("Number")
576603
/** A special floating-point value denoting the result of an

0 commit comments

Comments
 (0)