github.com/tetratelabs/wazero@v1.7.3-0.20240513003603-48f702e154b5/internal/integration_test/spectest/v2/testdata/bulk.wast (about)

     1  ;; segment syntax
     2  (module
     3    (memory 1)
     4    (data "foo"))
     5  
     6  (module
     7    (table 3 funcref)
     8    (elem funcref (ref.func 0) (ref.null func) (ref.func 1))
     9    (func)
    10    (func))
    11  
    12  ;; memory.fill
    13  (module
    14    (memory 1)
    15  
    16    (func (export "fill") (param i32 i32 i32)
    17      (memory.fill
    18        (local.get 0)
    19        (local.get 1)
    20        (local.get 2)))
    21  
    22    (func (export "load8_u") (param i32) (result i32)
    23      (i32.load8_u (local.get 0)))
    24  )
    25  
    26  ;; Basic fill test.
    27  (invoke "fill" (i32.const 1) (i32.const 0xff) (i32.const 3))
    28  (assert_return (invoke "load8_u" (i32.const 0)) (i32.const 0))
    29  (assert_return (invoke "load8_u" (i32.const 1)) (i32.const 0xff))
    30  (assert_return (invoke "load8_u" (i32.const 2)) (i32.const 0xff))
    31  (assert_return (invoke "load8_u" (i32.const 3)) (i32.const 0xff))
    32  (assert_return (invoke "load8_u" (i32.const 4)) (i32.const 0))
    33  
    34  ;; Fill value is stored as a byte.
    35  (invoke "fill" (i32.const 0) (i32.const 0xbbaa) (i32.const 2))
    36  (assert_return (invoke "load8_u" (i32.const 0)) (i32.const 0xaa))
    37  (assert_return (invoke "load8_u" (i32.const 1)) (i32.const 0xaa))
    38  
    39  ;; Fill all of memory
    40  (invoke "fill" (i32.const 0) (i32.const 0) (i32.const 0x10000))
    41  
    42  ;; Out-of-bounds writes trap, and nothing is written
    43  (assert_trap (invoke "fill" (i32.const 0xff00) (i32.const 1) (i32.const 0x101))
    44      "out of bounds memory access")
    45  (assert_return (invoke "load8_u" (i32.const 0xff00)) (i32.const 0))
    46  (assert_return (invoke "load8_u" (i32.const 0xffff)) (i32.const 0))
    47  
    48  ;; Succeed when writing 0 bytes at the end of the region.
    49  (invoke "fill" (i32.const 0x10000) (i32.const 0) (i32.const 0))
    50  
    51  ;; Writing 0 bytes outside the memory traps.
    52  (assert_trap (invoke "fill" (i32.const 0x10001) (i32.const 0) (i32.const 0))
    53      "out of bounds memory access")
    54  
    55  
    56  ;; memory.copy
    57  (module
    58    (memory (data "\aa\bb\cc\dd"))
    59  
    60    (func (export "copy") (param i32 i32 i32)
    61      (memory.copy
    62        (local.get 0)
    63        (local.get 1)
    64        (local.get 2)))
    65  
    66    (func (export "load8_u") (param i32) (result i32)
    67      (i32.load8_u (local.get 0)))
    68  )
    69  
    70  ;; Non-overlapping copy.
    71  (invoke "copy" (i32.const 10) (i32.const 0) (i32.const 4))
    72  
    73  (assert_return (invoke "load8_u" (i32.const 9)) (i32.const 0))
    74  (assert_return (invoke "load8_u" (i32.const 10)) (i32.const 0xaa))
    75  (assert_return (invoke "load8_u" (i32.const 11)) (i32.const 0xbb))
    76  (assert_return (invoke "load8_u" (i32.const 12)) (i32.const 0xcc))
    77  (assert_return (invoke "load8_u" (i32.const 13)) (i32.const 0xdd))
    78  (assert_return (invoke "load8_u" (i32.const 14)) (i32.const 0))
    79  
    80  ;; Overlap, source > dest
    81  (invoke "copy" (i32.const 8) (i32.const 10) (i32.const 4))
    82  (assert_return (invoke "load8_u" (i32.const 8)) (i32.const 0xaa))
    83  (assert_return (invoke "load8_u" (i32.const 9)) (i32.const 0xbb))
    84  (assert_return (invoke "load8_u" (i32.const 10)) (i32.const 0xcc))
    85  (assert_return (invoke "load8_u" (i32.const 11)) (i32.const 0xdd))
    86  (assert_return (invoke "load8_u" (i32.const 12)) (i32.const 0xcc))
    87  (assert_return (invoke "load8_u" (i32.const 13)) (i32.const 0xdd))
    88  
    89  ;; Overlap, source < dest
    90  (invoke "copy" (i32.const 10) (i32.const 7) (i32.const 6))
    91  (assert_return (invoke "load8_u" (i32.const 10)) (i32.const 0))
    92  (assert_return (invoke "load8_u" (i32.const 11)) (i32.const 0xaa))
    93  (assert_return (invoke "load8_u" (i32.const 12)) (i32.const 0xbb))
    94  (assert_return (invoke "load8_u" (i32.const 13)) (i32.const 0xcc))
    95  (assert_return (invoke "load8_u" (i32.const 14)) (i32.const 0xdd))
    96  (assert_return (invoke "load8_u" (i32.const 15)) (i32.const 0xcc))
    97  (assert_return (invoke "load8_u" (i32.const 16)) (i32.const 0))
    98  
    99  ;; Copy ending at memory limit is ok.
   100  (invoke "copy" (i32.const 0xff00) (i32.const 0) (i32.const 0x100))
   101  (invoke "copy" (i32.const 0xfe00) (i32.const 0xff00) (i32.const 0x100))
   102  
   103  ;; Succeed when copying 0 bytes at the end of the region.
   104  (invoke "copy" (i32.const 0x10000) (i32.const 0) (i32.const 0))
   105  (invoke "copy" (i32.const 0) (i32.const 0x10000) (i32.const 0))
   106  
   107  ;; Copying 0 bytes outside the memory traps.
   108  (assert_trap (invoke "copy" (i32.const 0x10001) (i32.const 0) (i32.const 0))
   109      "out of bounds memory access")
   110  (assert_trap (invoke "copy" (i32.const 0) (i32.const 0x10001) (i32.const 0))
   111      "out of bounds memory access")
   112  
   113  
   114  ;; memory.init
   115  (module
   116    (memory 1)
   117    (data "\aa\bb\cc\dd")
   118  
   119    (func (export "init") (param i32 i32 i32)
   120      (memory.init 0
   121        (local.get 0)
   122        (local.get 1)
   123        (local.get 2)))
   124  
   125    (func (export "load8_u") (param i32) (result i32)
   126      (i32.load8_u (local.get 0)))
   127  )
   128  
   129  (invoke "init" (i32.const 0) (i32.const 1) (i32.const 2))
   130  (assert_return (invoke "load8_u" (i32.const 0)) (i32.const 0xbb))
   131  (assert_return (invoke "load8_u" (i32.const 1)) (i32.const 0xcc))
   132  (assert_return (invoke "load8_u" (i32.const 2)) (i32.const 0))
   133  
   134  ;; Init ending at memory limit and segment limit is ok.
   135  (invoke "init" (i32.const 0xfffc) (i32.const 0) (i32.const 4))
   136  
   137  ;; Out-of-bounds writes trap, and nothing is written.
   138  (assert_trap (invoke "init" (i32.const 0xfffe) (i32.const 0) (i32.const 3))
   139      "out of bounds memory access")
   140  (assert_return (invoke "load8_u" (i32.const 0xfffe)) (i32.const 0xcc))
   141  (assert_return (invoke "load8_u" (i32.const 0xffff)) (i32.const 0xdd))
   142  
   143  ;; Succeed when writing 0 bytes at the end of either region.
   144  (invoke "init" (i32.const 0x10000) (i32.const 0) (i32.const 0))
   145  (invoke "init" (i32.const 0) (i32.const 4) (i32.const 0))
   146  
   147  ;; Writing 0 bytes outside the memory traps.
   148  (assert_trap (invoke "init" (i32.const 0x10001) (i32.const 0) (i32.const 0))
   149      "out of bounds memory access")
   150  (assert_trap (invoke "init" (i32.const 0) (i32.const 5) (i32.const 0))
   151      "out of bounds memory access")
   152  
   153  ;; data.drop
   154  (module
   155    (memory 1)
   156    (data $p "x")
   157    (data $a (memory 0) (i32.const 0) "x")
   158  
   159    (func (export "drop_passive") (data.drop $p))
   160    (func (export "init_passive") (param $len i32)
   161      (memory.init $p (i32.const 0) (i32.const 0) (local.get $len)))
   162  
   163    (func (export "drop_active") (data.drop $a))
   164    (func (export "init_active") (param $len i32)
   165      (memory.init $a (i32.const 0) (i32.const 0) (local.get $len)))
   166  )
   167  
   168  (invoke "init_passive" (i32.const 1))
   169  (invoke "drop_passive")
   170  (invoke "drop_passive")
   171  (assert_return (invoke "init_passive" (i32.const 0)))
   172  (assert_trap (invoke "init_passive" (i32.const 1)) "out of bounds memory access")
   173  (invoke "init_passive" (i32.const 0))
   174  (invoke "drop_active")
   175  (assert_return (invoke "init_active" (i32.const 0)))
   176  (assert_trap (invoke "init_active" (i32.const 1)) "out of bounds memory access")
   177  (invoke "init_active" (i32.const 0))
   178  
   179  ;; Test that the data segment index is properly encoded as an unsigned (not
   180  ;; signed) LEB.
   181  (module
   182    ;; 65 data segments. 64 is the smallest positive number that is encoded
   183    ;; differently as a signed LEB.
   184    (data "") (data "") (data "") (data "") (data "") (data "") (data "") (data "")
   185    (data "") (data "") (data "") (data "") (data "") (data "") (data "") (data "")
   186    (data "") (data "") (data "") (data "") (data "") (data "") (data "") (data "")
   187    (data "") (data "") (data "") (data "") (data "") (data "") (data "") (data "")
   188    (data "") (data "") (data "") (data "") (data "") (data "") (data "") (data "")
   189    (data "") (data "") (data "") (data "") (data "") (data "") (data "") (data "")
   190    (data "") (data "") (data "") (data "") (data "") (data "") (data "") (data "")
   191    (data "") (data "") (data "") (data "") (data "") (data "") (data "") (data "")
   192    (data "")
   193    (func (data.drop 64)))
   194  
   195  ;; No memory is required for the data.drop instruction.
   196  (module (data "goodbye") (func (data.drop 0)))
   197  
   198  ;; table.init
   199  (module
   200    (table 3 funcref)
   201    (elem funcref
   202      (ref.func $zero) (ref.func $one) (ref.func $zero) (ref.func $one))
   203  
   204    (func $zero (result i32) (i32.const 0))
   205    (func $one (result i32) (i32.const 1))
   206  
   207    (func (export "init") (param i32 i32 i32)
   208      (table.init 0
   209        (local.get 0)
   210        (local.get 1)
   211        (local.get 2)))
   212  
   213    (func (export "call") (param i32) (result i32)
   214      (call_indirect (result i32)
   215        (local.get 0)))
   216  )
   217  
   218  ;; Out-of-bounds stores trap, and nothing is written.
   219  (assert_trap (invoke "init" (i32.const 2) (i32.const 0) (i32.const 2))
   220      "out of bounds table access")
   221  (assert_trap (invoke "call" (i32.const 2))
   222      "uninitialized element 2")
   223  
   224  (invoke "init" (i32.const 0) (i32.const 1) (i32.const 2))
   225  (assert_return (invoke "call" (i32.const 0)) (i32.const 1))
   226  (assert_return (invoke "call" (i32.const 1)) (i32.const 0))
   227  (assert_trap (invoke "call" (i32.const 2)) "uninitialized element")
   228  
   229  ;; Init ending at table limit and segment limit is ok.
   230  (invoke "init" (i32.const 1) (i32.const 2) (i32.const 2))
   231  
   232  ;; Succeed when storing 0 elements at the end of either region.
   233  (invoke "init" (i32.const 3) (i32.const 0) (i32.const 0))
   234  (invoke "init" (i32.const 0) (i32.const 4) (i32.const 0))
   235  
   236  ;; Writing 0 elements outside the table traps.
   237  (assert_trap (invoke "init" (i32.const 4) (i32.const 0) (i32.const 0))
   238      "out of bounds table access")
   239  (assert_trap (invoke "init" (i32.const 0) (i32.const 5) (i32.const 0))
   240      "out of bounds table access")
   241  
   242  
   243  ;; elem.drop
   244  (module
   245    (table 1 funcref)
   246    (func $f)
   247    (elem $p funcref (ref.func $f))
   248    (elem $a (table 0) (i32.const 0) func $f)
   249  
   250    (func (export "drop_passive") (elem.drop $p))
   251    (func (export "init_passive") (param $len i32)
   252      (table.init $p (i32.const 0) (i32.const 0) (local.get $len))
   253    )
   254  
   255    (func (export "drop_active") (elem.drop $a))
   256    (func (export "init_active") (param $len i32)
   257      (table.init $a (i32.const 0) (i32.const 0) (local.get $len))
   258    )
   259  )
   260  
   261  (invoke "init_passive" (i32.const 1))
   262  (invoke "drop_passive")
   263  (invoke "drop_passive")
   264  (assert_return (invoke "init_passive" (i32.const 0)))
   265  (assert_trap (invoke "init_passive" (i32.const 1)) "out of bounds table access")
   266  (invoke "init_passive" (i32.const 0))
   267  (invoke "drop_active")
   268  (assert_return (invoke "init_active" (i32.const 0)))
   269  (assert_trap (invoke "init_active" (i32.const 1)) "out of bounds table access")
   270  (invoke "init_active" (i32.const 0))
   271  
   272  ;; Test that the elem segment index is properly encoded as an unsigned (not
   273  ;; signed) LEB.
   274  (module
   275    ;; 65 elem segments. 64 is the smallest positive number that is encoded
   276    ;; differently as a signed LEB.
   277    (elem funcref) (elem funcref) (elem funcref) (elem funcref)
   278    (elem funcref) (elem funcref) (elem funcref) (elem funcref)
   279    (elem funcref) (elem funcref) (elem funcref) (elem funcref)
   280    (elem funcref) (elem funcref) (elem funcref) (elem funcref)
   281    (elem funcref) (elem funcref) (elem funcref) (elem funcref)
   282    (elem funcref) (elem funcref) (elem funcref) (elem funcref)
   283    (elem funcref) (elem funcref) (elem funcref) (elem funcref)
   284    (elem funcref) (elem funcref) (elem funcref) (elem funcref)
   285    (elem funcref) (elem funcref) (elem funcref) (elem funcref)
   286    (elem funcref) (elem funcref) (elem funcref) (elem funcref)
   287    (elem funcref) (elem funcref) (elem funcref) (elem funcref)
   288    (elem funcref) (elem funcref) (elem funcref) (elem funcref)
   289    (elem funcref) (elem funcref) (elem funcref) (elem funcref)
   290    (elem funcref) (elem funcref) (elem funcref) (elem funcref)
   291    (elem funcref) (elem funcref) (elem funcref) (elem funcref)
   292    (elem funcref) (elem funcref) (elem funcref) (elem funcref)
   293    (elem funcref)
   294    (func (elem.drop 64)))
   295  
   296  ;; No table is required for the elem.drop instruction.
   297  (module (elem funcref (ref.func 0)) (func (elem.drop 0)))
   298  
   299  ;; table.copy
   300  (module
   301    (table 10 funcref)
   302    (elem (i32.const 0) $zero $one $two)
   303    (func $zero (result i32) (i32.const 0))
   304    (func $one (result i32) (i32.const 1))
   305    (func $two (result i32) (i32.const 2))
   306  
   307    (func (export "copy") (param i32 i32 i32)
   308      (table.copy
   309        (local.get 0)
   310        (local.get 1)
   311        (local.get 2)))
   312  
   313    (func (export "call") (param i32) (result i32)
   314      (call_indirect (result i32)
   315        (local.get 0)))
   316  )
   317  
   318  ;; Non-overlapping copy.
   319  (invoke "copy" (i32.const 3) (i32.const 0) (i32.const 3))
   320  ;; Now [$zero, $one, $two, $zero, $one, $two, ...]
   321  (assert_return (invoke "call" (i32.const 3)) (i32.const 0))
   322  (assert_return (invoke "call" (i32.const 4)) (i32.const 1))
   323  (assert_return (invoke "call" (i32.const 5)) (i32.const 2))
   324  
   325  ;; Overlap, source > dest
   326  (invoke "copy" (i32.const 0) (i32.const 1) (i32.const 3))
   327  ;; Now [$one, $two, $zero, $zero, $one, $two, ...]
   328  (assert_return (invoke "call" (i32.const 0)) (i32.const 1))
   329  (assert_return (invoke "call" (i32.const 1)) (i32.const 2))
   330  (assert_return (invoke "call" (i32.const 2)) (i32.const 0))
   331  
   332  ;; Overlap, source < dest
   333  (invoke "copy" (i32.const 2) (i32.const 0) (i32.const 3))
   334  ;; Now [$one, $two, $one, $two, $zero, $two, ...]
   335  (assert_return (invoke "call" (i32.const 2)) (i32.const 1))
   336  (assert_return (invoke "call" (i32.const 3)) (i32.const 2))
   337  (assert_return (invoke "call" (i32.const 4)) (i32.const 0))
   338  
   339  ;; Copy ending at table limit is ok.
   340  (invoke "copy" (i32.const 6) (i32.const 8) (i32.const 2))
   341  (invoke "copy" (i32.const 8) (i32.const 6) (i32.const 2))
   342  
   343  ;; Succeed when copying 0 elements at the end of the region.
   344  (invoke "copy" (i32.const 10) (i32.const 0) (i32.const 0))
   345  (invoke "copy" (i32.const 0) (i32.const 10) (i32.const 0))
   346  
   347  ;; Fail on out-of-bounds when copying 0 elements outside of table.
   348  (assert_trap (invoke "copy" (i32.const 11) (i32.const 0) (i32.const 0))
   349    "out of bounds table access")
   350  (assert_trap (invoke "copy" (i32.const 0) (i32.const 11) (i32.const 0))
   351    "out of bounds table access")