From fe64a7b6726c9596163cddaa87d3456710b99e66 Mon Sep 17 00:00:00 2001 From: chen ruixiang Date: Wed, 7 Sep 2022 13:14:30 +0800 Subject: [PATCH 01/10] Fix: multi implements issue --- src/program.ts | 61 ++- src/types.ts | 20 +- tests/compiler/class-implements.debug.wat | 179 +++++++- tests/compiler/class-implements.release.wat | 444 +++++++++++++++----- tests/compiler/class-implements.ts | 26 ++ 5 files changed, 578 insertions(+), 152 deletions(-) diff --git a/src/program.ts b/src/program.ts index 366de8e233..36445d36d4 100644 --- a/src/program.ts +++ b/src/program.ts @@ -2954,6 +2954,33 @@ export abstract class DeclaredElement extends Element { return this.declaration.decorators; } + /** Determine if two properties are compatibal during override by their getter and setter signature . */ + private _isCampatibalOverrideProperty(selfProperty: Property|null, baseProperty: Property|null, ignoreInheritLineCheck: bool = false): bool { + if (!selfProperty || !baseProperty) { + return false; + } else { + let selfGetter = selfProperty.getterInstance; + let baseGetter = baseProperty.getterInstance; + if (selfGetter) { + if (!baseGetter || !selfGetter.signature.isAssignableTo(baseGetter.signature, true)) { + return false; + } + } else if (baseGetter) { + return false; + } + let selfSetter = selfProperty.setterInstance; + let baseSetter = baseProperty.setterInstance; + if (selfSetter) { + if (!baseSetter || !selfSetter.signature.isAssignableTo(baseSetter.signature, true)) { + return false; + } + } else if (baseSetter) { + return false; + } + } + return true; + } + /** Checks if this element is a compatible override of the specified. */ isCompatibleOverride(base: DeclaredElement): bool { var self: DeclaredElement = this; // TS @@ -2963,28 +2990,24 @@ export abstract class DeclaredElement extends Element { case ElementKind.FUNCTION: { return (self).signature.isAssignableTo((base).signature); } + case ElementKind.FUNCTION_PROTOTYPE : { + let selfFunction = this.program.resolver.resolveFunction(self, null); + let baseFunction = this.program.resolver.resolveFunction(base, null); + if (selfFunction && baseFunction) { + return selfFunction.signature.isAssignableTo(baseFunction.signature, true); + } else { + return false; + } + } + case ElementKind.PROPERTY_PROTOTYPE: { + let selfProperty = this.program.resolver.resolveProperty(self); + let baseProperty = this.program.resolver.resolveProperty(base); + return this._isCampatibalOverrideProperty(selfProperty, baseProperty, true); + } case ElementKind.PROPERTY: { let selfProperty = self; let baseProperty = base; - let selfGetter = selfProperty.getterInstance; - let baseGetter = baseProperty.getterInstance; - if (selfGetter) { - if (!baseGetter || !selfGetter.signature.isAssignableTo(baseGetter.signature)) { - return false; - } - } else if (baseGetter) { - return false; - } - let selfSetter = selfProperty.setterInstance; - let baseSetter = baseProperty.setterInstance; - if (selfSetter) { - if (!baseSetter || !selfSetter.signature.isAssignableTo(baseSetter.signature)) { - return false; - } - } else if (baseSetter) { - return false; - } - return true; + return self._isCampatibalOverrideProperty(selfProperty, baseProperty); } } } diff --git a/src/types.ts b/src/types.ts index a07375990b..8d6d52355e 100644 --- a/src/types.ts +++ b/src/types.ts @@ -882,17 +882,19 @@ export class Signature { } /** Tests if a value of this function type is assignable to a target of the specified function type. */ - isAssignableTo(target: Signature): bool { - - // check `this` type - var thisThisType = this.thisType; - var targetThisType = target.thisType; - if (thisThisType) { - if (!targetThisType || !thisThisType.isAssignableTo(targetThisType)) { + isAssignableTo(target: Signature, ignoreInheritLineCheck: bool = false): bool { + + if (!ignoreInheritLineCheck) { + // check `this` type + var thisThisType = this.thisType; + var targetThisType = target.thisType; + if (thisThisType) { + if (!targetThisType || !thisThisType.isAssignableTo(targetThisType)) { + return false; + } + } else if (targetThisType) { return false; } - } else if (targetThisType) { - return false; } // check rest parameter diff --git a/tests/compiler/class-implements.debug.wat b/tests/compiler/class-implements.debug.wat index 447b1e89da..8d7bd1985d 100644 --- a/tests/compiler/class-implements.debug.wat +++ b/tests/compiler/class-implements.debug.wat @@ -25,10 +25,12 @@ (global $~lib/native/ASC_LOW_MEMORY_LIMIT i32 (i32.const 0)) (global $class-implements/a (mut i32) (i32.const 0)) (global $class-implements/c (mut i32) (i32.const 0)) + (global $class-implements/d (mut i32) (i32.const 0)) + (global $class-implements/e (mut i32) (i32.const 0)) (global $~lib/rt/__rtti_base i32 (i32.const 480)) - (global $~lib/memory/__data_end i32 (i32.const 540)) - (global $~lib/memory/__stack_pointer (mut i32) (i32.const 16924)) - (global $~lib/memory/__heap_base i32 (i32.const 16924)) + (global $~lib/memory/__data_end i32 (i32.const 580)) + (global $~lib/memory/__stack_pointer (mut i32) (i32.const 16964)) + (global $~lib/memory/__heap_base i32 (i32.const 16964)) (memory $0 1) (data (i32.const 12) "<\00\00\00\00\00\00\00\00\00\00\00\01\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") (data (i32.const 76) "<\00\00\00\00\00\00\00\00\00\00\00\01\00\00\00 \00\00\00~\00l\00i\00b\00/\00r\00t\00/\00i\00t\00c\00m\00s\00.\00t\00s\00\00\00\00\00\00\00\00\00\00\00\00\00") @@ -39,7 +41,7 @@ (data (i32.const 320) "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00") (data (i32.const 348) "<\00\00\00\00\00\00\00\00\00\00\00\01\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 412) "<\00\00\00\00\00\00\00\00\00\00\00\01\00\00\00&\00\00\00c\00l\00a\00s\00s\00-\00i\00m\00p\00l\00e\00m\00e\00n\00t\00s\00.\00t\00s\00\00\00\00\00\00\00") - (data (i32.const 480) "\07\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\00\00\00\00 \00\00\00\00\00\00\00 \00\00\00\06\00\00\00 \00\00\00\00\00\00\00") + (data (i32.const 480) "\0c\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\00\00\00\00 \00\00\00\00\00\00\00 \00\00\00\06\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\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)) @@ -2122,6 +2124,14 @@ (func $class-implements/C#foo (param $this i32) (result i32) i32.const 2 ) + (func $class-implements/D#foo (param $this i32) (result i32) + i32.const 3 + ) + (func $class-implements/E#set:a (param $0 i32) (param $1 i32) + local.get $0 + local.get $1 + i32.store $0 + ) (func $~lib/rt/__visit_globals (param $0 i32) (local $1 i32) global.get $class-implements/a @@ -2138,6 +2148,20 @@ local.get $0 call $~lib/rt/itcms/__visit end + global.get $class-implements/d + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $class-implements/e + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end i32.const 224 local.get $0 call $~lib/rt/itcms/__visit @@ -2158,26 +2182,41 @@ ) (func $~lib/rt/__visit_members (param $0 i32) (param $1 i32) block $invalid - block $class-implements/B - block $class-implements/C - block $class-implements/I - block $class-implements/A - block $~lib/arraybuffer/ArrayBufferView - block $~lib/string/String - block $~lib/arraybuffer/ArrayBuffer - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - br_table $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $class-implements/A $class-implements/I $class-implements/C $class-implements/B $invalid + block $class-implements/N + block $class-implements/M + block $class-implements/E + block $class-implements/J + block $class-implements/D + block $class-implements/B + block $class-implements/C + block $class-implements/I + block $class-implements/A + block $~lib/arraybuffer/ArrayBufferView + block $~lib/string/String + block $~lib/arraybuffer/ArrayBuffer + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + br_table $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $class-implements/A $class-implements/I $class-implements/C $class-implements/B $class-implements/D $class-implements/J $class-implements/E $class-implements/M $class-implements/N $invalid + end + return + end + return + end + local.get $0 + local.get $1 + call $~lib/arraybuffer/ArrayBufferView~visit + return + end + return + end + return end return end return end - local.get $0 - local.get $1 - call $~lib/arraybuffer/ArrayBufferView~visit return end return @@ -2198,8 +2237,8 @@ global.get $~lib/memory/__data_end i32.lt_s if - i32.const 16944 i32.const 16992 + i32.const 17040 i32.const 1 i32.const 1 call $~lib/builtins/abort @@ -2249,7 +2288,7 @@ if i32.const 0 i32.const 432 - i32.const 10 + i32.const 14 i32.const 1 call $~lib/builtins/abort unreachable @@ -2270,7 +2309,44 @@ if i32.const 0 i32.const 432 - i32.const 20 + i32.const 24 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 0 + call $class-implements/D#constructor + global.set $class-implements/d + global.get $class-implements/d + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store $0 + local.get $0 + call $class-implements/D#foo + i32.const 3 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 31 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 0 + call $class-implements/E#constructor + global.set $class-implements/e + global.get $class-implements/e + i32.load $0 + i32.const 4 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 46 i32.const 1 call $~lib/builtins/abort unreachable @@ -2369,4 +2445,63 @@ global.set $~lib/memory/__stack_pointer local.get $1 ) + (func $class-implements/D#constructor (param $0 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 $0 + i32.eqz + if + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.const 7 + call $~lib/rt/itcms/__new + local.tee $0 + i32.store $0 + end + local.get $0 + local.set $1 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $1 + ) + (func $class-implements/E#constructor (param $0 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 $0 + i32.eqz + if + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.const 9 + call $~lib/rt/itcms/__new + local.tee $0 + i32.store $0 + end + local.get $0 + i32.const 4 + call $class-implements/E#set:a + local.get $0 + 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/class-implements.release.wat b/tests/compiler/class-implements.release.wat index 2c4122b8a3..aadf9c0fe6 100644 --- a/tests/compiler/class-implements.release.wat +++ b/tests/compiler/class-implements.release.wat @@ -1,7 +1,7 @@ (module (type $none_=>_none (func)) (type $i32_i32_=>_none (func (param i32 i32))) - (type $i32_=>_i32 (func (param i32) (result i32))) + (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) (type $i32_=>_none (func (param i32))) (type $i32_i32_i32_i32_=>_none (func (param i32 i32 i32 i32))) (type $i32_i32_i32_=>_none (func (param i32 i32 i32))) @@ -19,7 +19,9 @@ (global $~lib/rt/tlsf/ROOT (mut i32) (i32.const 0)) (global $class-implements/a (mut i32) (i32.const 0)) (global $class-implements/c (mut i32) (i32.const 0)) - (global $~lib/memory/__stack_pointer (mut i32) (i32.const 17948)) + (global $class-implements/d (mut i32) (i32.const 0)) + (global $class-implements/e (mut i32) (i32.const 0)) + (global $~lib/memory/__stack_pointer (mut i32) (i32.const 17988)) (memory $0 1) (data (i32.const 1036) "<") (data (i32.const 1048) "\01\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") @@ -33,8 +35,8 @@ (data (i32.const 1384) "\01\00\00\00\1e\00\00\00~\00l\00i\00b\00/\00r\00t\00/\00t\00l\00s\00f\00.\00t\00s") (data (i32.const 1436) "<") (data (i32.const 1448) "\01\00\00\00&\00\00\00c\00l\00a\00s\00s\00-\00i\00m\00p\00l\00e\00m\00e\00n\00t\00s\00.\00t\00s") - (data (i32.const 1504) "\07\00\00\00 \00\00\00\00\00\00\00 ") - (data (i32.const 1532) " \00\00\00\00\00\00\00 \00\00\00\00\00\00\00 \00\00\00\06\00\00\00 ") + (data (i32.const 1504) "\0c\00\00\00 \00\00\00\00\00\00\00 ") + (data (i32.const 1532) " \00\00\00\00\00\00\00 \00\00\00\00\00\00\00 \00\00\00\06\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\00\00\00 \00\00\00\00\00\00\00 ") (export "memory" (memory $0)) (start $~start) (func $~lib/rt/itcms/visitRoots @@ -52,6 +54,18 @@ local.get $0 call $byn-split-outlined-A$~lib/rt/itcms/__visit end + global.get $class-implements/d + local.tee $0 + if + local.get $0 + call $byn-split-outlined-A$~lib/rt/itcms/__visit + end + global.get $class-implements/e + local.tee $0 + if + local.get $0 + call $byn-split-outlined-A$~lib/rt/itcms/__visit + end i32.const 1248 call $byn-split-outlined-A$~lib/rt/itcms/__visit i32.const 1056 @@ -625,10 +639,10 @@ if unreachable end - i32.const 17952 + i32.const 18000 i32.const 0 i32.store $0 - i32.const 19520 + i32.const 19568 i32.const 0 i32.store $0 loop $for-loop|0 @@ -639,7 +653,7 @@ local.get $0 i32.const 2 i32.shl - i32.const 17952 + i32.const 18000 i32.add i32.const 0 i32.store $0 offset=4 @@ -657,7 +671,7 @@ i32.add i32.const 2 i32.shl - i32.const 17952 + i32.const 18000 i32.add i32.const 0 i32.store $0 offset=96 @@ -675,13 +689,13 @@ br $for-loop|0 end end - i32.const 17952 - i32.const 19524 + i32.const 18000 + i32.const 19572 memory.size $0 i32.const 16 i32.shl call $~lib/rt/tlsf/addMemory - i32.const 17952 + i32.const 18000 global.set $~lib/rt/tlsf/ROOT ) (func $~lib/rt/itcms/step (result i32) @@ -766,7 +780,7 @@ local.set $0 loop $while-continue|0 local.get $0 - i32.const 17948 + i32.const 17988 i32.lt_u if local.get $0 @@ -866,7 +880,7 @@ unreachable end local.get $0 - i32.const 17948 + i32.const 17988 i32.lt_u if local.get $0 @@ -889,7 +903,7 @@ i32.const 4 i32.add local.tee $0 - i32.const 17948 + i32.const 17988 i32.ge_u if global.get $~lib/rt/tlsf/ROOT @@ -951,18 +965,83 @@ end i32.const 0 ) - (func $~lib/rt/tlsf/searchBlock (param $0 i32) (result i32) - (local $1 i32) + (func $~lib/rt/tlsf/searchBlock (param $0 i32) (param $1 i32) (result i32) (local $2 i32) + (local $3 i32) + local.get $1 + i32.const 256 + i32.lt_u + if (result i32) + local.get $1 + i32.const 4 + i32.shr_u + else + i32.const 31 + local.get $1 + i32.const 1 + i32.const 27 + local.get $1 + i32.clz + i32.sub + i32.shl + i32.add + i32.const 1 + i32.sub + local.get $1 + local.get $1 + i32.const 536870910 + i32.lt_u + select + local.tee $1 + i32.clz + i32.sub + local.tee $3 + i32.const 7 + i32.sub + local.set $2 + local.get $1 + local.get $3 + i32.const 4 + i32.sub + i32.shr_u + i32.const 16 + i32.xor + end + local.tee $1 + i32.const 16 + i32.lt_u + local.get $2 + i32.const 23 + i32.lt_u + i32.and + i32.eqz + if + i32.const 0 + i32.const 1392 + i32.const 330 + i32.const 14 + call $~lib/builtins/abort + unreachable + end local.get $0 + local.get $2 + i32.const 2 + i32.shl + i32.add i32.load $0 offset=4 - i32.const -2 + i32.const -1 + local.get $1 + i32.shl i32.and local.tee $1 if (result i32) local.get $0 local.get $1 i32.ctz + local.get $2 + i32.const 4 + i32.shl + i32.add i32.const 2 i32.shl i32.add @@ -970,19 +1049,23 @@ else local.get $0 i32.load $0 - i32.const -2 + i32.const -1 + local.get $2 + i32.const 1 + i32.add + i32.shl i32.and local.tee $1 if (result i32) local.get $0 local.get $1 i32.ctz - local.tee $2 + local.tee $1 i32.const 2 i32.shl i32.add i32.load $0 offset=4 - local.tee $1 + local.tee $2 i32.eqz if i32.const 0 @@ -993,9 +1076,9 @@ unreachable end local.get $0 - local.get $1 - i32.ctz local.get $2 + i32.ctz + local.get $1 i32.const 4 i32.shl i32.add @@ -1008,23 +1091,35 @@ end end ) - (func $~lib/rt/itcms/__new (param $0 i32) (result i32) - (local $1 i32) + (func $~lib/rt/itcms/__new (param $0 i32) (param $1 i32) (result i32) (local $2 i32) (local $3 i32) (local $4 i32) + (local $5 i32) + (local $6 i32) + local.get $0 + i32.const 1073741804 + i32.ge_u + if + i32.const 1056 + i32.const 1120 + i32.const 260 + i32.const 31 + call $~lib/builtins/abort + unreachable + end global.get $~lib/rt/itcms/total global.get $~lib/rt/itcms/threshold i32.ge_u if block $__inlined_func$~lib/rt/itcms/interrupt i32.const 2048 - local.set $1 + local.set $2 loop $do-loop|0 - local.get $1 + local.get $2 call $~lib/rt/itcms/step i32.sub - local.set $1 + local.set $2 global.get $~lib/rt/itcms/state i32.eqz if @@ -1040,14 +1135,14 @@ global.set $~lib/rt/itcms/threshold br $__inlined_func$~lib/rt/itcms/interrupt end - local.get $1 + local.get $2 i32.const 0 i32.gt_s br_if $do-loop|0 end global.get $~lib/rt/itcms/total - local.tee $1 - local.get $1 + local.tee $2 + local.get $2 global.get $~lib/rt/itcms/threshold i32.sub i32.const 1024 @@ -1064,31 +1159,75 @@ call $~lib/rt/tlsf/initialize end global.get $~lib/rt/tlsf/ROOT + local.set $4 + local.get $0 + i32.const 16 + i32.add local.tee $2 + i32.const 1073741820 + i32.gt_u + if + i32.const 1056 + i32.const 1392 + i32.const 458 + i32.const 29 + call $~lib/builtins/abort + unreachable + end + local.get $4 + i32.const 12 + local.get $2 + i32.const 19 + i32.add + i32.const -16 + i32.and + i32.const 4 + i32.sub + local.get $2 + i32.const 12 + i32.le_u + select + local.tee $5 call $~lib/rt/tlsf/searchBlock - local.tee $1 + local.tee $2 i32.eqz if memory.size $0 - local.tee $1 + local.tee $2 i32.const 4 - local.get $2 + local.get $4 i32.load $0 offset=1568 - local.get $1 + local.get $2 i32.const 16 i32.shl i32.const 4 i32.sub i32.ne i32.shl - i32.const 65563 + local.get $5 + i32.const 1 + i32.const 27 + local.get $5 + i32.clz + i32.sub + i32.shl + i32.const 1 + i32.sub + i32.add + local.get $5 + local.get $5 + i32.const 536870910 + i32.lt_u + select + i32.add + i32.const 65535 i32.add i32.const -65536 i32.and i32.const 16 i32.shr_u local.tee $3 - local.get $1 + local.get $2 local.get $3 i32.gt_s select @@ -1104,17 +1243,18 @@ unreachable end end + local.get $4 local.get $2 - local.get $1 i32.const 16 i32.shl memory.size $0 i32.const 16 i32.shl call $~lib/rt/tlsf/addMemory - local.get $2 + local.get $4 + local.get $5 call $~lib/rt/tlsf/searchBlock - local.tee $1 + local.tee $2 i32.eqz if i32.const 0 @@ -1125,12 +1265,12 @@ unreachable end end - local.get $1 + local.get $5 + local.get $2 i32.load $0 i32.const -4 i32.and - i32.const 28 - i32.lt_u + i32.gt_u if i32.const 0 i32.const 1392 @@ -1139,92 +1279,108 @@ call $~lib/builtins/abort unreachable end + local.get $4 local.get $2 - local.get $1 call $~lib/rt/tlsf/removeBlock - local.get $1 + local.get $2 i32.load $0 - local.tee $4 + local.set $3 + local.get $5 + i32.const 4 + i32.add + i32.const 15 + i32.and + if + i32.const 0 + i32.const 1392 + i32.const 357 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $3 i32.const -4 i32.and - i32.const 28 + local.get $5 i32.sub - local.tee $3 + local.tee $6 i32.const 16 i32.ge_u if - local.get $1 - local.get $4 + local.get $2 + local.get $5 + local.get $3 i32.const 2 i32.and - i32.const 28 i32.or i32.store $0 - local.get $1 - i32.const 32 + local.get $2 + i32.const 4 i32.add - local.tee $4 - local.get $3 + local.get $5 + i32.add + local.tee $3 + local.get $6 i32.const 4 i32.sub i32.const 1 i32.or i32.store $0 - local.get $2 local.get $4 + local.get $3 call $~lib/rt/tlsf/insertBlock else - local.get $1 - local.get $4 + local.get $2 + local.get $3 i32.const -2 i32.and i32.store $0 - local.get $1 + local.get $2 i32.const 4 i32.add - local.get $1 + local.get $2 i32.load $0 i32.const -4 i32.and i32.add - local.tee $2 - local.get $2 + local.tee $3 + local.get $3 i32.load $0 i32.const -3 i32.and i32.store $0 end + local.get $2 local.get $1 - local.get $0 i32.store $0 offset=12 - local.get $1 - i32.const 0 + local.get $2 + local.get $0 i32.store $0 offset=16 global.get $~lib/rt/itcms/fromSpace - local.tee $0 + local.tee $1 i32.load $0 offset=8 - local.set $2 + local.set $3 + local.get $2 local.get $1 - local.get $0 global.get $~lib/rt/itcms/white i32.or i32.store $0 offset=4 - local.get $1 local.get $2 + local.get $3 i32.store $0 offset=8 + local.get $3 local.get $2 - local.get $1 - local.get $2 + local.get $3 i32.load $0 offset=4 i32.const 3 i32.and i32.or i32.store $0 offset=4 - local.get $0 local.get $1 + local.get $2 i32.store $0 offset=8 global.get $~lib/rt/itcms/total - local.get $1 + local.get $2 i32.load $0 i32.const -4 i32.and @@ -1232,41 +1388,56 @@ i32.add i32.add global.set $~lib/rt/itcms/total - local.get $1 + local.get $2 i32.const 20 i32.add - local.tee $0 - i32.const 0 + local.tee $1 i32.const 0 - memory.fill $0 local.get $0 + memory.fill $0 + local.get $1 ) (func $~lib/rt/__visit_members (param $0 i32) block $invalid - block $class-implements/B - block $class-implements/C - block $class-implements/I - block $class-implements/A - block $~lib/arraybuffer/ArrayBufferView - block $~lib/string/String - block $~lib/arraybuffer/ArrayBuffer - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - br_table $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $class-implements/A $class-implements/I $class-implements/C $class-implements/B $invalid + block $class-implements/N + block $class-implements/M + block $class-implements/E + block $class-implements/J + block $class-implements/D + block $class-implements/B + block $class-implements/C + block $class-implements/I + block $class-implements/A + block $~lib/arraybuffer/ArrayBufferView + block $~lib/string/String + block $~lib/arraybuffer/ArrayBuffer + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + br_table $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $class-implements/A $class-implements/I $class-implements/C $class-implements/B $class-implements/D $class-implements/J $class-implements/E $class-implements/M $class-implements/N $invalid + end + return + 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 + end + return end return 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 @@ -1288,7 +1459,7 @@ global.set $~lib/memory/__stack_pointer block $folding-inner0 global.get $~lib/memory/__stack_pointer - i32.const 1564 + i32.const 1604 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -1298,7 +1469,7 @@ memory.size $0 i32.const 16 i32.shl - i32.const 17948 + i32.const 17988 i32.sub i32.const 1 i32.shr_u @@ -1332,7 +1503,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1564 + i32.const 1604 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -1340,6 +1511,7 @@ i32.const 0 i32.store $0 local.get $0 + i32.const 0 i32.const 3 call $~lib/rt/itcms/__new local.tee $0 @@ -1358,7 +1530,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1564 + i32.const 1604 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -1366,6 +1538,7 @@ i32.const 0 i32.store $0 local.get $0 + i32.const 0 i32.const 5 call $~lib/rt/itcms/__new local.tee $0 @@ -1376,7 +1549,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1564 + i32.const 1604 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -1386,6 +1559,7 @@ i32.eqz if global.get $~lib/memory/__stack_pointer + i32.const 0 i32.const 6 call $~lib/rt/itcms/__new local.tee $0 @@ -1409,12 +1583,78 @@ i32.store $0 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 1604 + 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 0 + i32.const 7 + call $~lib/rt/itcms/__new + 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 $class-implements/d + global.get $~lib/memory/__stack_pointer + global.get $class-implements/d + i32.store $0 + 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 1604 + 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 4 + i32.const 9 + call $~lib/rt/itcms/__new + local.tee $0 + i32.store $0 + local.get $0 + i32.const 4 + 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 $class-implements/e + global.get $class-implements/e + i32.load $0 + i32.const 4 + i32.ne + if + i32.const 0 + i32.const 1456 + i32.const 46 + 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 return end - i32.const 17968 i32.const 18016 + i32.const 18064 i32.const 1 i32.const 1 call $~lib/builtins/abort @@ -1465,7 +1705,7 @@ i32.load $0 offset=8 i32.eqz local.get $1 - i32.const 17948 + i32.const 17988 i32.lt_u i32.and i32.eqz diff --git a/tests/compiler/class-implements.ts b/tests/compiler/class-implements.ts index ec039b7367..43cb41bfb9 100644 --- a/tests/compiler/class-implements.ts +++ b/tests/compiler/class-implements.ts @@ -2,6 +2,10 @@ interface I { foo(): i32; } +interface J { + foo(): i32; +} + class A implements I { foo(): i32 { return 1; } } @@ -18,3 +22,25 @@ class C extends B implements I { var c = new C(); assert(c.foo() == 2); + +class D implements I, J { + foo(): i32 { return 3; } +} + +let d = new D(); +assert(d.foo() == 3); + +interface M { + a: i32; +} + +interface N { + a: i32; +} + +class E implements M, N { + a: i32 = 4; +} + +let e = new E(); +assert(e.a == 4); From 21297b9d804a1a5605480fb289e1f02915b8cbde Mon Sep 17 00:00:00 2001 From: chen ruixiang Date: Wed, 7 Sep 2022 13:51:58 +0800 Subject: [PATCH 02/10] Fix: fix extends and implements compatible issue --- src/program.ts | 21 +- tests/compiler/class-implements.debug.wat | 382 +++++++++++++++++-- tests/compiler/class-implements.release.wat | 397 +++++++++++++++++--- tests/compiler/class-implements.ts | 26 ++ 4 files changed, 726 insertions(+), 100 deletions(-) diff --git a/src/program.ts b/src/program.ts index 36445d36d4..7a1ebfb8aa 100644 --- a/src/program.ts +++ b/src/program.ts @@ -3011,6 +3011,25 @@ export abstract class DeclaredElement extends Element { } } } + if (self.kind == ElementKind.FIELD && base.kind == ElementKind.PROPERTY_PROTOTYPE) { + // class A implement I, class B extends A implement I + let selfField = self; + let baseProperty = this.program.resolver.resolveProperty(base); + + if (!selfField.internalGetterSignature + || !baseProperty + || !baseProperty.getterInstance + || !selfField.internalGetterSignature.isAssignableTo(baseProperty.getterInstance.signature)) { + return false; + } + if (!selfField.internalSetterSignature + || !baseProperty + || !baseProperty.setterInstance + || !selfField.internalSetterSignature.isAssignableTo(baseProperty.setterInstance.signature)) { + return false; + } + return true; + } return false; } } @@ -3932,7 +3951,7 @@ export class Field extends VariableLikeElement { get internalSetterSignature(): Signature { var cached = this._internalSetterSignature; if (!cached) { - this._internalGetterSignature = cached = new Signature(this.program, [ this.type ], Type.void, this.thisType); + this._internalSetterSignature = cached = new Signature(this.program, [ this.type ], Type.void, this.thisType); } return cached; } diff --git a/tests/compiler/class-implements.debug.wat b/tests/compiler/class-implements.debug.wat index 8d7bd1985d..4480850f46 100644 --- a/tests/compiler/class-implements.debug.wat +++ b/tests/compiler/class-implements.debug.wat @@ -1,6 +1,6 @@ (module - (type $i32_i32_=>_none (func (param i32 i32))) (type $i32_=>_i32 (func (param i32) (result i32))) + (type $i32_i32_=>_none (func (param i32 i32))) (type $i32_=>_none (func (param i32))) (type $none_=>_none (func)) (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) @@ -27,10 +27,14 @@ (global $class-implements/c (mut i32) (i32.const 0)) (global $class-implements/d (mut i32) (i32.const 0)) (global $class-implements/e (mut i32) (i32.const 0)) + (global $class-implements/f (mut i32) (i32.const 0)) + (global $class-implements/g (mut i32) (i32.const 0)) + (global $class-implements/h (mut i32) (i32.const 0)) + (global $class-implements/k (mut i32) (i32.const 0)) (global $~lib/rt/__rtti_base i32 (i32.const 480)) - (global $~lib/memory/__data_end i32 (i32.const 580)) - (global $~lib/memory/__stack_pointer (mut i32) (i32.const 16964)) - (global $~lib/memory/__heap_base i32 (i32.const 16964)) + (global $~lib/memory/__data_end i32 (i32.const 612)) + (global $~lib/memory/__stack_pointer (mut i32) (i32.const 16996)) + (global $~lib/memory/__heap_base i32 (i32.const 16996)) (memory $0 1) (data (i32.const 12) "<\00\00\00\00\00\00\00\00\00\00\00\01\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") (data (i32.const 76) "<\00\00\00\00\00\00\00\00\00\00\00\01\00\00\00 \00\00\00~\00l\00i\00b\00/\00r\00t\00/\00i\00t\00c\00m\00s\00.\00t\00s\00\00\00\00\00\00\00\00\00\00\00\00\00") @@ -41,7 +45,7 @@ (data (i32.const 320) "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00") (data (i32.const 348) "<\00\00\00\00\00\00\00\00\00\00\00\01\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 412) "<\00\00\00\00\00\00\00\00\00\00\00\01\00\00\00&\00\00\00c\00l\00a\00s\00s\00-\00i\00m\00p\00l\00e\00m\00e\00n\00t\00s\00.\00t\00s\00\00\00\00\00\00\00") - (data (i32.const 480) "\0c\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\00\00\00\00 \00\00\00\00\00\00\00 \00\00\00\06\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\00\00\00 \00\00\00\00\00\00\00 \00\00\00\00\00\00\00") + (data (i32.const 480) "\10\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\00\00\00\00 \00\00\00\00\00\00\00 \00\00\00\06\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\00\00\00 \00\00\00\00\00\00\00 \00\00\00\00\00\00\00 \00\00\00\t\00\00\00 \00\00\00\t\00\00\00 \00\00\00\07\00\00\00 \00\00\00\07\00\00\00") (table $0 1 1 funcref) (elem $0 (i32.const 1)) (export "memory" (memory $0)) @@ -2132,6 +2136,44 @@ local.get $1 i32.store $0 ) + (func $class-implements/E#get:a (param $0 i32) (result i32) + local.get $0 + i32.load $0 + ) + (func $class-implements/G#set:a (param $0 i32) (param $1 i32) + local.get $0 + local.get $1 + i32.store $0 + ) + (func $class-implements/G#get:a (param $0 i32) (result i32) + local.get $0 + i32.load $0 + ) + (func $class-implements/K#foo (param $this i32) (result i32) + i32.const 4 + ) + (func $class-implements/D#foo@virtual (param $0 i32) (result i32) + (local $1 i32) + block $default + block $case0 + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.set $1 + local.get $1 + i32.const 15 + i32.eq + br_if $case0 + br $default + end + local.get $0 + call $class-implements/K#foo + return + end + local.get $0 + call $class-implements/D#foo + ) (func $~lib/rt/__visit_globals (param $0 i32) (local $1 i32) global.get $class-implements/a @@ -2162,6 +2204,34 @@ local.get $0 call $~lib/rt/itcms/__visit end + global.get $class-implements/f + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $class-implements/g + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $class-implements/h + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $class-implements/k + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end i32.const 224 local.get $0 call $~lib/rt/itcms/__visit @@ -2182,31 +2252,43 @@ ) (func $~lib/rt/__visit_members (param $0 i32) (param $1 i32) block $invalid - block $class-implements/N - block $class-implements/M - block $class-implements/E - block $class-implements/J - block $class-implements/D - block $class-implements/B - block $class-implements/C - block $class-implements/I - block $class-implements/A - block $~lib/arraybuffer/ArrayBufferView - block $~lib/string/String - block $~lib/arraybuffer/ArrayBuffer - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - br_table $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $class-implements/A $class-implements/I $class-implements/C $class-implements/B $class-implements/D $class-implements/J $class-implements/E $class-implements/M $class-implements/N $invalid + block $class-implements/K + block $class-implements/H + block $class-implements/G + block $class-implements/F + block $class-implements/N + block $class-implements/M + block $class-implements/E + block $class-implements/J + block $class-implements/D + block $class-implements/B + block $class-implements/C + block $class-implements/I + block $class-implements/A + block $~lib/arraybuffer/ArrayBufferView + block $~lib/string/String + block $~lib/arraybuffer/ArrayBuffer + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + br_table $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $class-implements/A $class-implements/I $class-implements/C $class-implements/B $class-implements/D $class-implements/J $class-implements/E $class-implements/M $class-implements/N $class-implements/F $class-implements/G $class-implements/H $class-implements/K $invalid + end + return + end + return + end + local.get $0 + local.get $1 + call $~lib/arraybuffer/ArrayBufferView~visit + return + end + return end return end return end - local.get $0 - local.get $1 - call $~lib/arraybuffer/ArrayBufferView~visit return end return @@ -2237,8 +2319,8 @@ global.get $~lib/memory/__data_end i32.lt_s if - i32.const 16992 - i32.const 17040 + i32.const 17024 + i32.const 17072 i32.const 1 i32.const 1 call $~lib/builtins/abort @@ -2247,14 +2329,15 @@ ) (func $start:class-implements (local $0 i32) + (local $1 i32) global.get $~lib/memory/__stack_pointer - i32.const 4 + i32.const 8 i32.sub global.set $~lib/memory/__stack_pointer call $~stack_check global.get $~lib/memory/__stack_pointer - i32.const 0 - i32.store $0 + i64.const 0 + i64.store $0 memory.size $0 i32.const 16 i32.shl @@ -2276,11 +2359,11 @@ call $class-implements/A#constructor global.set $class-implements/a global.get $class-implements/a - local.set $0 + local.set $1 global.get $~lib/memory/__stack_pointer - local.get $0 + local.get $1 i32.store $0 - local.get $0 + local.get $1 call $class-implements/A#foo i32.const 1 i32.eq @@ -2297,11 +2380,11 @@ call $class-implements/C#constructor global.set $class-implements/c global.get $class-implements/c - local.set $0 + local.set $1 global.get $~lib/memory/__stack_pointer - local.get $0 + local.get $1 i32.store $0 - local.get $0 + local.get $1 call $class-implements/C#foo i32.const 2 i32.eq @@ -2318,12 +2401,12 @@ call $class-implements/D#constructor global.set $class-implements/d global.get $class-implements/d - local.set $0 + local.set $1 global.get $~lib/memory/__stack_pointer - local.get $0 + local.get $1 i32.store $0 - local.get $0 - call $class-implements/D#foo + local.get $1 + call $class-implements/D#foo@virtual i32.const 3 i32.eq i32.eqz @@ -2351,8 +2434,92 @@ call $~lib/builtins/abort unreachable end + i32.const 0 + call $class-implements/F#constructor + global.set $class-implements/f global.get $~lib/memory/__stack_pointer + global.get $class-implements/f + local.tee $0 + i32.store $0 offset=4 + local.get $0 i32.const 4 + call $class-implements/E#set:a + local.get $0 + call $class-implements/E#get:a + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 52 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 0 + call $class-implements/G#constructor + global.set $class-implements/g + global.get $~lib/memory/__stack_pointer + global.get $class-implements/g + local.tee $0 + i32.store $0 offset=4 + local.get $0 + i32.const 5 + call $class-implements/G#set:a + local.get $0 + call $class-implements/G#get:a + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 59 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 0 + call $class-implements/H#constructor + global.set $class-implements/h + global.get $class-implements/h + local.set $1 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store $0 + local.get $1 + call $class-implements/D#foo@virtual + i32.const 3 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 65 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 0 + call $class-implements/K#constructor + global.set $class-implements/k + global.get $class-implements/k + local.set $1 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store $0 + local.get $1 + call $class-implements/K#foo + i32.const 4 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 72 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 8 i32.add global.set $~lib/memory/__stack_pointer ) @@ -2504,4 +2671,139 @@ global.set $~lib/memory/__stack_pointer local.get $1 ) + (func $class-implements/F#constructor (param $0 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 $0 + i32.eqz + if + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.const 12 + call $~lib/rt/itcms/__new + local.tee $0 + i32.store $0 + end + global.get $~lib/memory/__stack_pointer + local.get $0 + call $class-implements/E#constructor + local.tee $0 + i32.store $0 + local.get $0 + local.set $1 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $1 + ) + (func $class-implements/G#constructor (param $0 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 $0 + i32.eqz + if + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.const 13 + call $~lib/rt/itcms/__new + local.tee $0 + i32.store $0 + end + global.get $~lib/memory/__stack_pointer + local.get $0 + call $class-implements/E#constructor + local.tee $0 + i32.store $0 + local.get $0 + i32.const 5 + call $class-implements/G#set:a + local.get $0 + local.set $1 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $1 + ) + (func $class-implements/H#constructor (param $0 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 $0 + i32.eqz + if + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.const 14 + call $~lib/rt/itcms/__new + local.tee $0 + i32.store $0 + end + global.get $~lib/memory/__stack_pointer + local.get $0 + call $class-implements/D#constructor + local.tee $0 + i32.store $0 + local.get $0 + local.set $1 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $1 + ) + (func $class-implements/K#constructor (param $0 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 $0 + i32.eqz + if + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.const 15 + call $~lib/rt/itcms/__new + local.tee $0 + i32.store $0 + end + global.get $~lib/memory/__stack_pointer + local.get $0 + call $class-implements/D#constructor + local.tee $0 + i32.store $0 + local.get $0 + 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/class-implements.release.wat b/tests/compiler/class-implements.release.wat index aadf9c0fe6..8610571c65 100644 --- a/tests/compiler/class-implements.release.wat +++ b/tests/compiler/class-implements.release.wat @@ -3,6 +3,7 @@ (type $i32_i32_=>_none (func (param i32 i32))) (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) (type $i32_=>_none (func (param i32))) + (type $i32_=>_i32 (func (param i32) (result i32))) (type $i32_i32_i32_i32_=>_none (func (param i32 i32 i32 i32))) (type $i32_i32_i32_=>_none (func (param i32 i32 i32))) (type $none_=>_i32 (func (result i32))) @@ -21,7 +22,11 @@ (global $class-implements/c (mut i32) (i32.const 0)) (global $class-implements/d (mut i32) (i32.const 0)) (global $class-implements/e (mut i32) (i32.const 0)) - (global $~lib/memory/__stack_pointer (mut i32) (i32.const 17988)) + (global $class-implements/f (mut i32) (i32.const 0)) + (global $class-implements/g (mut i32) (i32.const 0)) + (global $class-implements/h (mut i32) (i32.const 0)) + (global $class-implements/k (mut i32) (i32.const 0)) + (global $~lib/memory/__stack_pointer (mut i32) (i32.const 18020)) (memory $0 1) (data (i32.const 1036) "<") (data (i32.const 1048) "\01\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") @@ -35,8 +40,8 @@ (data (i32.const 1384) "\01\00\00\00\1e\00\00\00~\00l\00i\00b\00/\00r\00t\00/\00t\00l\00s\00f\00.\00t\00s") (data (i32.const 1436) "<") (data (i32.const 1448) "\01\00\00\00&\00\00\00c\00l\00a\00s\00s\00-\00i\00m\00p\00l\00e\00m\00e\00n\00t\00s\00.\00t\00s") - (data (i32.const 1504) "\0c\00\00\00 \00\00\00\00\00\00\00 ") - (data (i32.const 1532) " \00\00\00\00\00\00\00 \00\00\00\00\00\00\00 \00\00\00\06\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\00\00\00 \00\00\00\00\00\00\00 ") + (data (i32.const 1504) "\10\00\00\00 \00\00\00\00\00\00\00 ") + (data (i32.const 1532) " \00\00\00\00\00\00\00 \00\00\00\00\00\00\00 \00\00\00\06\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\00\00\00 \00\00\00\00\00\00\00 \00\00\00\00\00\00\00 \00\00\00\t\00\00\00 \00\00\00\t\00\00\00 \00\00\00\07\00\00\00 \00\00\00\07") (export "memory" (memory $0)) (start $~start) (func $~lib/rt/itcms/visitRoots @@ -66,6 +71,30 @@ local.get $0 call $byn-split-outlined-A$~lib/rt/itcms/__visit end + global.get $class-implements/f + local.tee $0 + if + local.get $0 + call $byn-split-outlined-A$~lib/rt/itcms/__visit + end + global.get $class-implements/g + local.tee $0 + if + local.get $0 + call $byn-split-outlined-A$~lib/rt/itcms/__visit + end + global.get $class-implements/h + local.tee $0 + if + local.get $0 + call $byn-split-outlined-A$~lib/rt/itcms/__visit + end + global.get $class-implements/k + local.tee $0 + if + local.get $0 + call $byn-split-outlined-A$~lib/rt/itcms/__visit + end i32.const 1248 call $byn-split-outlined-A$~lib/rt/itcms/__visit i32.const 1056 @@ -639,10 +668,10 @@ if unreachable end - i32.const 18000 + i32.const 18032 i32.const 0 i32.store $0 - i32.const 19568 + i32.const 19600 i32.const 0 i32.store $0 loop $for-loop|0 @@ -653,7 +682,7 @@ local.get $0 i32.const 2 i32.shl - i32.const 18000 + i32.const 18032 i32.add i32.const 0 i32.store $0 offset=4 @@ -671,7 +700,7 @@ i32.add i32.const 2 i32.shl - i32.const 18000 + i32.const 18032 i32.add i32.const 0 i32.store $0 offset=96 @@ -689,13 +718,13 @@ br $for-loop|0 end end - i32.const 18000 - i32.const 19572 + i32.const 18032 + i32.const 19604 memory.size $0 i32.const 16 i32.shl call $~lib/rt/tlsf/addMemory - i32.const 18000 + i32.const 18032 global.set $~lib/rt/tlsf/ROOT ) (func $~lib/rt/itcms/step (result i32) @@ -780,7 +809,7 @@ local.set $0 loop $while-continue|0 local.get $0 - i32.const 17988 + i32.const 18020 i32.lt_u if local.get $0 @@ -880,7 +909,7 @@ unreachable end local.get $0 - i32.const 17988 + i32.const 18020 i32.lt_u if local.get $0 @@ -903,7 +932,7 @@ i32.const 4 i32.add local.tee $0 - i32.const 17988 + i32.const 18020 i32.ge_u if global.get $~lib/rt/tlsf/ROOT @@ -1399,35 +1428,47 @@ ) (func $~lib/rt/__visit_members (param $0 i32) block $invalid - block $class-implements/N - block $class-implements/M - block $class-implements/E - block $class-implements/J - block $class-implements/D - block $class-implements/B - block $class-implements/C - block $class-implements/I - block $class-implements/A - block $~lib/arraybuffer/ArrayBufferView - block $~lib/string/String - block $~lib/arraybuffer/ArrayBuffer - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - br_table $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $class-implements/A $class-implements/I $class-implements/C $class-implements/B $class-implements/D $class-implements/J $class-implements/E $class-implements/M $class-implements/N $invalid + block $class-implements/K + block $class-implements/H + block $class-implements/G + block $class-implements/F + block $class-implements/N + block $class-implements/M + block $class-implements/E + block $class-implements/J + block $class-implements/D + block $class-implements/B + block $class-implements/C + block $class-implements/I + block $class-implements/A + block $~lib/arraybuffer/ArrayBufferView + block $~lib/string/String + block $~lib/arraybuffer/ArrayBuffer + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + br_table $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $class-implements/A $class-implements/I $class-implements/C $class-implements/B $class-implements/D $class-implements/J $class-implements/E $class-implements/M $class-implements/N $class-implements/F $class-implements/G $class-implements/H $class-implements/K $invalid + end + return + 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 end return 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 @@ -1451,25 +1492,28 @@ unreachable ) (func $~start + call $start:class-implements + ) + (func $start:class-implements (local $0 i32) (local $1 i32) global.get $~lib/memory/__stack_pointer - i32.const 4 + i32.const 8 i32.sub global.set $~lib/memory/__stack_pointer block $folding-inner0 global.get $~lib/memory/__stack_pointer - i32.const 1604 + i32.const 1636 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer local.tee $0 - i32.const 0 - i32.store $0 + i64.const 0 + i64.store $0 memory.size $0 i32.const 16 i32.shl - i32.const 17988 + i32.const 18020 i32.sub i32.const 1 i32.shr_u @@ -1503,7 +1547,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1604 + i32.const 1636 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -1530,7 +1574,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1604 + i32.const 1636 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -1549,7 +1593,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1604 + i32.const 1636 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -1581,12 +1625,56 @@ global.get $~lib/memory/__stack_pointer global.get $class-implements/c i32.store $0 + i32.const 0 + call $class-implements/D#constructor + global.set $class-implements/d + block $__inlined_func$class-implements/D#foo@virtual (result i32) + global.get $~lib/memory/__stack_pointer + global.get $class-implements/d + local.tee $0 + i32.store $0 + i32.const 4 + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + i32.const 15 + i32.eq + br_if $__inlined_func$class-implements/D#foo@virtual + drop + i32.const 3 + end + i32.const 3 + i32.ne + if + i32.const 0 + i32.const 1456 + i32.const 31 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 0 + call $class-implements/E#constructor + global.set $class-implements/e + global.get $class-implements/e + i32.load $0 + i32.const 4 + i32.ne + if + i32.const 0 + i32.const 1456 + i32.const 46 + 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 1604 + i32.const 1636 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -1594,26 +1682,46 @@ i32.const 0 i32.store $0 local.get $0 - i32.const 0 - i32.const 7 + i32.const 4 + i32.const 12 call $~lib/rt/itcms/__new local.tee $0 i32.store $0 global.get $~lib/memory/__stack_pointer + local.get $0 + call $class-implements/E#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 $class-implements/d + global.set $class-implements/f global.get $~lib/memory/__stack_pointer - global.get $class-implements/d + global.get $class-implements/f + local.tee $0 + i32.store $0 offset=4 + local.get $0 + i32.const 4 i32.store $0 + local.get $0 + i32.load $0 + i32.eqz + if + i32.const 0 + i32.const 1456 + i32.const 52 + 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 1604 + i32.const 1636 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -1622,44 +1730,215 @@ i32.store $0 local.get $0 i32.const 4 - i32.const 9 + i32.const 13 call $~lib/rt/itcms/__new local.tee $0 i32.store $0 + global.get $~lib/memory/__stack_pointer local.get $0 - i32.const 4 + call $class-implements/E#constructor + local.tee $0 + i32.store $0 + local.get $0 + i32.const 5 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 $class-implements/e - global.get $class-implements/e + global.set $class-implements/g + global.get $~lib/memory/__stack_pointer + global.get $class-implements/g + local.tee $0 + i32.store $0 offset=4 + local.get $0 + i32.const 5 + i32.store $0 + local.get $0 i32.load $0 + i32.eqz + if + i32.const 0 + i32.const 1456 + i32.const 59 + 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 1636 + 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 0 + i32.const 14 + call $~lib/rt/itcms/__new + local.tee $0 + i32.store $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + call $class-implements/D#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 $class-implements/h + block $__inlined_func$class-implements/D#foo@virtual13 (result i32) + global.get $~lib/memory/__stack_pointer + global.get $class-implements/h + local.tee $0 + i32.store $0 + i32.const 4 + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + i32.const 15 + i32.eq + br_if $__inlined_func$class-implements/D#foo@virtual13 + drop + i32.const 3 + end + i32.const 3 i32.ne if i32.const 0 i32.const 1456 - i32.const 46 + i32.const 65 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 1636 + 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 0 + i32.const 15 + call $~lib/rt/itcms/__new + local.tee $0 + i32.store $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + call $class-implements/D#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 $class-implements/k + global.get $~lib/memory/__stack_pointer + global.get $class-implements/k + i32.store $0 + global.get $~lib/memory/__stack_pointer + i32.const 8 i32.add global.set $~lib/memory/__stack_pointer return end - i32.const 18016 - i32.const 18064 + i32.const 18048 + i32.const 18096 i32.const 1 i32.const 1 call $~lib/builtins/abort unreachable ) + (func $class-implements/D#constructor (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 1636 + i32.lt_s + if + i32.const 18048 + i32.const 18096 + 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 + i32.const 0 + i32.const 7 + 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 $0 + ) + (func $class-implements/E#constructor (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 1636 + i32.lt_s + if + i32.const 18048 + i32.const 18096 + 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 + i32.const 4 + i32.const 9 + call $~lib/rt/itcms/__new + local.tee $0 + i32.store $0 + end + local.get $0 + i32.const 4 + 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 (param $0 i32) (local $1 i32) (local $2 i32) @@ -1705,7 +1984,7 @@ i32.load $0 offset=8 i32.eqz local.get $1 - i32.const 17988 + i32.const 18020 i32.lt_u i32.and i32.eqz diff --git a/tests/compiler/class-implements.ts b/tests/compiler/class-implements.ts index 43cb41bfb9..f09f403a2d 100644 --- a/tests/compiler/class-implements.ts +++ b/tests/compiler/class-implements.ts @@ -44,3 +44,29 @@ class E implements M, N { let e = new E(); assert(e.a == 4); + +class F extends E implements M { +} + +let f = new F(); +assert(f.a = 4); + +class G extends E implements M { + a: i32 = 5; +} + +let g = new G(); +assert(g.a = 5); + +class H extends D implements I { +} + +let h = new H(); +assert(h.foo() == 3); + +class K extends D implements I { + foo(): i32 { return 4; } +} + +let k = new K(); +assert(k.foo() == 4); From 75eeb9661c6eea7f8caf5c89f7fd42f8c4720895 Mon Sep 17 00:00:00 2001 From: chen ruixiang Date: Wed, 7 Sep 2022 14:31:52 +0800 Subject: [PATCH 03/10] fix bootstrap fail issue --- src/program.ts | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/src/program.ts b/src/program.ts index 7a1ebfb8aa..d8df8d03ed 100644 --- a/src/program.ts +++ b/src/program.ts @@ -3015,19 +3015,32 @@ export abstract class DeclaredElement extends Element { // class A implement I, class B extends A implement I let selfField = self; let baseProperty = this.program.resolver.resolveProperty(base); - - if (!selfField.internalGetterSignature - || !baseProperty - || !baseProperty.getterInstance - || !selfField.internalGetterSignature.isAssignableTo(baseProperty.getterInstance.signature)) { + if (!selfField.internalGetterSignature || !selfField.internalSetterSignature || !baseProperty) { return false; } - if (!selfField.internalSetterSignature - || !baseProperty - || !baseProperty.setterInstance - || !selfField.internalSetterSignature.isAssignableTo(baseProperty.setterInstance.signature)) { + let baseGetterInsance = baseProperty.getterInstance; + let baseSetterInsance = baseProperty.setterInstance; + if (baseGetterInsance && baseSetterInsance) { + if (!selfField.internalGetterSignature.isAssignableTo(baseGetterInsance.signature) + || !selfField.internalSetterSignature.isAssignableTo(baseSetterInsance.signature)) { + return false; + } + } else { return false; } + + // if (!selfField.internalGetterSignature + // || !baseProperty + // || !baseProperty.getterInstance + // || !selfField.internalGetterSignature.isAssignableTo(baseProperty.getterInstance.signature)) { + // return false; + // } + // if (!selfField.internalSetterSignature + // || !baseProperty + // || !baseProperty.setterInstance + // || !selfField.internalSetterSignature.isAssignableTo(baseProperty.setterInstance.signature)) { + // return false; + // } return true; } return false; From 4d1f63c75f959cc9b297037aa227f8a429dc644e Mon Sep 17 00:00:00 2001 From: chen ruixiang Date: Wed, 7 Sep 2022 14:32:54 +0800 Subject: [PATCH 04/10] fix: remove refactor code --- src/program.ts | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/program.ts b/src/program.ts index d8df8d03ed..0f25add332 100644 --- a/src/program.ts +++ b/src/program.ts @@ -3028,19 +3028,6 @@ export abstract class DeclaredElement extends Element { } else { return false; } - - // if (!selfField.internalGetterSignature - // || !baseProperty - // || !baseProperty.getterInstance - // || !selfField.internalGetterSignature.isAssignableTo(baseProperty.getterInstance.signature)) { - // return false; - // } - // if (!selfField.internalSetterSignature - // || !baseProperty - // || !baseProperty.setterInstance - // || !selfField.internalSetterSignature.isAssignableTo(baseProperty.setterInstance.signature)) { - // return false; - // } return true; } return false; From 2aa73d86aaf7be61b4eb305dcf8f1169e90ea104 Mon Sep 17 00:00:00 2001 From: dcode Date: Mon, 26 Sep 2022 23:37:20 +0200 Subject: [PATCH 05/10] refactor / fix --- src/program.ts | 92 +++++++++++------------ src/types.ts | 20 +++-- tests/compiler/class-implements.debug.wat | 68 ++++++++--------- 3 files changed, 92 insertions(+), 88 deletions(-) diff --git a/src/program.ts b/src/program.ts index 382aa49542..66dfc81250 100644 --- a/src/program.ts +++ b/src/program.ts @@ -3003,33 +3003,6 @@ export abstract class DeclaredElement extends Element { return this.declaration.decorators; } - /** Determine if two properties are compatibal during override by their getter and setter signature . */ - private _isCampatibalOverrideProperty(selfProperty: Property|null, baseProperty: Property|null, ignoreInheritLineCheck: bool = false): bool { - if (!selfProperty || !baseProperty) { - return false; - } else { - let selfGetter = selfProperty.getterInstance; - let baseGetter = baseProperty.getterInstance; - if (selfGetter) { - if (!baseGetter || !selfGetter.signature.isAssignableTo(baseGetter.signature, true)) { - return false; - } - } else if (baseGetter) { - return false; - } - let selfSetter = selfProperty.setterInstance; - let baseSetter = baseProperty.setterInstance; - if (selfSetter) { - if (!baseSetter || !selfSetter.signature.isAssignableTo(baseSetter.signature, true)) { - return false; - } - } else if (baseSetter) { - return false; - } - } - return true; - } - /** Checks if this element is a compatible override of the specified. */ isCompatibleOverride(base: DeclaredElement): bool { var self: DeclaredElement = this; // TS @@ -3050,35 +3023,58 @@ export abstract class DeclaredElement extends Element { } case ElementKind.PROPERTY_PROTOTYPE: { let selfProperty = this.program.resolver.resolveProperty(self); + if (!selfProperty) return false; let baseProperty = this.program.resolver.resolveProperty(base); - return this._isCampatibalOverrideProperty(selfProperty, baseProperty, true); + if (!baseProperty) return false; + self = selfProperty; + base = baseProperty; + // fall-through } case ElementKind.PROPERTY: { let selfProperty = self; let baseProperty = base; - return self._isCampatibalOverrideProperty(selfProperty, baseProperty); - } - } - } - if (self.kind == ElementKind.FIELD && base.kind == ElementKind.PROPERTY_PROTOTYPE) { - // class A implement I, class B extends A implement I - let selfField = self; - let baseProperty = this.program.resolver.resolveProperty(base); - if (!selfField.internalGetterSignature || !selfField.internalSetterSignature || !baseProperty) { - return false; - } - let baseGetterInsance = baseProperty.getterInstance; - let baseSetterInsance = baseProperty.setterInstance; - if (baseGetterInsance && baseSetterInsance) { - if (!selfField.internalGetterSignature.isAssignableTo(baseGetterInsance.signature) - || !selfField.internalSetterSignature.isAssignableTo(baseSetterInsance.signature)) { - return false; + let selfGetter = selfProperty.getterInstance; + let baseGetter = baseProperty.getterInstance; + if (selfGetter) { + if (!baseGetter || !selfGetter.signature.isAssignableTo(baseGetter.signature, true)) { + return false; + } + } else if (baseGetter) { + return false; + } + let selfSetter = selfProperty.setterInstance; + let baseSetter = baseProperty.setterInstance; + if (selfSetter) { + if (!baseSetter || !selfSetter.signature.isAssignableTo(baseSetter.signature, true)) { + return false; + } + } else if (baseSetter) { + return false; + } + return true; } - } else { - return false; } - return true; } + // TODO: field and property cannot override each other, have different codegen + // if (self.kind == ElementKind.FIELD && base.kind == ElementKind.PROPERTY_PROTOTYPE) { + // // class A implement I, class B extends A implement I + // let selfField = self; + // let baseProperty = this.program.resolver.resolveProperty(base); + // if (!selfField.internalGetterSignature || !selfField.internalSetterSignature || !baseProperty) { + // return false; + // } + // let baseGetterInsance = baseProperty.getterInstance; + // let baseSetterInsance = baseProperty.setterInstance; + // if (baseGetterInsance && baseSetterInsance) { + // if (!selfField.internalGetterSignature.isAssignableTo(baseGetterInsance.signature) + // || !selfField.internalSetterSignature.isAssignableTo(baseSetterInsance.signature)) { + // return false; + // } + // } else { + // return false; + // } + // return true; + // } return false; } } diff --git a/src/types.ts b/src/types.ts index 8e998cae34..41f77a9052 100644 --- a/src/types.ts +++ b/src/types.ts @@ -926,12 +926,11 @@ export class Signature { } /** Tests if a value of this function type is assignable to a target of the specified function type. */ - isAssignableTo(target: Signature, ignoreInheritLineCheck: bool = false): bool { - - if (!ignoreInheritLineCheck) { - // check `this` type - var thisThisType = this.thisType; - var targetThisType = target.thisType; + isAssignableTo(target: Signature, checkCompatibleOverride: bool = false): bool { + var thisThisType = this.thisType; + var targetThisType = target.thisType; + if (!checkCompatibleOverride) { + // check exact `this` type if (thisThisType) { if (!targetThisType || !thisThisType.isAssignableTo(targetThisType)) { return false; @@ -939,6 +938,15 @@ export class Signature { } else if (targetThisType) { return false; } + } else { + // check kind of `this` type + if (thisThisType) { + if (!targetThisType || thisThisType.kind != targetThisType.kind || thisThisType.isReference != targetThisType.isReference) { + return false; + } + } else if (targetThisType) { + return false; + } } // check rest parameter diff --git a/tests/compiler/class-implements.debug.wat b/tests/compiler/class-implements.debug.wat index d88dde7271..945a3b71d6 100644 --- a/tests/compiler/class-implements.debug.wat +++ b/tests/compiler/class-implements.debug.wat @@ -2612,7 +2612,7 @@ global.set $~lib/memory/__stack_pointer local.get $1 ) - (func $class-implements/D#constructor (param $0 i32) (result i32) + (func $class-implements/D#constructor (param $this i32) (result i32) (local $1 i32) global.get $~lib/memory/__stack_pointer i32.const 4 @@ -2622,17 +2622,17 @@ global.get $~lib/memory/__stack_pointer i32.const 0 i32.store $0 - local.get $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 $0 + local.tee $this i32.store $0 end - local.get $0 + local.get $this local.set $1 global.get $~lib/memory/__stack_pointer i32.const 4 @@ -2640,7 +2640,7 @@ global.set $~lib/memory/__stack_pointer local.get $1 ) - (func $class-implements/E#constructor (param $0 i32) (result i32) + (func $class-implements/E#constructor (param $this i32) (result i32) (local $1 i32) global.get $~lib/memory/__stack_pointer i32.const 4 @@ -2650,20 +2650,20 @@ global.get $~lib/memory/__stack_pointer i32.const 0 i32.store $0 - local.get $0 + local.get $this i32.eqz if global.get $~lib/memory/__stack_pointer i32.const 4 i32.const 9 call $~lib/rt/itcms/__new - local.tee $0 + local.tee $this i32.store $0 end - local.get $0 + local.get $this i32.const 4 call $class-implements/E#set:a - local.get $0 + local.get $this local.set $1 global.get $~lib/memory/__stack_pointer i32.const 4 @@ -2671,7 +2671,7 @@ global.set $~lib/memory/__stack_pointer local.get $1 ) - (func $class-implements/F#constructor (param $0 i32) (result i32) + (func $class-implements/F#constructor (param $this i32) (result i32) (local $1 i32) global.get $~lib/memory/__stack_pointer i32.const 4 @@ -2681,22 +2681,22 @@ global.get $~lib/memory/__stack_pointer i32.const 0 i32.store $0 - local.get $0 + local.get $this i32.eqz if global.get $~lib/memory/__stack_pointer i32.const 4 i32.const 12 call $~lib/rt/itcms/__new - local.tee $0 + local.tee $this i32.store $0 end global.get $~lib/memory/__stack_pointer - local.get $0 + local.get $this call $class-implements/E#constructor - local.tee $0 + local.tee $this i32.store $0 - local.get $0 + local.get $this local.set $1 global.get $~lib/memory/__stack_pointer i32.const 4 @@ -2704,7 +2704,7 @@ global.set $~lib/memory/__stack_pointer local.get $1 ) - (func $class-implements/G#constructor (param $0 i32) (result i32) + (func $class-implements/G#constructor (param $this i32) (result i32) (local $1 i32) global.get $~lib/memory/__stack_pointer i32.const 4 @@ -2714,25 +2714,25 @@ global.get $~lib/memory/__stack_pointer i32.const 0 i32.store $0 - local.get $0 + local.get $this i32.eqz if global.get $~lib/memory/__stack_pointer i32.const 4 i32.const 13 call $~lib/rt/itcms/__new - local.tee $0 + local.tee $this i32.store $0 end global.get $~lib/memory/__stack_pointer - local.get $0 + local.get $this call $class-implements/E#constructor - local.tee $0 + local.tee $this i32.store $0 - local.get $0 + local.get $this i32.const 5 call $class-implements/G#set:a - local.get $0 + local.get $this local.set $1 global.get $~lib/memory/__stack_pointer i32.const 4 @@ -2740,7 +2740,7 @@ global.set $~lib/memory/__stack_pointer local.get $1 ) - (func $class-implements/H#constructor (param $0 i32) (result i32) + (func $class-implements/H#constructor (param $this i32) (result i32) (local $1 i32) global.get $~lib/memory/__stack_pointer i32.const 4 @@ -2750,22 +2750,22 @@ global.get $~lib/memory/__stack_pointer i32.const 0 i32.store $0 - local.get $0 + local.get $this i32.eqz if global.get $~lib/memory/__stack_pointer i32.const 0 i32.const 14 call $~lib/rt/itcms/__new - local.tee $0 + local.tee $this i32.store $0 end global.get $~lib/memory/__stack_pointer - local.get $0 + local.get $this call $class-implements/D#constructor - local.tee $0 + local.tee $this i32.store $0 - local.get $0 + local.get $this local.set $1 global.get $~lib/memory/__stack_pointer i32.const 4 @@ -2773,7 +2773,7 @@ global.set $~lib/memory/__stack_pointer local.get $1 ) - (func $class-implements/K#constructor (param $0 i32) (result i32) + (func $class-implements/K#constructor (param $this i32) (result i32) (local $1 i32) global.get $~lib/memory/__stack_pointer i32.const 4 @@ -2783,22 +2783,22 @@ global.get $~lib/memory/__stack_pointer i32.const 0 i32.store $0 - local.get $0 + local.get $this i32.eqz if global.get $~lib/memory/__stack_pointer i32.const 0 i32.const 15 call $~lib/rt/itcms/__new - local.tee $0 + local.tee $this i32.store $0 end global.get $~lib/memory/__stack_pointer - local.get $0 + local.get $this call $class-implements/D#constructor - local.tee $0 + local.tee $this i32.store $0 - local.get $0 + local.get $this local.set $1 global.get $~lib/memory/__stack_pointer i32.const 4 From 5798aaa4b2f422fce188762aa91d60a76ae7e4c2 Mon Sep 17 00:00:00 2001 From: chen ruixiang Date: Tue, 27 Sep 2022 16:25:54 +0800 Subject: [PATCH 06/10] fix: modify the test --- tests/compiler/class-implements.debug.wat | 357 ++++------- tests/compiler/class-implements.release.wat | 650 +++++++------------- tests/compiler/class-implements.ts | 40 +- 3 files changed, 343 insertions(+), 704 deletions(-) diff --git a/tests/compiler/class-implements.debug.wat b/tests/compiler/class-implements.debug.wat index 945a3b71d6..7406a835b8 100644 --- a/tests/compiler/class-implements.debug.wat +++ b/tests/compiler/class-implements.debug.wat @@ -30,11 +30,10 @@ (global $class-implements/f (mut i32) (i32.const 0)) (global $class-implements/g (mut i32) (i32.const 0)) (global $class-implements/h (mut i32) (i32.const 0)) - (global $class-implements/k (mut i32) (i32.const 0)) (global $~lib/rt/__rtti_base i32 (i32.const 480)) - (global $~lib/memory/__data_end i32 (i32.const 612)) - (global $~lib/memory/__stack_pointer (mut i32) (i32.const 16996)) - (global $~lib/memory/__heap_base i32 (i32.const 16996)) + (global $~lib/memory/__data_end i32 (i32.const 572)) + (global $~lib/memory/__stack_pointer (mut i32) (i32.const 16956)) + (global $~lib/memory/__heap_base i32 (i32.const 16956)) (memory $0 1) (data (i32.const 12) "<\00\00\00\00\00\00\00\00\00\00\00\01\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") (data (i32.const 76) "<\00\00\00\00\00\00\00\00\00\00\00\01\00\00\00 \00\00\00~\00l\00i\00b\00/\00r\00t\00/\00i\00t\00c\00m\00s\00.\00t\00s\00\00\00\00\00\00\00\00\00\00\00\00\00") @@ -45,7 +44,7 @@ (data (i32.const 320) "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00") (data (i32.const 348) "<\00\00\00\00\00\00\00\00\00\00\00\01\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 412) "<\00\00\00\00\00\00\00\00\00\00\00\01\00\00\00&\00\00\00c\00l\00a\00s\00s\00-\00i\00m\00p\00l\00e\00m\00e\00n\00t\00s\00.\00t\00s\00\00\00\00\00\00\00") - (data (i32.const 480) "\10\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\00\00\00\00 \00\00\00\00\00\00\00 \00\00\00\06\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\00\00\00 \00\00\00\00\00\00\00 \00\00\00\00\00\00\00 \00\00\00\t\00\00\00 \00\00\00\t\00\00\00 \00\00\00\07\00\00\00 \00\00\00\07\00\00\00") + (data (i32.const 480) "\0b\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\00\00\00\00 \00\00\00\00\00\00\00 \00\00\00\06\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\07\00\00\00 \00\00\00\07\00\00\00") (table $0 1 1 funcref) (elem $0 (i32.const 1)) (export "memory" (memory $0)) @@ -2131,27 +2130,12 @@ (func $class-implements/D#foo (param $this i32) (result i32) i32.const 3 ) - (func $class-implements/E#set:a (param $0 i32) (param $1 i32) - local.get $0 - local.get $1 - i32.store $0 - ) - (func $class-implements/E#get:a (param $0 i32) (result i32) - local.get $0 - i32.load $0 - ) - (func $class-implements/G#set:a (param $0 i32) (param $1 i32) - local.get $0 - local.get $1 - i32.store $0 - ) - (func $class-implements/G#get:a (param $0 i32) (result i32) - local.get $0 - i32.load $0 - ) - (func $class-implements/K#foo (param $this i32) (result i32) + (func $class-implements/F#foo (param $this i32) (result i32) i32.const 4 ) + (func $class-implements/I#foo (param $this i32) (result i32) + unreachable + ) (func $class-implements/D#foo@virtual (param $0 i32) (result i32) (local $1 i32) block $default @@ -2162,18 +2146,70 @@ i32.load $0 local.set $1 local.get $1 - i32.const 15 + i32.const 10 i32.eq br_if $case0 br $default end local.get $0 - call $class-implements/K#foo + call $class-implements/F#foo return end local.get $0 call $class-implements/D#foo ) + (func $class-implements/I#foo@virtual (param $0 i32) (result i32) + (local $1 i32) + block $default + block $case3 + block $case2 + block $case1 + block $case0 + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.set $1 + local.get $1 + i32.const 3 + i32.eq + br_if $case0 + local.get $1 + i32.const 5 + i32.eq + br_if $case1 + local.get $1 + i32.const 7 + i32.eq + br_if $case2 + local.get $1 + i32.const 9 + i32.eq + br_if $case2 + local.get $1 + i32.const 10 + i32.eq + br_if $case3 + br $default + end + local.get $0 + call $class-implements/A#foo + return + end + local.get $0 + call $class-implements/C#foo + return + end + local.get $0 + call $class-implements/D#foo + return + end + local.get $0 + call $class-implements/F#foo + return + end + unreachable + ) (func $~lib/rt/__visit_globals (param $0 i32) (local $1 i32) global.get $class-implements/a @@ -2225,13 +2261,6 @@ local.get $0 call $~lib/rt/itcms/__visit end - global.get $class-implements/k - local.tee $1 - if - local.get $1 - local.get $0 - call $~lib/rt/itcms/__visit - end i32.const 224 local.get $0 call $~lib/rt/itcms/__visit @@ -2252,45 +2281,30 @@ ) (func $~lib/rt/__visit_members (param $0 i32) (param $1 i32) block $invalid - block $class-implements/K - block $class-implements/H - block $class-implements/G - block $class-implements/F - block $class-implements/N - block $class-implements/M - block $class-implements/E - block $class-implements/J - block $class-implements/D - block $class-implements/B - block $class-implements/C - block $class-implements/I - block $class-implements/A - block $~lib/arraybuffer/ArrayBufferView - block $~lib/string/String - block $~lib/arraybuffer/ArrayBuffer - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - br_table $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $class-implements/A $class-implements/I $class-implements/C $class-implements/B $class-implements/D $class-implements/J $class-implements/E $class-implements/M $class-implements/N $class-implements/F $class-implements/G $class-implements/H $class-implements/K $invalid - end - return - end - return - end - local.get $0 - local.get $1 - call $~lib/arraybuffer/ArrayBufferView~visit - return - end - return - end - return + block $class-implements/F + block $class-implements/E + block $class-implements/J + block $class-implements/D + block $class-implements/B + block $class-implements/C + block $class-implements/I + block $class-implements/A + block $~lib/arraybuffer/ArrayBufferView + block $~lib/string/String + block $~lib/arraybuffer/ArrayBuffer + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + br_table $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $class-implements/A $class-implements/I $class-implements/C $class-implements/B $class-implements/D $class-implements/J $class-implements/E $class-implements/F $invalid end return end return end + local.get $0 + local.get $1 + call $~lib/arraybuffer/ArrayBufferView~visit return end return @@ -2319,8 +2333,8 @@ global.get $~lib/memory/__data_end i32.lt_s if + i32.const 16976 i32.const 17024 - i32.const 17072 i32.const 1 i32.const 1 call $~lib/builtins/abort @@ -2329,15 +2343,14 @@ ) (func $start:class-implements (local $0 i32) - (local $1 i32) global.get $~lib/memory/__stack_pointer - i32.const 8 + i32.const 4 i32.sub global.set $~lib/memory/__stack_pointer call $~stack_check global.get $~lib/memory/__stack_pointer - i64.const 0 - i64.store $0 + i32.const 0 + i32.store $0 memory.size $0 i32.const 16 i32.shl @@ -2359,11 +2372,11 @@ call $class-implements/A#constructor global.set $class-implements/a global.get $class-implements/a - local.set $1 + local.set $0 global.get $~lib/memory/__stack_pointer - local.get $1 + local.get $0 i32.store $0 - local.get $1 + local.get $0 call $class-implements/A#foo i32.const 1 i32.eq @@ -2380,11 +2393,11 @@ call $class-implements/C#constructor global.set $class-implements/c global.get $class-implements/c - local.set $1 + local.set $0 global.get $~lib/memory/__stack_pointer - local.get $1 + local.get $0 i32.store $0 - local.get $1 + local.get $0 call $class-implements/C#foo i32.const 2 i32.eq @@ -2401,11 +2414,11 @@ call $class-implements/D#constructor global.set $class-implements/d global.get $class-implements/d - local.set $1 + local.set $0 global.get $~lib/memory/__stack_pointer - local.get $1 + local.get $0 i32.store $0 - local.get $1 + local.get $0 call $class-implements/D#foo@virtual i32.const 3 i32.eq @@ -2422,14 +2435,19 @@ call $class-implements/E#constructor global.set $class-implements/e global.get $class-implements/e - i32.load $0 - i32.const 4 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store $0 + local.get $0 + call $class-implements/D#foo@virtual + i32.const 3 i32.eq i32.eqz if i32.const 0 i32.const 432 - i32.const 46 + i32.const 37 i32.const 1 call $~lib/builtins/abort unreachable @@ -2437,89 +2455,68 @@ i32.const 0 call $class-implements/F#constructor global.set $class-implements/f - global.get $~lib/memory/__stack_pointer global.get $class-implements/f - local.tee $0 - i32.store $0 offset=4 + local.set $0 + global.get $~lib/memory/__stack_pointer local.get $0 - i32.const 4 - call $class-implements/E#set:a + i32.store $0 local.get $0 - call $class-implements/E#get:a + call $class-implements/F#foo + i32.const 4 + i32.eq i32.eqz if i32.const 0 i32.const 432 - i32.const 52 + i32.const 44 i32.const 1 call $~lib/builtins/abort unreachable end i32.const 0 - call $class-implements/G#constructor + call $class-implements/F#constructor global.set $class-implements/g - global.get $~lib/memory/__stack_pointer global.get $class-implements/g - local.tee $0 - i32.store $0 offset=4 - local.get $0 - i32.const 5 - call $class-implements/G#set:a - local.get $0 - call $class-implements/G#get:a - i32.eqz - if - i32.const 0 - i32.const 432 - i32.const 59 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const 0 - call $class-implements/H#constructor - global.set $class-implements/h - global.get $class-implements/h - local.set $1 + local.set $0 global.get $~lib/memory/__stack_pointer - local.get $1 + local.get $0 i32.store $0 - local.get $1 + local.get $0 call $class-implements/D#foo@virtual - i32.const 3 + i32.const 4 i32.eq i32.eqz if i32.const 0 i32.const 432 - i32.const 65 + i32.const 47 i32.const 1 call $~lib/builtins/abort unreachable end i32.const 0 - call $class-implements/K#constructor - global.set $class-implements/k - global.get $class-implements/k - local.set $1 + call $class-implements/F#constructor + global.set $class-implements/h + global.get $class-implements/h + local.set $0 global.get $~lib/memory/__stack_pointer - local.get $1 + local.get $0 i32.store $0 - local.get $1 - call $class-implements/K#foo + local.get $0 + call $class-implements/I#foo@virtual i32.const 4 i32.eq i32.eqz if i32.const 0 i32.const 432 - i32.const 72 + i32.const 50 i32.const 1 call $~lib/builtins/abort unreachable end global.get $~lib/memory/__stack_pointer - i32.const 8 + i32.const 4 i32.add global.set $~lib/memory/__stack_pointer ) @@ -2641,106 +2638,6 @@ local.get $1 ) (func $class-implements/E#constructor (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 4 - i32.const 9 - call $~lib/rt/itcms/__new - local.tee $this - i32.store $0 - end - local.get $this - i32.const 4 - call $class-implements/E#set:a - 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 $class-implements/F#constructor (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 4 - i32.const 12 - call $~lib/rt/itcms/__new - local.tee $this - i32.store $0 - end - global.get $~lib/memory/__stack_pointer - local.get $this - call $class-implements/E#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 $class-implements/G#constructor (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 4 - i32.const 13 - call $~lib/rt/itcms/__new - local.tee $this - i32.store $0 - end - global.get $~lib/memory/__stack_pointer - local.get $this - call $class-implements/E#constructor - local.tee $this - i32.store $0 - local.get $this - i32.const 5 - call $class-implements/G#set:a - 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 $class-implements/H#constructor (param $this i32) (result i32) (local $1 i32) global.get $~lib/memory/__stack_pointer i32.const 4 @@ -2755,7 +2652,7 @@ if global.get $~lib/memory/__stack_pointer i32.const 0 - i32.const 14 + i32.const 9 call $~lib/rt/itcms/__new local.tee $this i32.store $0 @@ -2773,7 +2670,7 @@ global.set $~lib/memory/__stack_pointer local.get $1 ) - (func $class-implements/K#constructor (param $this i32) (result i32) + (func $class-implements/F#constructor (param $this i32) (result i32) (local $1 i32) global.get $~lib/memory/__stack_pointer i32.const 4 @@ -2788,7 +2685,7 @@ if global.get $~lib/memory/__stack_pointer i32.const 0 - i32.const 15 + i32.const 10 call $~lib/rt/itcms/__new local.tee $this i32.store $0 diff --git a/tests/compiler/class-implements.release.wat b/tests/compiler/class-implements.release.wat index 5224287c15..986afde582 100644 --- a/tests/compiler/class-implements.release.wat +++ b/tests/compiler/class-implements.release.wat @@ -1,12 +1,11 @@ (module (type $none_=>_none (func)) + (type $i32_=>_i32 (func (param i32) (result i32))) (type $i32_i32_=>_none (func (param i32 i32))) - (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) + (type $none_=>_i32 (func (result i32))) (type $i32_=>_none (func (param i32))) - (type $i32_=>_i32 (func (param i32) (result i32))) (type $i32_i32_i32_i32_=>_none (func (param i32 i32 i32 i32))) (type $i32_i32_i32_=>_none (func (param i32 i32 i32))) - (type $none_=>_i32 (func (result i32))) (import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32))) (global $~lib/rt/itcms/total (mut i32) (i32.const 0)) (global $~lib/rt/itcms/threshold (mut i32) (i32.const 0)) @@ -25,8 +24,7 @@ (global $class-implements/f (mut i32) (i32.const 0)) (global $class-implements/g (mut i32) (i32.const 0)) (global $class-implements/h (mut i32) (i32.const 0)) - (global $class-implements/k (mut i32) (i32.const 0)) - (global $~lib/memory/__stack_pointer (mut i32) (i32.const 18020)) + (global $~lib/memory/__stack_pointer (mut i32) (i32.const 17980)) (memory $0 1) (data (i32.const 1036) "<") (data (i32.const 1048) "\01\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") @@ -40,8 +38,8 @@ (data (i32.const 1384) "\01\00\00\00\1e\00\00\00~\00l\00i\00b\00/\00r\00t\00/\00t\00l\00s\00f\00.\00t\00s") (data (i32.const 1436) "<") (data (i32.const 1448) "\01\00\00\00&\00\00\00c\00l\00a\00s\00s\00-\00i\00m\00p\00l\00e\00m\00e\00n\00t\00s\00.\00t\00s") - (data (i32.const 1504) "\10\00\00\00 \00\00\00\00\00\00\00 ") - (data (i32.const 1532) " \00\00\00\00\00\00\00 \00\00\00\00\00\00\00 \00\00\00\06\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\00\00\00 \00\00\00\00\00\00\00 \00\00\00\00\00\00\00 \00\00\00\t\00\00\00 \00\00\00\t\00\00\00 \00\00\00\07\00\00\00 \00\00\00\07") + (data (i32.const 1504) "\0b\00\00\00 \00\00\00\00\00\00\00 ") + (data (i32.const 1532) " \00\00\00\00\00\00\00 \00\00\00\00\00\00\00 \00\00\00\06\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\07\00\00\00 \00\00\00\07") (export "memory" (memory $0)) (start $~start) (func $~lib/rt/itcms/visitRoots @@ -89,12 +87,6 @@ local.get $0 call $byn-split-outlined-A$~lib/rt/itcms/__visit end - global.get $class-implements/k - local.tee $0 - if - local.get $0 - call $byn-split-outlined-A$~lib/rt/itcms/__visit - end i32.const 1248 call $byn-split-outlined-A$~lib/rt/itcms/__visit i32.const 1056 @@ -179,11 +171,11 @@ i32.shr_u else i32.const 31 - i32.const 1073741820 local.get $2 + i32.const 1073741820 local.get $2 i32.const 1073741820 - i32.ge_u + i32.lt_u select local.tee $2 i32.clz @@ -443,11 +435,11 @@ i32.shr_u else i32.const 31 - i32.const 1073741820 local.get $2 + i32.const 1073741820 local.get $2 i32.const 1073741820 - i32.ge_u + i32.lt_u select local.tee $2 i32.clz @@ -668,10 +660,10 @@ if unreachable end - i32.const 18032 + i32.const 17984 i32.const 0 i32.store $0 - i32.const 19600 + i32.const 19552 i32.const 0 i32.store $0 loop $for-loop|0 @@ -682,7 +674,7 @@ local.get $0 i32.const 2 i32.shl - i32.const 18032 + i32.const 17984 i32.add i32.const 0 i32.store $0 offset=4 @@ -700,7 +692,7 @@ i32.add i32.const 2 i32.shl - i32.const 18032 + i32.const 17984 i32.add i32.const 0 i32.store $0 offset=96 @@ -718,13 +710,13 @@ br $for-loop|0 end end - i32.const 18032 - i32.const 19604 + i32.const 17984 + i32.const 19556 memory.size $0 i32.const 16 i32.shl call $~lib/rt/tlsf/addMemory - i32.const 18032 + i32.const 17984 global.set $~lib/rt/tlsf/ROOT ) (func $~lib/rt/itcms/step (result i32) @@ -809,7 +801,7 @@ local.set $0 loop $while-continue|0 local.get $0 - i32.const 18020 + i32.const 17980 i32.lt_u if local.get $0 @@ -909,7 +901,7 @@ unreachable end local.get $0 - i32.const 18020 + i32.const 17980 i32.lt_u if local.get $0 @@ -932,7 +924,7 @@ i32.const 4 i32.add local.tee $0 - i32.const 18020 + i32.const 17980 i32.ge_u if global.get $~lib/rt/tlsf/ROOT @@ -994,83 +986,18 @@ end i32.const 0 ) - (func $~lib/rt/tlsf/searchBlock (param $0 i32) (param $1 i32) (result i32) + (func $~lib/rt/tlsf/searchBlock (param $0 i32) (result i32) + (local $1 i32) (local $2 i32) - (local $3 i32) - local.get $1 - i32.const 256 - i32.lt_u - if (result i32) - local.get $1 - i32.const 4 - i32.shr_u - else - i32.const 31 - local.get $1 - i32.const 1 - i32.const 27 - local.get $1 - i32.clz - i32.sub - i32.shl - i32.add - i32.const 1 - i32.sub - local.get $1 - local.get $1 - i32.const 536870910 - i32.lt_u - select - local.tee $1 - i32.clz - i32.sub - local.tee $3 - i32.const 7 - i32.sub - local.set $2 - local.get $1 - local.get $3 - i32.const 4 - i32.sub - i32.shr_u - i32.const 16 - i32.xor - end - local.tee $1 - i32.const 16 - i32.lt_u - local.get $2 - i32.const 23 - i32.lt_u - i32.and - i32.eqz - if - i32.const 0 - i32.const 1392 - i32.const 330 - i32.const 14 - call $~lib/builtins/abort - unreachable - end local.get $0 - local.get $2 - i32.const 2 - i32.shl - i32.add i32.load $0 offset=4 - i32.const -1 - local.get $1 - i32.shl + i32.const -2 i32.and local.tee $1 if (result i32) local.get $0 local.get $1 i32.ctz - local.get $2 - i32.const 4 - i32.shl - i32.add i32.const 2 i32.shl i32.add @@ -1078,23 +1005,19 @@ else local.get $0 i32.load $0 - i32.const -1 - local.get $2 - i32.const 1 - i32.add - i32.shl + i32.const -2 i32.and local.tee $1 if (result i32) local.get $0 local.get $1 i32.ctz - local.tee $1 + local.tee $2 i32.const 2 i32.shl i32.add i32.load $0 offset=4 - local.tee $2 + local.tee $1 i32.eqz if i32.const 0 @@ -1105,9 +1028,9 @@ unreachable end local.get $0 - local.get $2 - i32.ctz local.get $1 + i32.ctz + local.get $2 i32.const 4 i32.shl i32.add @@ -1120,35 +1043,23 @@ end end ) - (func $~lib/rt/itcms/__new (param $0 i32) (param $1 i32) (result i32) + (func $~lib/rt/itcms/__new (param $0 i32) (result i32) + (local $1 i32) (local $2 i32) (local $3 i32) (local $4 i32) - (local $5 i32) - (local $6 i32) - local.get $0 - i32.const 1073741804 - i32.ge_u - if - i32.const 1056 - i32.const 1120 - i32.const 260 - i32.const 31 - call $~lib/builtins/abort - unreachable - end global.get $~lib/rt/itcms/total global.get $~lib/rt/itcms/threshold i32.ge_u if block $__inlined_func$~lib/rt/itcms/interrupt i32.const 2048 - local.set $2 + local.set $1 loop $do-loop|0 - local.get $2 + local.get $1 call $~lib/rt/itcms/step i32.sub - local.set $2 + local.set $1 global.get $~lib/rt/itcms/state i32.eqz if @@ -1164,14 +1075,14 @@ global.set $~lib/rt/itcms/threshold br $__inlined_func$~lib/rt/itcms/interrupt end - local.get $2 + local.get $1 i32.const 0 i32.gt_s br_if $do-loop|0 end global.get $~lib/rt/itcms/total - local.tee $2 - local.get $2 + local.tee $1 + local.get $1 global.get $~lib/rt/itcms/threshold i32.sub i32.const 1024 @@ -1188,75 +1099,31 @@ call $~lib/rt/tlsf/initialize end global.get $~lib/rt/tlsf/ROOT - local.set $4 - local.get $0 - i32.const 16 - i32.add local.tee $2 - i32.const 1073741820 - i32.gt_u - if - i32.const 1056 - i32.const 1392 - i32.const 458 - i32.const 29 - call $~lib/builtins/abort - unreachable - end - local.get $4 - i32.const 12 - local.get $2 - i32.const 19 - i32.add - i32.const -16 - i32.and - i32.const 4 - i32.sub - local.get $2 - i32.const 12 - i32.le_u - select - local.tee $5 call $~lib/rt/tlsf/searchBlock - local.tee $2 + local.tee $1 i32.eqz if memory.size $0 - local.tee $2 + local.tee $1 i32.const 4 - local.get $4 - i32.load $0 offset=1568 local.get $2 + i32.load $0 offset=1568 + local.get $1 i32.const 16 i32.shl i32.const 4 i32.sub i32.ne i32.shl - local.get $5 - i32.const 1 - i32.const 27 - local.get $5 - i32.clz - i32.sub - i32.shl - i32.const 1 - i32.sub - i32.add - local.get $5 - local.get $5 - i32.const 536870910 - i32.lt_u - select - i32.add - i32.const 65535 + i32.const 65563 i32.add i32.const -65536 i32.and i32.const 16 i32.shr_u local.tee $3 - local.get $2 + local.get $1 local.get $3 i32.gt_s select @@ -1272,18 +1139,17 @@ unreachable end end - local.get $4 local.get $2 + local.get $1 i32.const 16 i32.shl memory.size $0 i32.const 16 i32.shl call $~lib/rt/tlsf/addMemory - local.get $4 - local.get $5 + local.get $2 call $~lib/rt/tlsf/searchBlock - local.tee $2 + local.tee $1 i32.eqz if i32.const 0 @@ -1294,12 +1160,12 @@ unreachable end end - local.get $5 - local.get $2 + local.get $1 i32.load $0 i32.const -4 i32.and - i32.gt_u + i32.const 28 + i32.lt_u if i32.const 0 i32.const 1392 @@ -1308,108 +1174,92 @@ call $~lib/builtins/abort unreachable end - local.get $4 local.get $2 + local.get $1 call $~lib/rt/tlsf/removeBlock - local.get $2 + local.get $1 i32.load $0 - local.set $3 - local.get $5 - i32.const 4 - i32.add - i32.const 15 - i32.and - if - i32.const 0 - i32.const 1392 - i32.const 357 - i32.const 14 - call $~lib/builtins/abort - unreachable - end - local.get $3 + local.tee $4 i32.const -4 i32.and - local.get $5 + i32.const 28 i32.sub - local.tee $6 + local.tee $3 i32.const 16 i32.ge_u if - local.get $2 - local.get $5 - local.get $3 + local.get $1 + local.get $4 i32.const 2 i32.and + i32.const 28 i32.or i32.store $0 - local.get $2 - i32.const 4 - i32.add - local.get $5 + local.get $1 + i32.const 32 i32.add - local.tee $3 - local.get $6 + local.tee $4 + local.get $3 i32.const 4 i32.sub i32.const 1 i32.or i32.store $0 + local.get $2 local.get $4 - local.get $3 call $~lib/rt/tlsf/insertBlock else - local.get $2 - local.get $3 + local.get $1 + local.get $4 i32.const -2 i32.and i32.store $0 - local.get $2 + local.get $1 i32.const 4 i32.add - local.get $2 + local.get $1 i32.load $0 i32.const -4 i32.and i32.add - local.tee $3 - local.get $3 + local.tee $2 + local.get $2 i32.load $0 i32.const -3 i32.and i32.store $0 end - local.get $2 local.get $1 - i32.store $0 offset=12 - local.get $2 local.get $0 + i32.store $0 offset=12 + local.get $1 + i32.const 0 i32.store $0 offset=16 global.get $~lib/rt/itcms/fromSpace - local.tee $1 + local.tee $0 i32.load $0 offset=8 - local.set $3 - local.get $2 + local.set $2 local.get $1 + local.get $0 global.get $~lib/rt/itcms/white i32.or i32.store $0 offset=4 + local.get $1 local.get $2 - local.get $3 i32.store $0 offset=8 - local.get $3 local.get $2 - local.get $3 + local.get $1 + local.get $2 i32.load $0 offset=4 i32.const 3 i32.and i32.or i32.store $0 offset=4 + local.get $0 local.get $1 - local.get $2 i32.store $0 offset=8 global.get $~lib/rt/itcms/total - local.get $2 + local.get $1 i32.load $0 i32.const -4 i32.and @@ -1417,60 +1267,45 @@ i32.add i32.add global.set $~lib/rt/itcms/total - local.get $2 + local.get $1 i32.const 20 i32.add - local.tee $1 + local.tee $0 + i32.const 0 i32.const 0 - local.get $0 memory.fill $0 - local.get $1 + local.get $0 ) (func $~lib/rt/__visit_members (param $0 i32) block $invalid - block $class-implements/K - block $class-implements/H - block $class-implements/G - block $class-implements/F - block $class-implements/N - block $class-implements/M - block $class-implements/E - block $class-implements/J - block $class-implements/D - block $class-implements/B - block $class-implements/C - block $class-implements/I - block $class-implements/A - block $~lib/arraybuffer/ArrayBufferView - block $~lib/string/String - block $~lib/arraybuffer/ArrayBuffer - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - br_table $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $class-implements/A $class-implements/I $class-implements/C $class-implements/B $class-implements/D $class-implements/J $class-implements/E $class-implements/M $class-implements/N $class-implements/F $class-implements/G $class-implements/H $class-implements/K $invalid - end - return - 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 - end - return + block $class-implements/F + block $class-implements/E + block $class-implements/J + block $class-implements/D + block $class-implements/B + block $class-implements/C + block $class-implements/I + block $class-implements/A + block $~lib/arraybuffer/ArrayBufferView + block $~lib/string/String + block $~lib/arraybuffer/ArrayBuffer + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + br_table $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $class-implements/A $class-implements/I $class-implements/C $class-implements/B $class-implements/D $class-implements/J $class-implements/E $class-implements/F $invalid end return 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 @@ -1492,28 +1327,25 @@ unreachable ) (func $~start - call $start:class-implements - ) - (func $start:class-implements (local $0 i32) (local $1 i32) global.get $~lib/memory/__stack_pointer - i32.const 8 + i32.const 4 i32.sub global.set $~lib/memory/__stack_pointer block $folding-inner0 global.get $~lib/memory/__stack_pointer - i32.const 1636 + i32.const 1596 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer local.tee $0 - i64.const 0 - i64.store $0 + i32.const 0 + i32.store $0 memory.size $0 i32.const 16 i32.shl - i32.const 18020 + i32.const 17980 i32.sub i32.const 1 i32.shr_u @@ -1547,7 +1379,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1636 + i32.const 1596 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -1555,7 +1387,6 @@ i32.const 0 i32.store $0 local.get $0 - i32.const 0 i32.const 3 call $~lib/rt/itcms/__new local.tee $0 @@ -1574,7 +1405,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1636 + i32.const 1596 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -1582,7 +1413,6 @@ i32.const 0 i32.store $0 local.get $0 - i32.const 0 i32.const 5 call $~lib/rt/itcms/__new local.tee $0 @@ -1593,7 +1423,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1636 + i32.const 1596 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -1603,7 +1433,6 @@ i32.eqz if global.get $~lib/memory/__stack_pointer - i32.const 0 i32.const 6 call $~lib/rt/itcms/__new local.tee $0 @@ -1638,7 +1467,7 @@ i32.const 8 i32.sub i32.load $0 - i32.const 15 + i32.const 10 i32.eq br_if $__inlined_func$class-implements/D#foo@virtual drop @@ -1654,27 +1483,12 @@ call $~lib/builtins/abort unreachable end - i32.const 0 - call $class-implements/E#constructor - global.set $class-implements/e - global.get $class-implements/e - i32.load $0 - i32.const 4 - i32.ne - if - i32.const 0 - i32.const 1456 - i32.const 46 - 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 1636 + i32.const 1596 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -1682,14 +1496,13 @@ i32.const 0 i32.store $0 local.get $0 - i32.const 4 - i32.const 12 + i32.const 9 call $~lib/rt/itcms/__new local.tee $0 i32.store $0 global.get $~lib/memory/__stack_pointer local.get $0 - call $class-implements/E#constructor + call $class-implements/D#constructor local.tee $0 i32.store $0 global.get $~lib/memory/__stack_pointer @@ -1697,107 +1510,43 @@ i32.add global.set $~lib/memory/__stack_pointer local.get $0 - global.set $class-implements/f - global.get $~lib/memory/__stack_pointer - global.get $class-implements/f - local.tee $0 - i32.store $0 offset=4 - local.get $0 - i32.const 4 - i32.store $0 - local.get $0 - i32.load $0 - i32.eqz - if - i32.const 0 - i32.const 1456 - i32.const 52 - i32.const 1 - call $~lib/builtins/abort - unreachable + global.set $class-implements/e + block $__inlined_func$class-implements/D#foo@virtual9 (result i32) + global.get $~lib/memory/__stack_pointer + global.get $class-implements/e + local.tee $0 + i32.store $0 + i32.const 4 + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + i32.const 10 + i32.eq + br_if $__inlined_func$class-implements/D#foo@virtual9 + drop + i32.const 3 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 1636 - 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 4 - i32.const 13 - call $~lib/rt/itcms/__new - local.tee $0 - i32.store $0 - global.get $~lib/memory/__stack_pointer - local.get $0 - call $class-implements/E#constructor - local.tee $0 - i32.store $0 - local.get $0 - i32.const 5 - 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 $class-implements/g - global.get $~lib/memory/__stack_pointer - global.get $class-implements/g - local.tee $0 - i32.store $0 offset=4 - local.get $0 - i32.const 5 - i32.store $0 - local.get $0 - i32.load $0 - i32.eqz + i32.const 3 + i32.ne if i32.const 0 i32.const 1456 - i32.const 59 + i32.const 37 i32.const 1 call $~lib/builtins/abort unreachable end + call $class-implements/F#constructor + global.set $class-implements/f 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 1636 - 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 0 - i32.const 14 - call $~lib/rt/itcms/__new - local.tee $0 - i32.store $0 - global.get $~lib/memory/__stack_pointer - local.get $0 - call $class-implements/D#constructor - local.tee $0 + global.get $class-implements/f 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 $class-implements/h - block $__inlined_func$class-implements/D#foo@virtual13 (result i32) + call $class-implements/F#constructor + global.set $class-implements/g + block $__inlined_func$class-implements/D#foo@virtual15 (result i32) global.get $~lib/memory/__stack_pointer - global.get $class-implements/h + global.get $class-implements/g local.tee $0 i32.store $0 i32.const 4 @@ -1805,62 +1554,79 @@ i32.const 8 i32.sub i32.load $0 - i32.const 15 + i32.const 10 i32.eq - br_if $__inlined_func$class-implements/D#foo@virtual13 + br_if $__inlined_func$class-implements/D#foo@virtual15 drop i32.const 3 end - i32.const 3 + i32.const 4 i32.ne if i32.const 0 i32.const 1456 - i32.const 65 + i32.const 47 i32.const 1 call $~lib/builtins/abort unreachable end + call $class-implements/F#constructor + global.set $class-implements/h 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 1636 - i32.lt_s - br_if $folding-inner0 - global.get $~lib/memory/__stack_pointer + global.get $class-implements/h local.tee $0 - i32.const 0 i32.store $0 + block $__inlined_func$class-implements/I#foo@virtual + block $default20 + block $case3 + block $case2 + block $case1 + block $case021 + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + i32.const 3 + i32.sub + br_table $case021 $default20 $case1 $default20 $case2 $default20 $case2 $case3 $default20 + end + i32.const 1 + local.set $0 + br $__inlined_func$class-implements/I#foo@virtual + end + i32.const 2 + local.set $0 + br $__inlined_func$class-implements/I#foo@virtual + end + i32.const 3 + local.set $0 + br $__inlined_func$class-implements/I#foo@virtual + end + i32.const 4 + local.set $0 + br $__inlined_func$class-implements/I#foo@virtual + end + unreachable + end local.get $0 - i32.const 0 - i32.const 15 - call $~lib/rt/itcms/__new - local.tee $0 - i32.store $0 - global.get $~lib/memory/__stack_pointer - local.get $0 - call $class-implements/D#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 $class-implements/k - global.get $~lib/memory/__stack_pointer - global.get $class-implements/k - i32.store $0 + i32.ne + if + i32.const 0 + i32.const 1456 + i32.const 50 + i32.const 1 + call $~lib/builtins/abort + unreachable + end global.get $~lib/memory/__stack_pointer - i32.const 8 + i32.const 4 i32.add global.set $~lib/memory/__stack_pointer return end + i32.const 18000 i32.const 18048 - i32.const 18096 i32.const 1 i32.const 1 call $~lib/builtins/abort @@ -1872,11 +1638,11 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1636 + i32.const 1596 i32.lt_s if + i32.const 18000 i32.const 18048 - i32.const 18096 i32.const 1 i32.const 1 call $~lib/builtins/abort @@ -1889,7 +1655,6 @@ i32.eqz if global.get $~lib/memory/__stack_pointer - i32.const 0 i32.const 7 call $~lib/rt/itcms/__new local.tee $0 @@ -1901,37 +1666,36 @@ global.set $~lib/memory/__stack_pointer local.get $0 ) - (func $class-implements/E#constructor (param $0 i32) (result i32) + (func $class-implements/F#constructor (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 1636 + i32.const 1596 i32.lt_s if + i32.const 18000 i32.const 18048 - i32.const 18096 i32.const 1 i32.const 1 call $~lib/builtins/abort unreachable end global.get $~lib/memory/__stack_pointer + local.tee $0 i32.const 0 i32.store $0 local.get $0 - i32.eqz - if - global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.const 9 - call $~lib/rt/itcms/__new - local.tee $0 - i32.store $0 - end + i32.const 10 + call $~lib/rt/itcms/__new + local.tee $0 + i32.store $0 + global.get $~lib/memory/__stack_pointer local.get $0 - i32.const 4 + call $class-implements/D#constructor + local.tee $0 i32.store $0 global.get $~lib/memory/__stack_pointer i32.const 4 @@ -1984,7 +1748,7 @@ i32.load $0 offset=8 i32.eqz local.get $1 - i32.const 18020 + i32.const 17980 i32.lt_u i32.and i32.eqz diff --git a/tests/compiler/class-implements.ts b/tests/compiler/class-implements.ts index f09f403a2d..cc6bfca763 100644 --- a/tests/compiler/class-implements.ts +++ b/tests/compiler/class-implements.ts @@ -30,43 +30,21 @@ class D implements I, J { let d = new D(); assert(d.foo() == 3); -interface M { - a: i32; -} - -interface N { - a: i32; -} - -class E implements M, N { - a: i32 = 4; +class E extends D implements I { } let e = new E(); -assert(e.a == 4); +assert(e.foo() == 3); -class F extends E implements M { +class F extends D implements I { + foo(): i32 { return 4; } } let f = new F(); -assert(f.a = 4); - -class G extends E implements M { - a: i32 = 5; -} +assert(f.foo() == 4); -let g = new G(); -assert(g.a = 5); - -class H extends D implements I { -} - -let h = new H(); -assert(h.foo() == 3); - -class K extends D implements I { - foo(): i32 { return 4; } -} +let g:D = new F(); +assert(g.foo() == 4); -let k = new K(); -assert(k.foo() == 4); +let h:I = new F(); +assert(h.foo() == 4); From 4171ae3ef6c8207cbfb707a734e73ea60f57dc3f Mon Sep 17 00:00:00 2001 From: chen ruixiang Date: Thu, 29 Sep 2022 18:03:29 +0800 Subject: [PATCH 07/10] add more conditions for inherit compatible --- src/types.ts | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/types.ts b/src/types.ts index 41f77a9052..a4b5e45ef9 100644 --- a/src/types.ts +++ b/src/types.ts @@ -6,7 +6,8 @@ import { Class, Program, - DecoratorFlags + DecoratorFlags, + ElementKind } from "./program"; import { @@ -475,6 +476,26 @@ export class Type { return false; } + /** Tests if a value of this class is compatible to the target class / interface in the multi extends / implements situation. */ + isInheritCompatibleTo(target: Type | null): bool { + if (target) { + if (this.isInternalReference && target.isInternalReference && this.isManaged && target.isManaged) { + let thisClass = this.getClass(); + let targetClass = target.getClass(); + if (thisClass && targetClass) { + // extends ThisClass implements TargetInterface + // implements ThisInterface, TargetInterface + if (thisClass.kind == ElementKind.CLASS || thisClass.kind == ElementKind.INTERFACE) { + if (targetClass.kind == ElementKind.INTERFACE) { + return true; + } + } + } + } + } + return false; + } + /** Tests if a value of this type is assignable to the target type excl. implicit conversion. */ isStrictlyAssignableTo(target: Type, signednessIsRelevant: bool = false): bool { if (this.isReference) return this.isAssignableTo(target); @@ -941,7 +962,7 @@ export class Signature { } else { // check kind of `this` type if (thisThisType) { - if (!targetThisType || thisThisType.kind != targetThisType.kind || thisThisType.isReference != targetThisType.isReference) { + if (!thisThisType.isInheritCompatibleTo(targetThisType)) { return false; } } else if (targetThisType) { From 633ce763e232ebaf23f6477cfe7eb8ba649b7695 Mon Sep 17 00:00:00 2001 From: dcode Date: Thu, 6 Oct 2022 05:25:04 +0200 Subject: [PATCH 08/10] refactor --- src/program.ts | 23 +++++++++++++++-------- src/types.ts | 46 +++++++++++++++++++++++----------------------- 2 files changed, 38 insertions(+), 31 deletions(-) diff --git a/src/program.ts b/src/program.ts index 66dfc81250..f41df72e75 100644 --- a/src/program.ts +++ b/src/program.ts @@ -3007,19 +3007,21 @@ export abstract class DeclaredElement extends Element { isCompatibleOverride(base: DeclaredElement): bool { var self: DeclaredElement = this; // TS var kind = self.kind; + var checkCompatibleOverride = false; if (kind == base.kind) { switch (kind) { - case ElementKind.FUNCTION: { - return (self).signature.isAssignableTo((base).signature); - } case ElementKind.FUNCTION_PROTOTYPE : { let selfFunction = this.program.resolver.resolveFunction(self, null); + if (!selfFunction) return false; let baseFunction = this.program.resolver.resolveFunction(base, null); - if (selfFunction && baseFunction) { - return selfFunction.signature.isAssignableTo(baseFunction.signature, true); - } else { - return false; - } + if (!baseFunction) return false; + self = selfFunction; + base = baseFunction; + checkCompatibleOverride = true; + // fall-through + } + case ElementKind.FUNCTION: { + return (self).signature.isAssignableTo((base).signature, checkCompatibleOverride); } case ElementKind.PROPERTY_PROTOTYPE: { let selfProperty = this.program.resolver.resolveProperty(self); @@ -4332,6 +4334,11 @@ export class Class extends TypedElement { ); } + /** Tests if this is an interface. */ + get isInterface(): bool { + return this.kind == ElementKind.INTERFACE; + } + /** Constructs a new class. */ constructor( /** Name incl. type parameters, i.e. `Foo`. */ diff --git a/src/types.ts b/src/types.ts index a4b5e45ef9..9a2f0361d6 100644 --- a/src/types.ts +++ b/src/types.ts @@ -6,8 +6,7 @@ import { Class, Program, - DecoratorFlags, - ElementKind + DecoratorFlags } from "./program"; import { @@ -476,26 +475,6 @@ export class Type { return false; } - /** Tests if a value of this class is compatible to the target class / interface in the multi extends / implements situation. */ - isInheritCompatibleTo(target: Type | null): bool { - if (target) { - if (this.isInternalReference && target.isInternalReference && this.isManaged && target.isManaged) { - let thisClass = this.getClass(); - let targetClass = target.getClass(); - if (thisClass && targetClass) { - // extends ThisClass implements TargetInterface - // implements ThisInterface, TargetInterface - if (thisClass.kind == ElementKind.CLASS || thisClass.kind == ElementKind.INTERFACE) { - if (targetClass.kind == ElementKind.INTERFACE) { - return true; - } - } - } - } - } - return false; - } - /** Tests if a value of this type is assignable to the target type excl. implicit conversion. */ isStrictlyAssignableTo(target: Type, signednessIsRelevant: bool = false): bool { if (this.isReference) return this.isAssignableTo(target); @@ -523,6 +502,27 @@ export class Type { return this.kind == target.kind; } + /** Tests if this type can extend or implement the given type. */ + canExtendOrImplement(base: Type): bool { + // Both must be class types + var thisClass = this.getClass(); + var baseClass = base.getClass(); + if (!thisClass || !baseClass) return false; + // Both types must be either managed or unmanaged + if (this.isManaged != base.isManaged) return false; + // Both types must be either internal or external references + if (this.isInternalReference) { + if (!base.isInternalReference) return false; + } else if (this.isExternalReference) { + if (!base.isExternalReference) return false; + } else { + return false; + } + // Interfaces can only extend interfaces + if (thisClass.isInterface && !baseClass.isInterface) return false; + return true; + } + /** Determines the common denominator type of two types, if there is any. */ static commonDenominator(left: Type, right: Type, signednessIsImportant: bool): Type | null { if (right.isAssignableTo(left, signednessIsImportant)) return left; @@ -962,7 +962,7 @@ export class Signature { } else { // check kind of `this` type if (thisThisType) { - if (!thisThisType.isInheritCompatibleTo(targetThisType)) { + if (!targetThisType || !thisThisType.canExtendOrImplement(targetThisType)) { return false; } } else if (targetThisType) { From 2b354aed60acf0822d799f01b4deafcc12268a92 Mon Sep 17 00:00:00 2001 From: dcode Date: Thu, 6 Oct 2022 05:40:39 +0200 Subject: [PATCH 09/10] update comment --- src/program.ts | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/src/program.ts b/src/program.ts index f41df72e75..3a9dfb09a0 100644 --- a/src/program.ts +++ b/src/program.ts @@ -3055,28 +3055,12 @@ export abstract class DeclaredElement extends Element { } return true; } + // TODO: Implement properties overriding fields and vice-versa. Challenge is that anything overridable requires + // a virtual stub, but fields aren't functions. Either all (such) fields should become property-like, with a + // getter and a setter that can participate as a virtual stub, or it's allowed one-way, with fields integrated + // into what can be a virtual stub as get=load and set=store, then not necessarily with own accessor functions. } } - // TODO: field and property cannot override each other, have different codegen - // if (self.kind == ElementKind.FIELD && base.kind == ElementKind.PROPERTY_PROTOTYPE) { - // // class A implement I, class B extends A implement I - // let selfField = self; - // let baseProperty = this.program.resolver.resolveProperty(base); - // if (!selfField.internalGetterSignature || !selfField.internalSetterSignature || !baseProperty) { - // return false; - // } - // let baseGetterInsance = baseProperty.getterInstance; - // let baseSetterInsance = baseProperty.setterInstance; - // if (baseGetterInsance && baseSetterInsance) { - // if (!selfField.internalGetterSignature.isAssignableTo(baseGetterInsance.signature) - // || !selfField.internalSetterSignature.isAssignableTo(baseSetterInsance.signature)) { - // return false; - // } - // } else { - // return false; - // } - // return true; - // } return false; } } From 9921a0df518cf1ef5ad304594b5e5bca197b0de7 Mon Sep 17 00:00:00 2001 From: dcode Date: Thu, 6 Oct 2022 07:34:03 +0200 Subject: [PATCH 10/10] update fixture with current Binaryen --- tests/compiler/class-implements.release.wat | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/compiler/class-implements.release.wat b/tests/compiler/class-implements.release.wat index 986afde582..154645f85d 100644 --- a/tests/compiler/class-implements.release.wat +++ b/tests/compiler/class-implements.release.wat @@ -171,11 +171,11 @@ i32.shr_u else i32.const 31 - local.get $2 i32.const 1073741820 local.get $2 + local.get $2 i32.const 1073741820 - i32.lt_u + i32.ge_u select local.tee $2 i32.clz @@ -435,11 +435,11 @@ i32.shr_u else i32.const 31 - local.get $2 i32.const 1073741820 local.get $2 + local.get $2 i32.const 1073741820 - i32.lt_u + i32.ge_u select local.tee $2 i32.clz