Skip to content

Commit d5c8c0d

Browse files
committed
fix
1 parent 15422ca commit d5c8c0d

File tree

1 file changed

+6
-94
lines changed

1 file changed

+6
-94
lines changed

src/compiler.ts

Lines changed: 6 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ import {
5959
isConstExpressionNaN,
6060
ensureType,
6161
createType,
62-
getConstValueInteger
62+
getConstValueInteger,
63+
isConstNonZero
6364
} from "./module";
6465

6566
import {
@@ -10026,95 +10027,6 @@ export class Compiler extends DiagnosticEmitter {
1002610027
// === Specialized code generation ==============================================================
1002710028

1002810029
/** Makes a constant zero of the specified type. */
10029-
/** Checks if an expression evaluates to a zero value for the given type. */
10030-
shouldSkipZeroInit(expr: ExpressionRef, type: Type): bool {
10031-
let module = this.module;
10032-
// Try to evaluate the expression at compile time
10033-
let evaled = module.runExpression(expr, ExpressionRunnerFlags.Default);
10034-
if (!evaled) return false; // Can't evaluate at compile time
10035-
10036-
const evaledType = getExpressionType(evaled);
10037-
switch (type.kind) {
10038-
case TypeKind.Bool:
10039-
case TypeKind.I8:
10040-
case TypeKind.I16:
10041-
case TypeKind.I32:
10042-
case TypeKind.U8:
10043-
case TypeKind.U16:
10044-
case TypeKind.U32:
10045-
// All small integer types are represented as i32 in WebAssembly
10046-
// But we still check for safety and consistency
10047-
if (evaledType == TypeRef.I32) {
10048-
return getConstValueI32(evaled) === 0;
10049-
}
10050-
return false;
10051-
case TypeKind.I64:
10052-
case TypeKind.U64:
10053-
case TypeKind.Isize:
10054-
case TypeKind.Usize:
10055-
// Only call getConstValueI64* if the expression is actually i64
10056-
if (evaledType == TypeRef.I64) {
10057-
return getConstValueI64Low(evaled) === 0 && getConstValueI64High(evaled) === 0;
10058-
}
10059-
// For size types on 32-bit platforms, they might be i32
10060-
if (evaledType == TypeRef.I32 && (type.kind == TypeKind.Isize || type.kind == TypeKind.Usize)) {
10061-
return getConstValueI32(evaled) === 0;
10062-
}
10063-
return false;
10064-
case TypeKind.F32:
10065-
if (evaledType == TypeRef.F32) {
10066-
return getConstValueF32(evaled) === 0.0;
10067-
}
10068-
return false;
10069-
case TypeKind.F64:
10070-
if (evaledType == TypeRef.F64) {
10071-
return getConstValueF64(evaled) === 0.0;
10072-
}
10073-
return false;
10074-
default:
10075-
// For reference types, zero means null
10076-
if (type.isReference && type.is(TypeFlags.Nullable)) {
10077-
return getExpressionId(evaled) === ExpressionId.RefNull;
10078-
}
10079-
return false;
10080-
}
10081-
}
10082-
10083-
/** Checks if a field type can use the default zero-initialized memory value. */
10084-
canUseZeroDefault(type: Type): bool {
10085-
switch (type.kind) {
10086-
default: assert(false);
10087-
case TypeKind.Bool:
10088-
case TypeKind.I8:
10089-
case TypeKind.I16:
10090-
case TypeKind.I32:
10091-
case TypeKind.U8:
10092-
case TypeKind.U16:
10093-
case TypeKind.U32:
10094-
case TypeKind.I64:
10095-
case TypeKind.U64:
10096-
case TypeKind.Isize:
10097-
case TypeKind.Usize:
10098-
case TypeKind.F32:
10099-
case TypeKind.F64:
10100-
case TypeKind.V128:
10101-
return true; // Value types default to zero in zero-initialized memory
10102-
case TypeKind.Func:
10103-
case TypeKind.Extern:
10104-
case TypeKind.Any:
10105-
case TypeKind.Eq:
10106-
case TypeKind.Struct:
10107-
case TypeKind.Array:
10108-
case TypeKind.String:
10109-
case TypeKind.StringviewWTF8:
10110-
case TypeKind.StringviewWTF16:
10111-
case TypeKind.StringviewIter:
10112-
case TypeKind.I31:
10113-
// Reference types: only nullable refs can use zero (null) default
10114-
return type.is(TypeFlags.Nullable);
10115-
}
10116-
}
10117-
1011810030
makeZero(type: Type): ExpressionRef {
1011910031
let module = this.module;
1012010032
switch (type.kind) {
@@ -10502,7 +10414,10 @@ export class Compiler extends DiagnosticEmitter {
1050210414
// Explicit initializer
1050310415
// Check if we need to initialize this field
1050410416
const valueExpr: ExpressionRef = this.compileExpression(initializerNode, fieldType, Constraints.ConvImplicit);
10505-
if (!this.shouldSkipZeroInit(valueExpr, fieldType)) {
10417+
// Memory will be filled with 0 on itcms.__new
10418+
// Memory grow will default to initialized with 0 as wasm spec
10419+
// So, optimize the active initialization away if it's zero
10420+
if ((this.options.runtime == Runtime.Incremental || this.options.runtime == Runtime.Stub) && isConstNonZero(valueExpr)) {
1050610421
let expr = this.makeCallDirect(setterInstance, [
1050710422
module.local_get(thisLocalIndex, sizeTypeRef),
1050810423
valueExpr
@@ -10512,9 +10427,6 @@ export class Compiler extends DiagnosticEmitter {
1051210427
}
1051310428
stmts.push(expr);
1051410429
}
10515-
} else {
10516-
// No explicit initializer
10517-
assert(this.canUseZeroDefault(fieldType));
1051810430
}
1051910431
}
1052010432
}

0 commit comments

Comments
 (0)