@@ -405,6 +405,8 @@ export class Compiler extends DiagnosticEmitter {
405
405
if ( options . hasFeature ( Feature . TAIL_CALLS ) ) featureFlags |= FeatureFlags . TailCall ;
406
406
if ( options . hasFeature ( Feature . REFERENCE_TYPES ) ) featureFlags |= FeatureFlags . ReferenceTypes ;
407
407
if ( options . hasFeature ( Feature . MULTI_VALUE ) ) featureFlags |= FeatureFlags . MultiValue ;
408
+ if ( options . hasFeature ( Feature . GC ) ) featureFlags |= FeatureFlags . GC ;
409
+ if ( options . hasFeature ( Feature . MEMORY64 ) ) featureFlags |= FeatureFlags . Memory64 ;
408
410
module . setFeatures ( featureFlags ) ;
409
411
410
412
// set up the main start function
@@ -3624,12 +3626,21 @@ export class Compiler extends DiagnosticEmitter {
3624
3626
fromType = fromType . nonNullableType ;
3625
3627
}
3626
3628
if ( fromType . isAssignableTo ( toType ) ) { // downcast or same
3627
- assert ( fromType . kind == toType . kind ) ;
3629
+ assert ( toType . isExternalReference || fromType . kind == toType . kind ) ;
3628
3630
this . currentType = toType ;
3629
3631
return expr ;
3630
3632
}
3631
3633
if ( explicit && toType . nonNullableType . isAssignableTo ( fromType ) ) { // upcast
3632
3634
// <Cat | null>(<Animal>maybeCat)
3635
+ if ( toType . isExternalReference ) {
3636
+ this . error (
3637
+ DiagnosticCode . Not_implemented_0 ,
3638
+ reportNode . range ,
3639
+ "ref.cast"
3640
+ ) ;
3641
+ this . currentType = toType ;
3642
+ return module . unreachable ( ) ;
3643
+ }
3633
3644
assert ( fromType . kind == toType . kind ) ;
3634
3645
if ( ! this . options . noAssert ) {
3635
3646
expr = this . makeRuntimeUpcastCheck ( expr , fromType , toType , reportNode ) ;
@@ -4390,12 +4401,15 @@ export class Compiler extends DiagnosticEmitter {
4390
4401
) ;
4391
4402
break ;
4392
4403
}
4393
- case TypeKind . EXTERNREF : {
4394
- // TODO: ref.eq
4404
+ case TypeKind . FUNCREF :
4405
+ case TypeKind . EXTERNREF :
4406
+ case TypeKind . EXNREF :
4407
+ case TypeKind . ANYREF : {
4395
4408
this . error (
4396
- DiagnosticCode . Not_implemented_0 ,
4409
+ DiagnosticCode . Operation_0_cannot_be_applied_to_type_1 ,
4397
4410
expression . range ,
4398
- "ref.eq instruction"
4411
+ "ref.eq" ,
4412
+ commonType . toString ( )
4399
4413
) ;
4400
4414
expr = module . unreachable ( ) ;
4401
4415
break ;
@@ -4491,12 +4505,15 @@ export class Compiler extends DiagnosticEmitter {
4491
4505
) ;
4492
4506
break ;
4493
4507
}
4494
- case TypeKind . EXTERNREF : {
4495
- // TODO: !ref.eq
4508
+ case TypeKind . FUNCREF :
4509
+ case TypeKind . EXTERNREF :
4510
+ case TypeKind . EXNREF :
4511
+ case TypeKind . ANYREF : {
4496
4512
this . error (
4497
- DiagnosticCode . Not_implemented_0 ,
4513
+ DiagnosticCode . Operation_0_cannot_be_applied_to_type_1 ,
4498
4514
expression . range ,
4499
- "ref.eq instruction"
4515
+ "ref.eq" ,
4516
+ commonType . toString ( )
4500
4517
) ;
4501
4518
expr = module . unreachable ( ) ;
4502
4519
break ;
@@ -8311,13 +8328,7 @@ export class Compiler extends DiagnosticEmitter {
8311
8328
this . currentType = signatureReference . type . asNullable ( ) ;
8312
8329
return options . isWasm64 ? module . i64 ( 0 ) : module . i32 ( 0 ) ;
8313
8330
}
8314
- // TODO: return null ref for externref or funcref
8315
- this . error (
8316
- DiagnosticCode . Not_implemented_0 ,
8317
- expression . range ,
8318
- "ref.null"
8319
- ) ;
8320
- return module . unreachable ( ) ;
8331
+ return this . makeZero ( contextualType , expression ) ;
8321
8332
}
8322
8333
this . currentType = options . usizeType ;
8323
8334
this . warning (
@@ -8508,7 +8519,7 @@ export class Compiler extends DiagnosticEmitter {
8508
8519
) ;
8509
8520
if ( ! functionInstance || ! this . compileFunction ( functionInstance ) ) return module . unreachable ( ) ;
8510
8521
if ( contextualType . isExternalReference ) {
8511
- this . currentType = Type . externref ;
8522
+ this . currentType = Type . funcref ;
8512
8523
return module . ref_func ( functionInstance . internalName ) ;
8513
8524
}
8514
8525
let offset = this . ensureRuntimeFunction ( functionInstance ) ;
@@ -10619,7 +10630,17 @@ export class Compiler extends DiagnosticEmitter {
10619
10630
checkTypeSupported ( type : Type , reportNode : Node ) : bool {
10620
10631
switch ( type . kind ) {
10621
10632
case TypeKind . V128 : return this . checkFeatureEnabled ( Feature . SIMD , reportNode ) ;
10622
- case TypeKind . EXTERNREF : return this . checkFeatureEnabled ( Feature . REFERENCE_TYPES , reportNode ) ;
10633
+ case TypeKind . FUNCREF :
10634
+ case TypeKind . EXTERNREF :
10635
+ return this . checkFeatureEnabled ( Feature . REFERENCE_TYPES , reportNode ) ;
10636
+ case TypeKind . EXNREF : {
10637
+ return this . checkFeatureEnabled ( Feature . REFERENCE_TYPES , reportNode )
10638
+ && this . checkFeatureEnabled ( Feature . EXCEPTION_HANDLING , reportNode ) ;
10639
+ }
10640
+ case TypeKind . ANYREF : {
10641
+ return this . checkFeatureEnabled ( Feature . REFERENCE_TYPES , reportNode )
10642
+ && this . checkFeatureEnabled ( Feature . GC , reportNode ) ;
10643
+ }
10623
10644
}
10624
10645
let classReference = type . getClass ( ) ;
10625
10646
if ( classReference ) {
@@ -10712,14 +10733,11 @@ export class Compiler extends DiagnosticEmitter {
10712
10733
case TypeKind . F32 : return module . f32 ( 0 ) ;
10713
10734
case TypeKind . F64 : return module . f64 ( 0 ) ;
10714
10735
case TypeKind . V128 : return module . v128 ( v128_zero ) ;
10736
+ case TypeKind . FUNCREF :
10715
10737
case TypeKind . EXTERNREF :
10716
- // TODO: return null ref for both externref as well as funcref
10717
- this . error (
10718
- DiagnosticCode . Not_implemented_0 ,
10719
- reportNode . range ,
10720
- "ref.null"
10721
- ) ;
10722
- return module . unreachable ( ) ;
10738
+ case TypeKind . EXNREF :
10739
+ case TypeKind . ANYREF :
10740
+ return module . ref_null ( type . toNativeType ( ) ) ;
10723
10741
}
10724
10742
}
10725
10743
@@ -10824,16 +10842,11 @@ export class Compiler extends DiagnosticEmitter {
10824
10842
module . i64 ( 0xFFFFFFFE , 0xFFDFFFFF ) // (0x7FF0000000000000 - 1) << 1
10825
10843
) ;
10826
10844
}
10827
- case TypeKind . EXTERNREF : {
10828
- // TODO: non-null object might still be considered falseish
10829
- // i.e. a ref to Boolean(false), Number(0), String("") etc.
10830
- // TODO: return module.unary(UnaryOp.EqzI32, module.ref_is_null(expr));
10831
- this . error (
10832
- DiagnosticCode . Not_implemented_0 ,
10833
- reportNode . range ,
10834
- "ref.is_null"
10835
- ) ;
10836
- return module . unreachable ( ) ;
10845
+ case TypeKind . FUNCREF :
10846
+ case TypeKind . EXTERNREF :
10847
+ case TypeKind . EXNREF :
10848
+ case TypeKind . ANYREF :{
10849
+ return module . ref_is_null ( expr ) ;
10837
10850
}
10838
10851
default : {
10839
10852
assert ( false ) ;
0 commit comments