From 5cc08ad0e7bc1b989cad555967b60ff92a7f3f61 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Thu, 2 May 2024 10:42:47 -0700 Subject: [PATCH] [table64] Fix validation rules for table.fill/copy/size/grow (#54) Also, add more tests. --- interpreter/syntax/types.ml | 2 + interpreter/valid/valid.ml | 25 +- test/core/table_copy.wast | 550 +++++++++++++++++++++++++++++++ test/core/table_fill.wast | 65 ++++ test/core/table_grow.wast | 33 ++ test/core/table_init.wast | 232 ++++++++++--- test/core/table_size.wast | 3 + test/meta/Makefile | 2 +- test/meta/generate_table_copy.js | 137 ++++---- test/meta/generate_table_init.js | 34 +- 10 files changed, 949 insertions(+), 134 deletions(-) diff --git a/interpreter/syntax/types.ml b/interpreter/syntax/types.ml index 9296c909f5..493ebde969 100644 --- a/interpreter/syntax/types.ml +++ b/interpreter/syntax/types.ml @@ -135,6 +135,8 @@ let string_of_value_types = function | [t] -> string_of_value_type t | ts -> "[" ^ String.concat " " (List.map string_of_value_type ts) ^ "]" +let string_of_index_type t = + string_of_value_type (value_type_of_index_type t) let string_of_limits to_string {min; max} = to_string min ^ diff --git a/interpreter/valid/valid.ml b/interpreter/valid/valid.ml index 291b9f4052..3122644817 100644 --- a/interpreter/valid/valid.ml +++ b/interpreter/valid/valid.ml @@ -326,32 +326,35 @@ let rec check_instr (c : context) (e : instr) (s : infer_result_type) : op_type [value_type_of_index_type it; RefType t] --> [] | TableSize x -> - let _tt = table c x in - [] --> [NumType I32Type] + let TableType (_lim, it, _t) = table c x in + [] --> [value_type_of_index_type it] | TableGrow x -> - let TableType (_lim, _it, t) = table c x in - [RefType t; NumType I32Type] --> [NumType I32Type] + let TableType (_lim, it, t) = table c x in + [RefType t; value_type_of_index_type it] --> [value_type_of_index_type it] | TableFill x -> - let TableType (_lim, _it, t) = table c x in - [NumType I32Type; RefType t; NumType I32Type] --> [] + let TableType (_lim, it, t) = table c x in + [value_type_of_index_type it; RefType t; value_type_of_index_type it] --> [] | TableCopy (x, y) -> - let TableType (_lim1, _it, t1) = table c x in - let TableType (_lim2, _it, t2) = table c y in + let TableType (_lim1, it1, t1) = table c x in + let TableType (_lim2, it2, t2) = table c y in require (t1 = t2) x.at ("type mismatch: source element type " ^ string_of_ref_type t1 ^ " does not match destination element type " ^ string_of_ref_type t2); - [NumType I32Type; NumType I32Type; NumType I32Type] --> [] + require (it1 = it2) x.at + ("type mismatch: source index type " ^ string_of_index_type it1 ^ + " does not match destination index type " ^ string_of_index_type it2); + [value_type_of_index_type it1; value_type_of_index_type it1; value_type_of_index_type it1] --> [] | TableInit (x, y) -> - let TableType (_lim1, _it, t1) = table c x in + let TableType (_lim, it, t1) = table c x in let t2 = elem c y in require (t1 = t2) x.at ("type mismatch: element segment's type " ^ string_of_ref_type t1 ^ " does not match table's element type " ^ string_of_ref_type t2); - [NumType I32Type; NumType I32Type; NumType I32Type] --> [] + [value_type_of_index_type it; NumType I32Type; NumType I32Type] --> [] | ElemDrop x -> ignore (elem c x); diff --git a/test/core/table_copy.wast b/test/core/table_copy.wast index 380e84ee59..613fc5295e 100644 --- a/test/core/table_copy.wast +++ b/test/core/table_copy.wast @@ -2218,6 +2218,556 @@ (assert_trap (invoke "test") "out of bounds table access") +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t0 $t0 (i64.const 28) (i64.const 1) (i64.const 3)) + )) + +(assert_trap (invoke "test") "out of bounds table access") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t0 $t0 (i64.const 0xFFFFFFFE) (i64.const 1) (i64.const 2)) + )) + +(assert_trap (invoke "test") "out of bounds table access") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t0 $t0 (i64.const 15) (i64.const 25) (i64.const 6)) + )) + +(assert_trap (invoke "test") "out of bounds table access") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t0 $t0 (i64.const 15) (i64.const 0xFFFFFFFE) (i64.const 2)) + )) + +(assert_trap (invoke "test") "out of bounds table access") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t0 $t0 (i64.const 15) (i64.const 25) (i64.const 0)) + )) + +(invoke "test") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t0 $t0 (i64.const 30) (i64.const 15) (i64.const 0)) + )) + +(invoke "test") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t0 $t0 (i64.const 31) (i64.const 15) (i64.const 0)) + )) + +(assert_trap (invoke "test") "out of bounds table access") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t0 $t0 (i64.const 15) (i64.const 30) (i64.const 0)) + )) + +(invoke "test") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t0 $t0 (i64.const 15) (i64.const 31) (i64.const 0)) + )) + +(assert_trap (invoke "test") "out of bounds table access") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t0 $t0 (i64.const 30) (i64.const 30) (i64.const 0)) + )) + +(invoke "test") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t0 $t0 (i64.const 31) (i64.const 31) (i64.const 0)) + )) + +(assert_trap (invoke "test") "out of bounds table access") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t1 $t0 (i64.const 28) (i64.const 1) (i64.const 3)) + )) + +(assert_trap (invoke "test") "out of bounds table access") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t1 $t0 (i64.const 0xFFFFFFFE) (i64.const 1) (i64.const 2)) + )) + +(assert_trap (invoke "test") "out of bounds table access") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t1 $t0 (i64.const 15) (i64.const 25) (i64.const 6)) + )) + +(assert_trap (invoke "test") "out of bounds table access") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t1 $t0 (i64.const 15) (i64.const 0xFFFFFFFE) (i64.const 2)) + )) + +(assert_trap (invoke "test") "out of bounds table access") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t1 $t0 (i64.const 15) (i64.const 25) (i64.const 0)) + )) + +(invoke "test") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t1 $t0 (i64.const 30) (i64.const 15) (i64.const 0)) + )) + +(invoke "test") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t1 $t0 (i64.const 31) (i64.const 15) (i64.const 0)) + )) + +(assert_trap (invoke "test") "out of bounds table access") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t1 $t0 (i64.const 15) (i64.const 30) (i64.const 0)) + )) + +(invoke "test") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t1 $t0 (i64.const 15) (i64.const 31) (i64.const 0)) + )) + +(assert_trap (invoke "test") "out of bounds table access") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t1 $t0 (i64.const 30) (i64.const 30) (i64.const 0)) + )) + +(invoke "test") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t1 $t0 (i64.const 31) (i64.const 31) (i64.const 0)) + )) + +(assert_trap (invoke "test") "out of bounds table access") + (module (type (func (result i32))) (table 32 64 funcref) diff --git a/test/core/table_fill.wast b/test/core/table_fill.wast index a8e2225520..ea0c752523 100644 --- a/test/core/table_fill.wast +++ b/test/core/table_fill.wast @@ -12,6 +12,16 @@ (func (export "get") (param $i i32) (result externref) (table.get $t (local.get $i)) ) + + (table $t64 i64 10 externref) + + (func (export "fill-t64") (param $i i64) (param $r externref) (param $n i64) + (table.fill $t64 (local.get $i) (local.get $r) (local.get $n)) + ) + + (func (export "get-t64") (param $i i64) (result externref) + (table.get $t64 (local.get $i)) + ) ) (assert_return (invoke "get" (i32.const 1)) (ref.null extern)) @@ -68,6 +78,61 @@ "out of bounds table access" ) +;; Same as above but for t64 + +(assert_return (invoke "get-t64" (i64.const 1)) (ref.null extern)) +(assert_return (invoke "get-t64" (i64.const 2)) (ref.null extern)) +(assert_return (invoke "get-t64" (i64.const 3)) (ref.null extern)) +(assert_return (invoke "get-t64" (i64.const 4)) (ref.null extern)) +(assert_return (invoke "get-t64" (i64.const 5)) (ref.null extern)) + +(assert_return (invoke "fill-t64" (i64.const 2) (ref.extern 1) (i64.const 3))) +(assert_return (invoke "get-t64" (i64.const 1)) (ref.null extern)) +(assert_return (invoke "get-t64" (i64.const 2)) (ref.extern 1)) +(assert_return (invoke "get-t64" (i64.const 3)) (ref.extern 1)) +(assert_return (invoke "get-t64" (i64.const 4)) (ref.extern 1)) +(assert_return (invoke "get-t64" (i64.const 5)) (ref.null extern)) + +(assert_return (invoke "fill-t64" (i64.const 4) (ref.extern 2) (i64.const 2))) +(assert_return (invoke "get-t64" (i64.const 3)) (ref.extern 1)) +(assert_return (invoke "get-t64" (i64.const 4)) (ref.extern 2)) +(assert_return (invoke "get-t64" (i64.const 5)) (ref.extern 2)) +(assert_return (invoke "get-t64" (i64.const 6)) (ref.null extern)) + +(assert_return (invoke "fill-t64" (i64.const 4) (ref.extern 3) (i64.const 0))) +(assert_return (invoke "get-t64" (i64.const 3)) (ref.extern 1)) +(assert_return (invoke "get-t64" (i64.const 4)) (ref.extern 2)) +(assert_return (invoke "get-t64" (i64.const 5)) (ref.extern 2)) + +(assert_return (invoke "fill-t64" (i64.const 8) (ref.extern 4) (i64.const 2))) +(assert_return (invoke "get-t64" (i64.const 7)) (ref.null extern)) +(assert_return (invoke "get-t64" (i64.const 8)) (ref.extern 4)) +(assert_return (invoke "get-t64" (i64.const 9)) (ref.extern 4)) + +(assert_return (invoke "fill-t64" (i64.const 9) (ref.null extern) (i64.const 1))) +(assert_return (invoke "get-t64" (i64.const 8)) (ref.extern 4)) +(assert_return (invoke "get-t64" (i64.const 9)) (ref.null extern)) + +(assert_return (invoke "fill-t64" (i64.const 10) (ref.extern 5) (i64.const 0))) +(assert_return (invoke "get-t64" (i64.const 9)) (ref.null extern)) + +(assert_trap + (invoke "fill-t64" (i64.const 8) (ref.extern 6) (i64.const 3)) + "out of bounds table access" +) +(assert_return (invoke "get-t64" (i64.const 7)) (ref.null extern)) +(assert_return (invoke "get-t64" (i64.const 8)) (ref.extern 4)) +(assert_return (invoke "get-t64" (i64.const 9)) (ref.null extern)) + +(assert_trap + (invoke "fill-t64" (i64.const 11) (ref.null extern) (i64.const 0)) + "out of bounds table access" +) + +(assert_trap + (invoke "fill-t64" (i64.const 11) (ref.null extern) (i64.const 10)) + "out of bounds table access" +) ;; Type errors diff --git a/test/core/table_grow.wast b/test/core/table_grow.wast index 9a931a7fa2..6d268f9665 100644 --- a/test/core/table_grow.wast +++ b/test/core/table_grow.wast @@ -11,6 +11,15 @@ (table.grow (local.get $init) (local.get $sz)) ) (func (export "size") (result i32) (table.size $t)) + + (table $t64 i64 0 externref) + + (func (export "get-t64") (param $i i64) (result externref) (table.get $t64 (local.get $i))) + (func (export "set-t64") (param $i i64) (param $r externref) (table.set $t64 (local.get $i) (local.get $r))) + (func (export "grow-t64") (param $sz i64) (param $init externref) (result i64) + (table.grow $t64 (local.get $init) (local.get $sz)) + ) + (func (export "size-t64") (result i64) (table.size $t64)) ) (assert_return (invoke "size") (i32.const 0)) @@ -37,6 +46,30 @@ (assert_trap (invoke "set" (i32.const 5) (ref.extern 2)) "out of bounds table access") (assert_trap (invoke "get" (i32.const 5)) "out of bounds table access") +;; Similar to above but for t64 +(assert_return (invoke "size-t64") (i64.const 0)) +(assert_trap (invoke "set-t64" (i64.const 0) (ref.extern 2)) "out of bounds table access") +(assert_trap (invoke "get-t64" (i64.const 0)) "out of bounds table access") + +(assert_return (invoke "grow-t64" (i64.const 1) (ref.null extern)) (i64.const 0)) +(assert_return (invoke "size-t64") (i64.const 1)) +(assert_return (invoke "get-t64" (i64.const 0)) (ref.null extern)) +(assert_return (invoke "set-t64" (i64.const 0) (ref.extern 2))) +(assert_return (invoke "get-t64" (i64.const 0)) (ref.extern 2)) +(assert_trap (invoke "set-t64" (i64.const 1) (ref.extern 2)) "out of bounds table access") +(assert_trap (invoke "get-t64" (i64.const 1)) "out of bounds table access") + +(assert_return (invoke "grow-t64" (i64.const 4) (ref.extern 3)) (i64.const 1)) +(assert_return (invoke "size-t64") (i64.const 5)) +(assert_return (invoke "get-t64" (i64.const 0)) (ref.extern 2)) +(assert_return (invoke "set-t64" (i64.const 0) (ref.extern 2))) +(assert_return (invoke "get-t64" (i64.const 0)) (ref.extern 2)) +(assert_return (invoke "get-t64" (i64.const 1)) (ref.extern 3)) +(assert_return (invoke "get-t64" (i64.const 4)) (ref.extern 3)) +(assert_return (invoke "set-t64" (i64.const 4) (ref.extern 4))) +(assert_return (invoke "get-t64" (i64.const 4)) (ref.extern 4)) +(assert_trap (invoke "set-t64" (i64.const 5) (ref.extern 2)) "out of bounds table access") +(assert_trap (invoke "get-t64" (i64.const 5)) "out of bounds table access") ;; Reject growing to size outside i32 value range (module diff --git a/test/core/table_init.wast b/test/core/table_init.wast index fa1e0fdf85..5c3679ab9a 100644 --- a/test/core/table_init.wast +++ b/test/core/table_init.wast @@ -21,13 +21,11 @@ (import "a" "ef4" (func (result i32))) ;; index 4 (table $t0 30 30 funcref) (table $t1 30 30 funcref) - (table $t64 i64 30 30 funcref) + (table $t2 i64 30 30 funcref) (elem (table $t0) (i32.const 2) func 3 1 4 1) - (elem (table $t64) (i64.const 2) func 3 1 4 1) (elem funcref (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) (elem (table $t0) (i32.const 12) func 7 5 2 3 6) - (elem (table $t64) (i64.const 12) func 7 5 2 3 6) (elem funcref (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) (func (result i32) (i32.const 5)) ;; index 5 @@ -36,13 +34,9 @@ (func (result i32) (i32.const 8)) (func (result i32) (i32.const 9)) ;; index 9 (func (export "test") - (table.init $t0 2 (i32.const 7) (i32.const 0) (i32.const 4))) - (func (export "test-t64") - (table.init $t64 2 (i32.const 7) (i32.const 0) (i32.const 4))) + (table.init $t0 1 (i32.const 7) (i32.const 0) (i32.const 4))) (func (export "check") (param i32) (result i32) (call_indirect $t0 (type 0) (local.get 0))) - (func (export "check-t64") (param i64) (result i32) - (call_indirect $t64 (type 0) (local.get 0))) ) (invoke "test") @@ -77,38 +71,6 @@ (assert_trap (invoke "check" (i32.const 28)) "uninitialized element") (assert_trap (invoke "check" (i32.const 29)) "uninitialized element") -(invoke "test-t64") -(assert_trap (invoke "check-t64" (i64.const 0)) "uninitialized element") -(assert_trap (invoke "check-t64" (i64.const 1)) "uninitialized element") -(assert_return (invoke "check-t64" (i64.const 2)) (i32.const 3)) -(assert_return (invoke "check-t64" (i64.const 3)) (i32.const 1)) -(assert_return (invoke "check-t64" (i64.const 4)) (i32.const 4)) -(assert_return (invoke "check-t64" (i64.const 5)) (i32.const 1)) -(assert_trap (invoke "check-t64" (i64.const 6)) "uninitialized element") -(assert_return (invoke "check-t64" (i64.const 7)) (i32.const 2)) -(assert_return (invoke "check-t64" (i64.const 8)) (i32.const 7)) -(assert_return (invoke "check-t64" (i64.const 9)) (i32.const 1)) -(assert_return (invoke "check-t64" (i64.const 10)) (i32.const 8)) -(assert_trap (invoke "check-t64" (i64.const 11)) "uninitialized element") -(assert_return (invoke "check-t64" (i64.const 12)) (i32.const 7)) -(assert_return (invoke "check-t64" (i64.const 13)) (i32.const 5)) -(assert_return (invoke "check-t64" (i64.const 14)) (i32.const 2)) -(assert_return (invoke "check-t64" (i64.const 15)) (i32.const 3)) -(assert_return (invoke "check-t64" (i64.const 16)) (i32.const 6)) -(assert_trap (invoke "check-t64" (i64.const 17)) "uninitialized element") -(assert_trap (invoke "check-t64" (i64.const 18)) "uninitialized element") -(assert_trap (invoke "check-t64" (i64.const 19)) "uninitialized element") -(assert_trap (invoke "check-t64" (i64.const 20)) "uninitialized element") -(assert_trap (invoke "check-t64" (i64.const 21)) "uninitialized element") -(assert_trap (invoke "check-t64" (i64.const 22)) "uninitialized element") -(assert_trap (invoke "check-t64" (i64.const 23)) "uninitialized element") -(assert_trap (invoke "check-t64" (i64.const 24)) "uninitialized element") -(assert_trap (invoke "check-t64" (i64.const 25)) "uninitialized element") -(assert_trap (invoke "check-t64" (i64.const 26)) "uninitialized element") -(assert_trap (invoke "check-t64" (i64.const 27)) "uninitialized element") -(assert_trap (invoke "check-t64" (i64.const 28)) "uninitialized element") -(assert_trap (invoke "check-t64" (i64.const 29)) "uninitialized element") - (module (type (func (result i32))) ;; type #0 (import "a" "ef0" (func (result i32))) ;; index 0 @@ -118,6 +80,7 @@ (import "a" "ef4" (func (result i32))) ;; index 4 (table $t0 30 30 funcref) (table $t1 30 30 funcref) + (table $t2 i64 30 30 funcref) (elem (table $t0) (i32.const 2) func 3 1 4 1) (elem funcref (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) @@ -176,6 +139,7 @@ (import "a" "ef4" (func (result i32))) ;; index 4 (table $t0 30 30 funcref) (table $t1 30 30 funcref) + (table $t2 i64 30 30 funcref) (elem (table $t0) (i32.const 2) func 3 1 4 1) (elem funcref (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) @@ -242,6 +206,7 @@ (import "a" "ef4" (func (result i32))) ;; index 4 (table $t0 30 30 funcref) (table $t1 30 30 funcref) + (table $t2 i64 30 30 funcref) (elem (table $t1) (i32.const 2) func 3 1 4 1) (elem funcref (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) @@ -300,6 +265,7 @@ (import "a" "ef4" (func (result i32))) ;; index 4 (table $t0 30 30 funcref) (table $t1 30 30 funcref) + (table $t2 i64 30 30 funcref) (elem (table $t1) (i32.const 2) func 3 1 4 1) (elem funcref (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) @@ -358,6 +324,7 @@ (import "a" "ef4" (func (result i32))) ;; index 4 (table $t0 30 30 funcref) (table $t1 30 30 funcref) + (table $t2 i64 30 30 funcref) (elem (table $t1) (i32.const 2) func 3 1 4 1) (elem funcref (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) @@ -414,6 +381,191 @@ (assert_trap (invoke "check" (i32.const 27)) "uninitialized element") (assert_trap (invoke "check" (i32.const 28)) "uninitialized element") (assert_trap (invoke "check" (i32.const 29)) "uninitialized element") + +(module + (type (func (result i32))) ;; type #0 + (import "a" "ef0" (func (result i32))) ;; index 0 + (import "a" "ef1" (func (result i32))) + (import "a" "ef2" (func (result i32))) + (import "a" "ef3" (func (result i32))) + (import "a" "ef4" (func (result i32))) ;; index 4 + (table $t0 30 30 funcref) + (table $t1 30 30 funcref) + (table $t2 i64 30 30 funcref) + (elem (table $t2) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t2) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 5)) ;; index 5 + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) ;; index 9 + (func (export "test") + (table.init $t2 1 (i64.const 7) (i32.const 0) (i32.const 4))) + (func (export "check") (param i64) (result i32) + (call_indirect $t2 (type 0) (local.get 0))) +) + +(invoke "test") +(assert_trap (invoke "check" (i64.const 0)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 1)) "uninitialized element") +(assert_return (invoke "check" (i64.const 2)) (i32.const 3)) +(assert_return (invoke "check" (i64.const 3)) (i32.const 1)) +(assert_return (invoke "check" (i64.const 4)) (i32.const 4)) +(assert_return (invoke "check" (i64.const 5)) (i32.const 1)) +(assert_trap (invoke "check" (i64.const 6)) "uninitialized element") +(assert_return (invoke "check" (i64.const 7)) (i32.const 2)) +(assert_return (invoke "check" (i64.const 8)) (i32.const 7)) +(assert_return (invoke "check" (i64.const 9)) (i32.const 1)) +(assert_return (invoke "check" (i64.const 10)) (i32.const 8)) +(assert_trap (invoke "check" (i64.const 11)) "uninitialized element") +(assert_return (invoke "check" (i64.const 12)) (i32.const 7)) +(assert_return (invoke "check" (i64.const 13)) (i32.const 5)) +(assert_return (invoke "check" (i64.const 14)) (i32.const 2)) +(assert_return (invoke "check" (i64.const 15)) (i32.const 3)) +(assert_return (invoke "check" (i64.const 16)) (i32.const 6)) +(assert_trap (invoke "check" (i64.const 17)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 18)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 19)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 20)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 21)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 22)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 23)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 24)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 25)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 26)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 27)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 28)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 29)) "uninitialized element") + +(module + (type (func (result i32))) ;; type #0 + (import "a" "ef0" (func (result i32))) ;; index 0 + (import "a" "ef1" (func (result i32))) + (import "a" "ef2" (func (result i32))) + (import "a" "ef3" (func (result i32))) + (import "a" "ef4" (func (result i32))) ;; index 4 + (table $t0 30 30 funcref) + (table $t1 30 30 funcref) + (table $t2 i64 30 30 funcref) + (elem (table $t2) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t2) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 5)) ;; index 5 + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) ;; index 9 + (func (export "test") + (table.init $t2 3 (i64.const 15) (i32.const 1) (i32.const 3))) + (func (export "check") (param i64) (result i32) + (call_indirect $t2 (type 0) (local.get 0))) +) + +(invoke "test") +(assert_trap (invoke "check" (i64.const 0)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 1)) "uninitialized element") +(assert_return (invoke "check" (i64.const 2)) (i32.const 3)) +(assert_return (invoke "check" (i64.const 3)) (i32.const 1)) +(assert_return (invoke "check" (i64.const 4)) (i32.const 4)) +(assert_return (invoke "check" (i64.const 5)) (i32.const 1)) +(assert_trap (invoke "check" (i64.const 6)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 7)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 8)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 9)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 10)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 11)) "uninitialized element") +(assert_return (invoke "check" (i64.const 12)) (i32.const 7)) +(assert_return (invoke "check" (i64.const 13)) (i32.const 5)) +(assert_return (invoke "check" (i64.const 14)) (i32.const 2)) +(assert_return (invoke "check" (i64.const 15)) (i32.const 9)) +(assert_return (invoke "check" (i64.const 16)) (i32.const 2)) +(assert_return (invoke "check" (i64.const 17)) (i32.const 7)) +(assert_trap (invoke "check" (i64.const 18)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 19)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 20)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 21)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 22)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 23)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 24)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 25)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 26)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 27)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 28)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 29)) "uninitialized element") + +(module + (type (func (result i32))) ;; type #0 + (import "a" "ef0" (func (result i32))) ;; index 0 + (import "a" "ef1" (func (result i32))) + (import "a" "ef2" (func (result i32))) + (import "a" "ef3" (func (result i32))) + (import "a" "ef4" (func (result i32))) ;; index 4 + (table $t0 30 30 funcref) + (table $t1 30 30 funcref) + (table $t2 i64 30 30 funcref) + (elem (table $t2) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t2) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 5)) ;; index 5 + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) ;; index 9 + (func (export "test") + (table.init $t2 1 (i64.const 7) (i32.const 0) (i32.const 4)) + (elem.drop 1) + (table.init $t2 3 (i64.const 15) (i32.const 1) (i32.const 3)) + (elem.drop 3) + (table.copy $t2 2 (i64.const 20) (i64.const 15) (i64.const 5)) + (table.copy $t2 2 (i64.const 21) (i64.const 29) (i64.const 1)) + (table.copy $t2 2 (i64.const 24) (i64.const 10) (i64.const 1)) + (table.copy $t2 2 (i64.const 13) (i64.const 11) (i64.const 4)) + (table.copy $t2 2 (i64.const 19) (i64.const 20) (i64.const 5))) + (func (export "check") (param i64) (result i32) + (call_indirect $t2 (type 0) (local.get 0))) +) + +(invoke "test") +(assert_trap (invoke "check" (i64.const 0)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 1)) "uninitialized element") +(assert_return (invoke "check" (i64.const 2)) (i32.const 3)) +(assert_return (invoke "check" (i64.const 3)) (i32.const 1)) +(assert_return (invoke "check" (i64.const 4)) (i32.const 4)) +(assert_return (invoke "check" (i64.const 5)) (i32.const 1)) +(assert_trap (invoke "check" (i64.const 6)) "uninitialized element") +(assert_return (invoke "check" (i64.const 7)) (i32.const 2)) +(assert_return (invoke "check" (i64.const 8)) (i32.const 7)) +(assert_return (invoke "check" (i64.const 9)) (i32.const 1)) +(assert_return (invoke "check" (i64.const 10)) (i32.const 8)) +(assert_trap (invoke "check" (i64.const 11)) "uninitialized element") +(assert_return (invoke "check" (i64.const 12)) (i32.const 7)) +(assert_trap (invoke "check" (i64.const 13)) "uninitialized element") +(assert_return (invoke "check" (i64.const 14)) (i32.const 7)) +(assert_return (invoke "check" (i64.const 15)) (i32.const 5)) +(assert_return (invoke "check" (i64.const 16)) (i32.const 2)) +(assert_return (invoke "check" (i64.const 17)) (i32.const 7)) +(assert_trap (invoke "check" (i64.const 18)) "uninitialized element") +(assert_return (invoke "check" (i64.const 19)) (i32.const 9)) +(assert_trap (invoke "check" (i64.const 20)) "uninitialized element") +(assert_return (invoke "check" (i64.const 21)) (i32.const 7)) +(assert_trap (invoke "check" (i64.const 22)) "uninitialized element") +(assert_return (invoke "check" (i64.const 23)) (i32.const 8)) +(assert_return (invoke "check" (i64.const 24)) (i32.const 8)) +(assert_trap (invoke "check" (i64.const 25)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 26)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 27)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 28)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 29)) "uninitialized element") (assert_invalid (module (func (export "test") diff --git a/test/core/table_size.wast b/test/core/table_size.wast index 83fef02b33..71081d7e6b 100644 --- a/test/core/table_size.wast +++ b/test/core/table_size.wast @@ -3,11 +3,13 @@ (table $t1 1 externref) (table $t2 0 2 externref) (table $t3 3 8 externref) + (table $t64 i64 42 42 externref) (func (export "size-t0") (result i32) table.size) (func (export "size-t1") (result i32) (table.size $t1)) (func (export "size-t2") (result i32) (table.size $t2)) (func (export "size-t3") (result i32) (table.size $t3)) + (func (export "size-t64") (result i64) (table.size $t64)) (func (export "grow-t0") (param $sz i32) (drop (table.grow $t0 (ref.null extern) (local.get $sz))) @@ -63,6 +65,7 @@ (assert_return (invoke "grow-t3" (i32.const 1))) (assert_return (invoke "size-t3") (i32.const 8)) +(assert_return (invoke "size-t64") (i64.const 42)) ;; Type errors diff --git a/test/meta/Makefile b/test/meta/Makefile index 20e9adb2f5..ed0a571c3d 100644 --- a/test/meta/Makefile +++ b/test/meta/Makefile @@ -4,7 +4,7 @@ SHARED_MEM=false JSSHELL=~/mozilla-central/js/src/build-debug/dist/bin/js -e 'const WITH_SHARED_MEMORY=$(SHARED_MEM);' -f common.js # Node.js -#JSSHELL=./noderun.sh $(SHARED_MEM) +JSSHELL=./noderun.sh $(SHARED_MEM) TARGETDIR=../core diff --git a/test/meta/generate_table_copy.js b/test/meta/generate_table_copy.js index f7fd47dcba..8fb0a92245 100644 --- a/test/meta/generate_table_copy.js +++ b/test/meta/generate_table_copy.js @@ -154,16 +154,17 @@ for ( let table of [0,1] ) { // Out-of-bounds checks. -function do_test(insn1, insn2, errText) +function do_test(tt, insn1, insn2, errText) { + const type = tt == 'i64' ? ' i64' : ''; print(` (module - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t0) (i32.const 2) func 3 1 4 1) + (table $t0${type} 30 30 funcref) + (table $t1${type} 30 30 funcref) + (elem (table $t0) (${tt}.const 2) func 3 1 4 1) (elem funcref (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t0) (i32.const 12) func 7 5 2 3 6) + (elem (table $t0) (${tt}.const 12) func 7 5 2 3 6) (elem funcref (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) (func (result i32) (i32.const 0)) @@ -188,72 +189,74 @@ function do_test(insn1, insn2, errText) } } -function tab_test2(insn1, insn2, errKind, errText) { - do_test(insn1, insn2, errKind, errText); +function tab_test2(tt, insn1, insn2, errKind, errText) { + do_test(tt, insn1, insn2, errKind, errText); } -function tab_test_nofail(insn1, insn2) { - do_test(insn1, insn2, undefined, undefined); +function tab_test_nofail(tt, insn1, insn2) { + do_test(tt, insn1, insn2, undefined, undefined); } -for ( let dest of ["$t0","$t1"] ) { - // Here we test the boundary-failure cases. The table's valid indices are 0..29 - // inclusive. - - // copy: dst range invalid - tab_test2(`(table.copy ${dest} $t0 (i32.const 28) (i32.const 1) (i32.const 3))`, - "", - "out of bounds table access"); - - // copy: dst wraparound end of 32 bit offset space - tab_test2(`(table.copy ${dest} $t0 (i32.const 0xFFFFFFFE) (i32.const 1) (i32.const 2))`, - "", - "out of bounds table access"); - - // copy: src range invalid - tab_test2(`(table.copy ${dest} $t0 (i32.const 15) (i32.const 25) (i32.const 6))`, - "", - "out of bounds table access"); - - // copy: src wraparound end of 32 bit offset space - tab_test2(`(table.copy ${dest} $t0 (i32.const 15) (i32.const 0xFFFFFFFE) (i32.const 2))`, - "", - "out of bounds table access"); - - // copy: zero length with both offsets in-bounds is OK - tab_test_nofail( - `(table.copy ${dest} $t0 (i32.const 15) (i32.const 25) (i32.const 0))`, - ""); - - // copy: zero length with dst offset out of bounds at the end of the table is allowed - tab_test2(`(table.copy ${dest} $t0 (i32.const 30) (i32.const 15) (i32.const 0))`, - "", - undefined); - - // copy: zero length with dst offset out of bounds past the end of the table is not allowed - tab_test2(`(table.copy ${dest} $t0 (i32.const 31) (i32.const 15) (i32.const 0))`, - "", - "out of bounds table access"); - - // copy: zero length with src offset out of bounds at the end of the table is allowed - tab_test2(`(table.copy ${dest} $t0 (i32.const 15) (i32.const 30) (i32.const 0))`, - "", - undefined); - - // copy: zero length with src offset out of bounds past the end of the table is not allowed - tab_test2(`(table.copy ${dest} $t0 (i32.const 15) (i32.const 31) (i32.const 0))`, - "", - "out of bounds table access"); - - // copy: zero length with both dst and src offset out of bounds at the end of the table is allowed - tab_test2(`(table.copy ${dest} $t0 (i32.const 30) (i32.const 30) (i32.const 0))`, - "", - undefined); - - // copy: zero length with both dst and src offset out of bounds past the end of the table is not allowed - tab_test2(`(table.copy ${dest} $t0 (i32.const 31) (i32.const 31) (i32.const 0))`, - "", - "out of bounds table access"); +for ( let tt of ["i32", "i64"] ) { + for ( let dest of ["$t0","$t1"] ) { + // Here we test the boundary-failure cases. The table's valid indices are 0..29 + // inclusive. + + // copy: dst range invalid + tab_test2(tt, `(table.copy ${dest} $t0 (${tt}.const 28) (${tt}.const 1) (${tt}.const 3))`, + "", + "out of bounds table access"); + + // copy: dst wraparound end of 32 bit offset space + tab_test2(tt, `(table.copy ${dest} $t0 (${tt}.const 0xFFFFFFFE) (${tt}.const 1) (${tt}.const 2))`, + "", + "out of bounds table access"); + + // copy: src range invalid + tab_test2(tt, `(table.copy ${dest} $t0 (${tt}.const 15) (${tt}.const 25) (${tt}.const 6))`, + "", + "out of bounds table access"); + + // copy: src wraparound end of 32 bit offset space + tab_test2(tt, `(table.copy ${dest} $t0 (${tt}.const 15) (${tt}.const 0xFFFFFFFE) (${tt}.const 2))`, + "", + "out of bounds table access"); + + // copy: zero length with both offsets in-bounds is OK + tab_test_nofail(tt, + `(table.copy ${dest} $t0 (${tt}.const 15) (${tt}.const 25) (${tt}.const 0))`, + ""); + + // copy: zero length with dst offset out of bounds at the end of the table is allowed + tab_test2(tt, `(table.copy ${dest} $t0 (${tt}.const 30) (${tt}.const 15) (${tt}.const 0))`, + "", + undefined); + + // copy: zero length with dst offset out of bounds past the end of the table is not allowed + tab_test2(tt, `(table.copy ${dest} $t0 (${tt}.const 31) (${tt}.const 15) (${tt}.const 0))`, + "", + "out of bounds table access"); + + // copy: zero length with src offset out of bounds at the end of the table is allowed + tab_test2(tt, `(table.copy ${dest} $t0 (${tt}.const 15) (${tt}.const 30) (${tt}.const 0))`, + "", + undefined); + + // copy: zero length with src offset out of bounds past the end of the table is not allowed + tab_test2(tt, `(table.copy ${dest} $t0 (${tt}.const 15) (${tt}.const 31) (${tt}.const 0))`, + "", + "out of bounds table access"); + + // copy: zero length with both dst and src offset out of bounds at the end of the table is allowed + tab_test2(tt, `(table.copy ${dest} $t0 (${tt}.const 30) (${tt}.const 30) (${tt}.const 0))`, + "", + undefined); + + // copy: zero length with both dst and src offset out of bounds past the end of the table is not allowed + tab_test2(tt, `(table.copy ${dest} $t0 (${tt}.const 31) (${tt}.const 31) (${tt}.const 0))`, + "", + "out of bounds table access"); + } } // table.copy: out of bounds of the table for the source or target, but should diff --git a/test/meta/generate_table_init.js b/test/meta/generate_table_init.js index 16b9a84067..5debac4e4a 100644 --- a/test/meta/generate_table_init.js +++ b/test/meta/generate_table_init.js @@ -27,6 +27,7 @@ function emit_a() { // the table entry is empty. function emit_b(insn, table) { + let tt = table == 2 ? 'i64' : 'i32'; print( ` (module @@ -38,10 +39,11 @@ function emit_b(insn, table) { (import "a" "ef4" (func (result i32))) ;; index 4 (table $t0 30 30 funcref) (table $t1 30 30 funcref) - (elem (table $t${table}) (i32.const 2) func 3 1 4 1) + (table $t2 i64 30 30 funcref) + (elem (table $t${table}) (${tt}.const 2) func 3 1 4 1) (elem funcref (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t${table}) (i32.const 12) func 7 5 2 3 6) + (elem (table $t${table}) (${tt}.const 12) func 7 5 2 3 6) (elem funcref (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) (func (result i32) (i32.const 5)) ;; index 5 @@ -51,7 +53,7 @@ function emit_b(insn, table) { (func (result i32) (i32.const 9)) ;; index 9 (func (export "test") ${insn}) - (func (export "check") (param i32) (result i32) + (func (export "check") (param ${tt}) (result i32) (call_indirect $t${table} (type 0) (local.get 0))) ) `); @@ -65,12 +67,13 @@ function emit_b(insn, table) { function tab_test(instruction, table, expected_result_vector) { emit_b(instruction, table); print(`(invoke "test")`); + let tt = table == 2 ? 'i64' : 'i32'; for (let i = 0; i < expected_result_vector.length; i++) { let expected = expected_result_vector[i]; if (expected === undefined) { - print(`(assert_trap (invoke "check" (i32.const ${i})) "uninitialized element")`); + print(`(assert_trap (invoke "check" (${tt}.const ${i})) "uninitialized element")`); } else { - print(`(assert_return (invoke "check" (i32.const ${i})) (i32.const ${expected}))`); + print(`(assert_return (invoke "check" (${tt}.const ${i})) (i32.const ${expected}))`); } } } @@ -81,28 +84,29 @@ emit_a(); // to count through the vector entries when debugging. let e = undefined; -for ( let table of [0, 1] ) { +for ( let table of [0, 1, 2] ) { + let tt = table == 2 ? 'i64' : 'i32'; // Passive init that overwrites all-null entries - tab_test(`(table.init $t${table} 1 (i32.const 7) (i32.const 0) (i32.const 4))`, + tab_test(`(table.init $t${table} 1 (${tt}.const 7) (i32.const 0) (i32.const 4))`, table, [e,e,3,1,4, 1,e,2,7,1, 8,e,7,5,2, 3,6,e,e,e, e,e,e,e,e, e,e,e,e,e]); // Passive init that overwrites existing active-init-created entries - tab_test(`(table.init $t${table} 3 (i32.const 15) (i32.const 1) (i32.const 3))`, + tab_test(`(table.init $t${table} 3 (${tt}.const 15) (i32.const 1) (i32.const 3))`, table, [e,e,3,1,4, 1,e,e,e,e, e,e,7,5,2, 9,2,7,e,e, e,e,e,e,e, e,e,e,e,e]); // Perform active and passive initialisation and then multiple copies tab_test( - `(table.init $t${table} 1 (i32.const 7) (i32.const 0) (i32.const 4)) + `(table.init $t${table} 1 (${tt}.const 7) (i32.const 0) (i32.const 4)) (elem.drop 1) - (table.init $t${table} 3 (i32.const 15) (i32.const 1) (i32.const 3)) + (table.init $t${table} 3 (${tt}.const 15) (i32.const 1) (i32.const 3)) (elem.drop 3) - (table.copy $t${table} ${table} (i32.const 20) (i32.const 15) (i32.const 5)) - (table.copy $t${table} ${table} (i32.const 21) (i32.const 29) (i32.const 1)) - (table.copy $t${table} ${table} (i32.const 24) (i32.const 10) (i32.const 1)) - (table.copy $t${table} ${table} (i32.const 13) (i32.const 11) (i32.const 4)) - (table.copy $t${table} ${table} (i32.const 19) (i32.const 20) (i32.const 5))`, + (table.copy $t${table} ${table} (${tt}.const 20) (${tt}.const 15) (${tt}.const 5)) + (table.copy $t${table} ${table} (${tt}.const 21) (${tt}.const 29) (${tt}.const 1)) + (table.copy $t${table} ${table} (${tt}.const 24) (${tt}.const 10) (${tt}.const 1)) + (table.copy $t${table} ${table} (${tt}.const 13) (${tt}.const 11) (${tt}.const 4)) + (table.copy $t${table} ${table} (${tt}.const 19) (${tt}.const 20) (${tt}.const 5))`, table, [e,e,3,1,4, 1,e,2,7,1, 8,e,7,e,7, 5,2,7,e,9, e,7,e,8,8, e,e,e,e,e]); }