diff --git a/ml-proto/src/check.ml b/ml-proto/src/check.ml index 616ff4987d..666137532e 100644 --- a/ml-proto/src/check.ml +++ b/ml-proto/src/check.ml @@ -271,9 +271,14 @@ let check_table c tab = List.iter (fun xI -> check_func_type (func c xI) s xI.at) xs; {c with tables = c.tables @ [s]} -let check_export c ex = - let {name = _; func = x} = ex.it in - ignore (func c x) +module NameSet = Set.Make(String) + +let check_export c set ex = + let {name; func = x} = ex.it in + ignore (func c x); + require (not (NameSet.mem name set)) ex.at + "duplicate export name"; + NameSet.add name set let check_segment size prev_end seg = let seg_end = seg.it.Memory.addr + String.length seg.it.Memory.data in @@ -295,4 +300,4 @@ let check_module m = globals = List.map it globals} in let c' = List.fold_left check_table c tables in List.iter (check_func c') funcs; - List.iter (check_export c') exports + ignore (List.fold_left (check_export c') NameSet.empty exports) diff --git a/ml-proto/test/basic.wasm b/ml-proto/test/basic.wasm deleted file mode 100644 index 180b9ec22b..0000000000 --- a/ml-proto/test/basic.wasm +++ /dev/null @@ -1,9 +0,0 @@ -(module - (func $f (param $n i32) (result i32) - (return (add.i32 (getlocal $n) (const.i32 1))) - ) - - (export "e" $f) -) - -(asserteq (invoke "e" (const.i32 42)) (const.i32 43)) diff --git a/ml-proto/test/exports.wasm b/ml-proto/test/exports.wasm new file mode 100644 index 0000000000..620fb01008 --- /dev/null +++ b/ml-proto/test/exports.wasm @@ -0,0 +1,22 @@ +(module (func (const.i32 1)) (export "a" 0)) +(module (func (const.i32 1)) (export "a" 0) (export "b" 0)) +(module (func (const.i32 1)) (func (const.i32 2)) (export "a" 0) (export "b" 1)) +(invalid + (module (func (const.i32 1)) (export "a" 1)) + "unknown function 1") +(invalid + (module (func (const.i32 1)) (func (const.i32 2)) (export "a" 0) (export "a" 1)) + "duplicate export name") +(invalid + (module (func (const.i32 1)) (export "a" 0) (export "a" 0)) + "duplicate export name") + +(module + (func $f (param $n i32) (result i32) + (return (add.i32 (getlocal $n) (const.i32 1))) + ) + + (export "e" $f) +) + +(asserteq (invoke "e" (const.i32 42)) (const.i32 43))