From e9f5ada2419763cf985ed7079e3c856bef399712 Mon Sep 17 00:00:00 2001 From: Andrew Scheidecker Date: Mon, 22 Aug 2016 07:38:46 -0400 Subject: [PATCH] Use the stored size as the natural alignment for memory operations, rather than the size of the value (4 or 8 bytes). --- ml-proto/spec/check.ml | 20 ++++++++++---------- ml-proto/spec/memory.ml | 5 +++++ ml-proto/spec/memory.mli | 2 ++ ml-proto/test/memory.wast | 16 ++++++++++++++-- 4 files changed, 31 insertions(+), 12 deletions(-) diff --git a/ml-proto/spec/check.ml b/ml-proto/spec/check.ml index abef23d65b..e4592c6398 100644 --- a/ml-proto/spec/check.ml +++ b/ml-proto/spec/check.ml @@ -175,18 +175,18 @@ let rec check_expr c et e = check_type (Some t) 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 @@ -237,15 +237,15 @@ 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 = check_has_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 = check_has_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 (Some memop.ty) et at @@ -253,11 +253,11 @@ and check_store c et memop e1 e2 at = and check_has_memory c at = require c.has_memory at "memory operators require a memory section" -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 4f6e75f8d5..6b4797b5d6 100644 --- a/ml-proto/spec/memory.ml +++ b/ml-proto/spec/memory.ml @@ -21,6 +21,11 @@ exception SizeOverflow 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 2e60e8eb66..15ceefd43a 100644 --- a/ml-proto/spec/memory.mli +++ b/ml-proto/spec/memory.mli @@ -15,6 +15,8 @@ exception SizeOverflow val page_size : size +val mem_size : mem_size -> int + val create : size -> memory val init : memory -> segment list -> unit val size : memory -> size diff --git a/ml-proto/test/memory.wast b/ml-proto/test/memory.wast index def709ba25..50c34427e9 100644 --- a/ml-proto/test/memory.wast +++ b/ml-proto/test/memory.wast @@ -46,8 +46,8 @@ ) ;; Test alignment annotation rules -(module (memory 0) (func (i32.load8_u align=2 (i32.const 0)))) -(module (memory 0) (func (i32.load16_u align=4 (i32.const 0)))) +(module (memory 0) (func (i32.load8_u align=1 (i32.const 0)))) +(module (memory 0) (func (i32.load16_u align=2 (i32.const 0)))) (module (memory 0) (func (i32.load align=4 (i32.const 0)))) (module (memory 0) (func (f32.load align=4 (i32.const 0)))) @@ -84,6 +84,18 @@ (module (memory 0) (func (i32.load align=8 (i32.const 0)))) "alignment must not be larger than natural" ) +(assert_invalid + (module (memory 0) (func (i32.load16_u align=4 (i32.const 0)))) + "alignment must not be larger than natural" +) +(assert_invalid + (module (memory 0) (func (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" +) (module (memory 1 (segment 0 "ABC\a7D") (segment 20 "WASM"))