diff --git a/interpreter/binary/decode.ml b/interpreter/binary/decode.ml index 9577ec35a..25dc51a86 100644 --- a/interpreter/binary/decode.ml +++ b/interpreter/binary/decode.ml @@ -276,14 +276,22 @@ let rectype s = | _ -> RecT [subtype s] -let limits uN s = +let limits allow_pt uN s = let flags = byte s in - require (flags land 0xfa = 0) s (pos s - 1) "malformed limits flags"; + let mask = if allow_pt then 0xf2 else 0xfa in + require (flags land mask = 0) s (pos s - 1) "malformed limits flags"; let has_max = (flags land 1 = 1) in let at = if flags land 4 = 4 then I64AT else I32AT in let min = uN s in let max = opt uN has_max s in - at, {min; max} + let pt = + if allow_pt then + let has_paget = (flags land 8 = 8) in + Some (PageT (if has_paget then Int32.to_int (u32 s) else 16)) + else + None + in + at, {min; max}, pt let tagtype s = zero s; @@ -295,12 +303,12 @@ let globaltype s = GlobalT (mut, t) let memorytype s = - let at, lim = limits u64 s in - MemoryT (at, lim, PageT 16) (* TODO(custom-page-sizes) *) + let at, lim, pt = limits true u64 s in + MemoryT (at, lim, Option.get pt) let tabletype s = let t = reftype s in - let at, lim = limits u64 s in + let at, lim, _ = limits false u64 s in TableT (at, lim, t) let externtype s = diff --git a/interpreter/binary/encode.ml b/interpreter/binary/encode.ml index 651bee528..d9d06b507 100644 --- a/interpreter/binary/encode.ml +++ b/interpreter/binary/encode.ml @@ -183,9 +183,12 @@ struct | RecT [st] -> subtype st | RecT sts -> s7 (-0x32); vec subtype sts - let limits at {min; max} = - let flags = flag (max <> None) 0 + flag (at = I64AT) 2 in - byte flags; u64 min; opt u64 max + let limits allow_pt at {min; max} pt_opt = + let ps = match pt_opt with Some (PageT ps) -> ps | None -> 16 in + let flags = flag (max <> None) 0 + flag (at = I64AT) 2 + + (if allow_pt then flag (ps <> 16) 3 else 0) in + byte flags; u64 min; opt u64 max; + if allow_pt && ps <> 16 then u32 (Int32.of_int ps) let tagtype = function | TagT ut -> u32 0x00l; typeuse u32 ut @@ -194,10 +197,10 @@ struct | GlobalT (mut, t) -> valtype t; mutability mut let memorytype = function - | MemoryT (at, lim, pt) -> limits at lim (* TODO(custom-page-sizes) *) + | MemoryT (at, lim, pt) -> limits true at lim (Some pt) let tabletype = function - | TableT (at, lim, t) -> reftype t; limits at lim + | TableT (at, lim, t) -> reftype t; limits false at lim None let externtype = function | ExternFuncT ut -> byte 0x00; typeuse u32 ut diff --git a/test/core/binary.wast b/test/core/binary.wast index e328be360..4bac27a58 100644 --- a/test/core/binary.wast +++ b/test/core/binary.wast @@ -661,7 +661,7 @@ (module binary "\00asm" "\01\00\00\00" "\05\02\01" ;; memory section with one entry - "\08" ;; malformed memory limits flag + "\10" ;; malformed memory limits flag ) "malformed limits flags" ) diff --git a/test/core/custom-page-sizes/custom-page-sizes-invalid.wast b/test/core/custom-page-sizes/custom-page-sizes-invalid.wast index 480d385ba..47dce24b5 100644 --- a/test/core/custom-page-sizes/custom-page-sizes-invalid.wast +++ b/test/core/custom-page-sizes/custom-page-sizes-invalid.wast @@ -79,7 +79,7 @@ ;; Power of two page size that cannot fit in a u64 to exercise checks against ;; shift overflow. -(assert_malformed +(assert_invalid (module binary "\00asm" "\01\00\00\00" "\05\04\01" ;; Memory section @@ -104,12 +104,12 @@ (module (memory (import "m" "small-pages-memory") 0 (pagesize 65536)) ) - "memory types incompatible" + "incompatible import type" ) (assert_unlinkable (module (memory (import "m" "large-pages-memory") 0 (pagesize 1)) ) - "memory types incompatible" + "incompatible import type" )