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))