@@ -2260,22 +2260,38 @@ void BinaryInstWriter::visitCallRef(CallRef* curr) {
2260
2260
2261
2261
void BinaryInstWriter::visitRefTest (RefTest* curr) {
2262
2262
o << int8_t (BinaryConsts::GCPrefix);
2263
- if (curr->castType .isNullable ()) {
2264
- o << U32LEB (BinaryConsts::RefTestNull);
2263
+ if (curr->castType .isExact () &&
2264
+ parent.getModule ()->features .hasCustomDescriptors ()) {
2265
+ // Fall back to the general form with a reftype immediate.
2266
+ o << U32LEB (BinaryConsts::RefTestRT);
2267
+ parent.writeType (curr->castType );
2265
2268
} else {
2266
- o << U32LEB (BinaryConsts::RefTest);
2269
+ // Use the special-case form with heap type immediate.
2270
+ if (curr->castType .isNullable ()) {
2271
+ o << U32LEB (BinaryConsts::RefTestNull);
2272
+ } else {
2273
+ o << U32LEB (BinaryConsts::RefTest);
2274
+ }
2275
+ parent.writeHeapType (curr->castType .getHeapType ());
2267
2276
}
2268
- parent.writeHeapType (curr->castType .getHeapType ());
2269
2277
}
2270
2278
2271
2279
void BinaryInstWriter::visitRefCast (RefCast* curr) {
2272
2280
o << int8_t (BinaryConsts::GCPrefix);
2273
- if (curr->type .isNullable ()) {
2274
- o << U32LEB (BinaryConsts::RefCastNull);
2281
+ if (curr->type .isExact () &&
2282
+ parent.getModule ()->features .hasCustomDescriptors ()) {
2283
+ // Fall back to the general form with a reftype immediate.
2284
+ o << U32LEB (BinaryConsts::RefCastRT);
2285
+ parent.writeType (curr->type );
2275
2286
} else {
2276
- o << U32LEB (BinaryConsts::RefCast);
2287
+ // Use the special-case form with heap type immediate.
2288
+ if (curr->type .isNullable ()) {
2289
+ o << U32LEB (BinaryConsts::RefCastNull);
2290
+ } else {
2291
+ o << U32LEB (BinaryConsts::RefCast);
2292
+ }
2293
+ parent.writeHeapType (curr->type .getHeapType ());
2277
2294
}
2278
- parent.writeHeapType (curr->type .getHeapType ());
2279
2295
}
2280
2296
2281
2297
void BinaryInstWriter::visitBrOn (BrOn* curr) {
@@ -2298,8 +2314,24 @@ void BinaryInstWriter::visitBrOn(BrOn* curr) {
2298
2314
}
2299
2315
assert (curr->ref ->type .isRef ());
2300
2316
assert (Type::isSubType (curr->castType , curr->ref ->type ));
2301
- uint8_t flags = (curr->ref ->type .isNullable () ? 1 : 0 ) |
2302
- (curr->castType .isNullable () ? 2 : 0 );
2317
+ uint8_t flags = 0 ;
2318
+ if (curr->ref ->type .isNullable ()) {
2319
+ flags |= BinaryConsts::BrOnCastFlag::InputNullable;
2320
+ }
2321
+ if (curr->castType .isNullable ()) {
2322
+ flags |= BinaryConsts::BrOnCastFlag::OutputNullable;
2323
+ }
2324
+ if (parent.getModule ()->features .hasCustomDescriptors ()) {
2325
+ // If custom descriptors (and therefore exact references) are not
2326
+ // enabled, then these flags wouldn't be recognized, and we will be
2327
+ // generalizing all exact references to be non-exact anyway.
2328
+ if (curr->ref ->type .isExact ()) {
2329
+ flags |= BinaryConsts::BrOnCastFlag::InputExact;
2330
+ }
2331
+ if (curr->castType .isExact ()) {
2332
+ flags |= BinaryConsts::BrOnCastFlag::OutputExact;
2333
+ }
2334
+ }
2303
2335
o << flags;
2304
2336
o << U32LEB (getBreakIndex (curr->name ));
2305
2337
parent.writeHeapType (curr->ref ->type .getHeapType ());
0 commit comments