From 33a28868fe6e23da2115fb1a0e75655b2645cb4f Mon Sep 17 00:00:00 2001 From: MaxGraey Date: Sat, 30 Jul 2022 22:40:03 +0300 Subject: [PATCH 1/6] refactor types --- src/types.ts | 117 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 70 insertions(+), 47 deletions(-) diff --git a/src/types.ts b/src/types.ts index dc3aa2976a..50f88f8655 100644 --- a/src/types.ts +++ b/src/types.ts @@ -120,8 +120,6 @@ export class Type { flags: TypeFlags; /** Size in bits. */ size: i32; - /** Size in bytes. */ - byteSize: i32; /** Underlying class reference, if a class type. */ classReference: Class | null; /** Underlying signature reference, if a function type. */ @@ -136,7 +134,6 @@ export class Type { this.kind = kind; this.flags = flags; this.size = size; - this.byteSize = ceil(size / 8); this.classReference = null; this.signatureReference = null; if (!(flags & TypeFlags.NULLABLE)) { @@ -169,8 +166,13 @@ export class Type { /** Substitutes this type with the auto type if this type is void. */ get exceptVoid(): Type { - if (this.kind == TypeKind.VOID) return Type.auto; - return this; + return this.kind == TypeKind.VOID ? Type.auto : this; + } + + /** Size in bytes. */ + get byteSize(): i32 { + // ceiled div by 8 + return this.size + 7 >>> 3; } /** Gets this type's logarithmic alignment in memory. */ @@ -258,13 +260,6 @@ export class Type { return this.is(TypeFlags.EXTERNAL | TypeFlags.REFERENCE); } - /** Tests if this type represents a class. */ - get isClass(): bool { - return this.isInternalReference - ? this.classReference != null - : false; - } - /** Gets the underlying class of this type, if any. */ getClass(): Class | null { return this.isInternalReference @@ -272,6 +267,11 @@ export class Type { : null; } + /** Tests if this type represents a class. */ + get isClass(): bool { + return this.getClass() != null; + } + /** Gets the underlying class or wrapper class of this type, if any. */ getClassOrWrapper(program: Program): Class | null { let classReference = this.getClass(); @@ -297,13 +297,6 @@ export class Type { return null; } - /** Tests if this type represents a function. */ - get isFunction(): bool { - return this.isInternalReference - ? this.signatureReference != null - : false; - } - /** Gets the underlying function signature of this type, if any. */ getSignature(): Signature | null { return this.isInternalReference @@ -311,6 +304,11 @@ export class Type { : null; } + /** Tests if this type represents a function. */ + get isFunction(): bool { + return this.getSignature() != null; + } + /** Tests if this is a managed type that needs GC hooks. */ get isManaged(): bool { if (this.isInternalReference) { @@ -347,7 +345,8 @@ export class Type { /** Computes the truncating mask in the target type. */ computeSmallIntegerMask(targetType: Type): i32 { - var size = this.is(TypeFlags.UNSIGNED) ? this.size : this.size - 1; + var size = this.size; + size = this.is(TypeFlags.UNSIGNED) ? size : size - 1; return ~0 >>> (targetType.size - size); } @@ -400,8 +399,13 @@ export class Type { if (targetFunction = target.getSignature()) { return currentFunction.isAssignableTo(targetFunction); } - } else if (this.isExternalReference && (this.kind == target.kind || (target.kind == TypeKind.ANYREF && this.kind != TypeKind.EXTERNREF))) { - return true; + } else if (this.isExternalReference) { + if ( + this.kind == target.kind || + (target.kind == TypeKind.ANYREF && this.kind != TypeKind.EXTERNREF) + ) { + return true; + } } } } @@ -452,7 +456,10 @@ export class Type { // special in that it allows integer references as well if (this.is(TypeFlags.INTEGER) && target.is(TypeFlags.INTEGER)) { let size = this.size; - return size == target.size && (size >= 32 || this.is(TypeFlags.SIGNED) == target.is(TypeFlags.SIGNED)); + return size == target.size && ( + size >= 32 || + this.is(TypeFlags.SIGNED) == target.is(TypeFlags.SIGNED) + ); } return this.kind == target.kind; } @@ -719,7 +726,9 @@ export class Type { export function typesToRefs(types: Type[]): TypeRef[] { var numTypes = types.length; var ret = new Array(numTypes); - for (let i = 0; i < numTypes; ++i) ret[i] = types[i].toRef(); + for (let i = 0; i < numTypes; ++i) { + unchecked(ret[i] = types[i].toRef()); + } return ret; } @@ -728,7 +737,9 @@ export function typesToString(types: Type[]): string { var numTypes = types.length; if (!numTypes) return ""; var sb = new Array(numTypes); - for (let i = 0; i < numTypes; ++i) sb[i] = types[i].toString(true); + for (let i = 0; i < numTypes; ++i) { + unchecked(sb[i] = types[i].toString(true)); + } return sb.join(","); } @@ -794,7 +805,7 @@ export class Signature { let typeRefs = new Array(1 + numParameterTypes); typeRefs[0] = thisType.toRef(); for (let i = 0; i < numParameterTypes; ++i) { - typeRefs[i + 1] = parameterTypes[i].toRef(); + unchecked(typeRefs[i + 1] = parameterTypes[i].toRef()); } return createType(typeRefs); } @@ -820,17 +831,21 @@ export class Signature { // check rest parameter if (this.hasRest != other.hasRest) return false; + // check return type + if (!this.returnType.equals(other.returnType)) return false; + // check parameter types var thisParameterTypes = this.parameterTypes; var otherParameterTypes = other.parameterTypes; var numParameters = thisParameterTypes.length; if (numParameters != otherParameterTypes.length) return false; + for (let i = 0; i < numParameters; ++i) { - if (!thisParameterTypes[i].equals(otherParameterTypes[i])) return false; + let thisParameterType = unchecked(thisParameterTypes[i]); + let otherParameterType = unchecked(otherParameterTypes[i]); + if (!thisParameterType.equals(otherParameterType)) return false; } - - // check return type - return this.returnType.equals(other.returnType); + return true; } /** Tests if a value of this function type is assignable to a target of the specified function type. */ @@ -840,7 +855,9 @@ export class Signature { var thisThisType = this.thisType; var targetThisType = target.thisType; if (thisThisType) { - if (!targetThisType || !thisThisType.isAssignableTo(targetThisType)) return false; + if (!targetThisType || !thisThisType.isAssignableTo(targetThisType)) { + return false; + } } else if (targetThisType) { return false; } @@ -848,32 +865,35 @@ export class Signature { // check rest parameter if (this.hasRest != target.hasRest) return false; // TODO + // check return type + var thisReturnType = this.returnType; + var targetReturnType = target.returnType; + if (!(thisReturnType == targetReturnType || thisReturnType.isAssignableTo(targetReturnType))) { + return false; + } // check parameter types var thisParameterTypes = this.parameterTypes; var targetParameterTypes = target.parameterTypes; var numParameters = thisParameterTypes.length; if (numParameters != targetParameterTypes.length) return false; // TODO + for (let i = 0; i < numParameters; ++i) { - let thisParameterType = thisParameterTypes[i]; - let targetParameterType = targetParameterTypes[i]; + let thisParameterType = unchecked(thisParameterTypes[i]); + let targetParameterType = unchecked(targetParameterTypes[i]); if (!thisParameterType.isAssignableTo(targetParameterType)) return false; } - - // check return type - var thisReturnType = this.returnType; - var targetReturnType = target.returnType; - return thisReturnType == targetReturnType || thisReturnType.isAssignableTo(targetReturnType); + return true; } /** Tests if this signature has at least one managed operand. */ get hasManagedOperands(): bool { var thisType = this.thisType; - if (thisType) { - if (thisType.isManaged) return true; + if (thisType && thisType.isManaged) { + return true; } var parameterTypes = this.parameterTypes; for (let i = 0, k = parameterTypes.length; i < k; ++i) { - if (parameterTypes[i].isManaged) return true; + if (unchecked(parameterTypes[i]).isManaged) return true; } return false; } @@ -884,14 +904,12 @@ export class Signature { var index = 0; var thisType = this.thisType; if (thisType) { - if (thisType.isManaged) { - indices.push(index); - } + if (thisType.isManaged) indices.push(index); ++index; } var parameterTypes = this.parameterTypes; for (let i = 0, k = parameterTypes.length; i < k; ++i) { - if (parameterTypes[i].isManaged) { + if (unchecked(parameterTypes[i]).isManaged) { indices.push(index); } ++index; @@ -934,8 +952,13 @@ export class Signature { var numParameterTypes = parameterTypes.length; var cloneParameterTypes = new Array(numParameterTypes); for (let i = 0; i < numParameterTypes; ++i) { - cloneParameterTypes[i] = parameterTypes[i]; + unchecked(cloneParameterTypes[i] = parameterTypes[i]); } - return new Signature(this.program, cloneParameterTypes, this.returnType, this.thisType); + return new Signature( + this.program, + cloneParameterTypes, + this.returnType, + this.thisType + ); } } From 64f730ea88661cca904691abe78cec281debbe0a Mon Sep 17 00:00:00 2001 From: MaxGraey Date: Sat, 30 Jul 2022 23:13:18 +0300 Subject: [PATCH 2/6] more --- src/types.ts | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/types.ts b/src/types.ts index 50f88f8655..d5d678600e 100644 --- a/src/types.ts +++ b/src/types.ts @@ -121,9 +121,9 @@ export class Type { /** Size in bits. */ size: i32; /** Underlying class reference, if a class type. */ - classReference: Class | null; + classReference: Class | null = null; /** Underlying signature reference, if a function type. */ - signatureReference: Signature | null; + signatureReference: Signature | null = null; /** Respective non-nullable type, if nullable. */ private _nonNullableType: Type | null = null; /** Respective nullable type, if non-nullable. */ @@ -134,8 +134,6 @@ export class Type { this.kind = kind; this.flags = flags; this.size = size; - this.classReference = null; - this.signatureReference = null; if (!(flags & TypeFlags.NULLABLE)) { this._nonNullableType = this; } else { @@ -776,9 +774,13 @@ export class Signature { this.program = program; this.hasRest = false; var usizeType = program.options.usizeType; - var type = new Type(usizeType.kind, usizeType.flags & ~TypeFlags.VALUE | TypeFlags.REFERENCE, usizeType.size); - this.type = type; + var type = new Type( + usizeType.kind, + usizeType.flags & ~TypeFlags.VALUE | TypeFlags.REFERENCE, + usizeType.size + ); type.signatureReference = this; + this.type = type; var signatureTypes = program.uniqueSignatures; var length = signatureTypes.length; @@ -798,12 +800,11 @@ export class Signature { var parameterTypes = this.parameterTypes; var numParameterTypes = parameterTypes.length; if (!numParameterTypes) { - if (!thisType) return TypeRef.None; - return thisType.toRef(); + return thisType ? thisType.toRef() : TypeRef.None; } if (thisType) { let typeRefs = new Array(1 + numParameterTypes); - typeRefs[0] = thisType.toRef(); + unchecked(typeRefs[0] = thisType.toRef()); for (let i = 0; i < numParameterTypes; ++i) { unchecked(typeRefs[i + 1] = parameterTypes[i].toRef()); } @@ -849,7 +850,7 @@ export class Signature { } /** Tests if a value of this function type is assignable to a target of the specified function type. */ - isAssignableTo(target: Signature, requireSameSize: bool = false): bool { + isAssignableTo(target: Signature): bool { // check `this` type var thisThisType = this.thisType; From eb4f6f2ef994299600f45e61c06530b29a9911fe Mon Sep 17 00:00:00 2001 From: MaxGraey Date: Sat, 30 Jul 2022 23:18:35 +0300 Subject: [PATCH 3/6] fix --- src/program.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/program.ts b/src/program.ts index 824252a1c7..e8d3917ac2 100644 --- a/src/program.ts +++ b/src/program.ts @@ -2979,7 +2979,7 @@ export abstract class DeclaredElement extends Element { if (kind == base.kind) { switch (kind) { case ElementKind.FUNCTION: { - return (self).signature.isAssignableTo((base).signature, /* sameSize */ true); + return (self).signature.isAssignableTo((base).signature); } case ElementKind.PROPERTY: { let selfProperty = self; @@ -2987,7 +2987,7 @@ export abstract class DeclaredElement extends Element { let selfGetter = selfProperty.getterInstance; let baseGetter = baseProperty.getterInstance; if (selfGetter) { - if (!baseGetter || !selfGetter.signature.isAssignableTo(baseGetter.signature, true)) { + if (!baseGetter || !selfGetter.signature.isAssignableTo(baseGetter.signature)) { return false; } } else if (baseGetter) { @@ -2996,7 +2996,7 @@ export abstract class DeclaredElement extends Element { let selfSetter = selfProperty.setterInstance; let baseSetter = baseProperty.setterInstance; if (selfSetter) { - if (!baseSetter || !selfSetter.signature.isAssignableTo(baseSetter.signature, true)) { + if (!baseSetter || !selfSetter.signature.isAssignableTo(baseSetter.signature)) { return false; } } else if (baseSetter) { From ce45251590b41081cd141156e99301ef20298c5c Mon Sep 17 00:00:00 2001 From: MaxGraey Date: Sat, 30 Jul 2022 23:22:40 +0300 Subject: [PATCH 4/6] fix --- src/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types.ts b/src/types.ts index d5d678600e..81c2fdf61f 100644 --- a/src/types.ts +++ b/src/types.ts @@ -779,8 +779,8 @@ export class Signature { usizeType.flags & ~TypeFlags.VALUE | TypeFlags.REFERENCE, usizeType.size ); - type.signatureReference = this; this.type = type; + type.signatureReference = this; var signatureTypes = program.uniqueSignatures; var length = signatureTypes.length; From 940cc30f7cd854bf57b8758f410451f197d62e09 Mon Sep 17 00:00:00 2001 From: MaxGraey Date: Sun, 31 Jul 2022 06:49:10 +0300 Subject: [PATCH 5/6] more --- src/types.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/types.ts b/src/types.ts index 81c2fdf61f..65dfb22836 100644 --- a/src/types.ts +++ b/src/types.ts @@ -785,14 +785,14 @@ export class Signature { var signatureTypes = program.uniqueSignatures; var length = signatureTypes.length; for (let i = 0; i < length; i++) { - let compare = signatureTypes[i]; + let compare = unchecked(signatureTypes[i]); if (this.equals(compare)) { this.id = compare.id; return this; } } this.id = program.nextSignatureId++; - program.uniqueSignatures.push(this); + signatureTypes.push(this); } get paramRefs(): TypeRef { From b39224957b316a482ace28564a1ca549af563f3a Mon Sep 17 00:00:00 2001 From: Max Graey Date: Sat, 6 Aug 2022 13:00:28 +0300 Subject: [PATCH 6/6] Update src/types.ts Co-authored-by: dcode --- src/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types.ts b/src/types.ts index 65dfb22836..e8a77844fc 100644 --- a/src/types.ts +++ b/src/types.ts @@ -344,7 +344,7 @@ export class Type { /** Computes the truncating mask in the target type. */ computeSmallIntegerMask(targetType: Type): i32 { var size = this.size; - size = this.is(TypeFlags.UNSIGNED) ? size : size - 1; + if (!this.is(TypeFlags.UNSIGNED)) size -= 1; return ~0 >>> (targetType.size - size); }