Skip to content

Unify ctor generation with and without base ctor #1590

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions src/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down
28 changes: 20 additions & 8 deletions tests/compiler/class-implements.optimized.wat
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
)
Expand All @@ -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
)
)
1 change: 1 addition & 0 deletions tests/compiler/class-implements.untouched.wat
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
106 changes: 105 additions & 1 deletion tests/compiler/extends-recursive.optimized.wat
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -19,4 +119,8 @@
local.get $1
i32.store
)
(func $~start
i32.const 1036
global.set $~lib/rt/stub/offset
)
)
1 change: 1 addition & 0 deletions tests/compiler/extends-recursive.untouched.wat
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
38 changes: 32 additions & 6 deletions tests/compiler/std/array.optimized.wat
Original file line number Diff line number Diff line change
Expand Up @@ -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<u32>#constructor@varargs))
(export "ArrayU32#constructor" (func $std/array/ArrayU32#constructor@varargs))
(export "ArrayU32#get:length" (func $~lib/array/Array<u8>#get:length))
(export "ArrayU32#set:length" (func $~lib/array/Array<u32>#set:length))
(export "ArrayU32#every" (func $~lib/array/Array<i32>#every))
Expand All @@ -454,7 +454,7 @@
(export "ArrayU32#flat" (func $~lib/array/Array<u32>#flat))
(export "ArrayU32#toString" (func $~lib/array/Array<u32>#toString))
(export "ArrayU8" (global $std/array/ArrayU8))
(export "ArrayU8#constructor" (func $~lib/array/Array<u8>#constructor@varargs))
(export "ArrayU8#constructor" (func $std/array/ArrayU8#constructor@varargs))
(export "ArrayU8#get:length" (func $~lib/array/Array<u8>#get:length))
(export "ArrayU8#set:length" (func $~lib/array/Array<u8>#set:length))
(export "ArrayU8#every" (func $~lib/array/Array<u8>#every))
Expand All @@ -480,7 +480,7 @@
(export "ArrayU8#flat" (func $~lib/array/Array<u32>#flat))
(export "ArrayU8#toString" (func $~lib/array/Array<u8>#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<u8>#get:length))
(export "ArrayStr#set:length" (func $~lib/array/Array<std/array/Ref>#set:length))
(export "ArrayStr#every" (func $~lib/array/Array<i32>#every))
Expand Down Expand Up @@ -19815,7 +19815,7 @@
i32.load
call $~lib/rt/pure/__visit
)
(func $~lib/array/Array<u32>#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)
Expand All @@ -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
Expand Down Expand Up @@ -20183,7 +20192,7 @@
local.get $1
call $~lib/array/Array<u32>#join
)
(func $~lib/array/Array<u8>#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)
Expand All @@ -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
Expand Down Expand Up @@ -20640,7 +20658,7 @@
local.get $1
call $~lib/array/Array<u8>#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
Expand All @@ -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
)
Expand Down
Loading