@@ -2672,7 +2672,18 @@ export class Compiler extends DiagnosticEmitter {
26722672 expr = module . createBinary ( BinaryOp . EqI32 , leftExpr , rightExpr ) ;
26732673 break ;
26742674 }
2675- case TypeKind . USIZE : // TODO: check operator overload
2675+ case TypeKind . USIZE : { // check operator overload
2676+ if ( this . currentType . is ( TypeFlags . REFERENCE ) ) {
2677+ let classInstance = assert ( this . currentType . classReference ) ;
2678+ let operatorName = classInstance . prototype . fnEquals ;
2679+ if ( operatorName != null ) {
2680+ expr = this . compileOperatorOverload ( classInstance , operatorName , leftExpr , rightExpr ) ;
2681+ assert ( this . currentType == Type . bool ) ;
2682+ break ;
2683+ }
2684+ }
2685+ // fall-through
2686+ }
26762687 case TypeKind . ISIZE : {
26772688 expr = module . createBinary (
26782689 this . options . isWasm64
@@ -2822,7 +2833,17 @@ export class Compiler extends DiagnosticEmitter {
28222833 expr = module . createBinary ( BinaryOp . AddI32 , leftExpr , rightExpr ) ;
28232834 break ;
28242835 }
2825- case TypeKind . USIZE : // TODO: check operator overload
2836+ case TypeKind . USIZE : { // check operator overload
2837+ if ( this . currentType . is ( TypeFlags . REFERENCE ) ) {
2838+ let classInstance = assert ( this . currentType . classReference ) ;
2839+ let operatorName = classInstance . prototype . fnConcat ;
2840+ if ( operatorName != null ) {
2841+ expr = this . compileOperatorOverload ( classInstance , operatorName , leftExpr , rightExpr ) ;
2842+ break ;
2843+ }
2844+ }
2845+ // fall-through
2846+ }
28262847 case TypeKind . ISIZE : {
28272848 expr = module . createBinary (
28282849 this . options . isWasm64
@@ -3726,6 +3747,20 @@ export class Compiler extends DiagnosticEmitter {
37263747 : expr ;
37273748 }
37283749
3750+ compileOperatorOverload (
3751+ classInstance : Class ,
3752+ operatorName : string ,
3753+ leftExpr : ExpressionRef ,
3754+ rightExpr : ExpressionRef
3755+ ) : ExpressionRef {
3756+ var classPrototype = classInstance . prototype ;
3757+ var operatorPrototype = assert ( assert ( classPrototype . members ) . get ( operatorName ) ) ;
3758+ assert ( operatorPrototype . kind == ElementKind . FUNCTION_PROTOTYPE ) ;
3759+ var operatorInstance = ( < FunctionPrototype > operatorPrototype ) . resolve ( ) ;
3760+ if ( ! operatorInstance ) return this . module . createUnreachable ( ) ;
3761+ return this . makeCallDirect ( operatorInstance , [ leftExpr , rightExpr ] ) ;
3762+ }
3763+
37293764 compileAssignment ( expression : Expression , valueExpression : Expression , contextualType : Type ) : ExpressionRef {
37303765 var currentFunction = this . currentFunction ;
37313766 var resolved = this . program . resolveExpression ( expression , currentFunction ) ; // reports
@@ -4526,7 +4561,6 @@ export class Compiler extends DiagnosticEmitter {
45264561 assert ( parent . kind == ElementKind . CLASS ) ;
45274562 let thisType = ( < Class > parent ) . type ;
45284563 if ( currentFunction . is ( CommonFlags . CONSTRUCTOR ) ) {
4529- let nativeSizeType = this . options . nativeSizeType ;
45304564 let flow = currentFunction . flow ;
45314565 if ( ! flow . is ( FlowFlags . ALLOCATES ) ) {
45324566 flow . set ( FlowFlags . ALLOCATES ) ;
@@ -5152,8 +5186,36 @@ export class Compiler extends DiagnosticEmitter {
51525186 : this . compileExpression ( ifElse , contextualType ) ;
51535187 }
51545188
5155- var ifThenExpr = this . compileExpression ( ifThen , contextualType ) ;
5156- var ifElseExpr = this . compileExpression ( ifElse , contextualType ) ;
5189+ var currentFunction = this . currentFunction ;
5190+ var ifThenExpr : ExpressionRef ;
5191+ var ifElseExpr : ExpressionRef ;
5192+
5193+ // if part of a constructor, keep track of memory allocations
5194+ if ( currentFunction . is ( CommonFlags . CONSTRUCTOR ) ) {
5195+ let flow = currentFunction . flow ;
5196+
5197+ flow = flow . enterBranchOrScope ( ) ;
5198+ currentFunction . flow = flow ;
5199+ ifThenExpr = this . compileExpression ( ifThen , contextualType ) ;
5200+ let ifThenAllocates = flow . is ( FlowFlags . ALLOCATES ) ;
5201+ flow = flow . leaveBranchOrScope ( ) ;
5202+ currentFunction . flow = flow ;
5203+
5204+ flow = flow . enterBranchOrScope ( ) ;
5205+ currentFunction . flow = flow ;
5206+ ifElseExpr = this . compileExpression ( ifElse , contextualType ) ;
5207+ let ifElseAllocates = flow . is ( FlowFlags . ALLOCATES ) ;
5208+ flow = flow . leaveBranchOrScope ( ) ;
5209+ currentFunction . flow = flow ;
5210+
5211+ if ( ifThenAllocates && ifElseAllocates ) flow . set ( FlowFlags . ALLOCATES ) ;
5212+
5213+ // otherwise simplify
5214+ } else {
5215+ ifThenExpr = this . compileExpression ( ifThen , contextualType ) ;
5216+ ifElseExpr = this . compileExpression ( ifElse , contextualType ) ;
5217+ }
5218+
51575219 return this . module . createIf ( condExpr , ifThenExpr , ifElseExpr ) ;
51585220 }
51595221
0 commit comments