|
296 | 296 | )
|
297 | 297 | )
|
298 | 298 |
|
| 299 | +;; GUFA can infer the first global contains a $func, so the struct type's field |
| 300 | +;; can be refined. However, doing so would require adding a cast from the |
| 301 | +;; global's declared type (ref func) to the refined type, so that the struct.new |
| 302 | +;; validates. (Alternatively, we would need to refine the global's type at the |
| 303 | +;; same time we refine the struct, but this pass only refines structs.) The type |
| 304 | +;; of the struct's field should only refine as much as is valid, which is the |
| 305 | +;; type of the global, (ref func), and not the declared type $func. Both GUFA |
| 306 | +;; and normal type refining succeed here (-O3 removes the entire module, and is |
| 307 | +;; not interesting here). |
| 308 | +(module |
| 309 | + ;; NRML: (rec |
| 310 | + ;; NRML-NEXT: (type $struct (struct (field (ref func)))) |
| 311 | + ;; GUFA: (rec |
| 312 | + ;; GUFA-NEXT: (type $struct (struct (field (ref func)))) |
| 313 | + (type $struct (struct (field funcref))) |
| 314 | + |
| 315 | + ;; NRML: (type $func (func)) |
| 316 | + ;; GUFA: (type $func (func)) |
| 317 | + (type $func (func)) |
| 318 | + |
| 319 | + ;; NRML: (global $A (ref func) (ref.func $func)) |
| 320 | + ;; GUFA: (global $A (ref func) (ref.func $func)) |
| 321 | + (global $A (ref func) (ref.func $func)) |
| 322 | + |
| 323 | + ;; NRML: (global $B (ref $struct) (struct.new $struct |
| 324 | + ;; NRML-NEXT: (global.get $A) |
| 325 | + ;; NRML-NEXT: )) |
| 326 | + ;; GUFA: (global $B (ref $struct) (struct.new $struct |
| 327 | + ;; GUFA-NEXT: (global.get $A) |
| 328 | + ;; GUFA-NEXT: )) |
| 329 | + (global $B (ref $struct) (struct.new $struct |
| 330 | + (global.get $A) |
| 331 | + )) |
| 332 | + |
| 333 | + ;; NRML: (func $func (type $func) |
| 334 | + ;; NRML-NEXT: ) |
| 335 | + ;; GUFA: (func $func (type $func) |
| 336 | + ;; GUFA-NEXT: ) |
| 337 | + (func $func (type $func) |
| 338 | + ) |
| 339 | +) |
| 340 | + |
| 341 | +;; As above, but now the global has a refined type, so we can refine fully. |
| 342 | +(module |
| 343 | + ;; NRML: (rec |
| 344 | + ;; NRML-NEXT: (type $struct (struct (field (ref $func)))) |
| 345 | + ;; GUFA: (rec |
| 346 | + ;; GUFA-NEXT: (type $struct (struct (field (ref $func)))) |
| 347 | + (type $struct (struct (field funcref))) |
| 348 | + |
| 349 | + ;; NRML: (type $func (func)) |
| 350 | + ;; GUFA: (type $func (func)) |
| 351 | + (type $func (func)) |
| 352 | + |
| 353 | + ;; NRML: (global $A (ref $func) (ref.func $func)) |
| 354 | + ;; GUFA: (global $A (ref $func) (ref.func $func)) |
| 355 | + (global $A (ref $func) (ref.func $func)) ;; the type here changed |
| 356 | + |
| 357 | + ;; NRML: (global $B (ref $struct) (struct.new $struct |
| 358 | + ;; NRML-NEXT: (global.get $A) |
| 359 | + ;; NRML-NEXT: )) |
| 360 | + ;; GUFA: (global $B (ref $struct) (struct.new $struct |
| 361 | + ;; GUFA-NEXT: (global.get $A) |
| 362 | + ;; GUFA-NEXT: )) |
| 363 | + (global $B (ref $struct) (struct.new $struct |
| 364 | + (global.get $A) |
| 365 | + )) |
| 366 | + |
| 367 | + ;; NRML: (func $func (type $func) |
| 368 | + ;; NRML-NEXT: ) |
| 369 | + ;; GUFA: (func $func (type $func) |
| 370 | + ;; GUFA-NEXT: ) |
| 371 | + (func $func (type $func) |
| 372 | + ) |
| 373 | +) |
| 374 | + |
| 375 | +;; Check we do not error on struct.new_default in a global. Here we can refine |
| 376 | +;; the field to nullref. |
| 377 | +(module |
| 378 | + ;; NRML: (type $struct (struct (field nullfuncref))) |
| 379 | + ;; GUFA: (type $struct (struct (field nullfuncref))) |
| 380 | + (type $struct (struct (field funcref))) |
| 381 | + |
| 382 | + ;; NRML: (global $C (ref $struct) (struct.new_default $struct)) |
| 383 | + ;; GUFA: (global $C (ref $struct) (struct.new_default $struct)) |
| 384 | + (global $C (ref $struct) (struct.new_default $struct)) |
| 385 | +) |
0 commit comments