Skip to content

Commit

Permalink
feat(compiler)!: Add Uint32 and Uint64 types (#1531)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
alex-snezhko committed Feb 13, 2023
1 parent 86b092c commit 42ffdc4
Show file tree
Hide file tree
Showing 80 changed files with 3,923 additions and 787 deletions.
6 changes: 6 additions & 0 deletions compiler/src/codegen/comp_utils.re
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,22 @@ let rec compile_const = (c): Literal.t => {
let identity: 'a. 'a => 'a = x => x;
let conv_int32 = n => Int32.(add(mul(2l, n), 1l));
let conv_int64 = n => Int64.(add(mul(2L, n), 1L));
let conv_uint32 = n => Int32.(add(mul(2l, n), 1l));
let conv_uint64 = n => Int64.(add(mul(2L, n), 1L));
let conv_float32 = identity;
let conv_float64 = identity;
switch (c) {
| MConstLiteral(MConstLiteral(_) as c) => compile_const(c)
| MConstI32(n) => Literal.int32(conv_int32(n))
| MConstI64(n) => Literal.int64(conv_int64(n))
| MConstU32(n) => Literal.int32(conv_uint32(n))
| MConstU64(n) => Literal.int64(conv_uint64(n))
| MConstF32(n) => Literal.float32(conv_float32(n))
| MConstF64(n) => Literal.float64(conv_float64(n))
| MConstLiteral(MConstI32(n)) => Literal.int32(n)
| MConstLiteral(MConstI64(n)) => Literal.int64(n)
| MConstLiteral(MConstU32(n)) => Literal.int32(n)
| MConstLiteral(MConstU64(n)) => Literal.int64(n)
| MConstLiteral(MConstF32(n)) => Literal.float32(n)
| MConstLiteral(MConstF64(n)) => Literal.float64(n)
};
Expand Down
104 changes: 104 additions & 0 deletions compiler/src/codegen/compcore.re
Original file line number Diff line number Diff line change
Expand Up @@ -2047,6 +2047,94 @@ let allocate_record = (wasm_mod, env, ttag, elts) => {
);
};

let allocate_uint_uninitialized = (wasm_mod, env, is_32_bit) => {
let get_swap = () => get_swap(wasm_mod, env, 0);
let make_alloc = () =>
heap_allocate(wasm_mod, env, if (is_32_bit) {2} else {4});

let (tag, label) =
if (is_32_bit) {
(Uint32Type, "allocate_unitialized_uint32");
} else {
(Uint64Type, "allocate_unitialized_uint64");
};

let preamble = [
store(
~offset=0,
wasm_mod,
tee_swap(~skip_incref=true, wasm_mod, env, 0, make_alloc()),
Expression.Const.make(
wasm_mod,
const_int32(tag_val_of_heap_tag_type(tag)),
),
),
];
let postamble = [get_swap()];
Expression.Block.make(
wasm_mod,
gensym_label(label),
List.concat([preamble, postamble]),
);
};

type alloc_uint_type =
| Uint32(Expression.t)
| Uint64(Expression.t);

let allocate_uint = (wasm_mod, env, uint_value) => {
let get_swap = () => get_swap(wasm_mod, env, 0);

let (tag, instrs, needed_words, label) =
switch (uint_value) {
| Uint32(uint32) => (
Uint32Type,
[store(~offset=4, ~ty=Type.int32, wasm_mod, get_swap(), uint32)],
2,
"allocate_uint32",
)
| Uint64(uint64) => (
Uint64Type,
[store(~offset=8, ~ty=Type.int64, wasm_mod, get_swap(), uint64)],
// Allocate 4 words to store with 8-byte alignment
4,
"allocate_uint64",
)
};

let preamble = [
store(
~offset=0,
wasm_mod,
tee_swap(
~skip_incref=true,
wasm_mod,
env,
0,
heap_allocate(wasm_mod, env, needed_words),
),
Expression.Const.make(
wasm_mod,
const_int32(tag_val_of_heap_tag_type(tag)),
),
),
];
let postamble = [get_swap()];
Expression.Block.make(
wasm_mod,
gensym_label(label),
List.concat([preamble, instrs, postamble]),
);
};

let allocate_uint32 = (wasm_mod, env, i) => {
allocate_uint(wasm_mod, env, Uint32(i));
};

let allocate_uint64 = (wasm_mod, env, i) => {
allocate_uint(wasm_mod, env, Uint64(i));
};

type alloc_number_type =
| Int32(Expression.t)
| Int64(Expression.t)
Expand Down Expand Up @@ -2289,6 +2377,8 @@ let compile_prim0 = (wasm_mod, env, p0): Expression.t => {
allocate_number_uninitialized(wasm_mod, env, BoxedFloat64)
| AllocateRational =>
allocate_number_uninitialized(wasm_mod, env, BoxedRational)
| AllocateUint32 => allocate_uint_uninitialized(wasm_mod, env, true)
| AllocateUint64 => allocate_uint_uninitialized(wasm_mod, env, false)
| Unreachable => Expression.Unreachable.make(wasm_mod)
};
};
Expand All @@ -2312,6 +2402,8 @@ let compile_prim1 = (wasm_mod, env, p1, arg, loc): Expression.t => {
| NewInt64 => allocate_number(wasm_mod, env, Int64(compiled_arg))
| NewFloat32 => allocate_number(wasm_mod, env, Float32(compiled_arg))
| NewFloat64 => allocate_number(wasm_mod, env, Float64(compiled_arg))
| NewUint32 => allocate_uint(wasm_mod, env, Uint32(compiled_arg))
| NewUint64 => allocate_uint(wasm_mod, env, Uint64(compiled_arg))
| LoadAdtVariant => load(~offset=12, wasm_mod, compiled_arg)
| StringSize
| BytesSize => load(~offset=4, wasm_mod, compiled_arg)
Expand Down Expand Up @@ -2724,6 +2816,18 @@ let compile_allocation = (wasm_mod, env, alloc_type) =>
env,
Expression.Const.make(wasm_mod, Literal.int64(i)),
)
| MUint32(i) =>
allocate_uint32(
wasm_mod,
env,
Expression.Const.make(wasm_mod, Literal.int32(i)),
)
| MUint64(i) =>
allocate_uint64(
wasm_mod,
env,
Expression.Const.make(wasm_mod, Literal.int64(i)),
)
| MFloat32(i) =>
allocate_float32(
wasm_mod,
Expand Down
8 changes: 8 additions & 0 deletions compiler/src/codegen/mashtree.re
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ type prim0 =
Parsetree.prim0 =
| AllocateInt32
| AllocateInt64
| AllocateUint32
| AllocateUint64
| AllocateFloat32
| AllocateFloat64
| AllocateRational
Expand All @@ -188,6 +190,8 @@ type prim1 =
| AllocateBigInt
| NewInt32
| NewInt64
| NewUint32
| NewUint64
| NewFloat32
| NewFloat64
| BuiltinId
Expand Down Expand Up @@ -284,6 +288,8 @@ type primn =
type constant =
| MConstI32(int32)
| MConstI64(int64)
| MConstU32(int32)
| MConstU64(int64)
| MConstF32(float)
| MConstF64(float)
| MConstLiteral(constant); /* Special case for things which should not be encoded */
Expand Down Expand Up @@ -322,6 +328,8 @@ type allocation_type =
| MChar(string)
| MInt32(int32)
| MInt64(int64)
| MUint32(int32)
| MUint64(int64)
| MFloat32(float)
| MFloat64(float)
| MRational({
Expand Down
4 changes: 4 additions & 0 deletions compiler/src/codegen/transl_anf.re
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,8 @@ let compile_const = (c: Asttypes.constant) =>
| Const_bigint(_) => failwith("compile_const: Const_bigint post-ANF")
| Const_int32(i32) => MConstI32(i32)
| Const_int64(i64) => MConstI64(i64)
| Const_uint32(u32) => MConstU32(u32)
| Const_uint64(u64) => MConstU64(u64)
| Const_float32(f) => MConstF32(f)
| Const_float64(f) => MConstF64(f)
| Const_wasmi32(i32) => MConstLiteral(MConstI32(i32))
Expand Down Expand Up @@ -890,6 +892,8 @@ let rec compile_comp = (~id=?, env, c) => {
)
| CInt32(i) => MAllocate(MInt32(i))
| CInt64(i) => MAllocate(MInt64(i))
| CUint32(i) => MAllocate(MUint32(i))
| CUint64(i) => MAllocate(MUint64(i))
| CFloat32(f) => MAllocate(MFloat32(f))
| CFloat64(f) => MAllocate(MFloat64(f))
| CGetTupleItem(idx, tup) =>
Expand Down
10 changes: 8 additions & 2 deletions compiler/src/codegen/value_tags.re
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ type heap_tag_type =
| BoxedNumberType
| LambdaType
| TupleType
| BytesType;
| BytesType
| Uint32Type
| Uint64Type;

let tag_val_of_heap_tag_type =
fun
Expand All @@ -21,7 +23,9 @@ let tag_val_of_heap_tag_type =
| BoxedNumberType => 5
| LambdaType => 6
| TupleType => 7
| BytesType => 8;
| BytesType => 8
| Uint32Type => 9
| Uint64Type => 10;

let heap_tag_type_of_tag_val =
fun
Expand All @@ -33,6 +37,8 @@ let heap_tag_type_of_tag_val =
| 6 => LambdaType
| 7 => TupleType
| 8 => BytesType
| 9 => Uint32Type
| 10 => Uint64Type
| x => failwith(Printf.sprintf("Unknown tag type: %d", x));

[@deriving sexp]
Expand Down
2 changes: 2 additions & 0 deletions compiler/src/middle_end/analyze_free_vars.re
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ module FreeVarsArg: Anf_iterator.IterArgument = {
| CNumber(_)
| CInt32(_)
| CInt64(_)
| CUint32(_)
| CUint64(_)
| CFloat32(_)
| CFloat64(_)
| CBytes(_)
Expand Down
8 changes: 7 additions & 1 deletion compiler/src/middle_end/analyze_purity.re
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ module PurityArg: Anf_iterator.IterArgument = {
| CImmExpr({imm_desc: ImmTrap}) => false
| CImmExpr(_) => true
| CPrim0(
AllocateInt32 | AllocateInt64 | AllocateFloat32 | AllocateFloat64 |
AllocateInt32 | AllocateInt64 | AllocateUint32 | AllocateUint64 |
AllocateFloat32 |
AllocateFloat64 |
AllocateRational,
) =>
true
Expand All @@ -51,6 +53,8 @@ module PurityArg: Anf_iterator.IterArgument = {
BuiltinId |
NewInt32 |
NewInt64 |
NewUint32 |
NewUint64 |
NewFloat32 |
NewFloat64 |
LoadAdtVariant |
Expand Down Expand Up @@ -137,6 +141,8 @@ module PurityArg: Anf_iterator.IterArgument = {
| CNumber(_)
| CInt32(_)
| CInt64(_)
| CUint32(_)
| CUint64(_)
| CFloat32(_)
| CFloat64(_)
| CBytes(_)
Expand Down
2 changes: 2 additions & 0 deletions compiler/src/middle_end/analyze_tail_calls.re
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ let rec analyze_comp_expression =
| CNumber(_)
| CInt32(_)
| CInt64(_)
| CUint32(_)
| CUint64(_)
| CFloat32(_)
| CFloat64(_)
| CPrim0(_)
Expand Down
4 changes: 4 additions & 0 deletions compiler/src/middle_end/anf_helper.re
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ module Comp = {
mk(~loc?, ~attributes?, ~allocation_type=Managed, ~env?, CInt32(i));
let int64 = (~loc=?, ~attributes=?, ~env=?, i) =>
mk(~loc?, ~attributes?, ~allocation_type=Managed, ~env?, CInt64(i));
let uint32 = (~loc=?, ~attributes=?, ~env=?, i) =>
mk(~loc?, ~attributes?, ~allocation_type=Managed, ~env?, CUint32(i));
let uint64 = (~loc=?, ~attributes=?, ~env=?, i) =>
mk(~loc?, ~attributes?, ~allocation_type=Managed, ~env?, CUint64(i));
let float32 = (~loc=?, ~attributes=?, ~env=?, i) =>
mk(~loc?, ~attributes?, ~allocation_type=Managed, ~env?, CFloat32(i));
let float64 = (~loc=?, ~attributes=?, ~env=?, i) =>
Expand Down
6 changes: 6 additions & 0 deletions compiler/src/middle_end/anf_helper.rei
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ module Comp: {
let int64:
(~loc: loc=?, ~attributes: attributes=?, ~env: env=?, int64) =>
comp_expression;
let uint32:
(~loc: loc=?, ~attributes: attributes=?, ~env: env=?, int32) =>
comp_expression;
let uint64:
(~loc: loc=?, ~attributes: attributes=?, ~env: env=?, int64) =>
comp_expression;
let float32:
(~loc: loc=?, ~attributes: attributes=?, ~env: env=?, float) =>
comp_expression;
Expand Down
2 changes: 2 additions & 0 deletions compiler/src/middle_end/anf_iterator.re
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ module MakeIter = (Iter: IterArgument) => {
| CNumber(i) => ()
| CInt32(i) => ()
| CInt64(i) => ()
| CUint32(i) => ()
| CUint64(i) => ()
| CFloat32(f) => ()
| CFloat64(f) => ()
};
Expand Down
2 changes: 2 additions & 0 deletions compiler/src/middle_end/anf_mapper.re
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,8 @@ module MakeMap = (Iter: MapArgument) => {
| CNumber(i) => leave_with(CNumber(i))
| CInt32(i) => leave_with(CInt32(i))
| CInt64(i) => leave_with(CInt64(i))
| CUint32(i) => leave_with(CUint32(i))
| CUint64(i) => leave_with(CUint64(i))
| CFloat32(f) => leave_with(CFloat32(f))
| CFloat64(f) => leave_with(CFloat64(f))
};
Expand Down
6 changes: 6 additions & 0 deletions compiler/src/middle_end/anftree.re
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@ type prim0 =
Parsetree.prim0 =
| AllocateInt32
| AllocateInt64
| AllocateUint32
| AllocateUint64
| AllocateFloat32
| AllocateFloat64
| AllocateRational
Expand All @@ -174,6 +176,8 @@ type prim1 =
| AllocateBigInt
| NewInt32
| NewInt64
| NewUint32
| NewUint64
| NewFloat32
| NewFloat64
| BuiltinId
Expand Down Expand Up @@ -360,6 +364,8 @@ and comp_expression_desc =
| CNumber(Asttypes.number_type)
| CInt32(int32)
| CInt64(int64)
| CUint32(int32)
| CUint64(int64)
| CFloat32(float)
| CFloat64(float)

Expand Down
6 changes: 6 additions & 0 deletions compiler/src/middle_end/anftree.rei
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ type prim0 =
Parsetree.prim0 =
| AllocateInt32
| AllocateInt64
| AllocateUint32
| AllocateUint64
| AllocateFloat32
| AllocateFloat64
| AllocateRational
Expand All @@ -175,6 +177,8 @@ type prim1 =
| AllocateBigInt
| NewInt32
| NewInt64
| NewUint32
| NewUint64
| NewFloat32
| NewFloat64
| BuiltinId
Expand Down Expand Up @@ -340,6 +344,8 @@ and comp_expression_desc =
| CNumber(Asttypes.number_type)
| CInt32(int32)
| CInt64(int64)
| CUint32(int32)
| CUint64(int64)
| CFloat32(float)
| CFloat64(float)

Expand Down
8 changes: 8 additions & 0 deletions compiler/src/middle_end/linearize.re
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,14 @@ let transl_const =
Right(with_bind("int32", tmp => [BLet(tmp, Comp.int32(i), Nonglobal)]))
| Const_int64(i) =>
Right(with_bind("int64", tmp => [BLet(tmp, Comp.int64(i), Nonglobal)]))
| Const_uint32(i) =>
Right(
with_bind("uint32", tmp => [BLet(tmp, Comp.uint32(i), Nonglobal)]),
)
| Const_uint64(i) =>
Right(
with_bind("uint64", tmp => [BLet(tmp, Comp.uint64(i), Nonglobal)]),
)
| Const_float64(i) =>
Right(
with_bind("float64", tmp => [BLet(tmp, Comp.float64(i), Nonglobal)]),
Expand Down
Loading

0 comments on commit 42ffdc4

Please sign in to comment.