Skip to content

Commit

Permalink
Merge upstream (WebAssembly#130)
Browse files Browse the repository at this point in the history
  • Loading branch information
rossberg committed Jan 20, 2021
2 parents dd92422 + fc4b17f commit cbb4030
Show file tree
Hide file tree
Showing 11 changed files with 388 additions and 32 deletions.
30 changes: 30 additions & 0 deletions interpreter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,36 @@ The `input` and `output` meta commands determine the requested file format from
The interpreter supports a "dry" mode (flag `-d`), in which modules are only validated. In this mode, all actions and assertions are ignored.
It also supports an "unchecked" mode (flag `-u`), in which module definitions are not validated before use.


### Spectest host module

When running scripts, the interpreter predefines a simple host module named `"spectest"` that has the following module type:
```
(module
(global (export "global_i32") i32)
(global (export "global_i64") i64)
(global (export "global_f32") f32)
(global (export "global_f64") f64)
(table (export "table") 10 20 funcref)
(memory (export "memory") 1 2)
(func (export "print"))
(func (export "print_i32") (param i32))
(func (export "print_i64") (param i64))
(func (export "print_f32") (param f32))
(func (export "print_f64") (param f64))
(func (export "print_i32_f32") (param i32 f32))
(func (export "print_f64_f64") (param f64 f64))
)
```
The `print` functions are assumes to print their respective argument values to stdout (followed by a newline) and can be used to produce observable output.

Note: This module predates the `register` command and should no longer be needed for new tests.
We might remove it in the future, so consider it deprecated.


### Binary Scripts

The grammar of binary scripts is a subset of the grammar for general scripts:
Expand Down
6 changes: 4 additions & 2 deletions interpreter/host/spectest.ml
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,15 @@ let lookup name t =
match Utf8.encode name, t with
| "print", _ -> ExternFunc (func print (FuncType ([], [])))
| "print_i32", _ -> ExternFunc (func print (FuncType ([NumType I32Type], [])))
| "print_i64", _ -> ExternFunc (func print (FuncType ([NumType I64Type], [])))
| "print_f32", _ -> ExternFunc (func print (FuncType ([NumType F32Type], [])))
| "print_f64", _ -> ExternFunc (func print (FuncType ([NumType F64Type], [])))
| "print_i32_f32", _ ->
ExternFunc (func print (FuncType ([NumType I32Type; NumType F32Type], [])))
| "print_f64_f64", _ ->
ExternFunc (func print (FuncType ([NumType F64Type; NumType F64Type], [])))
| "print_f32", _ -> ExternFunc (func print (FuncType ([NumType F32Type], [])))
| "print_f64", _ -> ExternFunc (func print (FuncType ([NumType F64Type], [])))
| "global_i32", _ -> ExternGlobal (global (GlobalType (NumType I32Type, Immutable)))
| "global_i64", _ -> ExternGlobal (global (GlobalType (NumType I64Type, Immutable)))
| "global_f32", _ -> ExternGlobal (global (GlobalType (NumType F32Type, Immutable)))
| "global_f64", _ -> ExternGlobal (global (GlobalType (NumType F64Type, Immutable)))
| "table", _ -> ExternTable table
Expand Down
2 changes: 1 addition & 1 deletion test/core/binary-leb128.wast
Original file line number Diff line number Diff line change
Expand Up @@ -853,7 +853,7 @@
"\41\00" ;; i32.const 0
"\41\03" ;; i32.const 3
"\36" ;; i32.store
"\03" ;; alignment 2
"\02" ;; alignment 2
"\82\80\80\80\10" ;; offset 2 with unused bits set
"\0b" ;; end
)
Expand Down
71 changes: 67 additions & 4 deletions test/core/binary.wast
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,19 @@
"\41\00\0b\00\00" ;; (i32.const 0) with no elements
)

;; Type section with signed LEB128 encoded type
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01" ;; Type section id
"\05" ;; Type section length
"\01" ;; Types vector length
"\e0\7f" ;; Malformed functype, -0x20 in signed LEB128 encoding
"\00\00"
)
"integer representation too long"
)

;; Unsigned LEB128 must not be overlong
(assert_malformed
(module binary
Expand Down Expand Up @@ -929,7 +942,24 @@
"zero byte expected"
)

;; No more than 2^32 locals.
;; Local number is unsigned 32 bit
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\04\01\60\00\00" ;; Type section
"\03\02\01\00" ;; Function section
"\0a\0c\01" ;; Code section

;; function 0
"\0a\02"
"\80\80\80\80\10\7f" ;; 0x100000000 i32
"\02\7e" ;; 0x00000002 i64
"\0b" ;; end
)
"integer too large"
)

;; No more than 2^32-1 locals.
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
Expand All @@ -946,6 +976,24 @@
"too many locals"
)

(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\06\01\60\02\7f\7f\00" ;; Type section: (param i32 i32)
"\03\02\01\00" ;; Function section
"\0a\1c\01" ;; Code section

;; function 0
"\1a\04"
"\80\80\80\80\04\7f" ;; 0x40000000 i32
"\80\80\80\80\04\7e" ;; 0x40000000 i64
"\80\80\80\80\04\7d" ;; 0x40000000 f32
"\80\80\80\80\04\7c" ;; 0x40000000 f64
"\0b" ;; end
)
"too many locals"
)

;; Local count can be 0.
(module binary
"\00asm" "\01\00\00\00"
Expand Down Expand Up @@ -1528,10 +1576,25 @@
"\09\07\02" ;; elem with inconsistent segment count (2 declared, 1 given)
"\00\41\00\0b\01\00" ;; elem 0
;; "\00\41\00\0b\01\00" ;; elem 1 (missed)
"\0a\04\01" ;; code section
"\02\00\0b" ;; function body
)
"malformed elements segment kind"
"unexpected end"
)

;; 2 elem segment declared, 1.5 given
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\04\01" ;; type section
"\60\00\00" ;; type 0
"\03\02\01\00" ;; func section
"\04\04\01" ;; table section
"\70\00\01" ;; table 0
"\09\07\02" ;; elem with inconsistent segment count (2 declared, 1 given)
"\00\41\00\0b\01\00" ;; elem 0
"\00\41\00" ;; elem 1 (partial)
;; "\0b\01\00" ;; elem 1 (missing part)
)
"unexpected end"
)

;; 1 elem segment declared, 2 given
Expand Down
35 changes: 35 additions & 0 deletions test/core/br_table.wast
Original file line number Diff line number Diff line change
Expand Up @@ -1488,6 +1488,16 @@
))
"type mismatch"
)
(assert_invalid
(module (func
(block (result i32)
(block (result i64)
(br_table 0 1 (i32.const 0) (i32.const 0))
)
)
))
"type mismatch"
)

(assert_invalid
(module (func $type-index-void-vs-i32
Expand Down Expand Up @@ -1576,6 +1586,31 @@
"type mismatch"
)

(assert_invalid
(module
(func (param i32) (result i32)
(loop (result i32)
(block (result i32)
(br_table 0 1 (i32.const 1) (local.get 0))
)
)
)
)
"type mismatch"
)
(assert_invalid
(module
(func (param i32) (result i32)
(block (result i32)
(loop (result i32)
(br_table 0 1 (i32.const 1) (local.get 0))
)
)
)
)
"type mismatch"
)


(assert_invalid
(module (func $meet-bottom (param i32) (result externref)
Expand Down
76 changes: 76 additions & 0 deletions test/core/data.wast
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,82 @@
"unknown memory"
)

;; Data segment with memory index 1 (only memory 0 available)
(assert_invalid
(module binary
"\00asm" "\01\00\00\00"
"\05\03\01" ;; memory section
"\00\00" ;; memory 0
"\0b\07\01" ;; data section
"\02\01\41\00\0b" ;; data segment 0 for memory 1
"\00" ;; empty vec(byte)
)
"unknown memory 1"
)

;; Data segment with memory index 0 (no memory section)
(assert_invalid
(module binary
"\00asm" "\01\00\00\00"
"\0b\06\01" ;; data section
"\00\41\00\0b" ;; data segment 0 for memory 0
"\00" ;; empty vec(byte)
)
"unknown memory 0"
)

;; Data segment with memory index 1 (no memory section)
(assert_invalid
(module binary
"\00asm" "\01\00\00\00"
"\0b\07\01" ;; data section
"\02\01\41\00\0b" ;; data segment 0 for memory 1
"\00" ;; empty vec(byte)
)
"unknown memory 1"
)

;; Data segment with memory index 1 and vec(byte) as above,
;; only memory 0 available.
(assert_invalid
(module binary
"\00asm" "\01\00\00\00"
"\05\03\01" ;; memory section
"\00\00" ;; memory 0
"\0b\45\01" ;; data section
"\02" ;; active segment
"\01" ;; memory index
"\41\00\0b" ;; offset constant expression
"\3e" ;; vec(byte) length
"\00\01\02\03\04\05\06\07\08\09\0a\0b\0c\0d\0e\0f"
"\10\11\12\13\14\15\16\17\18\19\1a\1b\1c\1d\1e\1f"
"\20\21\22\23\24\25\26\27\28\29\2a\2b\2c\2d\2e\2f"
"\30\31\32\33\34\35\36\37\38\39\3a\3b\3c\3d"
)
"unknown memory 1"
)

;; Data segment with memory index 1 and specially crafted vec(byte) after.
;; This is to detect incorrect validation where memory index is interpreted
;; as a flag followed by "\41" interpreted as the size of vec(byte)
;; with the expected number of bytes following.
(assert_invalid
(module binary
"\00asm" "\01\00\00\00"
"\0b\45\01" ;; data section
"\02" ;; active segment
"\01" ;; memory index
"\41\00\0b" ;; offset constant expression
"\3e" ;; vec(byte) length
"\00\01\02\03\04\05\06\07\08\09\0a\0b\0c\0d\0e\0f"
"\10\11\12\13\14\15\16\17\18\19\1a\1b\1c\1d\1e\1f"
"\20\21\22\23\24\25\26\27\28\29\2a\2b\2c\2d\2e\2f"
"\30\31\32\33\34\35\36\37\38\39\3a\3b\3c\3d"
)
"unknown memory 1"
)


;; Invalid offsets

(assert_invalid
Expand Down
32 changes: 32 additions & 0 deletions test/core/exports.wast
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,18 @@
(module $Other1)
(assert_return (invoke $Func "e" (i32.const 42)) (i32.const 43))

(assert_invalid
(module (export "a" (func 0)))
"unknown function"
)
(assert_invalid
(module (func) (export "a" (func 1)))
"unknown function"
)
(assert_invalid
(module (import "spectest" "print_i32" (func (param i32))) (export "a" (func 1)))
"unknown function"
)
(assert_invalid
(module (func) (export "a" (func 0)) (export "a" (func 0)))
"duplicate export name"
Expand Down Expand Up @@ -74,10 +82,18 @@
(module $Other2)
(assert_return (get $Global "e") (i32.const 42))

(assert_invalid
(module (export "a" (global 0)))
"unknown global"
)
(assert_invalid
(module (global i32 (i32.const 0)) (export "a" (global 1)))
"unknown global"
)
(assert_invalid
(module (import "spectest" "global_i32" (global i32)) (export "a" (global 1)))
"unknown global"
)
(assert_invalid
(module (global i32 (i32.const 0)) (export "a" (global 0)) (export "a" (global 0)))
"duplicate export name"
Expand Down Expand Up @@ -121,10 +137,18 @@

(; TODO: access table ;)

(assert_invalid
(module (export "a" (table 0)))
"unknown table"
)
(assert_invalid
(module (table 0 funcref) (export "a" (table 1)))
"unknown table"
)
(assert_invalid
(module (import "spectest" "table" (table 10 20 funcref)) (export "a" (table 1)))
"unknown table"
)
(assert_invalid
(module (table 0 funcref) (export "a" (table 0)) (export "a" (table 0)))
"duplicate export name"
Expand Down Expand Up @@ -169,10 +193,18 @@

(; TODO: access memory ;)

(assert_invalid
(module (export "a" (memory 0)))
"unknown memory"
)
(assert_invalid
(module (memory 0) (export "a" (memory 1)))
"unknown memory"
)
(assert_invalid
(module (import "spectest" "memory" (memory 1 2)) (export "a" (memory 1)))
"unknown memory"
)
(assert_invalid
(module (memory 0) (export "a" (memory 0)) (export "a" (memory 0)))
"duplicate export name"
Expand Down
Loading

0 comments on commit cbb4030

Please sign in to comment.