diff --git a/src/compiler.ts b/src/compiler.ts index 347bc6da66..278199c01b 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -655,9 +655,10 @@ export class Compiler extends DiagnosticEmitter { break; } case ElementKind.PROPERTY_PROTOTYPE: { - let getter = (element).getterPrototype; + let prototype = element; + let getter = prototype.getterPrototype; if (getter) this.ensureModuleExport(GETTER_PREFIX + name, getter, prefix); - let setter = (element).setterPrototype; + let setter = prototype.setterPrototype; if (setter) this.ensureModuleExport(SETTER_PREFIX + name, setter, prefix); break; } @@ -699,28 +700,31 @@ export class Compiler extends DiagnosticEmitter { break; } case ElementKind.PROPERTY: { - let getter = (element).getterInstance; + let instance = element; + let getter = instance.getterInstance; if (getter) this.ensureModuleExport(GETTER_PREFIX + name, getter, prefix); - let setter = (element).setterInstance; + let setter = instance.setterInstance; if (setter) this.ensureModuleExport(SETTER_PREFIX + name, setter, prefix); break; } case ElementKind.FIELD: { + let instance = element; if (element.is(CommonFlags.COMPILED)) { let module = this.module; - module.addFunctionExport((element).internalGetterName, prefix + GETTER_PREFIX + name); + module.addFunctionExport(instance.internalGetterName, prefix + GETTER_PREFIX + name); if (!element.is(CommonFlags.READONLY)) { - module.addFunctionExport((element).internalSetterName, prefix + SETTER_PREFIX + name); + module.addFunctionExport(instance.internalSetterName, prefix + SETTER_PREFIX + name); } } break; } case ElementKind.CLASS: { + let instance = element; // make the class name itself represent its runtime id - if (!(element).type.isUnmanaged) { + if (!instance.type.isUnmanaged) { let module = this.module; - let internalName = (element).internalName; - module.addGlobal(internalName, NativeType.I32, false, module.i32((element).id)); + let internalName = instance.internalName; + module.addGlobal(internalName, NativeType.I32, false, module.i32(instance.id)); module.addGlobalExport(internalName, prefix + name); } break; @@ -1501,8 +1505,7 @@ export class Compiler extends DiagnosticEmitter { } } } - var ctorInstance = instance.constructorInstance; - if (ctorInstance) this.compileFunction(ctorInstance); + this.ensureConstructor(instance, instance.identifierNode); var instanceMembers = instance.members; if (instanceMembers) { // TODO: for (let element of instanceMembers.values()) { @@ -8704,7 +8707,7 @@ export class Compiler extends DiagnosticEmitter { CommonNames.constructor, new FunctionPrototype( CommonNames.constructor, - classInstance, + classInstance, // bound this.program.makeNativeFunctionDeclaration(CommonNames.constructor, CommonFlags.INSTANCE | CommonFlags.CONSTRUCTOR ) @@ -8712,6 +8715,9 @@ 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"; diff --git a/tests/compiler/extends-recursive.optimized.wat b/tests/compiler/extends-recursive.optimized.wat index fabf4f9e07..8fa6a8e0e6 100644 --- a/tests/compiler/extends-recursive.optimized.wat +++ b/tests/compiler/extends-recursive.optimized.wat @@ -1,12 +1,16 @@ (module + (type $none_=>_none (func)) (type $i32_i32_=>_none (func (param i32 i32))) (type $i32_=>_i32 (func (param i32) (result i32))) (memory $0 0) + (global $~lib/rt/stub/startOffset (mut i32) (i32.const 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)) + (start $~start) (func $extends-recursive/Parent#get:child (; 0 ;) (param $0 i32) (result i32) local.get $0 i32.load @@ -19,4 +23,10 @@ local.get $1 i32.store ) + (func $~start (; 2 ;) + i32.const 16 + global.set $~lib/rt/stub/startOffset + i32.const 16 + global.set $~lib/rt/stub/offset + ) ) diff --git a/tests/compiler/extends-recursive.untouched.wat b/tests/compiler/extends-recursive.untouched.wat index 8e8af59142..078551940a 100644 --- a/tests/compiler/extends-recursive.untouched.wat +++ b/tests/compiler/extends-recursive.untouched.wat @@ -1,26 +1,170 @@ (module (type $i32_=>_i32 (func (param i32) (result i32))) (type $i32_=>_none (func (param i32))) + (type $none_=>_none (func)) (type $i32_i32_=>_none (func (param i32 i32))) + (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) (memory $0 0) (table $0 1 funcref) + (global $~lib/rt/stub/startOffset (mut i32) (i32.const 0)) + (global $~lib/rt/stub/offset (mut i32) (i32.const 0)) + (global $~lib/heap/__heap_base i32 (i32.const 8)) (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)) - (func $~lib/rt/stub/__retain (; 0 ;) (param $0 i32) (result i32) + (start $~start) + (func $~lib/rt/stub/maybeGrowMemory (; 0 ;) (param $0 i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + memory.size + local.set $1 + local.get $1 + i32.const 16 + i32.shl + local.set $2 + local.get $0 + local.get $2 + i32.gt_u + if + local.get $0 + local.get $2 + i32.sub + i32.const 65535 + i32.add + i32.const 65535 + i32.const -1 + i32.xor + i32.and + i32.const 16 + i32.shr_u + local.set $3 + local.get $1 + local.tee $4 + local.get $3 + local.tee $5 + local.get $4 + local.get $5 + i32.gt_s + select + local.set $4 + local.get $4 + memory.grow + i32.const 0 + i32.lt_s + if + local.get $3 + memory.grow + i32.const 0 + i32.lt_s + if + unreachable + end + end + end + local.get $0 + global.set $~lib/rt/stub/offset + ) + (func $~lib/rt/stub/__alloc (; 1 ;) (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 1073741808 + i32.gt_u + if + unreachable + end + global.get $~lib/rt/stub/offset + i32.const 16 + i32.add + local.set $2 + local.get $0 + i32.const 15 + i32.add + i32.const 15 + i32.const -1 + i32.xor + i32.and + local.tee $3 + i32.const 16 + local.tee $4 + local.get $3 + local.get $4 + i32.gt_u + select + local.set $5 + local.get $2 + local.get $5 + i32.add + call $~lib/rt/stub/maybeGrowMemory + local.get $2 + i32.const 16 + i32.sub + local.set $6 + local.get $6 + local.get $5 + i32.store + local.get $6 + i32.const 1 + i32.store offset=4 + local.get $6 + local.get $1 + i32.store offset=8 + local.get $6 + local.get $0 + i32.store offset=12 + local.get $2 + ) + (func $~lib/rt/stub/__retain (; 2 ;) (param $0 i32) (result i32) local.get $0 ) - (func $extends-recursive/Parent#get:child (; 1 ;) (param $0 i32) (result i32) + (func $extends-recursive/Parent#constructor (; 3 ;) (param $0 i32) (result i32) + local.get $0 + i32.eqz + if + i32.const 4 + i32.const 4 + call $~lib/rt/stub/__alloc + call $~lib/rt/stub/__retain + local.set $0 + end + local.get $0 + i32.const 0 + call $~lib/rt/stub/__retain + i32.store + local.get $0 + ) + (func $extends-recursive/Child#constructor (; 4 ;) (param $0 i32) (result i32) + local.get $0 + i32.eqz + if + i32.const 4 + i32.const 3 + call $~lib/rt/stub/__alloc + call $~lib/rt/stub/__retain + local.set $0 + end + local.get $0 + call $extends-recursive/Parent#constructor + local.set $0 + local.get $0 + ) + (func $extends-recursive/Parent#get:child (; 5 ;) (param $0 i32) (result i32) local.get $0 i32.load call $~lib/rt/stub/__retain ) - (func $~lib/rt/stub/__release (; 2 ;) (param $0 i32) + (func $~lib/rt/stub/__release (; 6 ;) (param $0 i32) nop ) - (func $extends-recursive/Parent#set:child (; 3 ;) (param $0 i32) (param $1 i32) + (func $extends-recursive/Parent#set:child (; 7 ;) (param $0 i32) (param $1 i32) (local $2 i32) local.get $0 local.get $1 @@ -38,4 +182,16 @@ local.get $1 i32.store ) + (func $~start (; 8 ;) + global.get $~lib/heap/__heap_base + i32.const 15 + i32.add + i32.const 15 + i32.const -1 + i32.xor + i32.and + global.set $~lib/rt/stub/startOffset + global.get $~lib/rt/stub/startOffset + global.set $~lib/rt/stub/offset + ) ) diff --git a/tests/compiler/resolve-nested.optimized.wat b/tests/compiler/resolve-nested.optimized.wat index 3d605cd313..ff56d1ef0e 100644 --- a/tests/compiler/resolve-nested.optimized.wat +++ b/tests/compiler/resolve-nested.optimized.wat @@ -1,23 +1,126 @@ (module + (type $i32_=>_i32 (func (param i32) (result i32))) + (type $none_=>_none (func)) + (type $i32_=>_none (func (param i32))) (type $i32_i32_i32_=>_none (func (param i32 i32 i32))) (type $i32_i32_i32_i32_i32_=>_none (func (param i32 i32 i32 i32 i32))) (type $i32_i32_i32_i32_i32_i32_=>_none (func (param i32 i32 i32 i32 i32 i32))) (memory $0 0) + (global $~lib/rt/stub/startOffset (mut i32) (i32.const 0)) + (global $~lib/rt/stub/offset (mut i32) (i32.const 0)) (global $resolve-nested/Outer.InnerClass i32 (i32.const 4)) (global $resolve-nested/Outer.Inner.EvenInnerClass i32 (i32.const 5)) (export "memory" (memory $0)) (export "Outer.InnerClass" (global $resolve-nested/Outer.InnerClass)) + (export "Outer.InnerClass#constructor" (func $resolve-nested/Outer.InnerClass#constructor)) (export "Outer.Inner.EvenInnerClass" (global $resolve-nested/Outer.Inner.EvenInnerClass)) + (export "Outer.Inner.EvenInnerClass#constructor" (func $resolve-nested/Outer.Inner.EvenInnerClass#constructor)) (export "Outer.Inner.evenInner" (func $resolve-nested/Outer.Inner.evenInner)) (export "Outer.inner" (func $resolve-nested/Outer.inner)) (export "outer" (func $resolve-nested/outer)) - (func $resolve-nested/Outer.Inner.evenInner (; 0 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (param $5 i32) + (start $~start) + (func $~lib/rt/stub/maybeGrowMemory (; 0 ;) (param $0 i32) + (local $1 i32) + (local $2 i32) + local.get $0 + memory.size + local.tee $2 + i32.const 16 + i32.shl + local.tee $1 + i32.gt_u + if + local.get $2 + local.get $0 + local.get $1 + i32.sub + i32.const 65535 + i32.add + i32.const -65536 + i32.and + i32.const 16 + i32.shr_u + local.tee $1 + local.get $2 + local.get $1 + i32.gt_s + select + memory.grow + i32.const 0 + i32.lt_s + if + local.get $1 + memory.grow + i32.const 0 + i32.lt_s + if + unreachable + end + end + end + local.get $0 + global.set $~lib/rt/stub/offset + ) + (func $~lib/rt/stub/__alloc (; 1 ;) (param $0 i32) (result i32) + (local $1 i32) + (local $2 i32) + global.get $~lib/rt/stub/offset + i32.const 16 + i32.add + local.tee $2 + i32.const 16 + i32.add + call $~lib/rt/stub/maybeGrowMemory + local.get $2 + i32.const 16 + i32.sub + local.tee $1 + i32.const 16 + i32.store + local.get $1 + i32.const 1 + i32.store offset=4 + local.get $1 + local.get $0 + i32.store offset=8 + local.get $1 + i32.const 0 + i32.store offset=12 + local.get $2 + ) + (func $resolve-nested/Outer.InnerClass#constructor (; 2 ;) (param $0 i32) (result i32) + local.get $0 + i32.eqz + if + i32.const 4 + call $~lib/rt/stub/__alloc + local.set $0 + end + local.get $0 + ) + (func $resolve-nested/Outer.Inner.EvenInnerClass#constructor (; 3 ;) (param $0 i32) (result i32) + local.get $0 + i32.eqz + if + i32.const 5 + call $~lib/rt/stub/__alloc + local.set $0 + end + local.get $0 + ) + (func $resolve-nested/Outer.Inner.evenInner (; 4 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (param $5 i32) nop ) - (func $resolve-nested/Outer.inner (; 1 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) + (func $resolve-nested/Outer.inner (; 5 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) nop ) - (func $resolve-nested/outer (; 2 ;) (param $0 i32) (param $1 i32) (param $2 i32) + (func $resolve-nested/outer (; 6 ;) (param $0 i32) (param $1 i32) (param $2 i32) nop ) + (func $~start (; 7 ;) + i32.const 16 + global.set $~lib/rt/stub/startOffset + i32.const 16 + global.set $~lib/rt/stub/offset + ) ) diff --git a/tests/compiler/resolve-nested.untouched.wat b/tests/compiler/resolve-nested.untouched.wat index 498602efe8..b82f47c6a1 100644 --- a/tests/compiler/resolve-nested.untouched.wat +++ b/tests/compiler/resolve-nested.untouched.wat @@ -1,9 +1,11 @@ (module + (type $i32_=>_i32 (func (param i32) (result i32))) (type $i32_=>_none (func (param i32))) + (type $none_=>_none (func)) (type $i32_i32_i32_=>_none (func (param i32 i32 i32))) (type $i32_i32_i32_i32_i32_=>_none (func (param i32 i32 i32 i32 i32))) (type $i32_i32_i32_i32_i32_i32_=>_none (func (param i32 i32 i32 i32 i32 i32))) - (type $i32_=>_i32 (func (param i32) (result i32))) + (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) (memory $0 0) (table $0 1 funcref) (global $resolve-nested/Outer.Inner.a (mut i32) (i32.const 0)) @@ -20,21 +22,158 @@ (global $resolve-nested/a (mut i32) (i32.const 0)) (global $resolve-nested/b (mut i32) (i32.const 0)) (global $resolve-nested/c (mut i32) (i32.const 0)) + (global $~lib/rt/stub/startOffset (mut i32) (i32.const 0)) + (global $~lib/rt/stub/offset (mut i32) (i32.const 0)) + (global $~lib/heap/__heap_base i32 (i32.const 8)) (global $resolve-nested/Outer.InnerClass i32 (i32.const 4)) (global $resolve-nested/Outer.Inner.EvenInnerClass i32 (i32.const 5)) (export "memory" (memory $0)) (export "Outer.InnerClass" (global $resolve-nested/Outer.InnerClass)) + (export "Outer.InnerClass#constructor" (func $resolve-nested/Outer.InnerClass#constructor)) (export "Outer.Inner.EvenInnerClass" (global $resolve-nested/Outer.Inner.EvenInnerClass)) + (export "Outer.Inner.EvenInnerClass#constructor" (func $resolve-nested/Outer.Inner.EvenInnerClass#constructor)) (export "Outer.Inner.evenInner" (func $resolve-nested/Outer.Inner.evenInner)) (export "Outer.inner" (func $resolve-nested/Outer.inner)) (export "outer" (func $resolve-nested/outer)) - (func $~lib/rt/stub/__retain (; 0 ;) (param $0 i32) (result i32) + (start $~start) + (func $~lib/rt/stub/maybeGrowMemory (; 0 ;) (param $0 i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + memory.size + local.set $1 + local.get $1 + i32.const 16 + i32.shl + local.set $2 + local.get $0 + local.get $2 + i32.gt_u + if + local.get $0 + local.get $2 + i32.sub + i32.const 65535 + i32.add + i32.const 65535 + i32.const -1 + i32.xor + i32.and + i32.const 16 + i32.shr_u + local.set $3 + local.get $1 + local.tee $4 + local.get $3 + local.tee $5 + local.get $4 + local.get $5 + i32.gt_s + select + local.set $4 + local.get $4 + memory.grow + i32.const 0 + i32.lt_s + if + local.get $3 + memory.grow + i32.const 0 + i32.lt_s + if + unreachable + end + end + end + local.get $0 + global.set $~lib/rt/stub/offset + ) + (func $~lib/rt/stub/__alloc (; 1 ;) (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 1073741808 + i32.gt_u + if + unreachable + end + global.get $~lib/rt/stub/offset + i32.const 16 + i32.add + local.set $2 + local.get $0 + i32.const 15 + i32.add + i32.const 15 + i32.const -1 + i32.xor + i32.and + local.tee $3 + i32.const 16 + local.tee $4 + local.get $3 + local.get $4 + i32.gt_u + select + local.set $5 + local.get $2 + local.get $5 + i32.add + call $~lib/rt/stub/maybeGrowMemory + local.get $2 + i32.const 16 + i32.sub + local.set $6 + local.get $6 + local.get $5 + i32.store + local.get $6 + i32.const 1 + i32.store offset=4 + local.get $6 + local.get $1 + i32.store offset=8 + local.get $6 + local.get $0 + i32.store offset=12 + local.get $2 + ) + (func $~lib/rt/stub/__retain (; 2 ;) (param $0 i32) (result i32) local.get $0 ) - (func $~lib/rt/stub/__release (; 1 ;) (param $0 i32) + (func $resolve-nested/Outer.InnerClass#constructor (; 3 ;) (param $0 i32) (result i32) + local.get $0 + i32.eqz + if + i32.const 0 + i32.const 4 + call $~lib/rt/stub/__alloc + call $~lib/rt/stub/__retain + local.set $0 + end + local.get $0 + ) + (func $resolve-nested/Outer.Inner.EvenInnerClass#constructor (; 4 ;) (param $0 i32) (result i32) + local.get $0 + i32.eqz + if + i32.const 0 + i32.const 5 + call $~lib/rt/stub/__alloc + call $~lib/rt/stub/__retain + local.set $0 + end + local.get $0 + ) + (func $~lib/rt/stub/__release (; 5 ;) (param $0 i32) nop ) - (func $resolve-nested/Outer.Inner.evenInner (; 2 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (param $5 i32) + (func $resolve-nested/Outer.Inner.evenInner (; 6 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (param $5 i32) local.get $0 call $~lib/rt/stub/__retain local.set $0 @@ -66,7 +205,7 @@ local.get $5 call $~lib/rt/stub/__release ) - (func $resolve-nested/Outer.inner (; 3 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) + (func $resolve-nested/Outer.inner (; 7 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) local.get $0 call $~lib/rt/stub/__retain local.set $0 @@ -93,7 +232,7 @@ local.get $4 call $~lib/rt/stub/__release ) - (func $resolve-nested/outer (; 4 ;) (param $0 i32) (param $1 i32) (param $2 i32) + (func $resolve-nested/outer (; 8 ;) (param $0 i32) (param $1 i32) (param $2 i32) local.get $0 call $~lib/rt/stub/__retain local.set $0 @@ -110,4 +249,16 @@ local.get $2 call $~lib/rt/stub/__release ) + (func $~start (; 9 ;) + global.get $~lib/heap/__heap_base + i32.const 15 + i32.add + i32.const 15 + i32.const -1 + i32.xor + i32.and + global.set $~lib/rt/stub/startOffset + global.get $~lib/rt/stub/startOffset + global.set $~lib/rt/stub/offset + ) )