@@ -9965,6 +9965,14 @@ export class Compiler extends DiagnosticEmitter {
99659965
99669966 // === Specialized code generation ==============================================================
99679967
9968+ /** Check if possible to optimize the active initialization away if it's zero */
9969+ canOptimizeZeroInitialization ( valueExpr : ExpressionRef ) : bool {
9970+ const runtime = this . options . runtime ;
9971+ return ( runtime == Runtime . Incremental || runtime == Runtime . Stub )
9972+ ? isConstZero ( valueExpr )
9973+ : false ;
9974+ }
9975+
99689976 /** Makes a constant zero of the specified type. */
99699977 makeZero ( type : Type ) : ExpressionRef {
99709978 let module = this . module ;
@@ -10312,6 +10320,7 @@ export class Compiler extends DiagnosticEmitter {
1031210320 let parameterIndex = fieldPrototype . parameterIndex ;
1031310321
1031410322 // Defer non-parameter fields until parameter fields are initialized
10323+ // Since non-parameter may depend on parameter fields
1031510324 if ( parameterIndex < 0 ) {
1031610325 if ( ! nonParameterFields ) nonParameterFields = new Array ( ) ;
1031710326 nonParameterFields . push ( property ) ;
@@ -10347,16 +10356,25 @@ export class Compiler extends DiagnosticEmitter {
1034710356 let initializerNode = fieldPrototype . initializerNode ;
1034810357 assert ( fieldPrototype . parameterIndex < 0 ) ;
1034910358 let setterInstance = assert ( field . setterInstance ) ;
10350- let expr = this . makeCallDirect ( setterInstance , [
10351- module . local_get ( thisLocalIndex , sizeTypeRef ) ,
10352- initializerNode // use initializer if present, otherwise initialize with zero
10353- ? this . compileExpression ( initializerNode , fieldType , Constraints . ConvImplicit )
10354- : this . makeZero ( fieldType )
10355- ] , field . identifierNode , true ) ;
10356- if ( this . currentType != Type . void ) { // in case
10357- expr = module . drop ( expr ) ;
10359+
10360+ if ( initializerNode ) {
10361+ // Explicit initializer
10362+ // Check if we need to initialize this field
10363+ const valueExpr : ExpressionRef = this . compileExpression ( initializerNode , fieldType , Constraints . ConvImplicit ) ;
10364+ // Memory will be filled with 0 on itcms.__new
10365+ // Memory grow will default to initialized with 0 as wasm spec
10366+ // So, optimize the active initialization away if it's zero
10367+ if ( ! this . canOptimizeZeroInitialization ( valueExpr ) ) {
10368+ let expr = this . makeCallDirect ( setterInstance , [
10369+ module . local_get ( thisLocalIndex , sizeTypeRef ) ,
10370+ valueExpr
10371+ ] , field . identifierNode , true ) ;
10372+ if ( this . currentType != Type . void ) { // in case
10373+ expr = module . drop ( expr ) ;
10374+ }
10375+ stmts . push ( expr ) ;
10376+ }
1035810377 }
10359- stmts . push ( expr ) ;
1036010378 }
1036110379 }
1036210380
0 commit comments