From 2b0cc74cf25d11219ff97705946fdf3cfdbe77a6 Mon Sep 17 00:00:00 2001 From: dcode Date: Wed, 14 Dec 2022 23:19:29 +0100 Subject: [PATCH 01/16] Add LUB computation for class types --- src/program.ts | 21 +++++++++++++++++++++ src/types.ts | 10 ++++++++++ 2 files changed, 31 insertions(+) diff --git a/src/program.ts b/src/program.ts index 7ca4cab9f4..ba14333779 100644 --- a/src/program.ts +++ b/src/program.ts @@ -4415,6 +4415,27 @@ export class Class extends TypedElement { registerConcreteElement(program, this); } + /** Computes the least upper bound of two class types. */ + static leastUpperBound(a: Class, b: Class): Class | null { + if (a == b) return a; + let candidates = new Set(); + candidates.add(a); + candidates.add(b); + while (true) { + let aBase = a.base; + let bBase = b.base; + if (!aBase && !bBase) return null; // none + if (aBase) { + if (candidates.has(aBase)) return aBase; + candidates.add(a = aBase); + } + if (bBase) { + if (candidates.has(bBase)) return bBase; + candidates.add(b = bBase); + } + } + } + /** Sets the base class. */ setBase(base: Class): void { assert(!this.base); diff --git a/src/types.ts b/src/types.ts index 5e22db7ce3..8adcc7b8e2 100644 --- a/src/types.ts +++ b/src/types.ts @@ -548,6 +548,16 @@ export class Type { /** Determines the common denominator type of two types, if there is any. */ static commonDenominator(left: Type, right: Type, signednessIsImportant: bool): Type | null { + if (left.isInternalReference && right.isInternalReference) { + let leftClass = left.getClass(); + let rightClass = right.getClass(); + if (leftClass && rightClass) { + let lubClass = Class.leastUpperBound(leftClass, rightClass); + if (lubClass) { + return left.is(TypeFlags.Nullable) || right.is(TypeFlags.Nullable) ? lubClass.type.nullableType : lubClass.type; + } + } + } if (right.isAssignableTo(left, signednessIsImportant)) return left; else if (left.isAssignableTo(right, signednessIsImportant)) return right; return null; From 155a0ed5eaaae98534514ea1a436f9e41f49c109 Mon Sep 17 00:00:00 2001 From: dcode Date: Sun, 18 Dec 2022 11:15:04 +0100 Subject: [PATCH 02/16] more --- src/module.ts | 40 ++++++++++++++++++++++++++++++++++++++++ src/types.ts | 14 ++++++-------- 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/src/module.ts b/src/module.ts index 20c05e8130..cad042b46b 100644 --- a/src/module.ts +++ b/src/module.ts @@ -128,6 +128,46 @@ export namespace HeapTypeRef { export function isSubtype(ht: HeapTypeRef, superHt: HeapTypeRef): bool { return binaryen._BinaryenHeapTypeIsSubType(ht, superHt); } + + export function leastUpperBound(a: HeapTypeRef, b: HeapTypeRef): HeapTypeRef { + // see binaryen/src/wasm/wasm-type.cpp + if (a == b) return a; + if (getBottom(a) != getBottom(b)) return -1; + if (isBottom(a)) return b; + if (isBottom(b)) return a; + if (a > b) { + let t = a; + a = b; + b = t; + } + switch (a) { + case HeapTypeRef.Extern: + case HeapTypeRef.Func: return -1; + case HeapTypeRef.Any: return a; + case HeapTypeRef.Eq: { + return b == HeapTypeRef.I31 || b == HeapTypeRef.Data || b == HeapTypeRef.Array + ? HeapTypeRef.Eq + : HeapTypeRef.Any; + } + case HeapTypeRef.I31: { + return b == HeapTypeRef.Data || b == HeapTypeRef.Array + ? HeapTypeRef.Eq + : HeapTypeRef.Any; + } + case HeapTypeRef.Data: { + return b == HeapTypeRef.Array + ? HeapTypeRef.Data + : HeapTypeRef.Any; + } + case HeapTypeRef.Array: + case HeapTypeRef.String: + case HeapTypeRef.StringviewWTF8: + case HeapTypeRef.StringviewWTF16: + case HeapTypeRef.StringviewIter: return HeapTypeRef.Any; + } + assert(false); + return -1; + } } /** Packed array element respectively struct field types. */ diff --git a/src/types.ts b/src/types.ts index 8adcc7b8e2..be94db3b7b 100644 --- a/src/types.ts +++ b/src/types.ts @@ -548,14 +548,12 @@ export class Type { /** Determines the common denominator type of two types, if there is any. */ static commonDenominator(left: Type, right: Type, signednessIsImportant: bool): Type | null { - if (left.isInternalReference && right.isInternalReference) { - let leftClass = left.getClass(); - let rightClass = right.getClass(); - if (leftClass && rightClass) { - let lubClass = Class.leastUpperBound(leftClass, rightClass); - if (lubClass) { - return left.is(TypeFlags.Nullable) || right.is(TypeFlags.Nullable) ? lubClass.type.nullableType : lubClass.type; - } + let leftClass = left.getClass(); + let rightClass = right.getClass(); + if (leftClass && rightClass) { + let lubClass = Class.leastUpperBound(leftClass, rightClass); + if (lubClass) { + return left.is(TypeFlags.Nullable) || right.is(TypeFlags.Nullable) ? lubClass.type.nullableType : lubClass.type; } } if (right.isAssignableTo(left, signednessIsImportant)) return left; From 47d599a296fc380dbd07ef34c12da0ffa78d630b Mon Sep 17 00:00:00 2001 From: dcode Date: Tue, 20 Dec 2022 19:27:48 +0100 Subject: [PATCH 03/16] more --- src/compiler.ts | 83 +++-- src/resolver.ts | 51 +++- src/types.ts | 48 ++- tests/compiler/logical.debug.wat | 291 ++++++++++++++---- tests/compiler/logical.json | 3 +- tests/compiler/logical.release.wat | 473 ++++++++++++++++++----------- tests/compiler/logical.ts | 22 +- 7 files changed, 683 insertions(+), 288 deletions(-) diff --git a/src/compiler.ts b/src/compiler.ts index 2d55c91e12..3f3f00df27 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -3767,7 +3767,7 @@ export class Compiler extends DiagnosticEmitter { rightExpr = this.compileExpression(right, leftType); rightType = this.currentType; - commonType = Type.commonDenominator(leftType, rightType, true); + commonType = Type.commonType(leftType, rightType, contextualType, true); if (!commonType || !commonType.isNumericValue) { this.error( DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2, @@ -3802,7 +3802,7 @@ export class Compiler extends DiagnosticEmitter { rightExpr = this.compileExpression(right, leftType); rightType = this.currentType; - commonType = Type.commonDenominator(leftType, rightType, true); + commonType = Type.commonType(leftType, rightType, contextualType, true); if (!commonType || !commonType.isNumericValue) { this.error( DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2, @@ -3837,7 +3837,7 @@ export class Compiler extends DiagnosticEmitter { rightExpr = this.compileExpression(right, leftType); rightType = this.currentType; - commonType = Type.commonDenominator(leftType, rightType, true); + commonType = Type.commonType(leftType, rightType, contextualType, true); if (!commonType || !commonType.isNumericValue) { this.error( DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2, @@ -3872,7 +3872,7 @@ export class Compiler extends DiagnosticEmitter { rightExpr = this.compileExpression(right, leftType); rightType = this.currentType; - commonType = Type.commonDenominator(leftType, rightType, true); + commonType = Type.commonType(leftType, rightType, contextualType, true); if (!commonType || !commonType.isNumericValue) { this.error( DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2, @@ -3909,7 +3909,7 @@ export class Compiler extends DiagnosticEmitter { rightExpr = this.compileExpression(right, leftType); rightType = this.currentType; - commonType = Type.commonDenominator(leftType, rightType, false); + commonType = Type.commonType(leftType, rightType, contextualType); if (!commonType) { this.error( DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2, @@ -3961,7 +3961,7 @@ export class Compiler extends DiagnosticEmitter { rightExpr = this.compileExpression(right, leftType); rightType = this.currentType; - commonType = Type.commonDenominator(leftType, rightType, false); + commonType = Type.commonType(leftType, rightType, contextualType); if (!commonType) { this.error( DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2, @@ -4026,7 +4026,7 @@ export class Compiler extends DiagnosticEmitter { } else { rightExpr = this.compileExpression(right, leftType); rightType = this.currentType; - commonType = Type.commonDenominator(leftType, rightType, false); + commonType = Type.commonType(leftType, rightType, contextualType); if (!commonType || !commonType.isNumericValue) { this.error( DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2, @@ -4071,7 +4071,7 @@ export class Compiler extends DiagnosticEmitter { } else { rightExpr = this.compileExpression(right, leftType); rightType = this.currentType; - commonType = Type.commonDenominator(leftType, rightType, false); + commonType = Type.commonType(leftType, rightType, contextualType); if (!commonType || !leftType.isNumericValue) { this.error( DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2, @@ -4116,7 +4116,7 @@ export class Compiler extends DiagnosticEmitter { } else { rightExpr = this.compileExpression(right, leftType); rightType = this.currentType; - commonType = Type.commonDenominator(leftType, rightType, false); + commonType = Type.commonType(leftType, rightType, contextualType); if (!commonType || !commonType.isNumericValue) { this.error( DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2, @@ -4161,7 +4161,7 @@ export class Compiler extends DiagnosticEmitter { } else { rightExpr = this.compileExpression(right, leftType); rightType = this.currentType; - commonType = Type.commonDenominator(leftType, rightType, false); + commonType = Type.commonType(leftType, rightType, contextualType); if (!commonType || !commonType.isNumericValue) { this.error( DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2, @@ -4206,7 +4206,7 @@ export class Compiler extends DiagnosticEmitter { } else { rightExpr = this.compileExpression(right, leftType); rightType = this.currentType; - commonType = Type.commonDenominator(leftType, rightType, false); + commonType = Type.commonType(leftType, rightType, contextualType); if (!commonType || !commonType.isNumericValue) { this.error( DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2, @@ -4251,7 +4251,7 @@ export class Compiler extends DiagnosticEmitter { } else { rightExpr = this.compileExpression(right, leftType); rightType = this.currentType; - commonType = Type.commonDenominator(leftType, rightType, false); + commonType = Type.commonType(leftType, rightType, contextualType); if (!commonType || !commonType.isNumericValue) { this.error( DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2, @@ -4378,7 +4378,7 @@ export class Compiler extends DiagnosticEmitter { } else { rightExpr = this.compileExpression(right, leftType); rightType = this.currentType; - commonType = Type.commonDenominator(leftType, rightType, false); + commonType = Type.commonType(leftType, rightType, contextualType); if (!commonType || !commonType.isIntegerValue) { this.error( DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2, @@ -4423,7 +4423,7 @@ export class Compiler extends DiagnosticEmitter { } else { rightExpr = this.compileExpression(right, leftType); rightType = this.currentType; - commonType = Type.commonDenominator(leftType, rightType, false); + commonType = Type.commonType(leftType, rightType, contextualType); if (!commonType || !commonType.isIntegerValue) { this.error( DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2, @@ -4468,7 +4468,7 @@ export class Compiler extends DiagnosticEmitter { } else { rightExpr = this.compileExpression(right, leftType); rightType = this.currentType; - commonType = Type.commonDenominator(leftType, rightType, false); + commonType = Type.commonType(leftType, rightType, contextualType); if (!commonType || !commonType.isIntegerValue) { this.error( DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2, @@ -4525,8 +4525,21 @@ export class Compiler extends DiagnosticEmitter { this.currentType = Type.bool; } else { - rightExpr = this.compileExpression(right, leftType, inheritedConstraints | Constraints.ConvImplicit); + rightExpr = this.compileExpression(right, leftType, inheritedConstraints); rightType = this.currentType; + commonType = Type.commonType(leftType, rightType, contextualType); + if (!commonType) { + this.error( + DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2, + expression.range, "&&", leftType.toString(), rightType.toString() + ); + this.currentType = contextualType; + return module.unreachable(); + } + leftExpr = this.convertExpression(leftExpr, leftType, commonType, false, left); + leftType = commonType; + rightExpr = this.convertExpression(rightExpr, rightType, commonType, false, right); + rightType = commonType; // simplify if copying left is trivial if (expr = module.tryCopyTrivialExpression(leftExpr)) { @@ -4550,7 +4563,7 @@ export class Compiler extends DiagnosticEmitter { flow.mergeBranch(rightFlow); // LHS && RHS -> RHS conditionally executes flow.noteThen(expr, rightFlow); // LHS && RHS == true -> RHS always executes this.currentFlow = flow; - this.currentType = leftType; + this.currentType = commonType; } break; } @@ -4591,8 +4604,22 @@ export class Compiler extends DiagnosticEmitter { this.currentType = Type.bool; } else { - rightExpr = this.compileExpression(right, leftType, inheritedConstraints | Constraints.ConvImplicit); + rightExpr = this.compileExpression(right, leftType, inheritedConstraints); rightType = this.currentType; + commonType = Type.commonType(leftType, rightType, contextualType); + if (!commonType) { + this.error( + DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2, + expression.range, "||", leftType.toString(), rightType.toString() + ); + this.currentType = contextualType; + return module.unreachable(); + } + let possiblyNull = leftType.is(TypeFlags.Nullable) && rightType.is(TypeFlags.Nullable); + leftExpr = this.convertExpression(leftExpr, leftType, commonType, false, left); + leftType = commonType; + rightExpr = this.convertExpression(rightExpr, rightType, commonType, false, right); + rightType = commonType; // simplify if copying left is trivial if (expr = module.tryCopyTrivialExpression(leftExpr)) { @@ -4617,7 +4644,9 @@ export class Compiler extends DiagnosticEmitter { flow.mergeBranch(rightFlow); // LHS || RHS -> RHS conditionally executes flow.noteElse(expr, rightFlow); // LHS || RHS == false -> RHS always executes this.currentFlow = flow; - this.currentType = leftType; + this.currentType = possiblyNull + ? commonType + : commonType.nonNullableType; } break; } @@ -8933,7 +8962,7 @@ export class Compiler extends DiagnosticEmitter { private compileTernaryExpression( expression: TernaryExpression, - ctxType: Type, + contextualType: Type, constraints: Constraints ): ExpressionRef { let module = this.module; @@ -8946,24 +8975,24 @@ export class Compiler extends DiagnosticEmitter { // FIXME: skips common denominator, inconsistently picking branch type let condKind = this.evaluateCondition(condExprTrueish); if (condKind == ConditionKind.True) { - return module.maybeDropCondition(condExprTrueish, this.compileExpression(ifThen, ctxType)); + return module.maybeDropCondition(condExprTrueish, this.compileExpression(ifThen, contextualType)); } if (condKind == ConditionKind.False) { - return module.maybeDropCondition(condExprTrueish, this.compileExpression(ifElse, ctxType)); + return module.maybeDropCondition(condExprTrueish, this.compileExpression(ifElse, contextualType)); } let outerFlow = this.currentFlow; let ifThenFlow = outerFlow.forkThen(condExpr); this.currentFlow = ifThenFlow; - let ifThenExpr = this.compileExpression(ifThen, ctxType); + let ifThenExpr = this.compileExpression(ifThen, contextualType); let ifThenType = this.currentType; let ifElseFlow = outerFlow.forkElse(condExpr); this.currentFlow = ifElseFlow; - let ifElseExpr = this.compileExpression(ifElse, ctxType == Type.auto ? ifThenType : ctxType); + let ifElseExpr = this.compileExpression(ifElse, contextualType == Type.auto ? ifThenType : contextualType); let ifElseType = this.currentType; - if (ctxType == Type.void) { // values, including type mismatch, are irrelevant + if (contextualType == Type.void) { // values, including type mismatch, are irrelevant if (ifThenType != Type.void) { ifThenExpr = module.drop(ifThenExpr); ifThenType = Type.void; @@ -8974,13 +9003,13 @@ export class Compiler extends DiagnosticEmitter { } this.currentType = Type.void; } else { - let commonType = Type.commonDenominator(ifThenType, ifElseType, false); + let commonType = Type.commonType(ifThenType, ifElseType, contextualType); if (!commonType) { this.error( DiagnosticCode.Type_0_is_not_assignable_to_type_1, ifElse.range, ifElseType.toString(), ifThenType.toString() ); - this.currentType = ctxType; + this.currentType = contextualType; return module.unreachable(); } ifThenExpr = this.convertExpression(ifThenExpr, ifThenType, commonType, false, ifThen); diff --git a/src/resolver.ts b/src/resolver.ts index 20005b954d..a3abb9d70e 100644 --- a/src/resolver.ts +++ b/src/resolver.ts @@ -83,7 +83,8 @@ import { Type, Signature, typesToString, - TypeKind + TypeKind, + TypeFlags } from "./types"; import { @@ -2070,12 +2071,12 @@ export class Resolver extends DiagnosticEmitter { } let rightType = this.resolveExpression(right, ctxFlow, leftType, reportMode); if (!rightType) return null; - let commonType = Type.commonDenominator(leftType, rightType, false); + let commonType = Type.commonType(leftType, rightType, ctxType); if (!commonType) { if (reportMode == ReportMode.Report) { this.error( DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2, - node.range, leftType.toString(), rightType.toString() + node.range, operatorTokenToString(operator), leftType.toString(), rightType.toString() ); } } @@ -2120,7 +2121,7 @@ export class Resolver extends DiagnosticEmitter { } let rightType = this.resolveExpression(right, ctxFlow, ctxType, reportMode); if (!rightType) return null; - let commonType = Type.commonDenominator(leftType, rightType, false); + let commonType = Type.commonType(leftType, rightType, ctxType); if (!commonType || !commonType.isIntegerValue) { if (reportMode == ReportMode.Report) { this.error( @@ -2132,11 +2133,43 @@ export class Resolver extends DiagnosticEmitter { return commonType; } - // logical: result is LHS (RHS is converted to LHS), not supporting overloads + // logical - case Token.Ampersand_Ampersand: + case Token.Ampersand_Ampersand: { + let leftType = this.resolveExpression(left, ctxFlow, ctxType, reportMode); + if (!leftType) return null; + let rightType = this.resolveExpression(right, ctxFlow, leftType, reportMode); + if (!rightType) return null; + let commonType = Type.commonType(leftType, rightType, ctxType); + if (!commonType) { + if (reportMode == ReportMode.Report) { + this.error( + DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2, + node.range, "&&", leftType.toString(), rightType.toString() + ); + } + } + return commonType; + } case Token.Bar_Bar: { - return this.resolveExpression(left, ctxFlow, ctxType, reportMode); + let leftType = this.resolveExpression(left, ctxFlow, ctxType, reportMode); + if (!leftType) return null; + let rightType = this.resolveExpression(right, ctxFlow, leftType, reportMode); + if (!rightType) return null; + let commonType = Type.commonType(leftType, rightType, ctxType); + if (!commonType) { + if (reportMode == ReportMode.Report) { + this.error( + DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2, + node.range, "||", leftType.toString(), rightType.toString() + ); + } + return null; + } + // `LHS || RHS` can only be null if both LHS and RHS are null + return leftType.is(TypeFlags.Nullable) && rightType.is(TypeFlags.Nullable) + ? commonType + : commonType.nonNullableType; } } assert(false); @@ -2317,7 +2350,7 @@ export class Resolver extends DiagnosticEmitter { if (!currentType) return null; if (elementType == Type.auto) elementType = currentType; else if (currentType != elementType) { - let commonType = Type.commonDenominator(elementType, currentType, false); + let commonType = Type.commonType(elementType, currentType, elementType); if (commonType) elementType = commonType; // otherwise triggers error on compilation } @@ -2574,7 +2607,7 @@ export class Resolver extends DiagnosticEmitter { if (!thenType) return null; let elseType = this.resolveExpression(node.ifElse, ctxFlow, thenType, reportMode); if (!elseType) return null; - let commonType = Type.commonDenominator(thenType, elseType, false); + let commonType = Type.commonType(thenType, elseType, ctxType); if (!commonType) { if (reportMode == ReportMode.Report) { this.error( diff --git a/src/types.ts b/src/types.ts index be94db3b7b..acdf170ce8 100644 --- a/src/types.ts +++ b/src/types.ts @@ -65,12 +65,12 @@ export const enum TypeKind { /** A 128-bit vector. */ V128, - // references + // references (keep in same order as in Binaryen) - /** Function reference. */ - Funcref, /** External reference. */ Externref, + /** Function reference. */ + Funcref, /** Any reference. */ Anyref, /** Equatable reference. */ @@ -546,18 +546,40 @@ export class Type { return true; } - /** Determines the common denominator type of two types, if there is any. */ - static commonDenominator(left: Type, right: Type, signednessIsImportant: bool): Type | null { - let leftClass = left.getClass(); - let rightClass = right.getClass(); - if (leftClass && rightClass) { - let lubClass = Class.leastUpperBound(leftClass, rightClass); - if (lubClass) { - return left.is(TypeFlags.Nullable) || right.is(TypeFlags.Nullable) ? lubClass.type.nullableType : lubClass.type; + /** Computes the common type of a binary-like expression, if any. */ + static commonType( + /** LHS type. */ + left: Type, + /** RHS type. */ + right: Type, + /** Contextual type, if any. */ + contextualType: Type = Type.auto, + /** Whether signedness is relevant. */ + signednessIsRelevant: bool = false + ): Type | null { + // Compute LUB of internal reference types (classes) + if (left.isInternalReference) { + if (!right.isInternalReference) return null; + // Prefer contextual type if meaningful + if (contextualType != Type.void && left.isAssignableTo(contextualType) && right.isAssignableTo(contextualType)) { + return contextualType; + } + let leftClass = left.getClass(); + let rightClass = right.getClass(); + if (leftClass && rightClass) { + let lubClass = Class.leastUpperBound(leftClass, rightClass); + if (lubClass) { + let ret = left.is(TypeFlags.Nullable) || right.is(TypeFlags.Nullable) ? lubClass.type.asNullable() : lubClass.type; + return ret; + } } + } else if (right.isInternalReference) { + return null; } - if (right.isAssignableTo(left, signednessIsImportant)) return left; - else if (left.isAssignableTo(right, signednessIsImportant)) return right; + // TODO: External reference types (needs nullability) + // Otherwise do a trivial check + if (right.isAssignableTo(left, signednessIsRelevant)) return left; + else if (left.isAssignableTo(right, signednessIsRelevant)) return right; return null; } diff --git a/tests/compiler/logical.debug.wat b/tests/compiler/logical.debug.wat index 67c7bf41e8..afa024a1ec 100644 --- a/tests/compiler/logical.debug.wat +++ b/tests/compiler/logical.debug.wat @@ -28,10 +28,12 @@ (global $~lib/rt/itcms/fromSpace (mut i32) (i32.const 0)) (global $~lib/rt/tlsf/ROOT (mut i32) (i32.const 0)) (global $~lib/native/ASC_LOW_MEMORY_LIMIT i32 (i32.const 0)) + (global $logical/b (mut i32) (i32.const 0)) + (global $logical/c (mut i32) (i32.const 0)) (global $~lib/rt/__rtti_base i32 (i32.const 464)) - (global $~lib/memory/__data_end i32 (i32.const 488)) - (global $~lib/memory/__stack_pointer (mut i32) (i32.const 33256)) - (global $~lib/memory/__heap_base i32 (i32.const 33256)) + (global $~lib/memory/__data_end i32 (i32.const 500)) + (global $~lib/memory/__stack_pointer (mut i32) (i32.const 33268)) + (global $~lib/memory/__heap_base i32 (i32.const 33268)) (memory $0 1) (data (i32.const 12) ",\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\14\00\00\00l\00o\00g\00i\00c\00a\00l\00.\00t\00s\00\00\00\00\00\00\00\00\00") (data (i32.const 60) "<\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00(\00\00\00A\00l\00l\00o\00c\00a\00t\00i\00o\00n\00 \00t\00o\00o\00 \00l\00a\00r\00g\00e\00\00\00\00\00") @@ -42,7 +44,7 @@ (data (i32.const 316) ",\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\14\00\00\00~\00l\00i\00b\00/\00r\00t\00.\00t\00s\00\00\00\00\00\00\00\00\00") (data (i32.const 368) "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00") (data (i32.const 396) "<\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\1e\00\00\00~\00l\00i\00b\00/\00r\00t\00/\00t\00l\00s\00f\00.\00t\00s\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00") - (data (i32.const 464) "\05\00\00\00 \00\00\00 \00\00\00 \00\00\00\00\00\00\00 \00\00\00") + (data (i32.const 464) "\08\00\00\00 \00\00\00 \00\00\00 \00\00\00\00\00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00") (table $0 1 1 funcref) (elem $0 (i32.const 1)) (export "memory" (memory $0)) @@ -2280,54 +2282,40 @@ end return ) - (func $~lib/rt/itcms/__collect (type $none_=>_none) - i32.const 0 - drop - global.get $~lib/rt/itcms/state - i32.const 0 - i32.gt_s - if - loop $while-continue|0 - global.get $~lib/rt/itcms/state - i32.const 0 - i32.ne - if - call $~lib/rt/itcms/step - drop - br $while-continue|0 - end - end + (func $logical/commonOr (type $i32_=>_i32) (param $b i32) (result i32) + local.get $b + if (result i32) + local.get $b + else + global.get $logical/c end - call $~lib/rt/itcms/step - drop - loop $while-continue|1 - global.get $~lib/rt/itcms/state - i32.const 0 - i32.ne - if - call $~lib/rt/itcms/step - drop - br $while-continue|1 - end + return + ) + (func $logical/commonAnd (type $i32_=>_i32) (param $b i32) (result i32) + local.get $b + if (result i32) + global.get $logical/c + else + local.get $b end - global.get $~lib/rt/itcms/total - i64.extend_i32_u - i32.const 200 - i64.extend_i32_u - i64.mul - i64.const 100 - i64.div_u - i32.wrap_i64 - i32.const 1024 - i32.add - global.set $~lib/rt/itcms/threshold - i32.const 0 - drop - i32.const 0 - drop + return ) (func $~lib/rt/__visit_globals (type $i32_=>_none) (param $0 i32) (local $1 i32) + global.get $logical/b + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $logical/c + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end i32.const 272 local.get $0 call $~lib/rt/itcms/__visit @@ -2354,26 +2342,35 @@ ) (func $~lib/rt/__visit_members (type $i32_i32_=>_none) (param $0 i32) (param $1 i32) block $invalid - block $logical/Obj - block $~lib/arraybuffer/ArrayBufferView - block $~lib/string/String - block $~lib/arraybuffer/ArrayBuffer - block $~lib/object/Object - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - br_table $~lib/object/Object $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $logical/Obj $invalid + block $logical/C + block $logical/A + block $logical/B + block $logical/Obj + block $~lib/arraybuffer/ArrayBufferView + block $~lib/string/String + block $~lib/arraybuffer/ArrayBuffer + block $~lib/object/Object + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + br_table $~lib/object/Object $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $logical/Obj $logical/B $logical/A $logical/C $invalid + end + return + end + return + end + return end + local.get $0 + local.get $1 + call $~lib/arraybuffer/ArrayBufferView~visit return end return end return end - local.get $0 - local.get $1 - call $~lib/arraybuffer/ArrayBufferView~visit return end return @@ -2388,8 +2385,8 @@ global.get $~lib/memory/__data_end i32.lt_s if - i32.const 33280 - i32.const 33328 + i32.const 33296 + i32.const 33344 i32.const 1 i32.const 1 call $~lib/builtins/abort @@ -2941,9 +2938,74 @@ call $~lib/builtins/abort unreachable end - global.get $~lib/memory/__heap_base - global.set $~lib/memory/__stack_pointer - call $~lib/rt/itcms/__collect + i32.const 0 + call $logical/B#constructor + global.set $logical/b + i32.const 0 + call $logical/C#constructor + global.set $logical/c + global.get $logical/b + local.set $4 + global.get $~lib/memory/__stack_pointer + local.get $4 + i32.store $0 + local.get $4 + call $logical/commonOr + global.get $logical/b + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 106 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 0 + call $logical/commonOr + global.get $logical/c + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 107 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $logical/b + local.set $4 + global.get $~lib/memory/__stack_pointer + local.get $4 + i32.store $0 + local.get $4 + call $logical/commonAnd + global.get $logical/c + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 112 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 0 + call $logical/commonAnd + i32.const 0 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 113 + i32.const 1 + call $~lib/builtins/abort + unreachable + end global.get $~lib/memory/__stack_pointer i32.const 4 i32.add @@ -3010,4 +3072,103 @@ global.set $~lib/memory/__stack_pointer local.get $1 ) + (func $logical/A#constructor (type $i32_=>_i32) (param $this i32) (result i32) + (local $1 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store $0 + local.get $this + i32.eqz + if + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.const 6 + call $~lib/rt/itcms/__new + local.tee $this + i32.store $0 + end + global.get $~lib/memory/__stack_pointer + local.get $this + call $~lib/object/Object#constructor + local.tee $this + i32.store $0 + local.get $this + local.set $1 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $1 + ) + (func $logical/B#constructor (type $i32_=>_i32) (param $this i32) (result i32) + (local $1 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store $0 + local.get $this + i32.eqz + if + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.const 5 + call $~lib/rt/itcms/__new + local.tee $this + i32.store $0 + end + global.get $~lib/memory/__stack_pointer + local.get $this + call $logical/A#constructor + local.tee $this + i32.store $0 + local.get $this + local.set $1 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $1 + ) + (func $logical/C#constructor (type $i32_=>_i32) (param $this i32) (result i32) + (local $1 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store $0 + local.get $this + i32.eqz + if + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.const 7 + call $~lib/rt/itcms/__new + local.tee $this + i32.store $0 + end + global.get $~lib/memory/__stack_pointer + local.get $this + call $logical/A#constructor + local.tee $this + i32.store $0 + local.get $this + local.set $1 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $1 + ) ) diff --git a/tests/compiler/logical.json b/tests/compiler/logical.json index b83788465e..1bdd02b1be 100644 --- a/tests/compiler/logical.json +++ b/tests/compiler/logical.json @@ -1,5 +1,4 @@ { "asc_flags": [ - ], - "asc_rtrace": true + ] } diff --git a/tests/compiler/logical.release.wat b/tests/compiler/logical.release.wat index f872da9d51..3d6ce1483c 100644 --- a/tests/compiler/logical.release.wat +++ b/tests/compiler/logical.release.wat @@ -1,9 +1,9 @@ (module + (type $i32_=>_i32 (func_subtype (param i32) (result i32) func)) (type $none_=>_none (func_subtype func)) (type $i32_=>_none (func_subtype (param i32) func)) (type $i32_i32_=>_none (func_subtype (param i32 i32) func)) (type $none_=>_i32 (func_subtype (result i32) func)) - (type $i32_=>_i32 (func_subtype (param i32) (result i32) func)) (type $i32_i32_i32_i32_=>_none (func_subtype (param i32 i32 i32 i32) func)) (type $i32_i32_i32_=>_none (func_subtype (param i32 i32 i32) func)) (import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32))) @@ -17,7 +17,9 @@ (global $~lib/rt/itcms/white (mut i32) (i32.const 0)) (global $~lib/rt/itcms/fromSpace (mut i32) (i32.const 0)) (global $~lib/rt/tlsf/ROOT (mut i32) (i32.const 0)) - (global $~lib/memory/__stack_pointer (mut i32) (i32.const 34280)) + (global $logical/b (mut i32) (i32.const 0)) + (global $logical/c (mut i32) (i32.const 0)) + (global $~lib/memory/__stack_pointer (mut i32) (i32.const 34292)) (memory $0 1) (data (i32.const 1036) ",") (data (i32.const 1048) "\02\00\00\00\14\00\00\00l\00o\00g\00i\00c\00a\00l\00.\00t\00s") @@ -31,12 +33,24 @@ (data (i32.const 1352) "\02\00\00\00\14\00\00\00~\00l\00i\00b\00/\00r\00t\00.\00t\00s") (data (i32.const 1420) "<") (data (i32.const 1432) "\02\00\00\00\1e\00\00\00~\00l\00i\00b\00/\00r\00t\00/\00t\00l\00s\00f\00.\00t\00s") - (data (i32.const 1488) "\05\00\00\00 \00\00\00 \00\00\00 \00\00\00\00\00\00\00 ") + (data (i32.const 1488) "\08\00\00\00 \00\00\00 \00\00\00 \00\00\00\00\00\00\00 \00\00\00 \00\00\00 \00\00\00 ") (export "memory" (memory $0)) (start $~start) (func $~lib/rt/itcms/visitRoots (type $none_=>_none) (local $0 i32) (local $1 i32) + global.get $logical/b + local.tee $0 + if + local.get $0 + call $byn-split-outlined-A$~lib/rt/itcms/__visit + end + global.get $logical/c + local.tee $0 + if + local.get $0 + call $byn-split-outlined-A$~lib/rt/itcms/__visit + end i32.const 1296 call $byn-split-outlined-A$~lib/rt/itcms/__visit i32.const 1104 @@ -114,7 +128,7 @@ i32.load $0 offset=8 i32.eqz local.get $0 - i32.const 34280 + i32.const 34292 i32.lt_u i32.and i32.eqz @@ -742,10 +756,10 @@ if unreachable end - i32.const 34288 + i32.const 34304 i32.const 0 i32.store $0 - i32.const 35856 + i32.const 35872 i32.const 0 i32.store $0 loop $for-loop|0 @@ -756,7 +770,7 @@ local.get $0 i32.const 2 i32.shl - i32.const 34288 + i32.const 34304 i32.add i32.const 0 i32.store $0 offset=4 @@ -774,7 +788,7 @@ i32.add i32.const 2 i32.shl - i32.const 34288 + i32.const 34304 i32.add i32.const 0 i32.store $0 offset=96 @@ -792,13 +806,13 @@ br $for-loop|0 end end - i32.const 34288 - i32.const 35860 + i32.const 34304 + i32.const 35876 memory.size $0 i32.const 16 i32.shl call $~lib/rt/tlsf/addMemory - i32.const 34288 + i32.const 34304 global.set $~lib/rt/tlsf/ROOT ) (func $~lib/rt/itcms/step (type $none_=>_i32) (result i32) @@ -883,7 +897,7 @@ local.set $0 loop $while-continue|0 local.get $0 - i32.const 34280 + i32.const 34292 i32.lt_u if local.get $0 @@ -983,7 +997,7 @@ unreachable end local.get $0 - i32.const 34280 + i32.const 34292 i32.lt_u if local.get $0 @@ -1006,7 +1020,7 @@ i32.const 4 i32.add local.tee $0 - i32.const 34280 + i32.const 34292 i32.ge_u if global.get $~lib/rt/tlsf/ROOT @@ -1360,16 +1374,32 @@ ) (func $~lib/rt/__visit_members (type $i32_=>_none) (param $0 i32) block $invalid - block $logical/Obj - block $~lib/arraybuffer/ArrayBufferView - block $~lib/string/String - block $~lib/arraybuffer/ArrayBuffer - block $~lib/object/Object + block $logical/C + block $logical/A + block $logical/B + block $logical/Obj + block $~lib/arraybuffer/ArrayBufferView + block $~lib/string/String + block $~lib/arraybuffer/ArrayBuffer + block $~lib/object/Object + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + br_table $~lib/object/Object $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $logical/Obj $logical/B $logical/A $logical/C $invalid + end + return + end + return + end + return + end + local.get $0 + i32.load $0 + local.tee $0 + if local.get $0 - i32.const 8 - i32.sub - i32.load $0 - br_table $~lib/object/Object $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $logical/Obj $invalid + call $byn-split-outlined-A$~lib/rt/itcms/__visit end return end @@ -1377,13 +1407,6 @@ end return end - local.get $0 - i32.load $0 - local.tee $0 - if - local.get $0 - call $byn-split-outlined-A$~lib/rt/itcms/__visit - end return end return @@ -1392,16 +1415,200 @@ ) (func $~start (type $none_=>_none) (local $0 i32) + (local $1 i32) + block $__inlined_func$start:logical + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + block $folding-inner0 + global.get $~lib/memory/__stack_pointer + i32.const 1524 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store $0 + memory.size $0 + i32.const 16 + i32.shl + i32.const 34292 + i32.sub + i32.const 1 + i32.shr_u + global.set $~lib/rt/itcms/threshold + i32.const 1220 + i32.const 1216 + i32.store $0 + i32.const 1224 + i32.const 1216 + i32.store $0 + i32.const 1216 + global.set $~lib/rt/itcms/pinSpace + i32.const 1252 + i32.const 1248 + i32.store $0 + i32.const 1256 + i32.const 1248 + i32.store $0 + i32.const 1248 + global.set $~lib/rt/itcms/toSpace + i32.const 1396 + i32.const 1392 + i32.store $0 + i32.const 1400 + i32.const 1392 + i32.store $0 + i32.const 1392 + global.set $~lib/rt/itcms/fromSpace + call $logical/Obj#constructor + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store $0 + local.get $0 + i32.eqz + if + i32.const 0 + i32.const 1056 + i32.const 87 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + call $logical/Obj#constructor + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store $0 + local.get $0 + i32.eqz + if + i32.const 0 + i32.const 1056 + i32.const 92 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 1524 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + local.tee $0 + i32.const 0 + i32.store $0 + local.get $0 + i32.const 5 + call $~lib/rt/itcms/__new + local.tee $0 + i32.store $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + call $logical/A#constructor + local.tee $0 + i32.store $0 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $0 + global.set $logical/b + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 1524 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + local.tee $0 + i32.const 0 + i32.store $0 + local.get $0 + i32.const 7 + call $~lib/rt/itcms/__new + local.tee $0 + i32.store $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + call $logical/A#constructor + local.tee $0 + i32.store $0 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $0 + global.set $logical/c + global.get $~lib/memory/__stack_pointer + global.get $logical/b + local.tee $0 + i32.store $0 + local.get $0 + local.get $0 + global.get $logical/c + local.get $0 + select + i32.ne + if + i32.const 0 + i32.const 1056 + i32.const 106 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $logical/b + local.tee $0 + i32.store $0 + global.get $logical/c + local.tee $1 + local.get $0 + local.get $0 + select + local.get $1 + i32.ne + if + i32.const 0 + i32.const 1056 + i32.const 112 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + br $__inlined_func$start:logical + end + i32.const 34320 + i32.const 34368 + i32.const 1 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + ) + (func $~lib/object/Object#constructor (type $i32_=>_i32) (param $0 i32) (result i32) global.get $~lib/memory/__stack_pointer i32.const 4 i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1512 + i32.const 1524 i32.lt_s if - i32.const 34304 - i32.const 34352 + i32.const 34320 + i32.const 34368 i32.const 1 i32.const 1 call $~lib/builtins/abort @@ -1410,170 +1617,96 @@ global.get $~lib/memory/__stack_pointer i32.const 0 i32.store $0 - memory.size $0 - i32.const 16 - i32.shl - i32.const 34280 - i32.sub - i32.const 1 - i32.shr_u - global.set $~lib/rt/itcms/threshold - i32.const 1220 - i32.const 1216 - i32.store $0 - i32.const 1224 - i32.const 1216 - i32.store $0 - i32.const 1216 - global.set $~lib/rt/itcms/pinSpace - i32.const 1252 - i32.const 1248 - i32.store $0 - i32.const 1256 - i32.const 1248 - i32.store $0 - i32.const 1248 - global.set $~lib/rt/itcms/toSpace - i32.const 1396 - i32.const 1392 - i32.store $0 - i32.const 1400 - i32.const 1392 - i32.store $0 - i32.const 1392 - global.set $~lib/rt/itcms/fromSpace - call $logical/Obj#constructor - local.set $0 - global.get $~lib/memory/__stack_pointer - local.get $0 - i32.store $0 local.get $0 i32.eqz if + global.get $~lib/memory/__stack_pointer i32.const 0 - i32.const 1056 - i32.const 87 - i32.const 1 - call $~lib/builtins/abort - unreachable + call $~lib/rt/itcms/__new + local.tee $0 + i32.store $0 end - call $logical/Obj#constructor - local.set $0 global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer local.get $0 - i32.store $0 - local.get $0 - i32.eqz + ) + (func $logical/Obj#constructor (type $none_=>_i32) (result i32) + (local $0 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 1524 + i32.lt_s if - i32.const 0 - i32.const 1056 - i32.const 92 + i32.const 34320 + i32.const 34368 + i32.const 1 i32.const 1 call $~lib/builtins/abort unreachable end - i32.const 34280 - global.set $~lib/memory/__stack_pointer - global.get $~lib/rt/itcms/state + global.get $~lib/memory/__stack_pointer + local.tee $0 i32.const 0 - i32.gt_s - if - loop $while-continue|0 - global.get $~lib/rt/itcms/state - if - call $~lib/rt/itcms/step - drop - br $while-continue|0 - end - end - end - call $~lib/rt/itcms/step - drop - loop $while-continue|1 - global.get $~lib/rt/itcms/state - if - call $~lib/rt/itcms/step - drop - br $while-continue|1 - end - end - global.get $~lib/rt/itcms/total - i64.extend_i32_u - i64.const 200 - i64.mul - i64.const 100 - i64.div_u - i32.wrap_i64 - i32.const 1024 - i32.add - global.set $~lib/rt/itcms/threshold + i32.store $0 + local.get $0 + i32.const 4 + call $~lib/rt/itcms/__new + local.tee $0 + i32.store $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + call $~lib/object/Object#constructor + local.tee $0 + i32.store $0 global.get $~lib/memory/__stack_pointer i32.const 4 i32.add global.set $~lib/memory/__stack_pointer + local.get $0 ) - (func $logical/Obj#constructor (type $none_=>_i32) (result i32) - (local $0 i32) - (local $1 i32) + (func $logical/A#constructor (type $i32_=>_i32) (param $0 i32) (result i32) global.get $~lib/memory/__stack_pointer i32.const 4 i32.sub global.set $~lib/memory/__stack_pointer - block $folding-inner0 - global.get $~lib/memory/__stack_pointer - i32.const 1512 - i32.lt_s - br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + i32.const 1524 + i32.lt_s + if + i32.const 34320 + i32.const 34368 + i32.const 1 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store $0 + local.get $0 + i32.eqz + if global.get $~lib/memory/__stack_pointer - local.tee $0 - i32.const 0 - i32.store $0 - local.get $0 - i32.const 4 + i32.const 6 call $~lib/rt/itcms/__new local.tee $0 i32.store $0 - global.get $~lib/memory/__stack_pointer - local.tee $1 - i32.const 4 - i32.sub - global.set $~lib/memory/__stack_pointer - global.get $~lib/memory/__stack_pointer - i32.const 1512 - i32.lt_s - br_if $folding-inner0 - global.get $~lib/memory/__stack_pointer - i32.const 0 - i32.store $0 - local.get $0 - i32.eqz - if - global.get $~lib/memory/__stack_pointer - i32.const 0 - call $~lib/rt/itcms/__new - local.tee $0 - i32.store $0 - end - global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.add - global.set $~lib/memory/__stack_pointer - local.get $1 - local.get $0 - i32.store $0 - global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.add - global.set $~lib/memory/__stack_pointer - local.get $0 - return end - i32.const 34304 - i32.const 34352 - i32.const 1 - i32.const 1 - call $~lib/builtins/abort - unreachable + global.get $~lib/memory/__stack_pointer + local.get $0 + call $~lib/object/Object#constructor + local.tee $0 + i32.store $0 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $0 ) (func $byn-split-outlined-A$~lib/rt/itcms/__visit (type $i32_=>_none) (param $0 i32) global.get $~lib/rt/itcms/white diff --git a/tests/compiler/logical.ts b/tests/compiler/logical.ts index cad6dbed6e..62a26f9d66 100644 --- a/tests/compiler/logical.ts +++ b/tests/compiler/logical.ts @@ -91,5 +91,23 @@ function testContextualBoolOr(someObj: Obj, someInt: i32): bool { } assert(testContextualBoolOr(new Obj(), 0)); -__stack_pointer = __heap_base; -__collect(); +// Common type + +class A {} +class B extends A {} +class C extends A {} + +let b = new B(); +let c = new C(); + +function commonOr(b: B | null): A { + return b || c; +} +assert(commonOr(b) == b); +assert(commonOr(null) == c); + +function commonAnd(b: B | null): A | null { + return b && c; +} +assert(commonAnd(b) == c); +assert(commonAnd(null) == null); From d49b697b331f0064e06a000a159a40c0d00cedb1 Mon Sep 17 00:00:00 2001 From: dcode Date: Tue, 20 Dec 2022 22:17:45 +0100 Subject: [PATCH 04/16] ? From fffdf401aa2a086d059c5200dea4fdd89dfe53d4 Mon Sep 17 00:00:00 2001 From: dcode Date: Tue, 20 Dec 2022 22:53:26 +0100 Subject: [PATCH 05/16] ? --- src/flow.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/flow.ts b/src/flow.ts index 31909c258a..59c416a29b 100644 --- a/src/flow.ts +++ b/src/flow.ts @@ -725,6 +725,12 @@ export class Flow { /** Inherits two alternate branches to become this flow, i.e. then with else. */ inheritAlternatives(left: Flow, right: Flow): void { + if (left.targetFunction != right.targetFunction) { + console.log("left: " + left.toString()); + console.log("right: " + right.toString()); + console.log("left.targetFunction: " + left.targetFunction.toString()); + console.log("right.targetFunction: " + right.targetFunction.toString()); + } assert(left.targetFunction == right.targetFunction); assert(left.targetFunction == this.targetFunction); // Differs from `mergeBranch` in that the alternatives are intersected to From 979ff3f737fd340cc8f0bf6febf71e987b75eb5c Mon Sep 17 00:00:00 2001 From: dcode Date: Tue, 20 Dec 2022 23:38:36 +0100 Subject: [PATCH 06/16] ? --- src/flow.ts | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/flow.ts b/src/flow.ts index 59c416a29b..9e3fa4d103 100644 --- a/src/flow.ts +++ b/src/flow.ts @@ -725,11 +725,21 @@ export class Flow { /** Inherits two alternate branches to become this flow, i.e. then with else. */ inheritAlternatives(left: Flow, right: Flow): void { - if (left.targetFunction != right.targetFunction) { + let leftTargetFunction = left.targetFunction; + let rightTargetFunction = right.targetFunction; + if (leftTargetFunction != rightTargetFunction) { console.log("left: " + left.toString()); + let iter = left.parent; + while (iter) { + console.log("- " + iter.toString()); + iter = iter.parent; + } console.log("right: " + right.toString()); - console.log("left.targetFunction: " + left.targetFunction.toString()); - console.log("right.targetFunction: " + right.targetFunction.toString()); + iter = right.parent; + while (iter) { + console.log("- " + iter.toString()); + iter = iter.parent; + } } assert(left.targetFunction == right.targetFunction); assert(left.targetFunction == this.targetFunction); From 5d93f48c04401d81a157644295a187805a593996 Mon Sep 17 00:00:00 2001 From: dcode Date: Tue, 20 Dec 2022 23:57:00 +0100 Subject: [PATCH 07/16] what if: disable optimizing --- cli/index.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cli/index.js b/cli/index.js index 36eeb4715e..cea57bcf42 100644 --- a/cli/index.js +++ b/cli/index.js @@ -800,12 +800,12 @@ export async function main(argv, options) { { let begin = stats.begin(); - try { - stats.optimizeCount++; - assemblyscript.optimize(module, optimizeLevel, shrinkLevel, debugInfo, zeroFilledMemory); - } catch (e) { - crash("optimize", e); - } + // try { + // stats.optimizeCount++; + // assemblyscript.optimize(module, optimizeLevel, shrinkLevel, debugInfo, zeroFilledMemory); + // } catch (e) { + // crash("optimize", e); + // } try { binaryenModule.runPasses(runPasses); } catch (e) { From dbc3e3c941e3a8169a576ca5113a7147a1b4e4fe Mon Sep 17 00:00:00 2001 From: dcode Date: Wed, 21 Dec 2022 00:00:16 +0100 Subject: [PATCH 08/16] what if: don't log left --- cli/index.js | 12 ++++++------ src/flow.ts | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/cli/index.js b/cli/index.js index cea57bcf42..36eeb4715e 100644 --- a/cli/index.js +++ b/cli/index.js @@ -800,12 +800,12 @@ export async function main(argv, options) { { let begin = stats.begin(); - // try { - // stats.optimizeCount++; - // assemblyscript.optimize(module, optimizeLevel, shrinkLevel, debugInfo, zeroFilledMemory); - // } catch (e) { - // crash("optimize", e); - // } + try { + stats.optimizeCount++; + assemblyscript.optimize(module, optimizeLevel, shrinkLevel, debugInfo, zeroFilledMemory); + } catch (e) { + crash("optimize", e); + } try { binaryenModule.runPasses(runPasses); } catch (e) { diff --git a/src/flow.ts b/src/flow.ts index 9e3fa4d103..66b13cec71 100644 --- a/src/flow.ts +++ b/src/flow.ts @@ -729,13 +729,13 @@ export class Flow { let rightTargetFunction = right.targetFunction; if (leftTargetFunction != rightTargetFunction) { console.log("left: " + left.toString()); - let iter = left.parent; - while (iter) { - console.log("- " + iter.toString()); - iter = iter.parent; - } + // let iter = left.parent; + // while (iter) { + // console.log("- " + iter.toString()); + // iter = iter.parent; + // } console.log("right: " + right.toString()); - iter = right.parent; + let iter = right.parent; while (iter) { console.log("- " + iter.toString()); iter = iter.parent; From e7174aa768cc3020c6c0dc65d5da34fa96c8637f Mon Sep 17 00:00:00 2001 From: dcode Date: Wed, 21 Dec 2022 00:04:02 +0100 Subject: [PATCH 09/16] what if: ?! --- src/flow.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/flow.ts b/src/flow.ts index 66b13cec71..c793a13f9d 100644 --- a/src/flow.ts +++ b/src/flow.ts @@ -729,13 +729,14 @@ export class Flow { let rightTargetFunction = right.targetFunction; if (leftTargetFunction != rightTargetFunction) { console.log("left: " + left.toString()); - // let iter = left.parent; + let iter = left.parent; + console.log("- ?"); // while (iter) { // console.log("- " + iter.toString()); // iter = iter.parent; // } console.log("right: " + right.toString()); - let iter = right.parent; + iter = right.parent; while (iter) { console.log("- " + iter.toString()); iter = iter.parent; From f4125ac5916e244703abf3d6d1e2c1a5ff450f2b Mon Sep 17 00:00:00 2001 From: dcode Date: Wed, 21 Dec 2022 00:10:21 +0100 Subject: [PATCH 10/16] what if: ??! --- src/flow.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/flow.ts b/src/flow.ts index c793a13f9d..19f45adc97 100644 --- a/src/flow.ts +++ b/src/flow.ts @@ -729,14 +729,14 @@ export class Flow { let rightTargetFunction = right.targetFunction; if (leftTargetFunction != rightTargetFunction) { console.log("left: " + left.toString()); - let iter = left.parent; + // let iter = left.parent; console.log("- ?"); // while (iter) { // console.log("- " + iter.toString()); // iter = iter.parent; // } console.log("right: " + right.toString()); - iter = right.parent; + let iter = right.parent; while (iter) { console.log("- " + iter.toString()); iter = iter.parent; From 3fa793a08cd1020172145a9aca25a56794bf60f1 Mon Sep 17 00:00:00 2001 From: dcode Date: Wed, 21 Dec 2022 00:35:19 +0100 Subject: [PATCH 11/16] ? --- src/flow.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/flow.ts b/src/flow.ts index 19f45adc97..7c07caf808 100644 --- a/src/flow.ts +++ b/src/flow.ts @@ -725,20 +725,19 @@ export class Flow { /** Inherits two alternate branches to become this flow, i.e. then with else. */ inheritAlternatives(left: Flow, right: Flow): void { - let leftTargetFunction = left.targetFunction; - let rightTargetFunction = right.targetFunction; - if (leftTargetFunction != rightTargetFunction) { - console.log("left: " + left.toString()); + if (left.targetFunction != right.targetFunction) { + console.log("= left ="); + console.log(left.toString()); // let iter = left.parent; - console.log("- ?"); // while (iter) { // console.log("- " + iter.toString()); // iter = iter.parent; // } - console.log("right: " + right.toString()); + console.log("= right ="); + console.log(right.toString()); let iter = right.parent; while (iter) { - console.log("- " + iter.toString()); + console.log(iter.toString()); iter = iter.parent; } } From f00c06b687a31a4b1c88a617cce2a8ee3d317e66 Mon Sep 17 00:00:00 2001 From: dcode Date: Wed, 21 Dec 2022 01:00:03 +0100 Subject: [PATCH 12/16] what if: other node version --- .github/workflows/test.yml | 2 +- src/flow.ts | 16 ---------------- 2 files changed, 1 insertion(+), 17 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5e46805377..a556e7b81e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -52,7 +52,7 @@ jobs: - uses: actions/checkout@v3 - uses: dcodeIO/setup-node-nvm@master with: - node-version: current + node-version: 18 - name: Install dependencies run: npm ci --no-audit - name: Build diff --git a/src/flow.ts b/src/flow.ts index 7c07caf808..31909c258a 100644 --- a/src/flow.ts +++ b/src/flow.ts @@ -725,22 +725,6 @@ export class Flow { /** Inherits two alternate branches to become this flow, i.e. then with else. */ inheritAlternatives(left: Flow, right: Flow): void { - if (left.targetFunction != right.targetFunction) { - console.log("= left ="); - console.log(left.toString()); - // let iter = left.parent; - // while (iter) { - // console.log("- " + iter.toString()); - // iter = iter.parent; - // } - console.log("= right ="); - console.log(right.toString()); - let iter = right.parent; - while (iter) { - console.log(iter.toString()); - iter = iter.parent; - } - } assert(left.targetFunction == right.targetFunction); assert(left.targetFunction == this.targetFunction); // Differs from `mergeBranch` in that the alternatives are intersected to From 6a729b0f08224850b73db8f75d3531992d79508b Mon Sep 17 00:00:00 2001 From: dcode Date: Wed, 21 Dec 2022 11:57:02 +0100 Subject: [PATCH 13/16] ? --- .github/workflows/test.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a556e7b81e..ccf44de828 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -52,13 +52,19 @@ jobs: - uses: actions/checkout@v3 - uses: dcodeIO/setup-node-nvm@master with: - node-version: 18 + node-version: current - name: Install dependencies run: npm ci --no-audit - name: Build run: npm run build - name: "Bootstrap ${{ matrix.target }}" run: npm run bootstrap:${{ matrix.target }} + - name: Upload artifact + if: failure() + uses: actions/upload-artifact@v3 + with: + name: build + path: build/ - name: "Test ${{ matrix.target }}" run: npm run test:compiler -- --wasm build/assemblyscript.${{ matrix.target }}-bootstrap.js - name: "Compile ${{ matrix.target }} -> ${{ matrix.target == 'debug' && 'release' || 'debug' }}" From 65001b18b5b14a89d487cf961e89c9eba9cb5197 Mon Sep 17 00:00:00 2001 From: dcode Date: Wed, 21 Dec 2022 12:19:49 +0100 Subject: [PATCH 14/16] ? --- .github/workflows/test.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ccf44de828..973d6a33fe 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -64,7 +64,9 @@ jobs: uses: actions/upload-artifact@v3 with: name: build - path: build/ + path: | + build/ + dist/ - name: "Test ${{ matrix.target }}" run: npm run test:compiler -- --wasm build/assemblyscript.${{ matrix.target }}-bootstrap.js - name: "Compile ${{ matrix.target }} -> ${{ matrix.target == 'debug' && 'release' || 'debug' }}" From 568ef06f2a2c93a3769f0ab58123b0e4bc464144 Mon Sep 17 00:00:00 2001 From: dcode Date: Wed, 21 Dec 2022 13:08:37 +0100 Subject: [PATCH 15/16] ? --- cli/index.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/cli/index.js b/cli/index.js index 36eeb4715e..f59f24ce90 100644 --- a/cli/index.js +++ b/cli/index.js @@ -47,6 +47,15 @@ if (~wasmPos) { assemblyscript = await import(new URL(wasmPath, url.pathToFileURL(process.cwd() + "/"))); } +{ + let original = assemblyscript; + assemblyscript = Object.create(original); + assemblyscript.parse = assemblyscript.parse = function(program, text, path, isEntry) { + console.log(`parse ${path} (${text ? text.length : "not found"})`) + return original.parse(program, text, path, isEntry); + }; +} + const require = module.createRequire(import.meta.url); const WIN = process.platform === "win32"; From 2908ff098e41f643b631ac1fd4d3fd97269a89ea Mon Sep 17 00:00:00 2001 From: dcode Date: Thu, 22 Dec 2022 19:45:14 +0100 Subject: [PATCH 16/16] reset --- .github/workflows/test.yml | 8 -------- cli/index.js | 9 --------- 2 files changed, 17 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 973d6a33fe..5e46805377 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -59,14 +59,6 @@ jobs: run: npm run build - name: "Bootstrap ${{ matrix.target }}" run: npm run bootstrap:${{ matrix.target }} - - name: Upload artifact - if: failure() - uses: actions/upload-artifact@v3 - with: - name: build - path: | - build/ - dist/ - name: "Test ${{ matrix.target }}" run: npm run test:compiler -- --wasm build/assemblyscript.${{ matrix.target }}-bootstrap.js - name: "Compile ${{ matrix.target }} -> ${{ matrix.target == 'debug' && 'release' || 'debug' }}" diff --git a/cli/index.js b/cli/index.js index f59f24ce90..36eeb4715e 100644 --- a/cli/index.js +++ b/cli/index.js @@ -47,15 +47,6 @@ if (~wasmPos) { assemblyscript = await import(new URL(wasmPath, url.pathToFileURL(process.cwd() + "/"))); } -{ - let original = assemblyscript; - assemblyscript = Object.create(original); - assemblyscript.parse = assemblyscript.parse = function(program, text, path, isEntry) { - console.log(`parse ${path} (${text ? text.length : "not found"})`) - return original.parse(program, text, path, isEntry); - }; -} - const require = module.createRequire(import.meta.url); const WIN = process.platform === "win32";