Skip to content

Commit 5b910e3

Browse files
authored
fix: Propagate delayed file exports to import * as alias namespaces of the file
1 parent a73141f commit 5b910e3

13 files changed

+1546
-10
lines changed

src/compiler.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,8 @@ export class Compiler extends DiagnosticEmitter {
367367
virtualCalls: Set<Function> = new Set();
368368
/** Elements currently undergoing compilation. */
369369
pendingElements: Set<Element> = new Set();
370+
/** Elements, that are module exports, already processed */
371+
doneModuleExports: Set<Element> = new Set();
370372

371373
/** Compiles a {@link Program} to a {@link Module} using the specified options. */
372374
static compile(program: Program): Module {
@@ -815,7 +817,11 @@ export class Compiler extends DiagnosticEmitter {
815817
if (!classInstance.type.isUnmanaged) {
816818
let module = this.module;
817819
let internalName = classInstance.internalName;
818-
module.addGlobal(internalName, NativeType.I32, false, module.i32(classInstance.id));
820+
821+
if (!this.doneModuleExports.has(element)) {
822+
module.addGlobal(internalName, NativeType.I32, false, module.i32(classInstance.id));
823+
this.doneModuleExports.add(element);
824+
}
819825
module.addGlobalExport(internalName, prefix + name);
820826
}
821827
break;

src/program.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,7 +1053,7 @@ export class Program extends DiagnosticEmitter {
10531053
let localName = localIdentifier.text;
10541054
localFile.add(
10551055
localName,
1056-
foreignFile.asImportedNamespace(
1056+
foreignFile.asAliasNamespace(
10571057
localName,
10581058
localFile,
10591059
localIdentifier
@@ -2893,6 +2893,8 @@ export class File extends Element {
28932893
exportsStar: File[] | null = null;
28942894
/** Top-level start function of this file. */
28952895
startFunction!: Function;
2896+
/** Array of `import * as X` alias namespaces of this file. */
2897+
aliasNamespaces: Array<Namespace> = new Array<Namespace>();
28962898

28972899
/** Constructs a new file. */
28982900
constructor(
@@ -2962,6 +2964,12 @@ export class File extends Element {
29622964
if (!exports) this.exports = exports = new Map();
29632965
exports.set(name, element);
29642966
if (this.source.sourceKind == SourceKind.LIBRARY_ENTRY) this.program.ensureGlobal(name, element);
2967+
2968+
// Also, add to the namespaces that capture our exports
2969+
for(let i = 0; i < this.aliasNamespaces.length; i++) {
2970+
let ns = this.aliasNamespaces[i];
2971+
ns.add(name, element);
2972+
}
29652973
}
29662974

29672975
/** Ensures that another file is a re-export of this file. */
@@ -2987,12 +2995,20 @@ export class File extends Element {
29872995
}
29882996

29892997
/** Creates an imported namespace from this file. */
2990-
asImportedNamespace(name: string, parent: Element, localIdentifier: IdentifierExpression): Namespace {
2998+
asAliasNamespace(
2999+
name: string,
3000+
parent: Element,
3001+
localIdentifier: IdentifierExpression
3002+
): Namespace {
29913003
var declaration = this.program.makeNativeNamespaceDeclaration(name);
29923004
declaration.name = localIdentifier;
29933005
var ns = new Namespace(name, parent, declaration);
29943006
ns.set(CommonFlags.SCOPED);
29953007
this.copyExportsToNamespace(ns);
3008+
// NOTE: Some exports are still queued, and can't yet be added here,
3009+
// so we remember all the alias namespaces and add to them as well
3010+
// when adding an element to the file.
3011+
this.aliasNamespaces.push(ns);
29963012
return ns;
29973013
}
29983014

tests/compiler/exports.optimized.wat

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
(export "vehicles.Car.TIRES" (global $exports/vehicles.Car.TIRES))
4545
(export "vehicles.Car.getNumTires" (func $exports/Car.getNumTires))
4646
(export "outer.inner.a" (global $exports/outer.inner.a))
47+
(export "renamed_mul" (func $export/mul))
4748
(export "__setArgumentsLength" (func $~setArgumentsLength))
4849
(start $~start)
4950
(func $exports/add (param $0 i32) (param $1 i32) (result i32)
@@ -137,6 +138,11 @@
137138
(func $exports/Car#openDoors (param $0 i32)
138139
nop
139140
)
141+
(func $export/mul (param $0 i32) (param $1 i32) (result i32)
142+
local.get $0
143+
local.get $1
144+
i32.mul
145+
)
140146
(func $~start
141147
i32.const 1024
142148
global.set $~lib/rt/stub/offset

tests/compiler/exports.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,5 @@ export namespace outer {
5656
export const a = 42;
5757
}
5858
}
59+
60+
export {renamed_mul} from "./export";

tests/compiler/exports.untouched.wat

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
(global $exports/Car.TIRES i32 (i32.const 4))
1515
(global $exports/vehicles.Car.TIRES i32 (i32.const 4))
1616
(global $exports/outer.inner.a i32 (i32.const 42))
17+
(global $export/a i32 (i32.const 1))
18+
(global $export/b i32 (i32.const 2))
19+
(global $export/c i32 (i32.const 3))
1720
(global $~lib/rt/stub/startOffset (mut i32) (i32.const 0))
1821
(global $~lib/rt/stub/offset (mut i32) (i32.const 0))
1922
(global $~lib/heap/__heap_base i32 (i32.const 8))
@@ -47,6 +50,7 @@
4750
(export "vehicles.Car.TIRES" (global $exports/vehicles.Car.TIRES))
4851
(export "vehicles.Car.getNumTires" (func $exports/vehicles.Car.getNumTires))
4952
(export "outer.inner.a" (global $exports/outer.inner.a))
53+
(export "renamed_mul" (func $export/mul))
5054
(export "__setArgumentsLength" (func $~setArgumentsLength))
5155
(start $~start)
5256
(func $exports/add (param $0 i32) (param $1 i32) (result i32)
@@ -260,6 +264,11 @@
260264
(func $exports/vehicles.Car#openDoors (param $0 i32)
261265
nop
262266
)
267+
(func $export/mul (param $0 i32) (param $1 i32) (result i32)
268+
local.get $0
269+
local.get $1
270+
i32.mul
271+
)
263272
(func $~start
264273
global.get $~lib/heap/__heap_base
265274
i32.const 15

tests/compiler/exportstar-rereexport.optimized.wat

Lines changed: 129 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
11
(module
22
(type $i32_i32_=>_i32 (func (param i32 i32) (result i32)))
33
(type $none_=>_none (func))
4-
(memory $0 0)
4+
(type $i32_i32_i32_i32_=>_none (func (param i32 i32 i32 i32)))
5+
(type $none_=>_i32 (func (result i32)))
6+
(import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32)))
7+
(memory $0 1)
8+
(data (i32.const 1024) "\16\00\00\00\01\00\00\00\01\00\00\00\16\00\00\00r\00e\00e\00x\00p\00o\00r\00t\00.\00t\00s")
9+
(data (i32.const 1072) "\1a\00\00\00\01\00\00\00\01\00\00\00\1a\00\00\00r\00e\00r\00e\00e\00x\00p\00o\00r\00t\00.\00t\00s")
510
(global $export/a i32 (i32.const 1))
611
(global $export/b i32 (i32.const 2))
712
(global $export/c i32 (i32.const 3))
13+
(global $~lib/rt/stub/offset (mut i32) (i32.const 0))
14+
(global $reexport/car (mut i32) (i32.const 0))
15+
(global $rereexport/car (mut i32) (i32.const 0))
16+
(global $rereexport/exportsNamespaceCar (mut i32) (i32.const 0))
817
(export "memory" (memory $0))
918
(export "a" (global $export/a))
1019
(export "renamed_a" (global $export/a))
@@ -20,6 +29,7 @@
2029
(export "exportstar.renamed_c" (global $export/c))
2130
(export "exportstar.ns.two" (func $export-default/theDefault))
2231
(export "exportstar.default.two" (func $export-default/theDefault))
32+
(start $~start)
2333
(func $export/add (param $0 i32) (param $1 i32) (result i32)
2434
local.get $0
2535
local.get $1
@@ -30,6 +40,78 @@
3040
local.get $1
3141
i32.mul
3242
)
43+
(func $exports/Car#constructor (result i32)
44+
(local $0 i32)
45+
(local $1 i32)
46+
(local $2 i32)
47+
(local $3 i32)
48+
global.get $~lib/rt/stub/offset
49+
i32.const 16
50+
i32.add
51+
local.tee $1
52+
i32.const 16
53+
i32.add
54+
local.tee $0
55+
memory.size
56+
local.tee $3
57+
i32.const 16
58+
i32.shl
59+
local.tee $2
60+
i32.gt_u
61+
if
62+
local.get $3
63+
local.get $0
64+
local.get $2
65+
i32.sub
66+
i32.const 65535
67+
i32.add
68+
i32.const -65536
69+
i32.and
70+
i32.const 16
71+
i32.shr_u
72+
local.tee $2
73+
local.get $3
74+
local.get $2
75+
i32.gt_s
76+
select
77+
memory.grow
78+
i32.const 0
79+
i32.lt_s
80+
if
81+
local.get $2
82+
memory.grow
83+
i32.const 0
84+
i32.lt_s
85+
if
86+
unreachable
87+
end
88+
end
89+
end
90+
local.get $0
91+
global.set $~lib/rt/stub/offset
92+
local.get $1
93+
i32.const 16
94+
i32.sub
95+
local.tee $0
96+
i32.const 16
97+
i32.store
98+
local.get $0
99+
i32.const 1
100+
i32.store offset=4
101+
local.get $0
102+
i32.const 3
103+
i32.store offset=8
104+
local.get $0
105+
i32.const 4
106+
i32.store offset=12
107+
local.get $1
108+
i32.const 2
109+
i32.store
110+
local.get $1
111+
i32.const 2
112+
i32.store
113+
local.get $1
114+
)
33115
(func $export-default/theDefault
34116
nop
35117
)
@@ -38,4 +120,50 @@
38120
local.get $1
39121
i32.sub
40122
)
123+
(func $~start
124+
i32.const 1120
125+
global.set $~lib/rt/stub/offset
126+
call $exports/Car#constructor
127+
global.set $reexport/car
128+
global.get $reexport/car
129+
i32.load
130+
i32.const 2
131+
i32.ne
132+
if
133+
i32.const 0
134+
i32.const 1040
135+
i32.const 40
136+
i32.const 1
137+
call $~lib/builtins/abort
138+
unreachable
139+
end
140+
call $exports/Car#constructor
141+
global.set $rereexport/car
142+
global.get $rereexport/car
143+
i32.load
144+
i32.const 2
145+
i32.ne
146+
if
147+
i32.const 0
148+
i32.const 1088
149+
i32.const 18
150+
i32.const 1
151+
call $~lib/builtins/abort
152+
unreachable
153+
end
154+
call $exports/Car#constructor
155+
global.set $rereexport/exportsNamespaceCar
156+
global.get $rereexport/exportsNamespaceCar
157+
i32.load
158+
i32.const 2
159+
i32.ne
160+
if
161+
i32.const 0
162+
i32.const 1088
163+
i32.const 24
164+
i32.const 1
165+
call $~lib/builtins/abort
166+
unreachable
167+
end
168+
)
41169
)

0 commit comments

Comments
 (0)