@@ -412,15 +412,127 @@ struct SubtypingDiscoverer : public OverriddenVisitor<SubType> {
412
412
void visitStringWTF16Get (StringWTF16Get* curr) {}
413
413
void visitStringSliceWTF (StringSliceWTF* curr) {}
414
414
415
- void visitContNew (ContNew* curr) { WASM_UNREACHABLE (" not implemented" ); }
416
- void visitContBind (ContBind* curr) { WASM_UNREACHABLE (" not implemented" ); }
417
- void visitSuspend (Suspend* curr) { WASM_UNREACHABLE (" not implemented" ); }
418
- void visitResume (Resume* curr) { WASM_UNREACHABLE (" not implemented" ); }
415
+ void visitContNew (ContNew* curr) {
416
+ if (!curr->type .isContinuation ()) {
417
+ return ;
418
+ }
419
+ // The type of the function reference must remain a subtype of the function
420
+ // type expected by the continuation.
421
+ self ()->noteSubtype (curr->func ->type .getHeapType (),
422
+ curr->type .getHeapType ().getContinuation ().type );
423
+ }
424
+ void visitContBind (ContBind* curr) {
425
+ if (!curr->cont ->type .isContinuation ()) {
426
+ return ;
427
+ }
428
+ // Each of the bound arguments must remain subtypes of their expected
429
+ // parameters.
430
+ auto params = curr->cont ->type .getHeapType ()
431
+ .getContinuation ()
432
+ .type .getSignature ()
433
+ .params ;
434
+ assert (curr->operands .size () <= params.size ());
435
+ for (Index i = 0 ; i < curr->operands .size (); ++i) {
436
+ self ()->noteSubtype (curr->operands [i], params[i]);
437
+ }
438
+ }
439
+ void visitSuspend (Suspend* curr) {
440
+ // The operands must remain subtypes of the parameters given by the tag.
441
+ auto params =
442
+ self ()->getModule ()->getTag (curr->tag )->type .getSignature ().params ;
443
+ assert (curr->operands .size () == params.size ());
444
+ for (Index i = 0 ; i < curr->operands .size (); ++i) {
445
+ self ()->noteSubtype (curr->operands [i], params[i]);
446
+ }
447
+ }
448
+ void processResumeHandlers (Type contType,
449
+ const ArenaVector<Name>& handlerTags,
450
+ const ArenaVector<Name>& handlerBlocks) {
451
+ auto contSig = contType.getHeapType ().getContinuation ().type .getSignature ();
452
+ assert (handlerTags.size () == handlerBlocks.size ());
453
+ auto & wasm = *self ()->getModule ();
454
+ // Process each handler in turn.
455
+ for (Index i = 0 ; i < handlerTags.size (); ++i) {
456
+ if (!handlerBlocks[i]) {
457
+ // Switch handlers do not constrain types in any way.
458
+ continue ;
459
+ }
460
+ auto tagSig = wasm.getTag (handlerTags[i])->type .getSignature ();
461
+ // The types sent on suspensions with this tag must remain subtypes of the
462
+ // types expected at the target block.
463
+ auto expected = self ()->findBreakTarget (handlerBlocks[i])->type ;
464
+ assert (tagSig.params .size () + 1 == expected.size ());
465
+ for (Index j = 0 ; j < tagSig.params .size (); ++j) {
466
+ self ()->noteSubtype (tagSig.params [i], expected[i]);
467
+ }
468
+ auto nextSig = expected[expected.size () - 1 ]
469
+ .getHeapType ()
470
+ .getContinuation ()
471
+ .type .getSignature ();
472
+ // The types we send to the next continuation must remain subtypes of the
473
+ // types the continuation is expecting based on the tag results.
474
+ self ()->noteSubtype (nextSig.params , tagSig.results );
475
+ // The types returned by the current continuation must remain subtypes of
476
+ // the types returned by the next continuation.
477
+ self ()->noteSubtype (contSig.results , nextSig.results );
478
+ }
479
+ }
480
+ void visitResume (Resume* curr) {
481
+ if (!curr->cont ->type .isContinuation ()) {
482
+ return ;
483
+ }
484
+ processResumeHandlers (
485
+ curr->cont ->type , curr->handlerTags , curr->handlerBlocks );
486
+ // The types we send to the resumed continuation must remain subtypes of the
487
+ // types expected by the continuation.
488
+ auto params = curr->cont ->type .getHeapType ()
489
+ .getContinuation ()
490
+ .type .getSignature ()
491
+ .params ;
492
+ assert (curr->operands .size () == params.size ());
493
+ for (Index i = 0 ; i < curr->operands .size (); ++i) {
494
+ self ()->noteSubtype (curr->operands [i], params[i]);
495
+ }
496
+ }
419
497
void visitResumeThrow (ResumeThrow* curr) {
420
- WASM_UNREACHABLE (" not implemented" );
498
+ if (!curr->cont ->type .isContinuation ()) {
499
+ return ;
500
+ }
501
+ processResumeHandlers (
502
+ curr->cont ->type , curr->handlerTags , curr->handlerBlocks );
503
+ // The types we use to create the exception package must remain subtypes of
504
+ // the types expected by the exception tag.
505
+ auto params =
506
+ self ()->getModule ()->getTag (curr->tag )->type .getSignature ().params ;
507
+ assert (curr->operands .size () == params.size ());
508
+ for (Index i = 0 ; i < curr->operands .size (); ++i) {
509
+ self ()->noteSubtype (curr->operands [i], params[i]);
510
+ }
421
511
}
422
512
void visitStackSwitch (StackSwitch* curr) {
423
- WASM_UNREACHABLE (" not implemented" );
513
+ if (!curr->cont ->type .isContinuation ()) {
514
+ return ;
515
+ }
516
+ // The types sent when switching must remain subtypes of the types expected
517
+ // by the target continuation.
518
+ auto contSig =
519
+ curr->cont ->type .getHeapType ().getContinuation ().type .getSignature ();
520
+ assert (curr->operands .size () + 1 == contSig.params .size ());
521
+ for (Index i = 0 ; i < curr->operands .size (); ++i) {
522
+ self ()->noteSubtype (curr->operands [i], contSig.params [i]);
523
+ }
524
+ // The type returned by the target continuation must remain a subtype of the
525
+ // type the current continuation returns as indicated by the tag result.
526
+ auto currResult =
527
+ self ()->getModule ()->getTag (curr->tag )->type .getSignature ().results ;
528
+ self ()->noteSubtype (contSig.results , currResult);
529
+ // The type returned by the current continuation must remain a subtype of
530
+ // the type returned by the return continuation.
531
+ auto retSig = contSig.params [contSig.params .size () - 1 ]
532
+ .getHeapType ()
533
+ .getContinuation ()
534
+ .type .getSignature ();
535
+ self ()->noteSubtype (currResult, retSig.results );
424
536
}
425
537
};
426
538
0 commit comments