@@ -1201,7 +1201,7 @@ export class Compiler extends DiagnosticEmitter {
1201
1201
if ( global . is ( CommonFlags . INLINED ) ) {
1202
1202
initExpr = this . compileInlineConstant ( global , global . type , Constraints . PREFER_STATIC | Constraints . WILL_RETAIN ) ;
1203
1203
} else {
1204
- initExpr = this . makeZero ( type ) ;
1204
+ initExpr = this . makeZero ( type , global . declaration ) ;
1205
1205
}
1206
1206
}
1207
1207
@@ -1214,7 +1214,7 @@ export class Compiler extends DiagnosticEmitter {
1214
1214
findDecorator ( DecoratorKind . INLINE , global . decoratorNodes ) ! . range , "inline"
1215
1215
) ;
1216
1216
}
1217
- module . addGlobal ( internalName , nativeType , true , this . makeZero ( type ) ) ;
1217
+ module . addGlobal ( internalName , nativeType , true , this . makeZero ( type , global . declaration ) ) ;
1218
1218
if ( type . isManaged && ! this . skippedAutoreleases . has ( initExpr ) ) initExpr = this . makeRetain ( initExpr , type ) ;
1219
1219
this . currentBody . push (
1220
1220
module . global_set ( internalName , initExpr )
@@ -2361,7 +2361,8 @@ export class Compiler extends DiagnosticEmitter {
2361
2361
this . currentFlow = condFlow ;
2362
2362
let condExpr = this . makeIsTrueish (
2363
2363
this . compileExpression ( statement . condition , Type . i32 ) ,
2364
- this . currentType
2364
+ this . currentType ,
2365
+ statement . condition
2365
2366
) ;
2366
2367
let condKind = this . evaluateCondition ( condExpr ) ;
2367
2368
@@ -2505,7 +2506,8 @@ export class Compiler extends DiagnosticEmitter {
2505
2506
if ( condition ) {
2506
2507
condExpr = this . makeIsTrueish (
2507
2508
this . compileExpression ( condition , Type . bool ) ,
2508
- this . currentType
2509
+ this . currentType ,
2510
+ condition
2509
2511
) ;
2510
2512
condKind = this . evaluateCondition ( condExpr ) ;
2511
2513
@@ -2665,7 +2667,8 @@ export class Compiler extends DiagnosticEmitter {
2665
2667
// Precompute the condition (always executes)
2666
2668
var condExpr = this . makeIsTrueish (
2667
2669
this . compileExpression ( statement . condition , Type . bool ) ,
2668
- this . currentType
2670
+ this . currentType ,
2671
+ statement . condition
2669
2672
) ;
2670
2673
var condKind = this . evaluateCondition ( condExpr ) ;
2671
2674
@@ -3186,7 +3189,7 @@ export class Compiler extends DiagnosticEmitter {
3186
3189
// TODO: Detect this condition inside of a loop instead?
3187
3190
initializers . push (
3188
3191
module . local_set ( local . index ,
3189
- this . makeZero ( type )
3192
+ this . makeZero ( type , declaration )
3190
3193
)
3191
3194
) ;
3192
3195
flow . setLocalFlag ( local . index , LocalFlags . CONDITIONALLY_RETAINED ) ;
@@ -3255,7 +3258,8 @@ export class Compiler extends DiagnosticEmitter {
3255
3258
this . currentFlow = condFlow ;
3256
3259
var condExpr = this . makeIsTrueish (
3257
3260
this . compileExpression ( statement . condition , Type . bool ) ,
3258
- this . currentType
3261
+ this . currentType ,
3262
+ statement . condition
3259
3263
) ;
3260
3264
var condKind = this . evaluateCondition ( condExpr ) ;
3261
3265
@@ -5798,8 +5802,8 @@ export class Compiler extends DiagnosticEmitter {
5798
5802
rightFlow . freeScopedLocals ( ) ;
5799
5803
this . currentFlow = flow ;
5800
5804
expr = module . if (
5801
- this . makeIsTrueish ( leftExpr , leftType ) ,
5802
- this . makeIsTrueish ( rightExpr , rightType ) ,
5805
+ this . makeIsTrueish ( leftExpr , leftType , left ) ,
5806
+ this . makeIsTrueish ( rightExpr , rightType , right ) ,
5803
5807
module . i32 ( 0 )
5804
5808
) ;
5805
5809
this . currentType = Type . bool ;
@@ -5843,7 +5847,7 @@ export class Compiler extends DiagnosticEmitter {
5843
5847
this . currentFlow = flow ;
5844
5848
5845
5849
expr = module . if (
5846
- this . makeIsTrueish ( leftExpr , leftType ) ,
5850
+ this . makeIsTrueish ( leftExpr , leftType , left ) ,
5847
5851
rightExpr ,
5848
5852
retainLeftInElse
5849
5853
? this . makeRetain (
@@ -5864,7 +5868,7 @@ export class Compiler extends DiagnosticEmitter {
5864
5868
// simplify if cloning left without side effects is possible
5865
5869
if ( expr = module . cloneExpression ( leftExpr , true , 0 ) ) {
5866
5870
expr = module . if (
5867
- this . makeIsTrueish ( leftExpr , this . currentType ) ,
5871
+ this . makeIsTrueish ( leftExpr , this . currentType , left ) ,
5868
5872
rightExpr ,
5869
5873
expr
5870
5874
) ;
@@ -5875,7 +5879,7 @@ export class Compiler extends DiagnosticEmitter {
5875
5879
if ( ! flow . canOverflow ( leftExpr , leftType ) ) flow . setLocalFlag ( tempLocal . index , LocalFlags . WRAPPED ) ;
5876
5880
if ( flow . isNonnull ( leftExpr , leftType ) ) flow . setLocalFlag ( tempLocal . index , LocalFlags . NONNULL ) ;
5877
5881
expr = module . if (
5878
- this . makeIsTrueish ( module . local_tee ( tempLocal . index , leftExpr ) , leftType ) ,
5882
+ this . makeIsTrueish ( module . local_tee ( tempLocal . index , leftExpr ) , leftType , left ) ,
5879
5883
rightExpr ,
5880
5884
module . local_get ( tempLocal . index , leftType . toNativeType ( ) )
5881
5885
) ;
@@ -5904,9 +5908,9 @@ export class Compiler extends DiagnosticEmitter {
5904
5908
rightFlow . freeScopedLocals ( ) ;
5905
5909
this . currentFlow = flow ;
5906
5910
expr = module . if (
5907
- this . makeIsTrueish ( leftExpr , leftType ) ,
5911
+ this . makeIsTrueish ( leftExpr , leftType , left ) ,
5908
5912
module . i32 ( 1 ) ,
5909
- this . makeIsTrueish ( rightExpr , rightType )
5913
+ this . makeIsTrueish ( rightExpr , rightType , right )
5910
5914
) ;
5911
5915
this . currentType = Type . bool ;
5912
5916
@@ -5951,7 +5955,7 @@ export class Compiler extends DiagnosticEmitter {
5951
5955
this . currentFlow = flow ;
5952
5956
5953
5957
expr = module . if (
5954
- this . makeIsTrueish ( leftExpr , leftType ) ,
5958
+ this . makeIsTrueish ( leftExpr , leftType , left ) ,
5955
5959
retainLeftInThen
5956
5960
? this . makeRetain (
5957
5961
module . local_get ( temp . index , leftType . toNativeType ( ) ) ,
@@ -5972,7 +5976,7 @@ export class Compiler extends DiagnosticEmitter {
5972
5976
// simplify if cloning left without side effects is possible
5973
5977
if ( expr = module . cloneExpression ( leftExpr , true , 0 ) ) {
5974
5978
expr = module . if (
5975
- this . makeIsTrueish ( leftExpr , leftType ) ,
5979
+ this . makeIsTrueish ( leftExpr , leftType , left ) ,
5976
5980
expr ,
5977
5981
rightExpr
5978
5982
) ;
@@ -5983,7 +5987,7 @@ export class Compiler extends DiagnosticEmitter {
5983
5987
if ( ! flow . canOverflow ( leftExpr , leftType ) ) flow . setLocalFlag ( temp . index , LocalFlags . WRAPPED ) ;
5984
5988
if ( flow . isNonnull ( leftExpr , leftType ) ) flow . setLocalFlag ( temp . index , LocalFlags . NONNULL ) ;
5985
5989
expr = module . if (
5986
- this . makeIsTrueish ( module . local_tee ( temp . index , leftExpr ) , leftType ) ,
5990
+ this . makeIsTrueish ( module . local_tee ( temp . index , leftExpr ) , leftType , left ) ,
5987
5991
module . local_get ( temp . index , leftType . toNativeType ( ) ) ,
5988
5992
rightExpr
5989
5993
) ;
@@ -7389,7 +7393,7 @@ export class Compiler extends DiagnosticEmitter {
7389
7393
let needsVarargsStub = false ;
7390
7394
for ( let n = numParameters ; n < overloadNumParameters ; ++ n ) {
7391
7395
// TODO: inline constant initializers and skip varargs stub
7392
- paramExprs [ 1 + n ] = this . makeZero ( overloadParameterTypes [ n ] ) ;
7396
+ paramExprs [ 1 + n ] = this . makeZero ( overloadParameterTypes [ n ] , overloadInstance . declaration ) ;
7393
7397
needsVarargsStub = true ;
7394
7398
}
7395
7399
let calledName = needsVarargsStub
@@ -7874,7 +7878,7 @@ export class Compiler extends DiagnosticEmitter {
7874
7878
}
7875
7879
}
7876
7880
}
7877
- operands . push ( this . makeZero ( parameterTypes [ i ] ) ) ;
7881
+ operands . push ( this . makeZero ( parameterTypes [ i ] , instance . declaration ) ) ;
7878
7882
allOptionalsAreConstant = false ;
7879
7883
}
7880
7884
if ( ! allOptionalsAreConstant ) {
@@ -7966,15 +7970,16 @@ export class Compiler extends DiagnosticEmitter {
7966
7970
) ;
7967
7971
}
7968
7972
assert ( index == numArgumentsInclThis ) ;
7969
- return this . makeCallIndirect ( signature , indexArg , operands , immediatelyDropped ) ;
7973
+ return this . makeCallIndirect ( signature , indexArg , operands , immediatelyDropped , reportNode ) ;
7970
7974
}
7971
7975
7972
7976
/** Creates an indirect call to the function at `indexArg` in the function table. */
7973
7977
makeCallIndirect (
7974
7978
signature : Signature ,
7975
7979
indexArg : ExpressionRef ,
7976
7980
operands : ExpressionRef [ ] | null = null ,
7977
- immediatelyDropped : bool = false
7981
+ immediatelyDropped : bool = false ,
7982
+ reportNode : Node
7978
7983
) : ExpressionRef {
7979
7984
var module = this . module ;
7980
7985
var numOperands = operands ? operands . length : 0 ;
@@ -8000,7 +8005,7 @@ export class Compiler extends DiagnosticEmitter {
8000
8005
}
8001
8006
let parameterTypes = signature . parameterTypes ;
8002
8007
for ( let i = numArguments ; i < maxArguments ; ++ i ) {
8003
- operands . push ( this . makeZero ( parameterTypes [ i ] ) ) ;
8008
+ operands . push ( this . makeZero ( parameterTypes [ i ] , reportNode ) ) ;
8004
8009
}
8005
8010
}
8006
8011
@@ -8546,7 +8551,7 @@ export class Compiler extends DiagnosticEmitter {
8546
8551
? BinaryOp . NeI64
8547
8552
: BinaryOp . NeI32 ,
8548
8553
expr ,
8549
- this . makeZero ( actualType )
8554
+ this . makeZero ( actualType , expression . expression )
8550
8555
) ;
8551
8556
}
8552
8557
@@ -8653,7 +8658,7 @@ export class Compiler extends DiagnosticEmitter {
8653
8658
? BinaryOp . NeI64
8654
8659
: BinaryOp . NeI32 ,
8655
8660
expr ,
8656
- this . makeZero ( actualType )
8661
+ this . makeZero ( actualType , expression . expression )
8657
8662
) ;
8658
8663
8659
8664
// <nonNullable> is just `true`
@@ -8792,9 +8797,9 @@ export class Compiler extends DiagnosticEmitter {
8792
8797
var isStatic = true ;
8793
8798
var nativeElementType = elementType . toNativeType ( ) ;
8794
8799
for ( let i = 0 ; i < length ; ++ i ) {
8795
- let expression = expressions [ i ] ;
8796
- if ( expression ) {
8797
- let expr = this . compileExpression ( < Expression > expression , elementType ,
8800
+ let elementExpression = expressions [ i ] ;
8801
+ if ( elementExpression ) {
8802
+ let expr = this . compileExpression ( < Expression > elementExpression , elementType ,
8798
8803
Constraints . CONV_IMPLICIT | Constraints . WILL_RETAIN
8799
8804
) ;
8800
8805
let precomp = module . runExpression ( expr , ExpressionRunnerFlags . PreserveSideeffects ) ;
@@ -8805,7 +8810,7 @@ export class Compiler extends DiagnosticEmitter {
8805
8810
}
8806
8811
values [ i ] = expr ;
8807
8812
} else {
8808
- values [ i ] = this . makeZero ( elementType ) ;
8813
+ values [ i ] = this . makeZero ( elementType , expression ) ;
8809
8814
}
8810
8815
}
8811
8816
@@ -8962,9 +8967,9 @@ export class Compiler extends DiagnosticEmitter {
8962
8967
var nativeElementType = elementType . toNativeType ( ) ;
8963
8968
var isStatic = true ;
8964
8969
for ( let i = 0 ; i < length ; ++ i ) {
8965
- let expression = expressions [ i ] ;
8966
- if ( expression ) {
8967
- let expr = this . compileExpression ( expression , elementType ,
8970
+ let elementExpression = expressions [ i ] ;
8971
+ if ( elementExpression ) {
8972
+ let expr = this . compileExpression ( elementExpression , elementType ,
8968
8973
Constraints . CONV_IMPLICIT | Constraints . WILL_RETAIN
8969
8974
) ;
8970
8975
let precomp = module . runExpression ( expr , ExpressionRunnerFlags . PreserveSideeffects ) ;
@@ -8975,7 +8980,7 @@ export class Compiler extends DiagnosticEmitter {
8975
8980
}
8976
8981
values [ i ] = expr ;
8977
8982
} else {
8978
- values [ i ] = this . makeZero ( elementType ) ;
8983
+ values [ i ] = this . makeZero ( elementType , expression ) ;
8979
8984
}
8980
8985
}
8981
8986
@@ -9247,7 +9252,7 @@ export class Compiler extends DiagnosticEmitter {
9247
9252
module . store ( // TODO: handle setters as well
9248
9253
fieldType . byteSize ,
9249
9254
module . local_get ( tempLocal . index , nativeClassType ) ,
9250
- this . makeZero ( fieldType ) ,
9255
+ this . makeZero ( fieldType , expression ) ,
9251
9256
fieldType . toNativeType ( ) ,
9252
9257
fieldInstance . memoryOffset
9253
9258
)
@@ -9536,7 +9541,7 @@ export class Compiler extends DiagnosticEmitter {
9536
9541
ctorInstance ,
9537
9542
argumentExpressions ,
9538
9543
reportNode ,
9539
- this . makeZero ( this . options . usizeType ) ,
9544
+ this . makeZero ( this . options . usizeType , reportNode ) ,
9540
9545
constraints
9541
9546
) ;
9542
9547
if ( getExpressionType ( expr ) != NativeType . None ) { // possibly WILL_DROP
@@ -9702,7 +9707,8 @@ export class Compiler extends DiagnosticEmitter {
9702
9707
9703
9708
var condExpr = this . makeIsTrueish (
9704
9709
this . compileExpression ( expression . condition , Type . bool ) ,
9705
- this . currentType
9710
+ this . currentType ,
9711
+ expression . condition
9706
9712
) ;
9707
9713
// Try to eliminate unnecesssary branches if the condition is constant
9708
9714
// FIXME: skips common denominator, inconsistently picking branch type
@@ -10129,7 +10135,7 @@ export class Compiler extends DiagnosticEmitter {
10129
10135
this . options . isWasm64
10130
10136
? BinaryOp . SubI64
10131
10137
: BinaryOp . SubI32 ,
10132
- this . makeZero ( this . currentType ) ,
10138
+ this . makeZero ( this . currentType , expression . operand ) ,
10133
10139
expr
10134
10140
) ;
10135
10141
break ;
@@ -10316,7 +10322,7 @@ export class Compiler extends DiagnosticEmitter {
10316
10322
// allow '!' for references even without an overload
10317
10323
}
10318
10324
10319
- expr = module . unary ( UnaryOp . EqzI32 , this . makeIsTrueish ( expr , this . currentType ) ) ;
10325
+ expr = module . unary ( UnaryOp . EqzI32 , this . makeIsTrueish ( expr , this . currentType , expression . operand ) ) ;
10320
10326
this . currentType = Type . bool ;
10321
10327
break ;
10322
10328
}
@@ -10640,7 +10646,7 @@ export class Compiler extends DiagnosticEmitter {
10640
10646
// === Specialized code generation ==============================================================
10641
10647
10642
10648
/** Makes a constant zero of the specified type. */
10643
- makeZero ( type : Type ) : ExpressionRef {
10649
+ makeZero ( type : Type , reportNode : Node ) : ExpressionRef {
10644
10650
var module = this . module ;
10645
10651
switch ( type . kind ) {
10646
10652
default : assert ( false ) ;
@@ -10660,7 +10666,11 @@ export class Compiler extends DiagnosticEmitter {
10660
10666
case TypeKind . V128 : return module . v128 ( v128_zero ) ;
10661
10667
case TypeKind . EXTERNREF :
10662
10668
// TODO: return null ref for both externref as well as funcref
10663
- assert ( false , 'null for externref is not yet supported' ) ;
10669
+ this . error (
10670
+ DiagnosticCode . Not_implemented_0 ,
10671
+ reportNode . range ,
10672
+ "ref.null<externref>"
10673
+ ) ;
10664
10674
return module . unreachable ( ) ;
10665
10675
}
10666
10676
}
@@ -10707,7 +10717,7 @@ export class Compiler extends DiagnosticEmitter {
10707
10717
}
10708
10718
10709
10719
/** Creates a comparison whether an expression is 'true' in a broader sense. */
10710
- makeIsTrueish ( expr : ExpressionRef , type : Type ) : ExpressionRef {
10720
+ makeIsTrueish ( expr : ExpressionRef , type : Type , reportNode : Node ) : ExpressionRef {
10711
10721
var module = this . module ;
10712
10722
switch ( type . kind ) {
10713
10723
case TypeKind . I8 :
@@ -10764,7 +10774,11 @@ export class Compiler extends DiagnosticEmitter {
10764
10774
// TODO: non-null object might still be considered falseish
10765
10775
// i.e. a ref to Boolean(false), Number(0), String("") etc.
10766
10776
// TODO: return module.unary(UnaryOp.EqzI32, module.ref_is_null(expr));
10767
- assert ( false , 'Truthy checks for externref are not yet supported' ) ;
10777
+ this . error (
10778
+ DiagnosticCode . Not_implemented_0 ,
10779
+ reportNode . range ,
10780
+ "ref.is_null"
10781
+ ) ;
10768
10782
}
10769
10783
default : {
10770
10784
assert ( false ) ;
@@ -10855,7 +10869,7 @@ export class Compiler extends DiagnosticEmitter {
10855
10869
10856
10870
// otherwise initialize with zero
10857
10871
} else {
10858
- initExpr = this . makeZero ( fieldType ) ;
10872
+ initExpr = this . makeZero ( fieldType , fieldPrototype . declaration ) ;
10859
10873
}
10860
10874
10861
10875
stmts . push (
@@ -10890,7 +10904,7 @@ export class Compiler extends DiagnosticEmitter {
10890
10904
// essentially ignoring the message GC-wise. Doesn't matter anyway on a crash.
10891
10905
messageArg = this . compileExpression ( message , stringInstance . type , Constraints . CONV_IMPLICIT | Constraints . WILL_RETAIN ) ;
10892
10906
} else {
10893
- messageArg = this . makeZero ( stringInstance . type ) ;
10907
+ messageArg = this . makeZero ( stringInstance . type , codeLocation ) ;
10894
10908
}
10895
10909
10896
10910
return this . makeStaticAbort ( messageArg , codeLocation ) ;
0 commit comments