Skip to content

Commit 7a8995b

Browse files
committed
Properly inline getters; Simplify blocks when last statement returns
1 parent 525795b commit 7a8995b

File tree

75 files changed

+4873
-6619
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+4873
-6619
lines changed

dist/asc.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/asc.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.

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/ast.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1413,6 +1413,20 @@ export class UnaryPrefixExpression extends UnaryExpression {
14131413

14141414
// statements
14151415

1416+
export function isLastStatement(statement: Statement): bool {
1417+
var parent = assert(statement.parent);
1418+
if (parent.kind == NodeKind.BLOCK) {
1419+
let statements = (<BlockStatement>parent).statements;
1420+
if (statements[statements.length - 1] === statement) {
1421+
switch (assert(parent.parent).kind) {
1422+
case NodeKind.FUNCTIONDECLARATION:
1423+
case NodeKind.METHODDECLARATION: return true;
1424+
}
1425+
}
1426+
}
1427+
return false;
1428+
}
1429+
14161430
/** Base class of all statement nodes. */
14171431
export abstract class Statement extends Node { }
14181432

src/compiler.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,8 @@ import {
128128
UnaryPrefixExpression,
129129
FieldDeclaration,
130130

131-
nodeIsConstantValue
131+
nodeIsConstantValue,
132+
isLastStatement
132133
} from "./ast";
133134

134135
import {
@@ -1486,11 +1487,17 @@ export class Compiler extends DiagnosticEmitter {
14861487
this.currentFunction.flow = blockFlow;
14871488

14881489
var stmts = this.compileStatements(statements);
1490+
var lastType: NativeType;
14891491
var stmt = stmts.length == 0
14901492
? this.module.createNop()
14911493
: stmts.length == 1
14921494
? stmts[0]
1493-
: this.module.createBlock(null, stmts, NativeType.None);
1495+
: this.module.createBlock(null, stmts,
1496+
// if the last expression is a value, annotate the block's return value
1497+
(lastType = getExpressionType(stmts[stmts.length - 1])) == NativeType.None
1498+
? NativeType.None
1499+
: lastType
1500+
);
14941501

14951502
// Switch back to the parent flow
14961503
var parentFlow = blockFlow.leaveBranchOrScope();
@@ -1776,6 +1783,9 @@ export class Compiler extends DiagnosticEmitter {
17761783
if (!flow.canOverflow(expr, returnType)) flow.set(FlowFlags.RETURNS_WRAPPED);
17771784
}
17781785

1786+
// If the last statement anyway, make it the block's return value
1787+
if (isLastStatement(statement)) return expr ? expr : module.createNop();
1788+
17791789
// When inlining, break to the end of the inlined function's block (no need to wrap)
17801790
return flow.is(FlowFlags.INLINE_CONTEXT)
17811791
? module.createBreak(assert(flow.returnLabel), 0, expr)
@@ -6440,6 +6450,7 @@ export class Compiler extends DiagnosticEmitter {
64406450
)) {
64416451
return module.createUnreachable();
64426452
}
6453+
let inline = (instance.decoratorFlags & DecoratorFlags.INLINE) != 0;
64436454
if (instance.is(CommonFlags.INSTANCE)) {
64446455
let parent = assert(instance.parent);
64456456
assert(parent.kind == ElementKind.CLASS);
@@ -6450,10 +6461,10 @@ export class Compiler extends DiagnosticEmitter {
64506461
WrapMode.NONE
64516462
);
64526463
this.currentType = signature.returnType;
6453-
return this.compileCallDirect(instance, [], propertyAccess, thisExpr);
6464+
return this.compileCallDirect(instance, [], propertyAccess, thisExpr, inline);
64546465
} else {
64556466
this.currentType = signature.returnType;
6456-
return this.compileCallDirect(instance, [], propertyAccess);
6467+
return this.compileCallDirect(instance, [], propertyAccess, 0, inline);
64576468
}
64586469
} else {
64596470
this.error(

std/assembly.d.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
* @module std/assembly
44
*//***/
55

6+
/// <reference no-default-lib="true"/>
7+
68
// Types
79

810
/** An 8-bit signed integer. */
@@ -467,11 +469,12 @@ declare class Set<T> {
467469
clear(): void;
468470
}
469471

470-
declare class Symbol {
471-
constructor(description?: string | null);
472-
static for(key: string): Symbol;
473-
static keyFor(sym: Symbol): string | null;
472+
interface SymbolConstructor {
473+
(description?: string | null): symbol;
474+
for(key: string): symbol;
475+
keyFor(sym: symbol): string | null;
474476
}
477+
declare const Symbol: SymbolConstructor;
475478

476479
interface IMath<T> {
477480
/** The base of natural logarithms, e, approximately 2.718. */

std/assembly/symbol.ts

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,50 @@
11
import { Map } from "./map";
22

3-
var nextId: usize = 1;
43
var stringToId: Map<string, usize>;
54
var idToString: Map<usize, string>;
5+
var nextId: usize = 12; // Symbol.unscopables + 1
66

7-
export class Symbol {
7+
@unmanaged export class symbol {}
88

9-
static for(key: string): Symbol {
9+
type Symbol = symbol;
10+
11+
export function Symbol(description: string | null = null): symbol {
12+
var id = nextId++;
13+
if (!id) unreachable(); // out of ids
14+
return changetype<symbol>(id);
15+
}
16+
17+
export namespace Symbol {
18+
19+
// well-known symbols
20+
export const hasInstance = changetype<symbol>(1);
21+
export const concatSpreadable = changetype<symbol>(2);
22+
export const isRegExp = changetype<symbol>(3);
23+
export const iterator = changetype<symbol>(3);
24+
export const match = changetype<symbol>(4);
25+
export const replace = changetype<symbol>(5);
26+
export const search = changetype<symbol>(6);
27+
export const species = changetype<symbol>(7);
28+
export const split = changetype<symbol>(8);
29+
export const toPrimitive = changetype<symbol>(9);
30+
export const toStringTag = changetype<symbol>(10);
31+
export const unscopables = changetype<symbol>(11);
32+
33+
/* tslint:disable */// not valid TS
34+
export function for(key: string): symbol {
1035
if (!stringToId) { stringToId = new Map(); idToString = new Map(); }
11-
else if (stringToId.has(key)) return changetype<Symbol>(stringToId.get(key));
36+
else if (stringToId.has(key)) return changetype<symbol>(stringToId.get(key));
1237
var id = nextId++;
1338
if (!id) unreachable(); // out of ids
1439
stringToId.set(key, id);
1540
idToString.set(id, key);
16-
return changetype<Symbol>(id);
41+
return changetype<symbol>(id);
1742
}
43+
/* tslint:enable */
1844

19-
static keyFor(sym: Symbol): string | null {
45+
export function keyFor(sym: symbol): string | null {
2046
return idToString !== null && idToString.has(changetype<usize>(sym))
2147
? idToString.get(changetype<usize>(sym))
2248
: null;
2349
}
24-
25-
constructor(description: string | null = null) {
26-
var id = nextId++;
27-
if (!id) unreachable(); // out of ids
28-
return changetype<Symbol>(id);
29-
}
3050
}

std/portable.d.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
* @module std/portable
1313
*//***/
1414

15+
/// <reference no-default-lib="true"/>
16+
1517
// Portable types
1618

1719
declare type i8 = number;
@@ -309,11 +311,6 @@ declare class Error {
309311
stack: string | null;
310312
}
311313

312-
declare class Symbol {
313-
private constructor();
314-
static readonly iterator: symbol;
315-
}
316-
317314
declare class Set<T> {
318315
constructor(entries?: T[]);
319316
readonly size: i32;
@@ -337,6 +334,14 @@ declare class Map<K,V> {
337334
[Symbol.iterator](): Iterator<[K,V]>;
338335
}
339336

337+
interface SymbolConstructor {
338+
(description?: string | null): symbol;
339+
for(key: string): symbol;
340+
keyFor(sym: symbol): string | null;
341+
readonly iterator: symbol;
342+
}
343+
declare const Symbol: SymbolConstructor;
344+
340345
interface Iterable<T> {
341346
[Symbol.iterator](): Iterator<T>;
342347
}

tests/compiler/abi.untouched.wat

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,35 +14,27 @@
1414
(export "memory" (memory $0))
1515
(start $start)
1616
(func $abi/exported (; 1 ;) (type $i) (result i32)
17-
(return
18-
(i32.shr_s
19-
(i32.shl
20-
(i32.const 128)
21-
(i32.const 24)
22-
)
17+
(i32.shr_s
18+
(i32.shl
19+
(i32.const 128)
2320
(i32.const 24)
2421
)
22+
(i32.const 24)
2523
)
2624
)
2725
(func $abi/exportedExported (; 2 ;) (type $i) (result i32)
28-
(return
29-
(call $abi/exported)
30-
)
26+
(call $abi/exported)
3127
)
3228
(func $abi/internal (; 3 ;) (type $i) (result i32)
33-
(return
34-
(i32.const 128)
35-
)
29+
(i32.const 128)
3630
)
3731
(func $abi/exportedInternal (; 4 ;) (type $i) (result i32)
38-
(return
39-
(i32.shr_s
40-
(i32.shl
41-
(call $abi/internal)
42-
(i32.const 24)
43-
)
32+
(i32.shr_s
33+
(i32.shl
34+
(call $abi/internal)
4435
(i32.const 24)
4536
)
37+
(i32.const 24)
4638
)
4739
)
4840
(func $start (; 5 ;) (type $v)

0 commit comments

Comments
 (0)