@@ -405,6 +405,8 @@ export class Compiler extends DiagnosticEmitter {
405405 if ( options . hasFeature ( Feature . TAIL_CALLS ) ) featureFlags |= FeatureFlags . TailCall ;
406406 if ( options . hasFeature ( Feature . REFERENCE_TYPES ) ) featureFlags |= FeatureFlags . ReferenceTypes ;
407407 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 ;
408410 module . setFeatures ( featureFlags ) ;
409411
410412 // set up the main start function
@@ -3624,12 +3626,21 @@ export class Compiler extends DiagnosticEmitter {
36243626 fromType = fromType . nonNullableType ;
36253627 }
36263628 if ( fromType . isAssignableTo ( toType ) ) { // downcast or same
3627- assert ( fromType . kind == toType . kind ) ;
3629+ assert ( toType . isExternalReference || fromType . kind == toType . kind ) ;
36283630 this . currentType = toType ;
36293631 return expr ;
36303632 }
36313633 if ( explicit && toType . nonNullableType . isAssignableTo ( fromType ) ) { // upcast
36323634 // <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+ }
36333644 assert ( fromType . kind == toType . kind ) ;
36343645 if ( ! this . options . noAssert ) {
36353646 expr = this . makeRuntimeUpcastCheck ( expr , fromType , toType , reportNode ) ;
@@ -4390,12 +4401,15 @@ export class Compiler extends DiagnosticEmitter {
43904401 ) ;
43914402 break ;
43924403 }
4393- case TypeKind . EXTERNREF : {
4394- // TODO: ref.eq
4404+ case TypeKind . FUNCREF :
4405+ case TypeKind . EXTERNREF :
4406+ case TypeKind . EXNREF :
4407+ case TypeKind . ANYREF : {
43954408 this . error (
4396- DiagnosticCode . Not_implemented_0 ,
4409+ DiagnosticCode . Operation_0_cannot_be_applied_to_type_1 ,
43974410 expression . range ,
4398- "ref.eq instruction"
4411+ "ref.eq" ,
4412+ commonType . toString ( )
43994413 ) ;
44004414 expr = module . unreachable ( ) ;
44014415 break ;
@@ -4491,12 +4505,15 @@ export class Compiler extends DiagnosticEmitter {
44914505 ) ;
44924506 break ;
44934507 }
4494- case TypeKind . EXTERNREF : {
4495- // TODO: !ref.eq
4508+ case TypeKind . FUNCREF :
4509+ case TypeKind . EXTERNREF :
4510+ case TypeKind . EXNREF :
4511+ case TypeKind . ANYREF : {
44964512 this . error (
4497- DiagnosticCode . Not_implemented_0 ,
4513+ DiagnosticCode . Operation_0_cannot_be_applied_to_type_1 ,
44984514 expression . range ,
4499- "ref.eq instruction"
4515+ "ref.eq" ,
4516+ commonType . toString ( )
45004517 ) ;
45014518 expr = module . unreachable ( ) ;
45024519 break ;
@@ -8311,13 +8328,7 @@ export class Compiler extends DiagnosticEmitter {
83118328 this . currentType = signatureReference . type . asNullable ( ) ;
83128329 return options . isWasm64 ? module . i64 ( 0 ) : module . i32 ( 0 ) ;
83138330 }
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 ) ;
83218332 }
83228333 this . currentType = options . usizeType ;
83238334 this . warning (
@@ -8508,7 +8519,7 @@ export class Compiler extends DiagnosticEmitter {
85088519 ) ;
85098520 if ( ! functionInstance || ! this . compileFunction ( functionInstance ) ) return module . unreachable ( ) ;
85108521 if ( contextualType . isExternalReference ) {
8511- this . currentType = Type . externref ;
8522+ this . currentType = Type . funcref ;
85128523 return module . ref_func ( functionInstance . internalName ) ;
85138524 }
85148525 let offset = this . ensureRuntimeFunction ( functionInstance ) ;
@@ -10619,7 +10630,17 @@ export class Compiler extends DiagnosticEmitter {
1061910630 checkTypeSupported ( type : Type , reportNode : Node ) : bool {
1062010631 switch ( type . kind ) {
1062110632 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+ }
1062310644 }
1062410645 let classReference = type . getClass ( ) ;
1062510646 if ( classReference ) {
@@ -10712,14 +10733,11 @@ export class Compiler extends DiagnosticEmitter {
1071210733 case TypeKind . F32 : return module . f32 ( 0 ) ;
1071310734 case TypeKind . F64 : return module . f64 ( 0 ) ;
1071410735 case TypeKind . V128 : return module . v128 ( v128_zero ) ;
10736+ case TypeKind . FUNCREF :
1071510737 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 ( ) ) ;
1072310741 }
1072410742 }
1072510743
@@ -10824,16 +10842,11 @@ export class Compiler extends DiagnosticEmitter {
1082410842 module . i64 ( 0xFFFFFFFE , 0xFFDFFFFF ) // (0x7FF0000000000000 - 1) << 1
1082510843 ) ;
1082610844 }
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 ) ;
1083710850 }
1083810851 default : {
1083910852 assert ( false ) ;
0 commit comments