From d0152ffdf368e6e379593553a55e89f5364b6f0d Mon Sep 17 00:00:00 2001 From: Gabor Greif Date: Mon, 18 Mar 2019 17:24:49 +0100 Subject: [PATCH 1/4] AST-32: hashing of Int --- src/compile.ml | 5 +++++ src/prelude.ml | 8 ++++++++ test/run/hashes.as | 4 ++++ 3 files changed, 17 insertions(+) create mode 100644 test/run/hashes.as diff --git a/src/compile.ml b/src/compile.ml index 3febadc7e38..d9d81f1612a 100644 --- a/src/compile.ml +++ b/src/compile.ml @@ -3782,6 +3782,11 @@ and compile_exp (env : E.t) exp = compile_unboxed_const 8l ^^ G.i (Binary (Wasm.Values.I32 I32Op.Shl)) + | "Int~hash" -> + SR.UnboxedWord32, + compile_exp_as env SR.UnboxedInt64 e ^^ + Prim.prim_intToWord32 + | "popcnt" -> SR.UnboxedWord32, compile_exp_as env SR.UnboxedWord32 e ^^ diff --git a/src/prelude.ml b/src/prelude.ml index 2de8f86c42a..44e9dbbec8c 100644 --- a/src/prelude.ml +++ b/src/prelude.ml @@ -34,6 +34,10 @@ class revrange(x : Nat, y : Nat) { func printInt(x : Int) { (prim "printInt" : Int -> ()) x }; func print(x : Text) { (prim "print" : Text -> ()) x }; +// Hashing +func hashInt(n : Int) : Word32 = (prim "Int~hash" : Int -> Word32) n; + + // Conversions func natToWord8(n : Nat) : Word8 = (prim "Nat->Word8" : Nat -> Word8) n; func word8ToNat(n : Word8) : Nat = (prim "Word8->Nat" : Word8 -> Nat) n; @@ -138,6 +142,10 @@ end (* Conv *) let prim = function | "abs" -> fun v k -> k (Int (Nat.abs (as_int v))) + | "Int~hash" -> fun v k -> + let i = Word64.of_int_u (Big_int.int_of_big_int (as_int v)) in + let j = Word64.(and_ 0xFFFFFFFFL (xor (shr_u i 32L) i)) + in k (Word32 (Word32.of_int_u (Int64.to_int j))) | "Nat->Word8" -> fun v k -> let i = Big_int.int_of_big_int (as_int v) in k (Word8 (Word8.of_int_u i)) diff --git a/test/run/hashes.as b/test/run/hashes.as new file mode 100644 index 00000000000..bb528cd36d8 --- /dev/null +++ b/test/run/hashes.as @@ -0,0 +1,4 @@ + +assert (hashInt (10**7) == (10000000 : Word32)); +assert (hashInt 0 == (0 : Word32)); +assert (hashInt (10**18) == (2_860_824_243 : Word32)); From e2ae8f67956931f21afbff26fe1ef7c6eb86f006 Mon Sep 17 00:00:00 2001 From: Gabor Greif Date: Mon, 18 Mar 2019 17:41:39 +0100 Subject: [PATCH 2/4] define and use prim_hashInt --- src/compile.ml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/compile.ml b/src/compile.ml index d9d81f1612a..f5f688c5f81 100644 --- a/src/compile.ml +++ b/src/compile.ml @@ -1440,6 +1440,12 @@ module Prim = struct let prim_shiftToWordN b = prim_intToWord32 ^^ UnboxedSmallWord.shift_leftWordNtoI32 b + let prim_hashInt env = + let (set_n, get_n) = new_local64 env "n" in + set_n ^^ + get_n ^^ get_n ^^ compile_const_64 32L ^^ G.i (Binary (Wasm.Values.I64 I64Op.ShrU)) ^^ + G.i (Binary (Wasm.Values.I64 I64Op.Xor)) ^^ + prim_intToWord32 end (* Prim *) module Object = struct @@ -3785,7 +3791,7 @@ and compile_exp (env : E.t) exp = | "Int~hash" -> SR.UnboxedWord32, compile_exp_as env SR.UnboxedInt64 e ^^ - Prim.prim_intToWord32 + Prim.prim_hashInt env | "popcnt" -> SR.UnboxedWord32, From efe340fb0b770c48c3a252e4331cd344512f013c Mon Sep 17 00:00:00 2001 From: Gabor Greif Date: Mon, 18 Mar 2019 22:32:33 +0100 Subject: [PATCH 3/4] fix interpreter and add negative test points --- src/prelude.ml | 2 +- test/run/hashes.as | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/prelude.ml b/src/prelude.ml index 44e9dbbec8c..e343f5545f2 100644 --- a/src/prelude.ml +++ b/src/prelude.ml @@ -143,7 +143,7 @@ let prim = function | "abs" -> fun v k -> k (Int (Nat.abs (as_int v))) | "Int~hash" -> fun v k -> - let i = Word64.of_int_u (Big_int.int_of_big_int (as_int v)) in + let i = Word64.of_int_s (Big_int.int_of_big_int (as_int v)) in let j = Word64.(and_ 0xFFFFFFFFL (xor (shr_u i 32L) i)) in k (Word32 (Word32.of_int_u (Int64.to_int j))) | "Nat->Word8" -> fun v k -> diff --git a/test/run/hashes.as b/test/run/hashes.as index bb528cd36d8..eed93e35d45 100644 --- a/test/run/hashes.as +++ b/test/run/hashes.as @@ -2,3 +2,7 @@ assert (hashInt (10**7) == (10000000 : Word32)); assert (hashInt 0 == (0 : Word32)); assert (hashInt (10**18) == (2_860_824_243 : Word32)); + +assert (hashInt (-1) == (0 : Word32)); +assert (hashInt (-387) == (386 : Word32)); +assert (hashInt (-3876548352991) == (2_487_851_096 : Word32)); From 76e1cf18c80db89ada75ab67305696d9de63a754 Mon Sep 17 00:00:00 2001 From: Gabor Greif Date: Mon, 18 Mar 2019 22:41:00 +0100 Subject: [PATCH 4/4] accept --- test/run-dfinity/ok/counter-class.wasm.stderr.ok | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/run-dfinity/ok/counter-class.wasm.stderr.ok b/test/run-dfinity/ok/counter-class.wasm.stderr.ok index cb1f1836617..306445d241a 100644 --- a/test/run-dfinity/ok/counter-class.wasm.stderr.ok +++ b/test/run-dfinity/ok/counter-class.wasm.stderr.ok @@ -18,31 +18,31 @@ non-closed actor: (ActorE (FuncE read (shared 1 -> 0) - (params $68) + (params $69) () (BlockE (LetD - (TupP (VarP $66)) - (TupE (CallE ( 1 -> 1) (PrimE @deserialize) (VarE $68))) + (TupP (VarP $67)) + (TupE (CallE ( 1 -> 1) (PrimE @deserialize) (VarE $69))) ) (CallE ( 1 -> 0) (FuncE $lambda ( 1 -> 0) - (params $65) + (params $66) () - (CallE ( 1 -> 0) (VarE $65) (VarE c)) + (CallE ( 1 -> 0) (VarE $66) (VarE c)) ) (FuncE $lambda ( 1 -> 0) - (params $67) + (params $68) () (CallE (shared 1 -> 0) - (VarE $66) - (CallE ( 1 -> 1) (PrimE @serialize) (VarE $67)) + (VarE $67) + (CallE ( 1 -> 1) (PrimE @serialize) (VarE $68)) ) ) )