Added support for global value offsets

This commit depends on this PR landing on cranelift:
https://github.com/CraneStation/cranelift/pull/612
This commit is contained in:
Syrus Akbary 2018-11-18 20:22:18 -08:00
parent 998d7294f0
commit 9f561db90b
7 changed files with 411 additions and 352 deletions

View File

@ -146,7 +146,3 @@ Currently cranelift_wasm::ModuleEnvironment does not provide `declare_table_impo
```
- `elem.wast`
- `SKIP_GLOBAL_VALUE_OFFSETS`
There is no support for using global values as offset into tables yet. I believe this is an issue from cranelift side as well, so we will have to wait for it to be supported.
- `elem.wast`

View File

@ -50,21 +50,19 @@
(elem (i32.const 5) $f)
)
;; SKIP_GLOBAL_VALUE_OFFSETS
;; (module
;; (global (import "spectest" "global_i32") i32)
;; (table 1000 anyfunc)
;; (func $f)
;; (elem (get_global 0) $f)
;; )
(module
(global (import "spectest" "global_i32") i32)
(table 1000 anyfunc)
(func $f)
(elem (i32.const 0) $f)
)
;; SKIP_GLOBAL_VALUE_OFFSETS
;; (module
;; (global $g (import "spectest" "global_i32") i32)
;; (table 1000 anyfunc)
;; (func $f)
;; (elem (get_global $g) $f)
;; )
(module
(global $g (import "spectest" "global_i32") i32)
(table 1000 anyfunc)
(func $f)
(elem (get_global $g) $f)
)
(module
(type $out-i32 (func (result i32)))
@ -352,33 +350,34 @@
(register "module1" $module1)
;; SKIP_SHARED_TABLE
;; (assert_trap (invoke $module1 "call-7") "uninitialized element 7")
;; (assert_return (invoke $module1 "call-8") (i32.const 65))
;; (assert_return (invoke $module1 "call-9") (i32.const 66))
(assert_trap (invoke $module1 "call-7") "uninitialized element 7")
(assert_return (invoke $module1 "call-8") (i32.const 65))
(assert_return (invoke $module1 "call-9") (i32.const 66))
(module $module2
(type $out-i32 (func (result i32)))
(import "module1" "shared-table" (table 10 anyfunc))
(elem (i32.const 7) $const-i32-c)
(elem (i32.const 8) $const-i32-d)
(func $const-i32-c (type $out-i32) (i32.const 67))
(func $const-i32-d (type $out-i32) (i32.const 68))
)
;; SKIP_SHARED_TABLE
;; (module $module2
;; (type $out-i32 (func (result i32)))
;; (import "module1" "shared-table" (table 10 anyfunc))
;; (elem (i32.const 7) $const-i32-c)
;; (elem (i32.const 8) $const-i32-d)
;; (func $const-i32-c (type $out-i32) (i32.const 67))
;; (func $const-i32-d (type $out-i32) (i32.const 68))
;; )
;; SKIP_SHARED_TABLE
;; (assert_return (invoke $module1 "call-7") (i32.const 67))
;; (assert_return (invoke $module1 "call-8") (i32.const 68))
;; (assert_return (invoke $module1 "call-9") (i32.const 66))
(module $module3
(type $out-i32 (func (result i32)))
(import "module1" "shared-table" (table 10 anyfunc))
(elem (i32.const 8) $const-i32-e)
(elem (i32.const 9) $const-i32-f)
(func $const-i32-e (type $out-i32) (i32.const 69))
(func $const-i32-f (type $out-i32) (i32.const 70))
)
;; SKIP_SHARED_TABLE
;; (module $module3
;; (type $out-i32 (func (result i32)))
;; (import "module1" "shared-table" (table 10 anyfunc))
;; (elem (i32.const 8) $const-i32-e)
;; (elem (i32.const 9) $const-i32-f)
;; (func $const-i32-e (type $out-i32) (i32.const 69))
;; (func $const-i32-f (type $out-i32) (i32.const 70))
;; )
;; SKIP_SHARED_TABLE
;; (assert_return (invoke $module1 "call-7") (i32.const 67))

View File

@ -12,7 +12,7 @@ pub fn spectest_importobject<'a, 'b>() -> ImportObject<&'a str, &'b str> {
let mut import_object = ImportObject::new();
import_object.set("spectest", "print_i32", ImportValue::Func(print_i32 as *const u8));
import_object.set("spectest", "print", ImportValue::Func(print as *const u8));
import_object.set("spectest", "global_i32", ImportValue::Func(GLOBAL_I32 as *const u8));
import_object.set("spectest", "global_i32", ImportValue::Global(GLOBAL_I32 as _));
import_object.set("spectest", "table", ImportValue::Table(vec![0; 30]));
return import_object;
}

View File

@ -142,7 +142,7 @@ fn start_module_5(result_object: &ResultObject) {
result_object.instance.start();
}
// Line 69
// Line 53
#[test]
fn test_module_5() {
@ -151,6 +151,54 @@ fn test_module_5() {
start_module_5(&result_object);
}
fn create_module_6() -> ResultObject {
let module_str = "(module
(type (;0;) (func))
(import \"spectest\" \"global_i32\" (global (;0;) i32))
(func (;0;) (type 0))
(table (;0;) 1000 anyfunc)
(elem (;0;) (i32.const 0) 0))
";
let wasm_binary = wat2wasm(module_str.as_bytes()).expect("WAST not valid or malformed");
instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated")
}
fn start_module_6(result_object: &ResultObject) {
result_object.instance.start();
}
// Line 60
#[test]
fn test_module_6() {
let result_object = create_module_6();
// We group the calls together
start_module_6(&result_object);
}
fn create_module_7() -> ResultObject {
let module_str = "(module
(type (;0;) (func))
(import \"spectest\" \"global_i32\" (global (;0;) i32))
(func (;0;) (type 0))
(table (;0;) 1000 anyfunc)
(elem (;0;) (get_global 0) 0))
";
let wasm_binary = wat2wasm(module_str.as_bytes()).expect("WAST not valid or malformed");
instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated")
}
fn start_module_7(result_object: &ResultObject) {
result_object.instance.start();
}
// Line 67
#[test]
fn test_module_7() {
let result_object = create_module_7();
// We group the calls together
start_module_7(&result_object);
}
fn create_module_8() -> ResultObject {
let module_str = "(module
(type (;0;) (func (result i32)))
(func (;0;) (type 0) (result i32)
@ -173,13 +221,13 @@ fn create_module_6() -> ResultObject {
instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated")
}
fn start_module_6(result_object: &ResultObject) {
fn start_module_8(result_object: &ResultObject) {
result_object.instance.start();
}
// Line 83
fn c6_l83_action_invoke(result_object: &ResultObject) {
println!("Executing function {}", "c6_l83_action_invoke");
// Line 81
fn c8_l81_action_invoke(result_object: &ResultObject) {
println!("Executing function {}", "c8_l81_action_invoke");
let func_index = match result_object.module.info.exports.get("call-7") {
Some(&Export::Function(index)) => index,
_ => panic!("Function not found"),
@ -189,9 +237,9 @@ fn c6_l83_action_invoke(result_object: &ResultObject) {
assert_eq!(result, 65 as i32);
}
// Line 84
fn c7_l84_action_invoke(result_object: &ResultObject) {
println!("Executing function {}", "c7_l84_action_invoke");
// Line 82
fn c9_l82_action_invoke(result_object: &ResultObject) {
println!("Executing function {}", "c9_l82_action_invoke");
let func_index = match result_object.module.info.exports.get("call-9") {
Some(&Export::Function(index)) => index,
_ => panic!("Function not found"),
@ -201,17 +249,17 @@ fn c7_l84_action_invoke(result_object: &ResultObject) {
assert_eq!(result, 66 as i32);
}
// Line 88
// Line 86
#[test]
fn test_module_6() {
let result_object = create_module_6();
fn test_module_8() {
let result_object = create_module_8();
// We group the calls together
start_module_6(&result_object);
c6_l83_action_invoke(&result_object);
c7_l84_action_invoke(&result_object);
start_module_8(&result_object);
c8_l81_action_invoke(&result_object);
c9_l82_action_invoke(&result_object);
}
fn create_module_7() -> ResultObject {
fn create_module_9() -> ResultObject {
let module_str = "(module
(type (;0;) (func))
(func (;0;) (type 0))
@ -222,19 +270,19 @@ fn create_module_7() -> ResultObject {
instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated")
}
fn start_module_7(result_object: &ResultObject) {
fn start_module_9(result_object: &ResultObject) {
result_object.instance.start();
}
// Line 93
// Line 91
#[test]
fn test_module_7() {
let result_object = create_module_7();
fn test_module_9() {
let result_object = create_module_9();
// We group the calls together
start_module_7(&result_object);
start_module_9(&result_object);
}
fn create_module_8() -> ResultObject {
fn create_module_10() -> ResultObject {
let module_str = "(module
(type (;0;) (func))
(import \"spectest\" \"table\" (table (;0;) 10 anyfunc))
@ -245,53 +293,11 @@ fn create_module_8() -> ResultObject {
instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated")
}
fn start_module_8(result_object: &ResultObject) {
result_object.instance.start();
}
// Line 99
#[test]
fn test_module_8() {
let result_object = create_module_8();
// We group the calls together
start_module_8(&result_object);
}
fn create_module_9() -> ResultObject {
let module_str = "(module
(table (;0;) 0 anyfunc)
(elem (;0;) (i32.const 0)))
";
let wasm_binary = wat2wasm(module_str.as_bytes()).expect("WAST not valid or malformed");
instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated")
}
fn start_module_9(result_object: &ResultObject) {
result_object.instance.start();
}
// Line 103
#[test]
fn test_module_9() {
let result_object = create_module_9();
// We group the calls together
start_module_9(&result_object);
}
fn create_module_10() -> ResultObject {
let module_str = "(module
(import \"spectest\" \"table\" (table (;0;) 0 anyfunc))
(elem (;0;) (i32.const 0)))
";
let wasm_binary = wat2wasm(module_str.as_bytes()).expect("WAST not valid or malformed");
instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated")
}
fn start_module_10(result_object: &ResultObject) {
result_object.instance.start();
}
// Line 108
// Line 97
#[test]
fn test_module_10() {
@ -301,7 +307,7 @@ fn test_module_10() {
}
fn create_module_11() -> ResultObject {
let module_str = "(module
(table (;0;) 0 0 anyfunc)
(table (;0;) 0 anyfunc)
(elem (;0;) (i32.const 0)))
";
let wasm_binary = wat2wasm(module_str.as_bytes()).expect("WAST not valid or malformed");
@ -312,7 +318,7 @@ fn start_module_11(result_object: &ResultObject) {
result_object.instance.start();
}
// Line 113
// Line 101
#[test]
fn test_module_11() {
@ -322,8 +328,8 @@ fn test_module_11() {
}
fn create_module_12() -> ResultObject {
let module_str = "(module
(table (;0;) 20 anyfunc)
(elem (;0;) (i32.const 20)))
(import \"spectest\" \"table\" (table (;0;) 0 anyfunc))
(elem (;0;) (i32.const 0)))
";
let wasm_binary = wat2wasm(module_str.as_bytes()).expect("WAST not valid or malformed");
instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated")
@ -333,7 +339,7 @@ fn start_module_12(result_object: &ResultObject) {
result_object.instance.start();
}
// Line 118
// Line 106
#[test]
fn test_module_12() {
@ -343,10 +349,8 @@ fn test_module_12() {
}
fn create_module_13() -> ResultObject {
let module_str = "(module
(type (;0;) (func))
(import \"spectest\" \"table\" (table (;0;) 0 anyfunc))
(func (;0;) (type 0))
(elem (;0;) (i32.const 0) 0))
(table (;0;) 0 0 anyfunc)
(elem (;0;) (i32.const 0)))
";
let wasm_binary = wat2wasm(module_str.as_bytes()).expect("WAST not valid or malformed");
instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated")
@ -356,7 +360,7 @@ fn start_module_13(result_object: &ResultObject) {
result_object.instance.start();
}
// Line 124
// Line 111
#[test]
fn test_module_13() {
@ -366,10 +370,8 @@ fn test_module_13() {
}
fn create_module_14() -> ResultObject {
let module_str = "(module
(type (;0;) (func))
(import \"spectest\" \"table\" (table (;0;) 0 100 anyfunc))
(func (;0;) (type 0))
(elem (;0;) (i32.const 0) 0))
(table (;0;) 20 anyfunc)
(elem (;0;) (i32.const 20)))
";
let wasm_binary = wat2wasm(module_str.as_bytes()).expect("WAST not valid or malformed");
instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated")
@ -379,7 +381,7 @@ fn start_module_14(result_object: &ResultObject) {
result_object.instance.start();
}
// Line 130
// Line 116
#[test]
fn test_module_14() {
@ -392,7 +394,7 @@ fn create_module_15() -> ResultObject {
(type (;0;) (func))
(import \"spectest\" \"table\" (table (;0;) 0 anyfunc))
(func (;0;) (type 0))
(elem (;0;) (i32.const 1) 0))
(elem (;0;) (i32.const 0) 0))
";
let wasm_binary = wat2wasm(module_str.as_bytes()).expect("WAST not valid or malformed");
instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated")
@ -402,7 +404,7 @@ fn start_module_15(result_object: &ResultObject) {
result_object.instance.start();
}
// Line 136
// Line 122
#[test]
fn test_module_15() {
@ -413,9 +415,9 @@ fn test_module_15() {
fn create_module_16() -> ResultObject {
let module_str = "(module
(type (;0;) (func))
(import \"spectest\" \"table\" (table (;0;) 0 30 anyfunc))
(import \"spectest\" \"table\" (table (;0;) 0 100 anyfunc))
(func (;0;) (type 0))
(elem (;0;) (i32.const 1) 0))
(elem (;0;) (i32.const 0) 0))
";
let wasm_binary = wat2wasm(module_str.as_bytes()).expect("WAST not valid or malformed");
instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated")
@ -425,79 +427,7 @@ fn start_module_16(result_object: &ResultObject) {
result_object.instance.start();
}
// Line 145
// Line 154
// Line 163
// Line 172
// Line 180
// Line 188
// Line 197
// Line 205
// Line 214
// Line 222
// Line 231
// Line 239
// Line 250
#[test]
fn c30_l250_assert_invalid() {
let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 1, 4, 1, 96, 0, 0, 3, 2, 1, 0, 9, 7, 1, 0, 65, 0, 11, 1, 0, 10, 4, 1, 2, 0, 11];
let compilation = compile(wasm_binary.to_vec());
assert!(compilation.is_err(), "WASM should not compile as is invalid");
}
// Line 260
#[test]
fn c31_l260_assert_invalid() {
let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 4, 4, 1, 112, 0, 1, 9, 6, 1, 0, 66, 0, 11, 0];
let compilation = compile(wasm_binary.to_vec());
assert!(compilation.is_err(), "WASM should not compile as is invalid");
}
// Line 268
#[test]
fn c32_l268_assert_invalid() {
let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 4, 4, 1, 112, 0, 1, 9, 7, 1, 0, 65, 0, 104, 11, 0];
let compilation = compile(wasm_binary.to_vec());
assert!(compilation.is_err(), "WASM should not compile as is invalid");
}
// Line 276
#[test]
fn c33_l276_assert_invalid() {
let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 4, 4, 1, 112, 0, 1, 9, 5, 1, 0, 1, 11, 0];
let compilation = compile(wasm_binary.to_vec());
assert!(compilation.is_err(), "WASM should not compile as is invalid");
}
// Line 284
#[test]
fn c34_l284_assert_invalid() {
let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 4, 4, 1, 112, 0, 1, 9, 7, 1, 0, 1, 65, 0, 11, 0];
let compilation = compile(wasm_binary.to_vec());
assert!(compilation.is_err(), "WASM should not compile as is invalid");
}
// Line 292
#[test]
fn c35_l292_assert_invalid() {
let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 4, 4, 1, 112, 0, 1, 9, 7, 1, 0, 65, 0, 1, 11, 0];
let compilation = compile(wasm_binary.to_vec());
assert!(compilation.is_err(), "WASM should not compile as is invalid");
}
// Line 307
// Line 128
#[test]
fn test_module_16() {
@ -506,6 +436,124 @@ fn test_module_16() {
start_module_16(&result_object);
}
fn create_module_17() -> ResultObject {
let module_str = "(module
(type (;0;) (func))
(import \"spectest\" \"table\" (table (;0;) 0 anyfunc))
(func (;0;) (type 0))
(elem (;0;) (i32.const 1) 0))
";
let wasm_binary = wat2wasm(module_str.as_bytes()).expect("WAST not valid or malformed");
instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated")
}
fn start_module_17(result_object: &ResultObject) {
result_object.instance.start();
}
// Line 134
#[test]
fn test_module_17() {
let result_object = create_module_17();
// We group the calls together
start_module_17(&result_object);
}
fn create_module_18() -> ResultObject {
let module_str = "(module
(type (;0;) (func))
(import \"spectest\" \"table\" (table (;0;) 0 30 anyfunc))
(func (;0;) (type 0))
(elem (;0;) (i32.const 1) 0))
";
let wasm_binary = wat2wasm(module_str.as_bytes()).expect("WAST not valid or malformed");
instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated")
}
fn start_module_18(result_object: &ResultObject) {
result_object.instance.start();
}
// Line 143
// Line 152
// Line 161
// Line 170
// Line 178
// Line 186
// Line 195
// Line 203
// Line 212
// Line 220
// Line 229
// Line 237
// Line 248
#[test]
fn c32_l248_assert_invalid() {
let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 1, 4, 1, 96, 0, 0, 3, 2, 1, 0, 9, 7, 1, 0, 65, 0, 11, 1, 0, 10, 4, 1, 2, 0, 11];
let compilation = compile(wasm_binary.to_vec());
assert!(compilation.is_err(), "WASM should not compile as is invalid");
}
// Line 258
#[test]
fn c33_l258_assert_invalid() {
let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 4, 4, 1, 112, 0, 1, 9, 6, 1, 0, 66, 0, 11, 0];
let compilation = compile(wasm_binary.to_vec());
assert!(compilation.is_err(), "WASM should not compile as is invalid");
}
// Line 266
#[test]
fn c34_l266_assert_invalid() {
let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 4, 4, 1, 112, 0, 1, 9, 7, 1, 0, 65, 0, 104, 11, 0];
let compilation = compile(wasm_binary.to_vec());
assert!(compilation.is_err(), "WASM should not compile as is invalid");
}
// Line 274
#[test]
fn c35_l274_assert_invalid() {
let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 4, 4, 1, 112, 0, 1, 9, 5, 1, 0, 1, 11, 0];
let compilation = compile(wasm_binary.to_vec());
assert!(compilation.is_err(), "WASM should not compile as is invalid");
}
// Line 282
#[test]
fn c36_l282_assert_invalid() {
let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 4, 4, 1, 112, 0, 1, 9, 7, 1, 0, 1, 65, 0, 11, 0];
let compilation = compile(wasm_binary.to_vec());
assert!(compilation.is_err(), "WASM should not compile as is invalid");
}
// Line 290
#[test]
fn c37_l290_assert_invalid() {
let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 4, 4, 1, 112, 0, 1, 9, 7, 1, 0, 65, 0, 1, 11, 0];
let compilation = compile(wasm_binary.to_vec());
assert!(compilation.is_err(), "WASM should not compile as is invalid");
}
// Line 305
#[test]
fn test_module_18() {
let result_object = create_module_18();
// We group the calls together
start_module_18(&result_object);
}
fn create_module_19() -> ResultObject {
let module_str = "(module
(type (;0;) (func (result i32)))
(func (;0;) (type 0) (result i32)
@ -524,13 +572,13 @@ fn create_module_17() -> ResultObject {
instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated")
}
fn start_module_17(result_object: &ResultObject) {
fn start_module_19(result_object: &ResultObject) {
result_object.instance.start();
}
// Line 318
fn c37_l318_action_invoke(result_object: &ResultObject) {
println!("Executing function {}", "c37_l318_action_invoke");
// Line 316
fn c39_l316_action_invoke(result_object: &ResultObject) {
println!("Executing function {}", "c39_l316_action_invoke");
let func_index = match result_object.module.info.exports.get("call-overwritten") {
Some(&Export::Function(index)) => index,
_ => panic!("Function not found"),
@ -540,16 +588,16 @@ fn c37_l318_action_invoke(result_object: &ResultObject) {
assert_eq!(result, 66 as i32);
}
// Line 320
// Line 318
#[test]
fn test_module_17() {
let result_object = create_module_17();
fn test_module_19() {
let result_object = create_module_19();
// We group the calls together
start_module_17(&result_object);
c37_l318_action_invoke(&result_object);
start_module_19(&result_object);
c39_l316_action_invoke(&result_object);
}
fn create_module_18() -> ResultObject {
fn create_module_20() -> ResultObject {
let module_str = "(module
(type (;0;) (func (result i32)))
(import \"spectest\" \"table\" (table (;0;) 10 anyfunc))
@ -568,13 +616,13 @@ fn create_module_18() -> ResultObject {
instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated")
}
fn start_module_18(result_object: &ResultObject) {
fn start_module_20(result_object: &ResultObject) {
result_object.instance.start();
}
// Line 331
fn c39_l331_action_invoke(result_object: &ResultObject) {
println!("Executing function {}", "c39_l331_action_invoke");
// Line 329
fn c41_l329_action_invoke(result_object: &ResultObject) {
println!("Executing function {}", "c41_l329_action_invoke");
let func_index = match result_object.module.info.exports.get("call-overwritten-element") {
Some(&Export::Function(index)) => index,
_ => panic!("Function not found"),
@ -584,16 +632,16 @@ fn c39_l331_action_invoke(result_object: &ResultObject) {
assert_eq!(result, 66 as i32);
}
// Line 335
// Line 333
#[test]
fn test_module_18() {
let result_object = create_module_18();
fn test_module_20() {
let result_object = create_module_20();
// We group the calls together
start_module_18(&result_object);
c39_l331_action_invoke(&result_object);
start_module_20(&result_object);
c41_l329_action_invoke(&result_object);
}
fn create_module_19() -> ResultObject {
fn create_module_21() -> ResultObject {
let module_str = "(module
(type (;0;) (func (result i32)))
(func (;0;) (type 0) (result i32)
@ -621,69 +669,62 @@ fn create_module_19() -> ResultObject {
instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated")
}
fn start_module_19(result_object: &ResultObject) {
result_object.instance.start();
}
// Line 353
// Line 360
#[test]
fn test_module_19() {
let result_object = create_module_19();
// We group the calls together
start_module_19(&result_object);
}
fn create_module_20() -> ResultObject {
let module_str = "(module
(type (;0;) (func (result i32)))
(import \"module1\" \"shared-table\" (table (;0;) 10 anyfunc))
(func (;0;) (type 0) (result i32)
i32.const 67)
(func (;1;) (type 0) (result i32)
i32.const 68)
(elem (;0;) (i32.const 7) 0)
(elem (;1;) (i32.const 8) 1))
";
let wasm_binary = wat2wasm(module_str.as_bytes()).expect("WAST not valid or malformed");
instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated")
}
fn start_module_20(result_object: &ResultObject) {
result_object.instance.start();
}
// Line 374
#[test]
fn test_module_20() {
let result_object = create_module_20();
// We group the calls together
start_module_20(&result_object);
}
fn create_module_21() -> ResultObject {
let module_str = "(module
(type (;0;) (func (result i32)))
(import \"module1\" \"shared-table\" (table (;0;) 10 anyfunc))
(func (;0;) (type 0) (result i32)
i32.const 69)
(func (;1;) (type 0) (result i32)
i32.const 70)
(elem (;0;) (i32.const 8) 0)
(elem (;1;) (i32.const 9) 1))
";
let wasm_binary = wat2wasm(module_str.as_bytes()).expect("WAST not valid or malformed");
instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated")
}
fn start_module_21(result_object: &ResultObject) {
result_object.instance.start();
}
// Line 351
// Line 353
fn c44_l353_action_invoke(result_object: &ResultObject) {
println!("Executing function {}", "c44_l353_action_invoke");
let func_index = match result_object.module.info.exports.get("call-7") {
Some(&Export::Function(index)) => index,
_ => panic!("Function not found"),
};
let invoke_fn: fn(&Instance) = get_instance_function!(result_object.instance, func_index);
let result = invoke_fn(&result_object.instance);
}
#[test]
fn c44_l353_assert_trap() {
let result_object = create_module_21();
let result = panic::catch_unwind(|| {
c44_l353_action_invoke(&result_object);
});
assert!(result.is_err());
}
// Line 354
fn c45_l354_action_invoke(result_object: &ResultObject) {
println!("Executing function {}", "c45_l354_action_invoke");
let func_index = match result_object.module.info.exports.get("call-8") {
Some(&Export::Function(index)) => index,
_ => panic!("Function not found"),
};
let invoke_fn: fn(&Instance) -> i32 = get_instance_function!(result_object.instance, func_index);
let result = invoke_fn(&result_object.instance);
assert_eq!(result, 65 as i32);
}
// Line 355
fn c46_l355_action_invoke(result_object: &ResultObject) {
println!("Executing function {}", "c46_l355_action_invoke");
let func_index = match result_object.module.info.exports.get("call-9") {
Some(&Export::Function(index)) => index,
_ => panic!("Function not found"),
};
let invoke_fn: fn(&Instance) -> i32 = get_instance_function!(result_object.instance, func_index);
let result = invoke_fn(&result_object.instance);
assert_eq!(result, 66 as i32);
}
#[test]
fn test_module_21() {
let result_object = create_module_21();
// We group the calls together
start_module_21(&result_object);
c45_l354_action_invoke(&result_object);
c46_l355_action_invoke(&result_object);
}

View File

@ -112,7 +112,7 @@ where
#[derive(PartialEq, Debug)]
pub enum ImportValue {
Func(*const u8),
Global(u8),
Global(i64),
Table(Vec<usize>),
Memory(LinearMemory),
}

View File

@ -9,7 +9,7 @@
use cranelift_codegen::ir::LibCall;
use cranelift_codegen::{binemit, Context};
use cranelift_entity::EntityRef;
use cranelift_wasm::{FuncIndex, GlobalInit};
use cranelift_wasm::{FuncIndex, GlobalInit, GlobalIndex};
use cranelift_codegen::isa::TargetIsa;
use region;
use std::iter::Iterator;
@ -22,8 +22,7 @@ use super::super::common::slice::{BoundedSlice, UncheckedSlice};
use super::errors::ErrorKind;
use super::import_object::{ImportObject, ImportValue};
use super::memory::LinearMemory;
use super::module::Export;
use super::module::Module;
use super::module::{Export, Exportable, Module};
use super::relocation::{Reloc, RelocSink, RelocationType};
use super::math_intrinsics;
@ -145,9 +144,6 @@ impl Instance {
let mut functions: Vec<Vec<u8>> = Vec::new();
let mut import_functions: Vec<*const u8> = Vec::new();
let mut imported_memories: Vec<LinearMemory> = Vec::new();
let mut imported_tables: Vec<Vec<usize>> = Vec::new();
debug!("Instance - Instantiating functions");
// Instantiate functions
{
@ -295,45 +291,81 @@ impl Instance {
}
}
// Looping through and getting the imported objects
for (_key, value) in import_object.map {
match value {
ImportValue::Memory(value) =>
imported_memories.push(value),
ImportValue::Table(value) =>
imported_tables.push(value),
_ => (),
debug!("Instance - Instantiating globals");
// Instantiate Globals
let globals_data = {
let globals_count = module.info.globals.len();
// Allocate the underlying memory and initialize it to zeros
let globals_data_size = globals_count * 8;
globals.resize(globals_data_size, 0);
// cast the globals slice to a slice of i64.
let globals_data = unsafe {
slice::from_raw_parts_mut(globals.as_mut_ptr() as *mut i64, globals_count)
};
for (i, global) in module.info.globals.iter().enumerate() {
let Exportable {entity, import_name, ..} = global;
let value: i64 = match entity.initializer {
GlobalInit::I32Const(n) => n as _,
GlobalInit::I64Const(n) => n,
GlobalInit::F32Const(f) => f as _, // unsafe { mem::transmute(f as f64) },
GlobalInit::F64Const(f) => f as _, // unsafe { mem::transmute(f) },
GlobalInit::GlobalRef(_global_index) => {
unimplemented!("GlobalInit::GlobalRef is not yet supported")
}
GlobalInit::Import() => {
let (module_name, field_name) = import_name.as_ref().expect("Expected a import name for the global import");
let imported = import_object.get(&module_name.as_str(), &field_name.as_str());
match imported {
Some(ImportValue::Global(value)) => {
*value
},
_ => panic!("Imported global value was not provided {:?} ({}.{})", imported, module_name, field_name)
}
}
};
globals_data[i] = value;
}
}
globals_data
};
debug!("Instance - Instantiating tables");
// Instantiate tables
{
// Reserve space for tables
tables.reserve_exact(imported_tables.len() + module.info.tables.len());
// Get imported tables
for table in imported_tables {
tables.push(table);
}
tables.reserve_exact(module.info.tables.len());
// Get tables in module
for table in &module.info.tables {
let len = table.entity.size;
let mut v = Vec::with_capacity(len);
v.resize(len, 0);
tables.push(v);
let table: Vec<usize> = match table.import_name.as_ref() {
Some((module_name, field_name)) => {
let imported = import_object.get(&module_name.as_str(), &field_name.as_str());
match imported {
Some(ImportValue::Table(t)) => {
t.to_vec()
},
_ => panic!("Imported table was not provided {:?} ({}.{})", imported, module_name, field_name)
}
},
None => {
let len = table.entity.size;
let mut v = Vec::with_capacity(len);
v.resize(len, 0);
v
}
};
tables.push(table);
}
// instantiate tables
for table_element in &module.info.table_elements {
// TODO: We shouldn't assert here since we are returning a Result<Instance, ErrorKind>
assert!(
table_element.base.is_none(),
"globalvalue base not supported yet."
);
let base = 0;
let base = match table_element.base {
Some(global_index) => {
globals_data[global_index.index()] as usize
},
None => 0
};
let table = &mut tables[table_element.table_index.index()];
for (i, func_index) in table_element.elements.iter().enumerate() {
@ -343,6 +375,7 @@ impl Instance {
// let func_index = *elem_index - module.info.imported_funcs.len() as u32;
// let func_addr = functions[func_index.index()].as_ptr();
println!("TABLE LENGTH: {}", table.len());
let func_addr = get_function_addr(&func_index, &import_functions, &functions);
table[base + table_element.offset + i] = func_addr as _;
}
@ -353,12 +386,7 @@ impl Instance {
// Instantiate memories
{
// Reserve space for memories
memories.reserve_exact(imported_memories.len() + module.info.memories.len());
// Get imported memories
for memory in imported_memories {
memories.push(memory);
}
memories.reserve_exact(module.info.memories.len());
// Get memories in module
for memory in &module.info.memories {
@ -379,41 +407,6 @@ impl Instance {
}
}
debug!("Instance - Instantiating globals");
// TODO: Fix globals import
// Instantiate Globals
{
let globals_count = module.info.globals.len();
// Allocate the underlying memory and initialize it to zeros
let globals_data_size = globals_count * 8;
globals.resize(globals_data_size, 0);
// cast the globals slice to a slice of i64.
let globals_data = unsafe {
slice::from_raw_parts_mut(globals.as_mut_ptr() as *mut i64, globals_count)
};
for (i, global) in module.info.globals.iter().enumerate() {
let value: i64 = match global.entity.initializer {
GlobalInit::I32Const(n) => n as _,
GlobalInit::I64Const(n) => n,
GlobalInit::F32Const(f) => f as _, // unsafe { mem::transmute(f as f64) },
GlobalInit::F64Const(f) => f as _, // unsafe { mem::transmute(f) },
GlobalInit::GlobalRef(_global_index) => {
unimplemented!("GlobalInit::GlobalRef is not yet supported")
}
GlobalInit::Import() => {
// Right now (because there is no module/field fields on the Import
// https://github.com/CraneStation/cranelift/blob/5cabce9b58ff960534d4017fad11f2e78c72ceab/lib/wasm/src/sections_translator.rs#L90-L99 )
// It's impossible to know where to take the global from.
// This should be fixed in Cranelift itself.
unimplemented!("GlobalInit::Import is not yet supported")
}
};
globals_data[i] = value;
}
}
let start_func: Option<FuncIndex> =
module
.info

View File

@ -79,13 +79,17 @@ pub struct Exportable<T> {
/// Names under which the entity is exported.
pub export_names: Vec<String>,
/// Names under which the entity is imported.
pub import_name: Option<(String, String)>,
}
impl<T> Exportable<T> {
pub fn new(entity: T) -> Self {
pub fn new(entity: T, import_name: Option<(String, String)>) -> Self {
Self {
entity,
export_names: Vec::new(),
import_name: import_name
}
}
}
@ -708,7 +712,7 @@ impl<'data> ModuleEnvironment<'data> for Module {
self.info.imported_funcs.len(),
"Imported functions must be declared first"
);
self.info.functions.push(Exportable::new(sig_index));
self.info.functions.push(Exportable::new(sig_index, None));
self.info
.imported_funcs
.push((String::from(module), String::from(field)));
@ -719,7 +723,7 @@ impl<'data> ModuleEnvironment<'data> for Module {
}
fn declare_func_type(&mut self, sig_index: SignatureIndex) {
self.info.functions.push(Exportable::new(sig_index));
self.info.functions.push(Exportable::new(sig_index, None));
}
fn get_func_type(&self, func_index: FuncIndex) -> SignatureIndex {
@ -727,7 +731,16 @@ impl<'data> ModuleEnvironment<'data> for Module {
}
fn declare_global(&mut self, global: Global) {
self.info.globals.push(Exportable::new(global));
self.info.globals.push(Exportable::new(global, None));
}
fn declare_global_import(
&mut self,
global: Global,
module: &'data str,
field: &'data str,
) {
self.info.globals.push(Exportable::new(global, Some((String::from(module), String::from(field)))));
}
fn get_global(&self, global_index: GlobalIndex) -> &Global {
@ -735,7 +748,16 @@ impl<'data> ModuleEnvironment<'data> for Module {
}
fn declare_table(&mut self, table: Table) {
self.info.tables.push(Exportable::new(table));
self.info.tables.push(Exportable::new(table, None));
}
fn declare_table_import(
&mut self,
table: Table,
module: &'data str,
field: &'data str,
) {
self.info.tables.push(Exportable::new(table, Some((String::from(module), String::from(field)))));
}
fn declare_table_elements(
@ -745,7 +767,6 @@ impl<'data> ModuleEnvironment<'data> for Module {
offset: usize,
elements: Vec<FuncIndex>,
) {
debug_assert!(base.is_none(), "global-value offsets not supported yet");
self.info.table_elements.push(TableElements {
table_index,
base,
@ -755,7 +776,16 @@ impl<'data> ModuleEnvironment<'data> for Module {
}
fn declare_memory(&mut self, memory: Memory) {
self.info.memories.push(Exportable::new(memory));
self.info.memories.push(Exportable::new(memory, None));
}
fn declare_memory_import(
&mut self,
memory: Memory,
module: &'data str,
field: &'data str,
) {
self.info.memories.push(Exportable::new(memory, Some((String::from(module), String::from(field)))));
}
fn declare_data_initialization(