Skip to content

Commit

Permalink
[spec/interpreter] Correct and test segment offset syntax (#663)
Browse files Browse the repository at this point in the history
  • Loading branch information
rossberg authored Feb 14, 2018
1 parent 6700fd9 commit 1a03844
Show file tree
Hide file tree
Showing 4 changed files with 579 additions and 142 deletions.
22 changes: 20 additions & 2 deletions document/core/text/modules.rst
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,16 @@ When omitted, :math:`\T{0}` is assumed.
Abbreviations
.............

As an abbreviation, element segments may also be specified inline with :ref:`table <text-table>` definitions; see the respective section.
As an abbreviation, a single instruction may occur in place of the offset:

.. math:
\begin{array}{llcll}
\production{element offset} &
\Tinstr &\equiv&
\text{(}~\text{offset}~~\Tinstr~\text{)}
\end{array}
As another abbreviation, element segments may also be specified inline with :ref:`table <text-table>` definitions; see the respective section.


.. index:: data, memory, memory index, expression, byte
Expand Down Expand Up @@ -524,7 +533,16 @@ The data is written as a :ref:`string <text-string>`, which may be split up into
Abbreviations
.............

As an abbreviation, data segments may also be specified inline with :ref:`memory <text-mem>` definitions; see the respective section.
As an abbreviation, a single instruction may occur in place of the offset:

.. math:
\begin{array}{llcll}
\production{data offset} &
\Tinstr &\equiv&
\text{(}~\text{offset}~~\Tinstr~\text{)}
\end{array}
As another abbreviation, data segments may also be specified inline with :ref:`memory <text-mem>` definitions; see the respective section.


.. index:: module, type definition, function type, function, table, memory, global, element, data, start function, import, export, identifier context, identifier, name section
Expand Down
335 changes: 335 additions & 0 deletions test/core/data.wast
Original file line number Diff line number Diff line change
@@ -0,0 +1,335 @@
;; Test the data section

;; Syntax

(module
(memory $m 1)
(data (i32.const 0))
(data (i32.const 1) "a" "" "bcd")
(data (offset (i32.const 0)))
(data (offset (i32.const 0)) "" "a" "bc" "")
(data 0 (i32.const 0))
(data 0x0 (i32.const 1) "a" "" "bcd")
(data 0x000 (offset (i32.const 0)))
(data 0 (offset (i32.const 0)) "" "a" "bc" "")
(data $m (i32.const 0))
(data $m (i32.const 1) "a" "" "bcd")
(data $m (offset (i32.const 0)))
(data $m (offset (i32.const 0)) "" "a" "bc" "")
)

;; Basic use

(module
(memory 1)
(data (i32.const 0) "a")
)
(module
(import "spectest" "memory" (memory 1))
(data (i32.const 0) "a")
)

(module
(memory 1)
(data (i32.const 0) "a")
(data (i32.const 3) "b")
(data (i32.const 100) "cde")
(data (i32.const 5) "x")
(data (i32.const 3) "c")
)
(module
(import "spectest" "memory" (memory 1))
(data (i32.const 0) "a")
(data (i32.const 1) "b")
(data (i32.const 2) "cde")
(data (i32.const 3) "f")
(data (i32.const 2) "g")
(data (i32.const 1) "h")
)

(module
(global (import "spectest" "global_i32") i32)
(memory 1)
(data (get_global 0) "a")
)
(module
(global (import "spectest" "global_i32") i32)
(import "spectest" "memory" (memory 1))
(data (get_global 0) "a")
)

(module
(global $g (import "spectest" "global_i32") i32)
(memory 1)
(data (get_global $g) "a")
)
(module
(global $g (import "spectest" "global_i32") i32)
(import "spectest" "memory" (memory 1))
(data (get_global $g) "a")
)

;; Use of internal globals in constant expressions is not allowed in MVP.
;; (module (memory 1) (data (get_global 0) "a") (global i32 (i32.const 0)))
;; (module (memory 1) (data (get_global $g) "a") (global $g i32 (i32.const 0)))

;; Corner cases

(module
(memory 1)
(data (i32.const 0) "a")
(data (i32.const 0xffff) "b")
)
(module
(import "spectest" "memory" (memory 1))
(data (i32.const 0) "a")
(data (i32.const 0xffff) "b")
)

(module
(memory 2)
(data (i32.const 0x1_ffff) "a")
)

(module
(memory 0)
(data (i32.const 0))
)
(module
(import "spectest" "memory" (memory 0))
(data (i32.const 0))
)

(module
(memory 0 0)
(data (i32.const 0))
)

(module
(memory 1)
(data (i32.const 0x1_0000) "")
)

(module
(memory 0)
(data (i32.const 0) "" "")
)
(module
(import "spectest" "memory" (memory 0))
(data (i32.const 0) "" "")
)

(module
(memory 0 0)
(data (i32.const 0) "" "")
)

(module
(import "spectest" "memory" (memory 0))
(data (i32.const 0) "a")
)

(module
(import "spectest" "memory" (memory 0 3))
(data (i32.const 0) "a")
)

(module
(global (import "spectest" "global_i32") i32)
(import "spectest" "memory" (memory 0))
(data (get_global 0) "a")
)

(module
(global (import "spectest" "global_i32") i32)
(import "spectest" "memory" (memory 0 3))
(data (get_global 0) "a")
)

(module
(import "spectest" "memory" (memory 0))
(data (i32.const 1) "a")
)

(module
(import "spectest" "memory" (memory 0 3))
(data (i32.const 1) "a")
)

;; Invalid bounds for data

(assert_unlinkable
(module
(memory 0)
(data (i32.const 0) "a")
)
"data segment does not fit"
)

(assert_unlinkable
(module
(memory 0 0)
(data (i32.const 0) "a")
)
"data segment does not fit"
)

(assert_unlinkable
(module
(memory 0 1)
(data (i32.const 0) "a")
)
"data segment does not fit"
)

(assert_unlinkable
(module
(memory 0)
(data (i32.const 1))
)
"data segment does not fit"
)

(assert_unlinkable
(module
(memory 0 1)
(data (i32.const 1))
)
"data segment does not fit"
)

;; This seems to cause a time-out on Travis.
(;assert_unlinkable
(module
(memory 0x10000)
(data (i32.const 0xffffffff) "ab")
)
"" ;; either out of memory or segment does not fit
;)

(assert_unlinkable
(module
(global (import "spectest" "global_i32") i32)
(memory 0)
(data (get_global 0) "a")
)
"data segment does not fit"
)

(assert_unlinkable
(module
(memory 1 2)
(data (i32.const 0x1_0000) "a")
)
"data segment does not fit"
)
(assert_unlinkable
(module
(import "spectest" "memory" (memory 1))
(data (i32.const 0x1_0000) "a")
)
"data segment does not fit"
)

(assert_unlinkable
(module
(memory 2)
(data (i32.const 0x2_0000) "a")
)
"data segment does not fit"
)

(assert_unlinkable
(module
(memory 2 3)
(data (i32.const 0x2_0000) "a")
)
"data segment does not fit"
)

(assert_unlinkable
(module
(memory 1)
(data (i32.const -1) "a")
)
"data segment does not fit"
)
(assert_unlinkable
(module
(import "spectest" "memory" (memory 1))
(data (i32.const -1) "a")
)
"data segment does not fit"
)

(assert_unlinkable
(module
(memory 2)
(data (i32.const -100) "a")
)
"data segment does not fit"
)
(assert_unlinkable
(module
(import "spectest" "memory" (memory 1))
(data (i32.const -100) "a")
)
"data segment does not fit"
)

;; Data without memory

(assert_invalid
(module
(data (i32.const 0) "")
)
"unknown memory 0"
)

;; Invalid offsets

(assert_invalid
(module
(memory 1)
(data (i64.const 0))
)
"type mismatch"
)

(assert_invalid
(module
(memory 1)
(data (i32.ctz (i32.const 0)))
)
"constant expression required"
)

(assert_invalid
(module
(memory 1)
(data (nop))
)
"constant expression required"
)

(assert_invalid
(module
(memory 1)
(data (offset (nop) (i32.const 0)))
)
"constant expression required"
)

(assert_invalid
(module
(memory 1)
(data (offset (i32.const 0) (nop)))
)
"constant expression required"
)

;; Use of internal globals in constant expressions is not allowed in MVP.
;; (assert_invalid
;; (module (memory 1) (data (get_global $g)) (global $g (mut i32) (i32.const 0)))
;; "constant expression required"
;; )
Loading

0 comments on commit 1a03844

Please sign in to comment.