Skip to content

Commit 7ee6e1c

Browse files
committed
Fix compilation of immediate called function expressions
1 parent c93f0bb commit 7ee6e1c

File tree

8 files changed

+92
-19
lines changed

8 files changed

+92
-19
lines changed

dist/assemblyscript.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/assemblyscript.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/compiler.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import {
3131
Field,
3232
FunctionPrototype,
3333
Function,
34+
FunctionTarget,
3435
Global,
3536
Local,
3637
Namespace,
@@ -3876,8 +3877,9 @@ export class Compiler extends DiagnosticEmitter {
38763877
}
38773878
}
38783879
case ElementKind.FIELD: {
3879-
if (signature = (<Field>element).type.functionType) {
3880-
let targetExpr = this.compileExpression(assert(resolved.targetExpression), Type.u32);
3880+
let type = (<Field>element).type;
3881+
if (signature = type.functionType) {
3882+
let targetExpr = this.compileExpression(assert(resolved.targetExpression), type);
38813883
indexArg = this.module.createLoad(
38823884
4,
38833885
false,
@@ -3894,9 +3896,12 @@ export class Compiler extends DiagnosticEmitter {
38943896
return this.module.createUnreachable();
38953897
}
38963898
}
3897-
case ElementKind.PROPERTY: {
3898-
// TODO
3899+
case ElementKind.FUNCTION_TARGET: {
3900+
signature = (<FunctionTarget>element).signature;
3901+
indexArg = this.compileExpression(expression.expression, (<FunctionTarget>element).type);
3902+
break;
38993903
}
3904+
case ElementKind.PROPERTY: // TODO
39003905

39013906
// not supported
39023907
default: {

src/program.ts

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1774,10 +1774,15 @@ export class Program extends DiagnosticEmitter {
17741774
if (!resolvedElement) resolvedElement = new ResolvedElement();
17751775
return resolvedElement.set(classType);
17761776
} else {
1777-
let functionType = returnType.functionType;
1778-
if (functionType) {
1779-
// TODO: Signatures aren't elements but probably should be
1780-
throw new Error("not implemented");
1777+
let signature = returnType.functionType;
1778+
if (signature) {
1779+
let functionTarget = signature.cachedFunctionTarget;
1780+
if (!functionTarget) {
1781+
functionTarget = new FunctionTarget(this, signature);
1782+
signature.cachedFunctionTarget = functionTarget;
1783+
}
1784+
if (!resolvedElement) resolvedElement = new ResolvedElement();
1785+
return resolvedElement.set(functionTarget);
17811786
}
17821787
}
17831788
}
@@ -1846,6 +1851,8 @@ export enum ElementKind {
18461851
FUNCTION_PROTOTYPE,
18471852
/** A {@link Function}. */
18481853
FUNCTION,
1854+
/** A {@link FunctionTarget}. */
1855+
FUNCTION_TARGET,
18491856
/** A {@link ClassPrototype}. */
18501857
CLASS_PROTOTYPE,
18511858
/** A {@link Class}. */
@@ -2671,6 +2678,27 @@ export class Function extends Element {
26712678
toString(): string { return this.prototype.simpleName; }
26722679
}
26732680

2681+
/** A resolved function table entry, that is an function called by an index and signature. */
2682+
export class FunctionTarget extends Element {
2683+
2684+
kind = ElementKind.FUNCTION_TARGET;
2685+
2686+
/** Underlying signature. */
2687+
signature: Signature;
2688+
/** Function type. */
2689+
type: Type;
2690+
2691+
/** Constructs a new function target. */
2692+
constructor(program: Program, signature: Signature) {
2693+
super(program, "", "");
2694+
var simpleName = signature.toSignatureString();
2695+
this.simpleName = simpleName;
2696+
this.internalName = simpleName;
2697+
this.signature = signature;
2698+
this.type = Type.u32.asFunction(signature);
2699+
}
2700+
}
2701+
26742702
/** A yet unresolved instance field prototype. */
26752703
export class FieldPrototype extends Element {
26762704

src/types.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {
2-
Class
2+
Class,
3+
FunctionTarget
34
} from "./program";
45

56
import {
@@ -452,6 +453,8 @@ export class Signature {
452453
thisType: Type | null;
453454
/** Whether the last parameter is a rest parameter. */
454455
hasRest: bool;
456+
/** Cached {@link FunctionTarget}. */
457+
cachedFunctionTarget: FunctionTarget | null = null;
455458

456459
constructor(
457460
parameterTypes: Type[] | null = null,

tests/compiler/function-types.optimized.wat

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22
(type $i (func (result i32)))
33
(type $iii (func (param i32 i32) (result i32)))
44
(type $III (func (param i64 i64) (result i64)))
5+
(type $FFF (func (param f64 f64) (result f64)))
56
(type $v (func))
67
(global $function-types/i32Adder (mut i32) (i32.const 0))
78
(global $function-types/i64Adder (mut i32) (i32.const 0))
8-
(table 2 2 anyfunc)
9-
(elem (i32.const 0) $function-types/makeAdder<i32>~anonymous|0 $function-types/makeAdder<i64>~anonymous|1)
9+
(table 3 3 anyfunc)
10+
(elem (i32.const 0) $function-types/makeAdder<i32>~anonymous|0 $function-types/makeAdder<i64>~anonymous|1 $function-types/makeAdder<f64>~anonymous|2)
1011
(memory $0 1)
1112
(export "memory" (memory $0))
1213
(start $start)
@@ -28,7 +29,16 @@
2829
(func $function-types/makeAdder<i64> (; 3 ;) (type $i) (result i32)
2930
(i32.const 1)
3031
)
31-
(func $start (; 4 ;) (type $v)
32+
(func $function-types/makeAdder<f64>~anonymous|2 (; 4 ;) (type $FFF) (param $0 f64) (param $1 f64) (result f64)
33+
(f64.add
34+
(get_local $0)
35+
(get_local $1)
36+
)
37+
)
38+
(func $function-types/makeAdder<f64> (; 5 ;) (type $i) (result i32)
39+
(i32.const 2)
40+
)
41+
(func $start (; 6 ;) (type $v)
3242
(set_global $function-types/i32Adder
3343
(call $function-types/makeAdder<i32>)
3444
)
@@ -49,5 +59,12 @@
4959
(get_global $function-types/i64Adder)
5060
)
5161
)
62+
(drop
63+
(call_indirect (type $FFF)
64+
(f64.const 1)
65+
(f64.const 2)
66+
(call $function-types/makeAdder<f64>)
67+
)
68+
)
5269
)
5370
)

tests/compiler/function-types.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,4 @@ i32Adder(1, 2);
1212
var i64Adder = makeAdder<i64>();
1313
i64Adder(1, 2);
1414

15-
// TODO:
16-
// makeAdder<f64>()(1, 2);
15+
makeAdder<f64>()(1, 2);

tests/compiler/function-types.untouched.wat

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22
(type $i (func (result i32)))
33
(type $iii (func (param i32 i32) (result i32)))
44
(type $III (func (param i64 i64) (result i64)))
5+
(type $FFF (func (param f64 f64) (result f64)))
56
(type $v (func))
67
(global $function-types/i32Adder (mut i32) (i32.const 0))
78
(global $function-types/i64Adder (mut i32) (i32.const 0))
89
(global $HEAP_BASE i32 (i32.const 4))
9-
(table 2 2 anyfunc)
10-
(elem (i32.const 0) $function-types/makeAdder<i32>~anonymous|0 $function-types/makeAdder<i64>~anonymous|1)
10+
(table 3 3 anyfunc)
11+
(elem (i32.const 0) $function-types/makeAdder<i32>~anonymous|0 $function-types/makeAdder<i64>~anonymous|1 $function-types/makeAdder<f64>~anonymous|2)
1112
(memory $0 1)
1213
(export "memory" (memory $0))
1314
(start $start)
@@ -37,7 +38,20 @@
3738
(i32.const 1)
3839
)
3940
)
40-
(func $start (; 4 ;) (type $v)
41+
(func $function-types/makeAdder<f64>~anonymous|2 (; 4 ;) (type $FFF) (param $0 f64) (param $1 f64) (result f64)
42+
(return
43+
(f64.add
44+
(get_local $0)
45+
(get_local $1)
46+
)
47+
)
48+
)
49+
(func $function-types/makeAdder<f64> (; 5 ;) (type $i) (result i32)
50+
(return
51+
(i32.const 2)
52+
)
53+
)
54+
(func $start (; 6 ;) (type $v)
4155
(nop)
4256
(set_global $function-types/i32Adder
4357
(call $function-types/makeAdder<i32>)
@@ -59,5 +73,12 @@
5973
(get_global $function-types/i64Adder)
6074
)
6175
)
76+
(drop
77+
(call_indirect (type $FFF)
78+
(f64.const 1)
79+
(f64.const 2)
80+
(call $function-types/makeAdder<f64>)
81+
)
82+
)
6283
)
6384
)

0 commit comments

Comments
 (0)