diff --git a/src/compiler.ts b/src/compiler.ts index a2dce12390..588ececa43 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -9242,7 +9242,8 @@ export class Compiler extends DiagnosticEmitter { // do not attempt to compile if inlined anyway if (!instance.hasDecorator(DecoratorFlags.INLINE)) this.compileFunction(instance); } else { - // clone base constructor if a derived class + // clone base constructor if a derived class. note that we cannot just + // call the base ctor since the derived class may have additional fields. let baseClass = classInstance.base; let contextualTypeArguments = uniqueMap(classInstance.contextualTypeArguments); if (baseClass) { @@ -9276,15 +9277,18 @@ export class Compiler extends DiagnosticEmitter { new Signature(this.program, null, classInstance.type, classInstance.type), contextualTypeArguments ); - let members = classInstance.members; - if (!members) classInstance.members = members = new Map(); - members.set("constructor", instance.prototype); } - instance.internalName = classInstance.internalName + INSTANCE_DELIMITER + "constructor"; instance.set(CommonFlags.COMPILED); instance.prototype.setResolvedInstance("", instance); + if (classInstance.is(CommonFlags.MODULE_EXPORT)) { + instance.set(CommonFlags.MODULE_EXPORT); + } classInstance.constructorInstance = instance; + let members = classInstance.members; + if (!members) classInstance.members = members = new Map(); + members.set("constructor", instance.prototype); + let previousFlow = this.currentFlow; let flow = instance.flow; this.currentFlow = flow; diff --git a/tests/compiler/class-implements.optimized.wat b/tests/compiler/class-implements.optimized.wat index 64708cfd4b..ea5c4529fc 100644 --- a/tests/compiler/class-implements.optimized.wat +++ b/tests/compiler/class-implements.optimized.wat @@ -12,6 +12,7 @@ (export "A#constructor" (func $class-implements/A#constructor)) (export "C" (global $class-implements/C)) (export "C#foo" (func $class-implements/C#foo)) + (export "C#constructor" (func $class-implements/C#constructor)) (start $~start) (func $~lib/rt/stub/__new (param $0 i32) (result i32) (local $1 i32) @@ -101,6 +102,22 @@ (func $class-implements/A#foo (param $0 i32) (result i32) i32.const 1 ) + (func $class-implements/C#constructor (param $0 i32) (result i32) + local.get $0 + i32.eqz + if + i32.const 5 + call $~lib/rt/stub/__new + local.set $0 + end + local.get $0 + if (result i32) + local.get $0 + else + i32.const 6 + call $~lib/rt/stub/__new + end + ) (func $class-implements/C#foo (param $0 i32) (result i32) i32.const 2 ) @@ -110,13 +127,8 @@ i32.const 3 call $~lib/rt/stub/__new drop - i32.const 5 - call $~lib/rt/stub/__new - i32.eqz - if - i32.const 6 - call $~lib/rt/stub/__new - drop - end + i32.const 0 + call $class-implements/C#constructor + drop ) ) diff --git a/tests/compiler/class-implements.untouched.wat b/tests/compiler/class-implements.untouched.wat index 9183b0aee1..d8923c0fc2 100644 --- a/tests/compiler/class-implements.untouched.wat +++ b/tests/compiler/class-implements.untouched.wat @@ -21,6 +21,7 @@ (export "A#constructor" (func $class-implements/A#constructor)) (export "C" (global $class-implements/C)) (export "C#foo" (func $class-implements/C#foo)) + (export "C#constructor" (func $class-implements/C#constructor)) (start $~start) (func $~lib/rt/stub/computeSize (param $0 i32) (result i32) local.get $0 diff --git a/tests/compiler/extends-recursive.optimized.wat b/tests/compiler/extends-recursive.optimized.wat index eaf97cd657..0493622a51 100644 --- a/tests/compiler/extends-recursive.optimized.wat +++ b/tests/compiler/extends-recursive.optimized.wat @@ -1,12 +1,112 @@ (module - (type $i32_i32_=>_none (func (param i32 i32))) (type $i32_=>_i32 (func (param i32) (result i32))) + (type $none_=>_none (func)) + (type $i32_i32_=>_none (func (param i32 i32))) (memory $0 0) + (global $~lib/rt/stub/offset (mut i32) (i32.const 0)) (global $extends-recursive/Child i32 (i32.const 3)) (export "memory" (memory $0)) (export "Child" (global $extends-recursive/Child)) (export "Child#get:child" (func $extends-recursive/Parent#get:child)) (export "Child#set:child" (func $extends-recursive/Parent#set:child)) + (export "Child#constructor" (func $extends-recursive/Child#constructor)) + (start $~start) + (func $~lib/rt/stub/__new (param $0 i32) (result i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + global.get $~lib/rt/stub/offset + global.get $~lib/rt/stub/offset + i32.const 4 + i32.add + local.tee $3 + i32.const 28 + i32.add + local.tee $1 + memory.size + local.tee $4 + i32.const 16 + i32.shl + i32.const 15 + i32.add + i32.const -16 + i32.and + local.tee $2 + i32.gt_u + if + local.get $4 + local.get $1 + local.get $2 + i32.sub + i32.const 65535 + i32.add + i32.const -65536 + i32.and + i32.const 16 + i32.shr_u + local.tee $2 + local.get $2 + local.get $4 + i32.lt_s + select + memory.grow + i32.const 0 + i32.lt_s + if + local.get $2 + memory.grow + i32.const 0 + i32.lt_s + if + unreachable + end + end + end + local.get $1 + global.set $~lib/rt/stub/offset + i32.const 28 + i32.store + local.get $3 + i32.const 4 + i32.sub + local.tee $1 + i32.const 0 + i32.store offset=4 + local.get $1 + i32.const 0 + i32.store offset=8 + local.get $1 + local.get $0 + i32.store offset=12 + local.get $1 + i32.const 4 + i32.store offset=16 + local.get $3 + i32.const 16 + i32.add + ) + (func $extends-recursive/Child#constructor (param $0 i32) (result i32) + local.get $0 + i32.eqz + if + i32.const 3 + call $~lib/rt/stub/__new + local.set $0 + end + local.get $0 + i32.eqz + if + i32.const 4 + call $~lib/rt/stub/__new + local.set $0 + end + local.get $0 + i32.const 0 + i32.store + local.get $0 + ) (func $extends-recursive/Parent#get:child (param $0 i32) (result i32) local.get $0 i32.load @@ -19,4 +119,8 @@ local.get $1 i32.store ) + (func $~start + i32.const 1036 + global.set $~lib/rt/stub/offset + ) ) diff --git a/tests/compiler/extends-recursive.untouched.wat b/tests/compiler/extends-recursive.untouched.wat index 756e08c579..91170a9428 100644 --- a/tests/compiler/extends-recursive.untouched.wat +++ b/tests/compiler/extends-recursive.untouched.wat @@ -14,6 +14,7 @@ (export "Child" (global $extends-recursive/Child)) (export "Child#get:child" (func $extends-recursive/Parent#get:child)) (export "Child#set:child" (func $extends-recursive/Parent#set:child)) + (export "Child#constructor" (func $extends-recursive/Child#constructor)) (start $~start) (func $~lib/rt/stub/computeSize (param $0 i32) (result i32) local.get $0 diff --git a/tests/compiler/std/array.optimized.wat b/tests/compiler/std/array.optimized.wat index 119dc696a8..35953095fd 100644 --- a/tests/compiler/std/array.optimized.wat +++ b/tests/compiler/std/array.optimized.wat @@ -428,7 +428,7 @@ (global $std/array/ArrayStr i32 (i32.const 42)) (export "memory" (memory $0)) (export "ArrayU32" (global $std/array/ArrayU32)) - (export "ArrayU32#constructor" (func $~lib/array/Array#constructor@varargs)) + (export "ArrayU32#constructor" (func $std/array/ArrayU32#constructor@varargs)) (export "ArrayU32#get:length" (func $~lib/array/Array#get:length)) (export "ArrayU32#set:length" (func $~lib/array/Array#set:length)) (export "ArrayU32#every" (func $~lib/array/Array#every)) @@ -454,7 +454,7 @@ (export "ArrayU32#flat" (func $~lib/array/Array#flat)) (export "ArrayU32#toString" (func $~lib/array/Array#toString)) (export "ArrayU8" (global $std/array/ArrayU8)) - (export "ArrayU8#constructor" (func $~lib/array/Array#constructor@varargs)) + (export "ArrayU8#constructor" (func $std/array/ArrayU8#constructor@varargs)) (export "ArrayU8#get:length" (func $~lib/array/Array#get:length)) (export "ArrayU8#set:length" (func $~lib/array/Array#set:length)) (export "ArrayU8#every" (func $~lib/array/Array#every)) @@ -480,7 +480,7 @@ (export "ArrayU8#flat" (func $~lib/array/Array#flat)) (export "ArrayU8#toString" (func $~lib/array/Array#toString)) (export "ArrayStr" (global $std/array/ArrayStr)) - (export "ArrayStr#constructor" (func $~lib/array/Array<~lib/string/String>#constructor@varargs)) + (export "ArrayStr#constructor" (func $std/array/ArrayStr#constructor@varargs)) (export "ArrayStr#get:length" (func $~lib/array/Array#get:length)) (export "ArrayStr#set:length" (func $~lib/array/Array#set:length)) (export "ArrayStr#every" (func $~lib/array/Array#every)) @@ -19815,7 +19815,7 @@ i32.load call $~lib/rt/pure/__visit ) - (func $~lib/array/Array#constructor@varargs (param $0 i32) (param $1 i32) (result i32) + (func $std/array/ArrayU32#constructor@varargs (param $0 i32) (param $1 i32) (result i32) (local $2 i32) (local $3 i32) (local $4 i32) @@ -19833,6 +19833,15 @@ end local.get $0 i32.eqz + if + i32.const 16 + i32.const 40 + call $~lib/rt/pure/__new + call $~lib/rt/pure/__retain + local.set $0 + end + local.get $0 + i32.eqz if i32.const 16 i32.const 7 @@ -20183,7 +20192,7 @@ local.get $1 call $~lib/array/Array#join ) - (func $~lib/array/Array#constructor@varargs (param $0 i32) (param $1 i32) (result i32) + (func $std/array/ArrayU8#constructor@varargs (param $0 i32) (param $1 i32) (result i32) (local $2 i32) (local $3 i32) (local $4 i32) @@ -20200,6 +20209,15 @@ end local.get $0 i32.eqz + if + i32.const 16 + i32.const 41 + call $~lib/rt/pure/__new + call $~lib/rt/pure/__retain + local.set $0 + end + local.get $0 + i32.eqz if i32.const 16 i32.const 6 @@ -20640,7 +20658,7 @@ local.get $1 call $~lib/array/Array#join ) - (func $~lib/array/Array<~lib/string/String>#constructor@varargs (param $0 i32) (param $1 i32) (result i32) + (func $std/array/ArrayStr#constructor@varargs (param $0 i32) (param $1 i32) (result i32) block $1of1 block $0of1 block $outOfRange @@ -20653,6 +20671,14 @@ local.set $1 end local.get $0 + if (result i32) + local.get $0 + else + i32.const 16 + i32.const 42 + call $~lib/rt/pure/__new + call $~lib/rt/pure/__retain + end local.get $1 call $~lib/array/Array<~lib/string/String>#constructor ) diff --git a/tests/compiler/std/array.untouched.wat b/tests/compiler/std/array.untouched.wat index 03c3c0ff01..bbaad8eb2f 100644 --- a/tests/compiler/std/array.untouched.wat +++ b/tests/compiler/std/array.untouched.wat @@ -318,7 +318,7 @@ (global $std/array/ArrayStr i32 (i32.const 42)) (export "memory" (memory $0)) (export "ArrayU32" (global $std/array/ArrayU32)) - (export "ArrayU32#constructor" (func $~lib/array/Array#constructor@varargs)) + (export "ArrayU32#constructor" (func $std/array/ArrayU32#constructor@varargs)) (export "ArrayU32#get:length" (func $~lib/array/Array#get:length)) (export "ArrayU32#set:length" (func $~lib/array/Array#set:length)) (export "ArrayU32#every" (func $~lib/array/Array#every)) @@ -344,7 +344,7 @@ (export "ArrayU32#flat" (func $~lib/array/Array#flat)) (export "ArrayU32#toString" (func $~lib/array/Array#toString)) (export "ArrayU8" (global $std/array/ArrayU8)) - (export "ArrayU8#constructor" (func $~lib/array/Array#constructor@varargs)) + (export "ArrayU8#constructor" (func $std/array/ArrayU8#constructor@varargs)) (export "ArrayU8#get:length" (func $~lib/array/Array#get:length)) (export "ArrayU8#set:length" (func $~lib/array/Array#set:length)) (export "ArrayU8#every" (func $~lib/array/Array#every)) @@ -370,7 +370,7 @@ (export "ArrayU8#flat" (func $~lib/array/Array#flat)) (export "ArrayU8#toString" (func $~lib/array/Array#toString)) (export "ArrayStr" (global $std/array/ArrayStr)) - (export "ArrayStr#constructor" (func $~lib/array/Array<~lib/string/String>#constructor@varargs)) + (export "ArrayStr#constructor" (func $std/array/ArrayStr#constructor@varargs)) (export "ArrayStr#get:length" (func $~lib/array/Array<~lib/string/String>#get:length)) (export "ArrayStr#set:length" (func $~lib/array/Array<~lib/string/String>#set:length)) (export "ArrayStr#every" (func $~lib/array/Array<~lib/string/String>#every)) @@ -31992,7 +31992,7 @@ end unreachable ) - (func $~lib/array/Array#constructor@varargs (param $0 i32) (param $1 i32) (result i32) + (func $std/array/ArrayU32#constructor@varargs (param $0 i32) (param $1 i32) (result i32) block $1of1 block $0of1 block $outOfRange @@ -32006,7 +32006,7 @@ end local.get $0 local.get $1 - call $~lib/array/Array#constructor + call $std/array/ArrayU32#constructor ) (func $~lib/array/Array#fill@varargs (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) block $2of2 @@ -32166,7 +32166,7 @@ local.get $1 call $~lib/array/Array#join ) - (func $~lib/array/Array#constructor@varargs (param $0 i32) (param $1 i32) (result i32) + (func $std/array/ArrayU8#constructor@varargs (param $0 i32) (param $1 i32) (result i32) block $1of1 block $0of1 block $outOfRange @@ -32180,7 +32180,7 @@ end local.get $0 local.get $1 - call $~lib/array/Array#constructor + call $std/array/ArrayU8#constructor ) (func $~lib/array/Array#fill@varargs (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) block $2of2 @@ -32395,7 +32395,7 @@ local.get $1 call $~lib/array/Array#join ) - (func $~lib/array/Array<~lib/string/String>#constructor@varargs (param $0 i32) (param $1 i32) (result i32) + (func $std/array/ArrayStr#constructor@varargs (param $0 i32) (param $1 i32) (result i32) block $1of1 block $0of1 block $outOfRange @@ -32409,7 +32409,7 @@ end local.get $0 local.get $1 - call $~lib/array/Array<~lib/string/String>#constructor + call $std/array/ArrayStr#constructor ) (func $~lib/array/Array<~lib/string/String>#fill@varargs (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) block $2of2