@@ -25,7 +25,6 @@ import {
25
25
ExpressionRef ,
26
26
UnaryOp ,
27
27
BinaryOp ,
28
- RefIsOp ,
29
28
TypeRef ,
30
29
FunctionRef ,
31
30
ExpressionId ,
@@ -1245,7 +1244,7 @@ export class Compiler extends DiagnosticEmitter {
1245
1244
if ( global . is ( CommonFlags . INLINED ) ) {
1246
1245
initExpr = this . compileInlineConstant ( global , global . type , Constraints . PREFER_STATIC ) ;
1247
1246
} else {
1248
- initExpr = this . makeZero ( type , global . declaration ) ;
1247
+ initExpr = this . makeZero ( type ) ;
1249
1248
}
1250
1249
}
1251
1250
@@ -1258,7 +1257,7 @@ export class Compiler extends DiagnosticEmitter {
1258
1257
findDecorator ( DecoratorKind . INLINE , global . decoratorNodes ) ! . range , "inline"
1259
1258
) ;
1260
1259
}
1261
- module . addGlobal ( internalName , typeRef , true , this . makeZero ( type , global . declaration ) ) ;
1260
+ module . addGlobal ( internalName , typeRef , true , this . makeZero ( type ) ) ;
1262
1261
this . currentBody . push (
1263
1262
module . global_set ( internalName , initExpr )
1264
1263
) ;
@@ -7041,7 +7040,7 @@ export class Compiler extends DiagnosticEmitter {
7041
7040
let needsVarargsStub = false ;
7042
7041
for ( let n = numParameters ; n < overloadNumParameters ; ++ n ) {
7043
7042
// TODO: inline constant initializers and skip varargs stub
7044
- paramExprs [ 1 + n ] = this . makeZero ( overloadParameterTypes [ n ] , overloadInstance . declaration ) ;
7043
+ paramExprs [ 1 + n ] = this . makeZero ( overloadParameterTypes [ n ] ) ;
7045
7044
needsVarargsStub = true ;
7046
7045
}
7047
7046
let calledName = needsVarargsStub
@@ -7241,7 +7240,7 @@ export class Compiler extends DiagnosticEmitter {
7241
7240
}
7242
7241
}
7243
7242
}
7244
- operands . push ( this . makeZero ( parameterTypes [ i ] , instance . declaration ) ) ;
7243
+ operands . push ( this . makeZero ( parameterTypes [ i ] ) ) ;
7245
7244
allOptionalsAreConstant = false ;
7246
7245
}
7247
7246
if ( ! allOptionalsAreConstant && ! instance . is ( CommonFlags . MODULE_IMPORT ) ) {
@@ -7351,7 +7350,7 @@ export class Compiler extends DiagnosticEmitter {
7351
7350
}
7352
7351
let parameterTypes = signature . parameterTypes ;
7353
7352
for ( let i = numArguments ; i < maxArguments ; ++ i ) {
7354
- operands . push ( this . makeZero ( parameterTypes [ i ] , reportNode ) ) ;
7353
+ operands . push ( this . makeZero ( parameterTypes [ i ] ) ) ;
7355
7354
}
7356
7355
}
7357
7356
@@ -7645,7 +7644,7 @@ export class Compiler extends DiagnosticEmitter {
7645
7644
this . currentType = signatureReference . type . asNullable ( ) ;
7646
7645
return options . isWasm64 ? module . i64 ( 0 ) : module . i32 ( 0 ) ;
7647
7646
}
7648
- return this . makeZero ( contextualType , expression ) ;
7647
+ return this . makeZero ( contextualType ) ;
7649
7648
}
7650
7649
this . currentType = options . usizeType ;
7651
7650
this . warning (
@@ -7937,7 +7936,7 @@ export class Compiler extends DiagnosticEmitter {
7937
7936
? BinaryOp . NeI64
7938
7937
: BinaryOp . NeI32 ,
7939
7938
expr ,
7940
- this . makeZero ( actualType , expression . expression )
7939
+ this . makeZero ( actualType )
7941
7940
) ;
7942
7941
}
7943
7942
@@ -8044,7 +8043,7 @@ export class Compiler extends DiagnosticEmitter {
8044
8043
? BinaryOp . NeI64
8045
8044
: BinaryOp . NeI32 ,
8046
8045
expr ,
8047
- this . makeZero ( actualType , expression . expression )
8046
+ this . makeZero ( actualType )
8048
8047
) ;
8049
8048
8050
8049
// <nonNullable> is just `true`
@@ -8395,7 +8394,7 @@ export class Compiler extends DiagnosticEmitter {
8395
8394
}
8396
8395
values [ i ] = expr ;
8397
8396
} else {
8398
- values [ i ] = this . makeZero ( elementType , elementExpression ) ;
8397
+ values [ i ] = this . makeZero ( elementType ) ;
8399
8398
}
8400
8399
}
8401
8400
@@ -8547,7 +8546,7 @@ export class Compiler extends DiagnosticEmitter {
8547
8546
}
8548
8547
values [ i ] = expr ;
8549
8548
} else {
8550
- values [ i ] = this . makeZero ( elementType , elementExpression ) ;
8549
+ values [ i ] = this . makeZero ( elementType ) ;
8551
8550
}
8552
8551
}
8553
8552
@@ -8784,7 +8783,7 @@ export class Compiler extends DiagnosticEmitter {
8784
8783
exprs . push (
8785
8784
module . call ( fieldInstance . internalSetterName , [
8786
8785
module . local_get ( tempLocal . index , classTypeRef ) ,
8787
- this . makeZero ( fieldType , expression )
8786
+ this . makeZero ( fieldType )
8788
8787
] , TypeRef . None )
8789
8788
) ;
8790
8789
this . compileFieldSetter ( fieldInstance ) ;
@@ -9080,7 +9079,7 @@ export class Compiler extends DiagnosticEmitter {
9080
9079
ctorInstance ,
9081
9080
argumentExpressions ,
9082
9081
reportNode ,
9083
- this . makeZero ( this . options . usizeType , reportNode ) ,
9082
+ this . makeZero ( this . options . usizeType ) ,
9084
9083
constraints
9085
9084
) ;
9086
9085
if ( getExpressionType ( expr ) != TypeRef . None ) { // possibly WILL_DROP
@@ -9647,7 +9646,7 @@ export class Compiler extends DiagnosticEmitter {
9647
9646
this . options . isWasm64
9648
9647
? BinaryOp . SubI64
9649
9648
: BinaryOp . SubI32 ,
9650
- this . makeZero ( this . currentType , expression . operand ) ,
9649
+ this . makeZero ( this . currentType ) ,
9651
9650
expr
9652
9651
) ;
9653
9652
break ;
@@ -10197,7 +10196,7 @@ export class Compiler extends DiagnosticEmitter {
10197
10196
// === Specialized code generation ==============================================================
10198
10197
10199
10198
/** Makes a constant zero of the specified type. */
10200
- makeZero ( type : Type , reportNode : Node ) : ExpressionRef {
10199
+ makeZero ( type : Type ) : ExpressionRef {
10201
10200
var module = this . module ;
10202
10201
switch ( type . kind ) {
10203
10202
default : assert ( false ) ;
@@ -10263,6 +10262,7 @@ export class Compiler extends DiagnosticEmitter {
10263
10262
case TypeKind . U64 : return module . i64 ( - 1 , - 1 ) ;
10264
10263
case TypeKind . F32 : return module . f32 ( - 1 ) ;
10265
10264
case TypeKind . F64 : return module . f64 ( - 1 ) ;
10265
+ case TypeKind . I31REF : return module . i31_new ( module . i32 ( - 1 ) ) ;
10266
10266
}
10267
10267
}
10268
10268
@@ -10333,11 +10333,11 @@ export class Compiler extends DiagnosticEmitter {
10333
10333
case TypeKind . EXTERNREF :
10334
10334
case TypeKind . ANYREF :
10335
10335
case TypeKind . EQREF :
10336
- case TypeKind . DATAREF :
10337
- case TypeKind . I31REF : {
10336
+ case TypeKind . I31REF :
10337
+ case TypeKind . DATAREF : {
10338
10338
// Needs to be true (i.e. not zero) when the ref is _not_ null,
10339
10339
// which means `ref.is_null` returns false (i.e. zero).
10340
- return module . unary ( UnaryOp . EqzI32 , module . ref_is ( RefIsOp . RefIsNull , expr ) ) ;
10340
+ return module . unary ( UnaryOp . EqzI32 , module . ref_is_null ( expr ) ) ;
10341
10341
10342
10342
}
10343
10343
default : {
@@ -10512,7 +10512,7 @@ export class Compiler extends DiagnosticEmitter {
10512
10512
module . local_get ( thisLocalIndex , sizeTypeRef ) ,
10513
10513
initializerNode // use initializer if present, otherwise initialize with zero
10514
10514
? this . compileExpression ( initializerNode , fieldType , Constraints . CONV_IMPLICIT )
10515
- : this . makeZero ( fieldType , fieldPrototype . declaration )
10515
+ : this . makeZero ( fieldType )
10516
10516
] , TypeRef . None )
10517
10517
) ;
10518
10518
}
@@ -10538,7 +10538,7 @@ export class Compiler extends DiagnosticEmitter {
10538
10538
if ( message ) {
10539
10539
messageArg = this . compileExpression ( message , stringInstance . type , Constraints . CONV_IMPLICIT ) ;
10540
10540
} else {
10541
- messageArg = this . makeZero ( stringInstance . type , codeLocation ) ;
10541
+ messageArg = this . makeZero ( stringInstance . type ) ;
10542
10542
}
10543
10543
10544
10544
return this . makeStaticAbort ( messageArg , codeLocation ) ;
@@ -10587,11 +10587,31 @@ export class Compiler extends DiagnosticEmitter {
10587
10587
var temp = flow . getTempLocal ( type ) ;
10588
10588
if ( ! flow . canOverflow ( expr , type ) ) flow . setLocalFlag ( temp . index , LocalFlags . WRAPPED ) ;
10589
10589
flow . setLocalFlag ( temp . index , LocalFlags . NONNULL ) ;
10590
- expr = module . if (
10591
- module . local_tee ( temp . index , expr , type . isManaged ) ,
10592
- module . local_get ( temp . index , type . toRef ( ) ) ,
10593
- this . makeStaticAbort ( this . ensureStaticString ( "unexpected null" ) , reportNode ) // TODO: throw
10594
- ) ;
10590
+
10591
+ var staticAbortCallExpr = this . makeStaticAbort (
10592
+ this . ensureStaticString ( "unexpected null" ) ,
10593
+ reportNode
10594
+ ) ; // TODO: throw
10595
+
10596
+ if ( type . isExternalReference ) {
10597
+ let nonNullExpr = module . local_get ( temp . index , type . toRef ( ) ) ;
10598
+ if ( this . options . hasFeature ( Feature . GC ) ) {
10599
+ nonNullExpr = module . ref_as_nonnull ( nonNullExpr ) ;
10600
+ }
10601
+ expr = module . if (
10602
+ module . ref_is_null (
10603
+ module . local_tee ( temp . index , expr , false )
10604
+ ) ,
10605
+ staticAbortCallExpr ,
10606
+ nonNullExpr
10607
+ ) ;
10608
+ } else {
10609
+ expr = module . if (
10610
+ module . local_tee ( temp . index , expr , type . isManaged ) ,
10611
+ module . local_get ( temp . index , type . toRef ( ) ) ,
10612
+ staticAbortCallExpr
10613
+ ) ;
10614
+ }
10595
10615
flow . freeTempLocal ( temp ) ;
10596
10616
this . currentType = type . nonNullableType ;
10597
10617
return expr ;
@@ -10614,6 +10634,12 @@ export class Compiler extends DiagnosticEmitter {
10614
10634
var temp = flow . getTempLocal ( type ) ;
10615
10635
var instanceofInstance = this . program . instanceofInstance ;
10616
10636
assert ( this . compileFunction ( instanceofInstance ) ) ;
10637
+
10638
+ var staticAbortCallExpr = this . makeStaticAbort (
10639
+ this . ensureStaticString ( "unexpected upcast" ) ,
10640
+ reportNode
10641
+ ) ; // TODO: throw
10642
+
10617
10643
if ( ! toType . isNullableReference || flow . isNonnull ( expr , type ) ) {
10618
10644
// Simplify if the value cannot be `null`. If toType is non-nullable, a
10619
10645
// null-check would have been emitted separately so is not necessary here.
@@ -10623,7 +10649,7 @@ export class Compiler extends DiagnosticEmitter {
10623
10649
module . i32 ( toType . classReference ! . id )
10624
10650
] , TypeRef . I32 ) ,
10625
10651
module . local_get ( temp . index , type . toRef ( ) ) ,
10626
- this . makeStaticAbort ( this . ensureStaticString ( "unexpected upcast" ) , reportNode ) // TODO: throw
10652
+ staticAbortCallExpr
10627
10653
) ;
10628
10654
} else {
10629
10655
expr = module . if (
@@ -10634,7 +10660,7 @@ export class Compiler extends DiagnosticEmitter {
10634
10660
module . i32 ( toType . classReference ! . id )
10635
10661
] , TypeRef . I32 ) ,
10636
10662
module . local_get ( temp . index , type . toRef ( ) ) ,
10637
- this . makeStaticAbort ( this . ensureStaticString ( "unexpected upcast" ) , reportNode ) // TODO: throw
10663
+ staticAbortCallExpr
10638
10664
) ,
10639
10665
module . usize ( 0 )
10640
10666
) ;
0 commit comments