github.com/wasilibs/wazerox@v0.0.0-20240124024944-4923be63ab5f/internal/integration_test/spectest/v2/testdata/linking.wast (about)

     1  ;; Functions
     2  
     3  (module $Mf
     4    (func (export "call") (result i32) (call $g))
     5    (func $g (result i32) (i32.const 2))
     6  )
     7  (register "Mf" $Mf)
     8  
     9  (module $Nf
    10    (func $f (import "Mf" "call") (result i32))
    11    (export "Mf.call" (func $f))
    12    (func (export "call Mf.call") (result i32) (call $f))
    13    (func (export "call") (result i32) (call $g))
    14    (func $g (result i32) (i32.const 3))
    15  )
    16  
    17  (assert_return (invoke $Mf "call") (i32.const 2))
    18  (assert_return (invoke $Nf "Mf.call") (i32.const 2))
    19  (assert_return (invoke $Nf "call") (i32.const 3))
    20  (assert_return (invoke $Nf "call Mf.call") (i32.const 2))
    21  
    22  (module
    23    (import "spectest" "print_i32" (func $f (param i32)))
    24    (export "print" (func $f))
    25  )
    26  (register "reexport_f")
    27  (assert_unlinkable
    28    (module (import "reexport_f" "print" (func (param i64))))
    29    "incompatible import type"
    30  )
    31  (assert_unlinkable
    32    (module (import "reexport_f" "print" (func (param i32) (result i32))))
    33    "incompatible import type"
    34  )
    35  
    36  
    37  ;; Globals
    38  
    39  (module $Mg
    40    (global $glob (export "glob") i32 (i32.const 42))
    41    (func (export "get") (result i32) (global.get $glob))
    42  
    43    ;; export mutable globals
    44    (global $mut_glob (export "mut_glob") (mut i32) (i32.const 142))
    45    (func (export "get_mut") (result i32) (global.get $mut_glob))
    46    (func (export "set_mut") (param i32) (global.set $mut_glob (local.get 0)))
    47  )
    48  (register "Mg" $Mg)
    49  
    50  (module $Ng
    51    (global $x (import "Mg" "glob") i32)
    52    (global $mut_glob (import "Mg" "mut_glob") (mut i32))
    53    (func $f (import "Mg" "get") (result i32))
    54    (func $get_mut (import "Mg" "get_mut") (result i32))
    55    (func $set_mut (import "Mg" "set_mut") (param i32))
    56  
    57    (export "Mg.glob" (global $x))
    58    (export "Mg.get" (func $f))
    59    (global $glob (export "glob") i32 (i32.const 43))
    60    (func (export "get") (result i32) (global.get $glob))
    61  
    62    (export "Mg.mut_glob" (global $mut_glob))
    63    (export "Mg.get_mut" (func $get_mut))
    64    (export "Mg.set_mut" (func $set_mut))
    65  )
    66  
    67  (assert_return (get $Mg "glob") (i32.const 42))
    68  (assert_return (get $Ng "Mg.glob") (i32.const 42))
    69  (assert_return (get $Ng "glob") (i32.const 43))
    70  (assert_return (invoke $Mg "get") (i32.const 42))
    71  (assert_return (invoke $Ng "Mg.get") (i32.const 42))
    72  (assert_return (invoke $Ng "get") (i32.const 43))
    73  
    74  (assert_return (get $Mg "mut_glob") (i32.const 142))
    75  (assert_return (get $Ng "Mg.mut_glob") (i32.const 142))
    76  (assert_return (invoke $Mg "get_mut") (i32.const 142))
    77  (assert_return (invoke $Ng "Mg.get_mut") (i32.const 142))
    78  
    79  (assert_return (invoke $Mg "set_mut" (i32.const 241)))
    80  (assert_return (get $Mg "mut_glob") (i32.const 241))
    81  (assert_return (get $Ng "Mg.mut_glob") (i32.const 241))
    82  (assert_return (invoke $Mg "get_mut") (i32.const 241))
    83  (assert_return (invoke $Ng "Mg.get_mut") (i32.const 241))
    84  
    85  
    86  (assert_unlinkable
    87    (module (import "Mg" "mut_glob" (global i32)))
    88    "incompatible import type"
    89  )
    90  (assert_unlinkable
    91    (module (import "Mg" "glob" (global (mut i32))))
    92    "incompatible import type"
    93  )
    94  
    95  
    96  (module $Mref_ex
    97    (global (export "g-const-func") funcref (ref.null func))
    98    (global (export "g-var-func") (mut funcref) (ref.null func))
    99    (global (export "g-const-extern") externref (ref.null extern))
   100    (global (export "g-var-extern") (mut externref) (ref.null extern))
   101  )
   102  (register "Mref_ex" $Mref_ex)
   103  
   104  (module $Mref_im
   105    (global (import "Mref_ex" "g-const-func") funcref)
   106    (global (import "Mref_ex" "g-const-extern") externref)
   107  
   108    (global (import "Mref_ex" "g-var-func") (mut funcref))
   109    (global (import "Mref_ex" "g-var-extern") (mut externref))
   110  )
   111  
   112  (assert_unlinkable
   113    (module (global (import "Mref_ex" "g-const-extern") funcref))
   114    "incompatible import type"
   115  )
   116  (assert_unlinkable
   117    (module (global (import "Mref_ex" "g-const-func") externref))
   118    "incompatible import type"
   119  )
   120  
   121  
   122  (assert_unlinkable
   123    (module (global (import "Mref_ex" "g-var-func") (mut externref)))
   124    "incompatible import type"
   125  )
   126  (assert_unlinkable
   127    (module (global (import "Mref_ex" "g-var-extern") (mut funcref)))
   128    "incompatible import type"
   129  )
   130  
   131  
   132  ;; Tables
   133  
   134  (module $Mt
   135    (type (func (result i32)))
   136    (type (func))
   137  
   138    (table (export "tab") 10 funcref)
   139    (elem (i32.const 2) $g $g $g $g)
   140    (func $g (result i32) (i32.const 4))
   141    (func (export "h") (result i32) (i32.const -4))
   142  
   143    (func (export "call") (param i32) (result i32)
   144      (call_indirect (type 0) (local.get 0))
   145    )
   146  )
   147  (register "Mt" $Mt)
   148  
   149  (module $Nt
   150    (type (func))
   151    (type (func (result i32)))
   152  
   153    (func $f (import "Mt" "call") (param i32) (result i32))
   154    (func $h (import "Mt" "h") (result i32))
   155  
   156    (table funcref (elem $g $g $g $h $f))
   157    (func $g (result i32) (i32.const 5))
   158  
   159    (export "Mt.call" (func $f))
   160    (func (export "call Mt.call") (param i32) (result i32)
   161      (call $f (local.get 0))
   162    )
   163    (func (export "call") (param i32) (result i32)
   164      (call_indirect (type 1) (local.get 0))
   165    )
   166  )
   167  
   168  (assert_return (invoke $Mt "call" (i32.const 2)) (i32.const 4))
   169  (assert_return (invoke $Nt "Mt.call" (i32.const 2)) (i32.const 4))
   170  (assert_return (invoke $Nt "call" (i32.const 2)) (i32.const 5))
   171  (assert_return (invoke $Nt "call Mt.call" (i32.const 2)) (i32.const 4))
   172  
   173  (assert_trap (invoke $Mt "call" (i32.const 1)) "uninitialized element")
   174  (assert_trap (invoke $Nt "Mt.call" (i32.const 1)) "uninitialized element")
   175  (assert_return (invoke $Nt "call" (i32.const 1)) (i32.const 5))
   176  (assert_trap (invoke $Nt "call Mt.call" (i32.const 1)) "uninitialized element")
   177  
   178  (assert_trap (invoke $Mt "call" (i32.const 0)) "uninitialized element")
   179  (assert_trap (invoke $Nt "Mt.call" (i32.const 0)) "uninitialized element")
   180  (assert_return (invoke $Nt "call" (i32.const 0)) (i32.const 5))
   181  (assert_trap (invoke $Nt "call Mt.call" (i32.const 0)) "uninitialized element")
   182  
   183  (assert_trap (invoke $Mt "call" (i32.const 20)) "undefined element")
   184  (assert_trap (invoke $Nt "Mt.call" (i32.const 20)) "undefined element")
   185  (assert_trap (invoke $Nt "call" (i32.const 7)) "undefined element")
   186  (assert_trap (invoke $Nt "call Mt.call" (i32.const 20)) "undefined element")
   187  
   188  (assert_return (invoke $Nt "call" (i32.const 3)) (i32.const -4))
   189  (assert_trap (invoke $Nt "call" (i32.const 4)) "indirect call type mismatch")
   190  
   191  (module $Ot
   192    (type (func (result i32)))
   193  
   194    (func $h (import "Mt" "h") (result i32))
   195    (table (import "Mt" "tab") 5 funcref)
   196    (elem (i32.const 1) $i $h)
   197    (func $i (result i32) (i32.const 6))
   198  
   199    (func (export "call") (param i32) (result i32)
   200      (call_indirect (type 0) (local.get 0))
   201    )
   202  )
   203  
   204  (assert_return (invoke $Mt "call" (i32.const 3)) (i32.const 4))
   205  (assert_return (invoke $Nt "Mt.call" (i32.const 3)) (i32.const 4))
   206  (assert_return (invoke $Nt "call Mt.call" (i32.const 3)) (i32.const 4))
   207  (assert_return (invoke $Ot "call" (i32.const 3)) (i32.const 4))
   208  
   209  (assert_return (invoke $Mt "call" (i32.const 2)) (i32.const -4))
   210  (assert_return (invoke $Nt "Mt.call" (i32.const 2)) (i32.const -4))
   211  (assert_return (invoke $Nt "call" (i32.const 2)) (i32.const 5))
   212  (assert_return (invoke $Nt "call Mt.call" (i32.const 2)) (i32.const -4))
   213  (assert_return (invoke $Ot "call" (i32.const 2)) (i32.const -4))
   214  
   215  (assert_return (invoke $Mt "call" (i32.const 1)) (i32.const 6))
   216  (assert_return (invoke $Nt "Mt.call" (i32.const 1)) (i32.const 6))
   217  (assert_return (invoke $Nt "call" (i32.const 1)) (i32.const 5))
   218  (assert_return (invoke $Nt "call Mt.call" (i32.const 1)) (i32.const 6))
   219  (assert_return (invoke $Ot "call" (i32.const 1)) (i32.const 6))
   220  
   221  (assert_trap (invoke $Mt "call" (i32.const 0)) "uninitialized element")
   222  (assert_trap (invoke $Nt "Mt.call" (i32.const 0)) "uninitialized element")
   223  (assert_return (invoke $Nt "call" (i32.const 0)) (i32.const 5))
   224  (assert_trap (invoke $Nt "call Mt.call" (i32.const 0)) "uninitialized element")
   225  (assert_trap (invoke $Ot "call" (i32.const 0)) "uninitialized element")
   226  
   227  (assert_trap (invoke $Ot "call" (i32.const 20)) "undefined element")
   228  
   229  (module
   230    (table (import "Mt" "tab") 0 funcref)
   231    (elem (i32.const 9) $f)
   232    (func $f)
   233  )
   234  
   235  (module $G1 (global (export "g") i32 (i32.const 5)))
   236  (register "G1" $G1)
   237  (module $G2
   238    (global (import "G1" "g") i32)
   239    (global (export "g") i32 (global.get 0))
   240  )
   241  (assert_return (get $G2 "g") (i32.const 5))
   242  
   243  (assert_trap
   244    (module
   245      (table (import "Mt" "tab") 0 funcref)
   246      (elem (i32.const 10) $f)
   247      (func $f)
   248    )
   249    "out of bounds table access"
   250  )
   251  
   252  (assert_unlinkable
   253    (module
   254      (table (import "Mt" "tab") 10 funcref)
   255      (memory (import "Mt" "mem") 1)  ;; does not exist
   256      (func $f (result i32) (i32.const 0))
   257      (elem (i32.const 7) $f)
   258      (elem (i32.const 9) $f)
   259    )
   260    "unknown import"
   261  )
   262  (assert_trap (invoke $Mt "call" (i32.const 7)) "uninitialized element")
   263  
   264  ;; Unlike in the v1 spec, active element segments stored before an
   265  ;; out-of-bounds access persist after the instantiation failure.
   266  (assert_trap
   267    (module
   268      (table (import "Mt" "tab") 10 funcref)
   269      (func $f (result i32) (i32.const 0))
   270      (elem (i32.const 7) $f)
   271      (elem (i32.const 8) $f $f $f $f $f)  ;; (partially) out of bounds
   272    )
   273    "out of bounds table access"
   274  )
   275  (assert_return (invoke $Mt "call" (i32.const 7)) (i32.const 0))
   276  (assert_trap (invoke $Mt "call" (i32.const 8)) "uninitialized element")
   277  
   278  (assert_trap
   279    (module
   280      (table (import "Mt" "tab") 10 funcref)
   281      (func $f (result i32) (i32.const 0))
   282      (elem (i32.const 7) $f)
   283      (memory 1)
   284      (data (i32.const 0x10000) "d")  ;; out of bounds
   285    )
   286    "out of bounds memory access"
   287  )
   288  (assert_return (invoke $Mt "call" (i32.const 7)) (i32.const 0))
   289  
   290  
   291  (module $Mtable_ex
   292    (table $t1 (export "t-func") 1 funcref)
   293    (table $t2 (export "t-extern") 1 externref)
   294  )
   295  (register "Mtable_ex" $Mtable_ex)
   296  
   297  (module
   298    (table (import "Mtable_ex" "t-func") 1 funcref)
   299    (table (import "Mtable_ex" "t-extern") 1 externref)
   300  )
   301  
   302  (assert_unlinkable
   303    (module (table (import "Mtable_ex" "t-func") 1 externref))
   304    "incompatible import type"
   305  )
   306  (assert_unlinkable
   307    (module (table (import "Mtable_ex" "t-extern") 1 funcref))
   308    "incompatible import type"
   309  )
   310  
   311  
   312  ;; Memories
   313  
   314  (module $Mm
   315    (memory (export "mem") 1 5)
   316    (data (i32.const 10) "\00\01\02\03\04\05\06\07\08\09")
   317  
   318    (func (export "load") (param $a i32) (result i32)
   319      (i32.load8_u (local.get 0))
   320    )
   321  )
   322  (register "Mm" $Mm)
   323  
   324  (module $Nm
   325    (func $loadM (import "Mm" "load") (param i32) (result i32))
   326  
   327    (memory 1)
   328    (data (i32.const 10) "\f0\f1\f2\f3\f4\f5")
   329  
   330    (export "Mm.load" (func $loadM))
   331    (func (export "load") (param $a i32) (result i32)
   332      (i32.load8_u (local.get 0))
   333    )
   334  )
   335  
   336  (assert_return (invoke $Mm "load" (i32.const 12)) (i32.const 2))
   337  (assert_return (invoke $Nm "Mm.load" (i32.const 12)) (i32.const 2))
   338  (assert_return (invoke $Nm "load" (i32.const 12)) (i32.const 0xf2))
   339  
   340  (module $Om
   341    (memory (import "Mm" "mem") 1)
   342    (data (i32.const 5) "\a0\a1\a2\a3\a4\a5\a6\a7")
   343  
   344    (func (export "load") (param $a i32) (result i32)
   345      (i32.load8_u (local.get 0))
   346    )
   347  )
   348  
   349  (assert_return (invoke $Mm "load" (i32.const 12)) (i32.const 0xa7))
   350  (assert_return (invoke $Nm "Mm.load" (i32.const 12)) (i32.const 0xa7))
   351  (assert_return (invoke $Nm "load" (i32.const 12)) (i32.const 0xf2))
   352  (assert_return (invoke $Om "load" (i32.const 12)) (i32.const 0xa7))
   353  
   354  (module
   355    (memory (import "Mm" "mem") 0)
   356    (data (i32.const 0xffff) "a")
   357  )
   358  
   359  (assert_trap
   360    (module
   361      (memory (import "Mm" "mem") 0)
   362      (data (i32.const 0x10000) "a")
   363    )
   364    "out of bounds memory access"
   365  )
   366  
   367  (module $Pm
   368    (memory (import "Mm" "mem") 1 8)
   369  
   370    (func (export "grow") (param $a i32) (result i32)
   371      (memory.grow (local.get 0))
   372    )
   373  )
   374  
   375  (assert_return (invoke $Pm "grow" (i32.const 0)) (i32.const 1))
   376  (assert_return (invoke $Pm "grow" (i32.const 2)) (i32.const 1))
   377  (assert_return (invoke $Pm "grow" (i32.const 0)) (i32.const 3))
   378  (assert_return (invoke $Pm "grow" (i32.const 1)) (i32.const 3))
   379  (assert_return (invoke $Pm "grow" (i32.const 1)) (i32.const 4))
   380  (assert_return (invoke $Pm "grow" (i32.const 0)) (i32.const 5))
   381  (assert_return (invoke $Pm "grow" (i32.const 1)) (i32.const -1))
   382  (assert_return (invoke $Pm "grow" (i32.const 0)) (i32.const 5))
   383  
   384  (assert_unlinkable
   385    (module
   386      (func $host (import "spectest" "print"))
   387      (memory (import "Mm" "mem") 1)
   388      (table (import "Mm" "tab") 0 funcref)  ;; does not exist
   389      (data (i32.const 0) "abc")
   390    )
   391    "unknown import"
   392  )
   393  (assert_return (invoke $Mm "load" (i32.const 0)) (i32.const 0))
   394  
   395  ;; Unlike in v1 spec, active data segments written before an
   396  ;; out-of-bounds access persist after the instantiation failure.
   397  (assert_trap
   398    (module
   399      ;; Note: the memory is 5 pages large by the time we get here.
   400      (memory (import "Mm" "mem") 1)
   401      (data (i32.const 0) "abc")
   402      (data (i32.const 327670) "zzzzzzzzzzzzzzzzzz") ;; (partially) out of bounds
   403    )
   404    "out of bounds memory access"
   405  )
   406  (assert_return (invoke $Mm "load" (i32.const 0)) (i32.const 97))
   407  (assert_return (invoke $Mm "load" (i32.const 327670)) (i32.const 0))
   408  
   409  (assert_trap
   410    (module
   411      (memory (import "Mm" "mem") 1)
   412      (data (i32.const 0) "abc")
   413      (table 0 funcref)
   414      (func)
   415      (elem (i32.const 0) 0)  ;; out of bounds
   416    )
   417    "out of bounds table access"
   418  )
   419  (assert_return (invoke $Mm "load" (i32.const 0)) (i32.const 97))
   420  
   421  ;; Store is modified if the start function traps.
   422  (module $Ms
   423    (type $t (func (result i32)))
   424    (memory (export "memory") 1)
   425    (table (export "table") 1 funcref)
   426    (func (export "get memory[0]") (type $t)
   427      (i32.load8_u (i32.const 0))
   428    )
   429    (func (export "get table[0]") (type $t)
   430      (call_indirect (type $t) (i32.const 0))
   431    )
   432  )
   433  (register "Ms" $Ms)
   434  
   435  (assert_trap
   436    (module
   437      (import "Ms" "memory" (memory 1))
   438      (import "Ms" "table" (table 1 funcref))
   439      (data (i32.const 0) "hello")
   440      (elem (i32.const 0) $f)
   441      (func $f (result i32)
   442        (i32.const 0xdead)
   443      )
   444      (func $main
   445        (unreachable)
   446      )
   447      (start $main)
   448    )
   449    "unreachable"
   450  )
   451  
   452  (assert_return (invoke $Ms "get memory[0]") (i32.const 104))  ;; 'h'
   453  (assert_return (invoke $Ms "get table[0]") (i32.const 0xdead))