Skip to content

Commit 42ffdc4

Browse files
authored
feat(compiler)!: Add Uint32 and Uint64 types (#1531)
* feat(compiler): Add unsigned int types update format/docs * fix random, signed/unsigned conversion, change to operators * removed deprecated int64 functions * remove extraneous incRefs * made docs more accurate * updated tests
1 parent 86b092c commit 42ffdc4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+3923
-787
lines changed

compiler/src/codegen/comp_utils.re

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,22 @@ let rec compile_const = (c): Literal.t => {
4040
let identity: 'a. 'a => 'a = x => x;
4141
let conv_int32 = n => Int32.(add(mul(2l, n), 1l));
4242
let conv_int64 = n => Int64.(add(mul(2L, n), 1L));
43+
let conv_uint32 = n => Int32.(add(mul(2l, n), 1l));
44+
let conv_uint64 = n => Int64.(add(mul(2L, n), 1L));
4345
let conv_float32 = identity;
4446
let conv_float64 = identity;
4547
switch (c) {
4648
| MConstLiteral(MConstLiteral(_) as c) => compile_const(c)
4749
| MConstI32(n) => Literal.int32(conv_int32(n))
4850
| MConstI64(n) => Literal.int64(conv_int64(n))
51+
| MConstU32(n) => Literal.int32(conv_uint32(n))
52+
| MConstU64(n) => Literal.int64(conv_uint64(n))
4953
| MConstF32(n) => Literal.float32(conv_float32(n))
5054
| MConstF64(n) => Literal.float64(conv_float64(n))
5155
| MConstLiteral(MConstI32(n)) => Literal.int32(n)
5256
| MConstLiteral(MConstI64(n)) => Literal.int64(n)
57+
| MConstLiteral(MConstU32(n)) => Literal.int32(n)
58+
| MConstLiteral(MConstU64(n)) => Literal.int64(n)
5359
| MConstLiteral(MConstF32(n)) => Literal.float32(n)
5460
| MConstLiteral(MConstF64(n)) => Literal.float64(n)
5561
};

compiler/src/codegen/compcore.re

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2047,6 +2047,94 @@ let allocate_record = (wasm_mod, env, ttag, elts) => {
20472047
);
20482048
};
20492049

2050+
let allocate_uint_uninitialized = (wasm_mod, env, is_32_bit) => {
2051+
let get_swap = () => get_swap(wasm_mod, env, 0);
2052+
let make_alloc = () =>
2053+
heap_allocate(wasm_mod, env, if (is_32_bit) {2} else {4});
2054+
2055+
let (tag, label) =
2056+
if (is_32_bit) {
2057+
(Uint32Type, "allocate_unitialized_uint32");
2058+
} else {
2059+
(Uint64Type, "allocate_unitialized_uint64");
2060+
};
2061+
2062+
let preamble = [
2063+
store(
2064+
~offset=0,
2065+
wasm_mod,
2066+
tee_swap(~skip_incref=true, wasm_mod, env, 0, make_alloc()),
2067+
Expression.Const.make(
2068+
wasm_mod,
2069+
const_int32(tag_val_of_heap_tag_type(tag)),
2070+
),
2071+
),
2072+
];
2073+
let postamble = [get_swap()];
2074+
Expression.Block.make(
2075+
wasm_mod,
2076+
gensym_label(label),
2077+
List.concat([preamble, postamble]),
2078+
);
2079+
};
2080+
2081+
type alloc_uint_type =
2082+
| Uint32(Expression.t)
2083+
| Uint64(Expression.t);
2084+
2085+
let allocate_uint = (wasm_mod, env, uint_value) => {
2086+
let get_swap = () => get_swap(wasm_mod, env, 0);
2087+
2088+
let (tag, instrs, needed_words, label) =
2089+
switch (uint_value) {
2090+
| Uint32(uint32) => (
2091+
Uint32Type,
2092+
[store(~offset=4, ~ty=Type.int32, wasm_mod, get_swap(), uint32)],
2093+
2,
2094+
"allocate_uint32",
2095+
)
2096+
| Uint64(uint64) => (
2097+
Uint64Type,
2098+
[store(~offset=8, ~ty=Type.int64, wasm_mod, get_swap(), uint64)],
2099+
// Allocate 4 words to store with 8-byte alignment
2100+
4,
2101+
"allocate_uint64",
2102+
)
2103+
};
2104+
2105+
let preamble = [
2106+
store(
2107+
~offset=0,
2108+
wasm_mod,
2109+
tee_swap(
2110+
~skip_incref=true,
2111+
wasm_mod,
2112+
env,
2113+
0,
2114+
heap_allocate(wasm_mod, env, needed_words),
2115+
),
2116+
Expression.Const.make(
2117+
wasm_mod,
2118+
const_int32(tag_val_of_heap_tag_type(tag)),
2119+
),
2120+
),
2121+
];
2122+
let postamble = [get_swap()];
2123+
Expression.Block.make(
2124+
wasm_mod,
2125+
gensym_label(label),
2126+
List.concat([preamble, instrs, postamble]),
2127+
);
2128+
};
2129+
2130+
let allocate_uint32 = (wasm_mod, env, i) => {
2131+
allocate_uint(wasm_mod, env, Uint32(i));
2132+
};
2133+
2134+
let allocate_uint64 = (wasm_mod, env, i) => {
2135+
allocate_uint(wasm_mod, env, Uint64(i));
2136+
};
2137+
20502138
type alloc_number_type =
20512139
| Int32(Expression.t)
20522140
| Int64(Expression.t)
@@ -2289,6 +2377,8 @@ let compile_prim0 = (wasm_mod, env, p0): Expression.t => {
22892377
allocate_number_uninitialized(wasm_mod, env, BoxedFloat64)
22902378
| AllocateRational =>
22912379
allocate_number_uninitialized(wasm_mod, env, BoxedRational)
2380+
| AllocateUint32 => allocate_uint_uninitialized(wasm_mod, env, true)
2381+
| AllocateUint64 => allocate_uint_uninitialized(wasm_mod, env, false)
22922382
| Unreachable => Expression.Unreachable.make(wasm_mod)
22932383
};
22942384
};
@@ -2312,6 +2402,8 @@ let compile_prim1 = (wasm_mod, env, p1, arg, loc): Expression.t => {
23122402
| NewInt64 => allocate_number(wasm_mod, env, Int64(compiled_arg))
23132403
| NewFloat32 => allocate_number(wasm_mod, env, Float32(compiled_arg))
23142404
| NewFloat64 => allocate_number(wasm_mod, env, Float64(compiled_arg))
2405+
| NewUint32 => allocate_uint(wasm_mod, env, Uint32(compiled_arg))
2406+
| NewUint64 => allocate_uint(wasm_mod, env, Uint64(compiled_arg))
23152407
| LoadAdtVariant => load(~offset=12, wasm_mod, compiled_arg)
23162408
| StringSize
23172409
| BytesSize => load(~offset=4, wasm_mod, compiled_arg)
@@ -2724,6 +2816,18 @@ let compile_allocation = (wasm_mod, env, alloc_type) =>
27242816
env,
27252817
Expression.Const.make(wasm_mod, Literal.int64(i)),
27262818
)
2819+
| MUint32(i) =>
2820+
allocate_uint32(
2821+
wasm_mod,
2822+
env,
2823+
Expression.Const.make(wasm_mod, Literal.int32(i)),
2824+
)
2825+
| MUint64(i) =>
2826+
allocate_uint64(
2827+
wasm_mod,
2828+
env,
2829+
Expression.Const.make(wasm_mod, Literal.int64(i)),
2830+
)
27272831
| MFloat32(i) =>
27282832
allocate_float32(
27292833
wasm_mod,

compiler/src/codegen/mashtree.re

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,8 @@ type prim0 =
174174
Parsetree.prim0 =
175175
| AllocateInt32
176176
| AllocateInt64
177+
| AllocateUint32
178+
| AllocateUint64
177179
| AllocateFloat32
178180
| AllocateFloat64
179181
| AllocateRational
@@ -188,6 +190,8 @@ type prim1 =
188190
| AllocateBigInt
189191
| NewInt32
190192
| NewInt64
193+
| NewUint32
194+
| NewUint64
191195
| NewFloat32
192196
| NewFloat64
193197
| BuiltinId
@@ -284,6 +288,8 @@ type primn =
284288
type constant =
285289
| MConstI32(int32)
286290
| MConstI64(int64)
291+
| MConstU32(int32)
292+
| MConstU64(int64)
287293
| MConstF32(float)
288294
| MConstF64(float)
289295
| MConstLiteral(constant); /* Special case for things which should not be encoded */
@@ -322,6 +328,8 @@ type allocation_type =
322328
| MChar(string)
323329
| MInt32(int32)
324330
| MInt64(int64)
331+
| MUint32(int32)
332+
| MUint64(int64)
325333
| MFloat32(float)
326334
| MFloat64(float)
327335
| MRational({

compiler/src/codegen/transl_anf.re

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,8 @@ let compile_const = (c: Asttypes.constant) =>
529529
| Const_bigint(_) => failwith("compile_const: Const_bigint post-ANF")
530530
| Const_int32(i32) => MConstI32(i32)
531531
| Const_int64(i64) => MConstI64(i64)
532+
| Const_uint32(u32) => MConstU32(u32)
533+
| Const_uint64(u64) => MConstU64(u64)
532534
| Const_float32(f) => MConstF32(f)
533535
| Const_float64(f) => MConstF64(f)
534536
| Const_wasmi32(i32) => MConstLiteral(MConstI32(i32))
@@ -890,6 +892,8 @@ let rec compile_comp = (~id=?, env, c) => {
890892
)
891893
| CInt32(i) => MAllocate(MInt32(i))
892894
| CInt64(i) => MAllocate(MInt64(i))
895+
| CUint32(i) => MAllocate(MUint32(i))
896+
| CUint64(i) => MAllocate(MUint64(i))
893897
| CFloat32(f) => MAllocate(MFloat32(f))
894898
| CFloat64(f) => MAllocate(MFloat64(f))
895899
| CGetTupleItem(idx, tup) =>

compiler/src/codegen/value_tags.re

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ type heap_tag_type =
1010
| BoxedNumberType
1111
| LambdaType
1212
| TupleType
13-
| BytesType;
13+
| BytesType
14+
| Uint32Type
15+
| Uint64Type;
1416

1517
let tag_val_of_heap_tag_type =
1618
fun
@@ -21,7 +23,9 @@ let tag_val_of_heap_tag_type =
2123
| BoxedNumberType => 5
2224
| LambdaType => 6
2325
| TupleType => 7
24-
| BytesType => 8;
26+
| BytesType => 8
27+
| Uint32Type => 9
28+
| Uint64Type => 10;
2529

2630
let heap_tag_type_of_tag_val =
2731
fun
@@ -33,6 +37,8 @@ let heap_tag_type_of_tag_val =
3337
| 6 => LambdaType
3438
| 7 => TupleType
3539
| 8 => BytesType
40+
| 9 => Uint32Type
41+
| 10 => Uint64Type
3642
| x => failwith(Printf.sprintf("Unknown tag type: %d", x));
3743

3844
[@deriving sexp]

compiler/src/middle_end/analyze_free_vars.re

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ module FreeVarsArg: Anf_iterator.IterArgument = {
131131
| CNumber(_)
132132
| CInt32(_)
133133
| CInt64(_)
134+
| CUint32(_)
135+
| CUint64(_)
134136
| CFloat32(_)
135137
| CFloat64(_)
136138
| CBytes(_)

compiler/src/middle_end/analyze_purity.re

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@ module PurityArg: Anf_iterator.IterArgument = {
4141
| CImmExpr({imm_desc: ImmTrap}) => false
4242
| CImmExpr(_) => true
4343
| CPrim0(
44-
AllocateInt32 | AllocateInt64 | AllocateFloat32 | AllocateFloat64 |
44+
AllocateInt32 | AllocateInt64 | AllocateUint32 | AllocateUint64 |
45+
AllocateFloat32 |
46+
AllocateFloat64 |
4547
AllocateRational,
4648
) =>
4749
true
@@ -51,6 +53,8 @@ module PurityArg: Anf_iterator.IterArgument = {
5153
BuiltinId |
5254
NewInt32 |
5355
NewInt64 |
56+
NewUint32 |
57+
NewUint64 |
5458
NewFloat32 |
5559
NewFloat64 |
5660
LoadAdtVariant |
@@ -137,6 +141,8 @@ module PurityArg: Anf_iterator.IterArgument = {
137141
| CNumber(_)
138142
| CInt32(_)
139143
| CInt64(_)
144+
| CUint32(_)
145+
| CUint64(_)
140146
| CFloat32(_)
141147
| CFloat64(_)
142148
| CBytes(_)

compiler/src/middle_end/analyze_tail_calls.re

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ let rec analyze_comp_expression =
8080
| CNumber(_)
8181
| CInt32(_)
8282
| CInt64(_)
83+
| CUint32(_)
84+
| CUint64(_)
8385
| CFloat32(_)
8486
| CFloat64(_)
8587
| CPrim0(_)

compiler/src/middle_end/anf_helper.re

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ module Comp = {
4949
mk(~loc?, ~attributes?, ~allocation_type=Managed, ~env?, CInt32(i));
5050
let int64 = (~loc=?, ~attributes=?, ~env=?, i) =>
5151
mk(~loc?, ~attributes?, ~allocation_type=Managed, ~env?, CInt64(i));
52+
let uint32 = (~loc=?, ~attributes=?, ~env=?, i) =>
53+
mk(~loc?, ~attributes?, ~allocation_type=Managed, ~env?, CUint32(i));
54+
let uint64 = (~loc=?, ~attributes=?, ~env=?, i) =>
55+
mk(~loc?, ~attributes?, ~allocation_type=Managed, ~env?, CUint64(i));
5256
let float32 = (~loc=?, ~attributes=?, ~env=?, i) =>
5357
mk(~loc?, ~attributes?, ~allocation_type=Managed, ~env?, CFloat32(i));
5458
let float64 = (~loc=?, ~attributes=?, ~env=?, i) =>

compiler/src/middle_end/anf_helper.rei

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,12 @@ module Comp: {
4949
let int64:
5050
(~loc: loc=?, ~attributes: attributes=?, ~env: env=?, int64) =>
5151
comp_expression;
52+
let uint32:
53+
(~loc: loc=?, ~attributes: attributes=?, ~env: env=?, int32) =>
54+
comp_expression;
55+
let uint64:
56+
(~loc: loc=?, ~attributes: attributes=?, ~env: env=?, int64) =>
57+
comp_expression;
5258
let float32:
5359
(~loc: loc=?, ~attributes: attributes=?, ~env: env=?, float) =>
5460
comp_expression;

0 commit comments

Comments
 (0)