diff --git a/ml-proto/spec/check.ml b/ml-proto/spec/check.ml index 03a4ba155e..a339dd58cf 100644 --- a/ml-proto/spec/check.ml +++ b/ml-proto/spec/check.ml @@ -216,18 +216,18 @@ let rec check_expr c et e = check_type None et e.at | Load (memop, e1) -> - check_load c et memop e1 e.at + check_load c et memop (size memop.ty) e1 e.at | Store (memop, e1, e2) -> - check_store c et memop e1 e2 e.at + check_store c et memop (size memop.ty) e1 e2 e.at | LoadExtend (extendop, e1) -> check_mem_type extendop.memop.ty extendop.sz e.at; - check_load c et extendop.memop e1 e.at + check_load c et extendop.memop (Memory.mem_size extendop.sz) e1 e.at | StoreWrap (wrapop, e1, e2) -> check_mem_type wrapop.memop.ty wrapop.sz e.at; - check_store c et wrapop.memop e1 e2 e.at + check_store c et wrapop.memop (Memory.mem_size wrapop.sz) e1 e2 e.at | Const v -> check_literal c et v @@ -279,24 +279,24 @@ and check_expr_opt c et eo at = and check_literal c et l = check_type (Some (type_value l.it)) et l.at -and check_load c et memop e1 at = +and check_load c et memop mem_size e1 at = ignore (memory c at); - check_memop memop at; + check_memop memop mem_size at; check_expr c (some Int32Type) e1; check_type (Some memop.ty) et at -and check_store c et memop e1 e2 at = +and check_store c et memop mem_size e1 e2 at = ignore (memory c at); - check_memop memop at; + check_memop memop mem_size at; check_expr c (some Int32Type) e1; check_expr c (some memop.ty) e2; check_type None et at -and check_memop memop at = +and check_memop memop mem_size at = require (memop.offset >= 0L) at "negative offset"; require (memop.offset <= 0xffffffffL) at "offset too large"; require (Lib.Int.is_power_of_two memop.align) at "alignment must be a power of two"; - require (memop.align <= size memop.ty) at "alignment must not be larger than natural" + require (memop.align <= mem_size) at "alignment must not be larger than natural" and check_mem_type ty sz at = require (ty = Int64Type || sz <> Memory.Mem32) at "memory size too big" diff --git a/ml-proto/spec/memory.ml b/ml-proto/spec/memory.ml index 0cf43e3107..536638f241 100644 --- a/ml-proto/spec/memory.ml +++ b/ml-proto/spec/memory.ml @@ -24,6 +24,11 @@ exception OutOfMemory let page_size = 0x10000L (* 64 KiB *) +let mem_size = function + | Mem8 -> 1 + | Mem16 -> 2 + | Mem32 -> 4 + (* * These limitations should be considered part of the host environment and not * part of the spec defined by this file. diff --git a/ml-proto/spec/memory.mli b/ml-proto/spec/memory.mli index 988637e9f6..b0695ed936 100644 --- a/ml-proto/spec/memory.mli +++ b/ml-proto/spec/memory.mli @@ -19,6 +19,8 @@ exception OutOfMemory val page_size : offset +val mem_size : mem_size -> int + val create : size -> size option -> memory (* raise SizeOverflow, OutOfMemory *) val size : memory -> size val grow : memory -> size -> unit (* raise SizeOverflow, OutOfMemory *) diff --git a/ml-proto/test/memory.wast b/ml-proto/test/memory.wast index 1170ade959..dbf6335976 100644 --- a/ml-proto/test/memory.wast +++ b/ml-proto/test/memory.wast @@ -85,8 +85,8 @@ ) ;; Test alignment annotation rules -(module (memory 0) (func (drop (i32.load8_u align=2 (i32.const 0))))) -(module (memory 0) (func (drop (i32.load16_u align=4 (i32.const 0))))) +(module (memory 0) (func (drop (i32.load8_u align=1 (i32.const 0))))) +(module (memory 0) (func (drop (i32.load16_u align=2 (i32.const 0))))) (module (memory 0) (func (drop (i32.load align=4 (i32.const 0))))) (module (memory 0) (func (drop (f32.load align=4 (i32.const 0))))) @@ -112,15 +112,27 @@ ) (assert_invalid - (module (memory 0) (func (i64.load align=16 (i32.const 0)))) + (module (memory 0) (func (drop (i64.load align=16 (i32.const 0))))) "alignment must not be larger than natural" ) (assert_invalid - (module (memory 0) (func (i64.load align=32 (i32.const 0)))) + (module (memory 0) (func (drop (i64.load align=32 (i32.const 0))))) "alignment must not be larger than natural" ) (assert_invalid - (module (memory 0) (func (i32.load align=8 (i32.const 0)))) + (module (memory 0) (func (drop (i32.load align=8 (i32.const 0))))) + "alignment must not be larger than natural" +) +(assert_invalid + (module (memory 0) (func (drop (i32.load16_u align=4 (i32.const 0))))) + "alignment must not be larger than natural" +) +(assert_invalid + (module (memory 0) (func (drop (i32.load8_u align=2 (i32.const 0))))) + "alignment must not be larger than natural" +) +(assert_invalid + (module (memory 0) (func (i32.store8 align=2 (i32.const 0) (i32.const 0)))) "alignment must not be larger than natural" )