Skip to content

Commit fe0f07b

Browse files
committed
Merge remote-tracking branch 'origin/master' into release
2 parents eb2a4dc + ac201fe commit fe0f07b

22 files changed

+497
-161
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
![](https://avatars1.githubusercontent.com/u/28916798?s=64) AssemblyScript
22
=================
33

4-
[![Actions Status](https://github.com/AssemblyScript/assemblyscript/workflows/CI/badge.svg)](https://github.com/AssemblyScript/assemblyscript/actions) [![npm](https://img.shields.io/npm/v/assemblyscript.svg?color=0074C1)](https://www.npmjs.com/package/assemblyscript) [![npm@nightly](https://img.shields.io/npm/v/assemblyscript/nightly.svg?color=0074C1)](https://www.npmjs.com/package/assemblyscript)
4+
[![Actions Status](https://github.com/AssemblyScript/assemblyscript/workflows/CI/badge.svg?branch=master&event=push)](https://github.com/AssemblyScript/assemblyscript/actions) [![npm](https://img.shields.io/npm/v/assemblyscript.svg?color=0074C1)](https://www.npmjs.com/package/assemblyscript) [![npm@nightly](https://img.shields.io/npm/v/assemblyscript/nightly.svg?color=0074C1)](https://www.npmjs.com/package/assemblyscript)
55

66
**AssemblyScript** compiles a strict subset of [TypeScript](http://www.typescriptlang.org) (basically JavaScript with types) to [WebAssembly](http://webassembly.org) using [Binaryen](https://github.com/WebAssembly/binaryen). It generates lean and mean WebAssembly modules while being just an `npm install` away.
77

@@ -35,7 +35,7 @@ The core team members and most contributors do this open source work in their fr
3535
Motivation
3636
----------
3737

38-
> You are now able to write WebAssembly, without learning a new language, and harness all these benefits WebAssembly might offer you. I think that is kind of powerful. [...] It [AssemblyScript] is absolutely usable, and very enjoyable! - Surma, [WebAssembly for Web Developers (Google I/O ’19)](https://youtu.be/njt-Qzw0mVY) (May 8th, 2019)
38+
> You are now able to write WebAssembly, without learning a new language, and harness all these benefits WebAssembly might offer you. I think that is kind of powerful. [...] It [AssemblyScript] is absolutely usable, and very enjoyable! - Surma, [WebAssembly for Web Developers (Google I/O ’19)](https://youtu.be/njt-Qzw0mVY) (May 8th, 2019)
3939
4040
> AssemblyScript was frictionless. Not only does it allow you to use TypeScript to write WebAssembly, [...] it also produces glue-free WebAssembly modules that are very small with decent performance. – Surma, [Replacing a hot path in your app's JavaScript with WebAssembly](https://developers.google.com/web/updates/2019/02/hotpath-with-wasm) (Feb 16, 2019)
4141

package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
"url": "https://github.com/AssemblyScript/assemblyscript/issues"
2222
},
2323
"dependencies": {
24-
"binaryen": "90.0.0-nightly.20200128",
24+
"binaryen": "90.0.0-nightly.20200208",
2525
"long": "^4.0.0",
2626
"source-map-support": "^0.5.16",
2727
"ts-node": "^6.2.0"

src/compiler.ts

Lines changed: 25 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -7442,6 +7442,10 @@ export class Compiler extends DiagnosticEmitter {
74427442
return module.ref_null();
74437443
}
74447444
this.currentType = options.usizeType;
7445+
this.warning(
7446+
DiagnosticCode.Expression_resolves_to_unusual_type_0,
7447+
expression.range, this.currentType.toString()
7448+
);
74457449
return options.isWasm64
74467450
? module.i64(0)
74477451
: module.i32(0);
@@ -7778,38 +7782,10 @@ export class Compiler extends DiagnosticEmitter {
77787782
switch (expression.literalKind) {
77797783
case LiteralKind.ARRAY: {
77807784
assert(!implicitlyNegate);
7781-
let elementExpressions = (<ArrayLiteralExpression>expression).elementExpressions;
7782-
7783-
// Infer from first element in auto contexts
7784-
if (contextualType == Type.auto) {
7785-
return this.compileArrayLiteral(
7786-
Type.auto,
7787-
elementExpressions,
7788-
constraints,
7789-
expression
7790-
);
7791-
}
7792-
7793-
// Use contextual type if an array
7794-
if (contextualType.is(TypeFlags.REFERENCE)) {
7795-
let classType = contextualType.classReference;
7796-
if (classType) {
7797-
if (classType.prototype == this.program.arrayPrototype) {
7798-
return this.compileArrayLiteral(
7799-
assert(classType.typeArguments)[0],
7800-
elementExpressions,
7801-
constraints,
7802-
expression
7803-
);
7804-
}
7805-
}
7806-
}
7807-
7808-
this.error(
7809-
DiagnosticCode.The_type_argument_for_type_parameter_0_cannot_be_inferred_from_the_usage_Consider_specifying_the_type_arguments_explicitly,
7810-
expression.range, "T"
7785+
return this.compileArrayLiteral(
7786+
<ArrayLiteralExpression>expression,
7787+
constraints
78117788
);
7812-
return module.unreachable();
78137789
}
78147790
case LiteralKind.FLOAT: {
78157791
let floatValue = (<FloatLiteralExpression>expression).value;
@@ -7875,50 +7851,29 @@ export class Compiler extends DiagnosticEmitter {
78757851
}
78767852

78777853
private compileArrayLiteral(
7878-
elementType: Type,
7879-
expressions: (Expression | null)[],
7880-
constraints: Constraints,
7881-
reportNode: Node
7854+
expression: ArrayLiteralExpression,
7855+
constraints: Constraints
78827856
): ExpressionRef {
78837857
var module = this.module;
7858+
var flow = this.currentFlow;
7859+
7860+
var arrayInstance = this.resolver.lookupExpression(expression, flow, this.currentType);
7861+
if (!arrayInstance) return module.unreachable();
7862+
78847863
var program = this.program;
7885-
var arrayPrototype = assert(program.arrayPrototype);
78867864
var arrayBufferInstance = assert(program.arrayBufferInstance);
7887-
var flow = this.currentFlow;
78887865

78897866
// block those here so compiling expressions doesn't conflict
78907867
var tempThis = flow.getTempLocal(this.options.usizeType);
78917868
var tempDataStart = flow.getTempLocal(arrayBufferInstance.type);
78927869

7893-
// infer common element type in auto contexts
7894-
var length = expressions.length;
7895-
if (elementType == Type.auto) {
7896-
for (let i = 0; i < length; ++i) {
7897-
let expression = expressions[i];
7898-
if (expression) {
7899-
let currentType = this.resolver.resolveExpression(expression, this.currentFlow, elementType);
7900-
if (!currentType) return module.unreachable();
7901-
if (elementType == Type.auto) elementType = currentType;
7902-
else if (currentType != elementType) {
7903-
let commonType = Type.commonDenominator(elementType, currentType, false);
7904-
if (commonType) elementType = commonType;
7905-
// otherwise triggers error further down
7906-
}
7907-
}
7908-
}
7909-
if (elementType /* still */ == Type.auto) {
7910-
this.error(
7911-
DiagnosticCode.The_type_argument_for_type_parameter_0_cannot_be_inferred_from_the_usage_Consider_specifying_the_type_arguments_explicitly,
7912-
reportNode.range, "T"
7913-
);
7914-
return module.unreachable();
7915-
}
7916-
}
7917-
7918-
var arrayInstance = assert(this.resolver.resolveClass(arrayPrototype, [ elementType ]));
7919-
var arrayType = arrayInstance.type;
7870+
assert(arrayInstance.kind == ElementKind.CLASS);
7871+
var arrayType = (<Class>arrayInstance).type;
7872+
var elementType = assert((<Class>arrayInstance).getTypeArgumentsTo(this.program.arrayPrototype))[0];
7873+
var expressions = expression.elementExpressions;
79207874

79217875
// compile value expressions and find out whether all are constant
7876+
var length = expressions.length;
79227877
var values = new Array<ExpressionRef>(length);
79237878
var isStatic = true;
79247879
var nativeElementType = elementType.toNativeType();
@@ -7966,11 +7921,11 @@ export class Compiler extends DiagnosticEmitter {
79667921
program.options.isWasm64
79677922
? module.i64(elementType.alignLog2)
79687923
: module.i32(elementType.alignLog2),
7969-
module.i32(arrayInstance.id),
7924+
module.i32((<Class>arrayInstance).id),
79707925
program.options.isWasm64
79717926
? module.i64(i64_low(bufferAddress), i64_high(bufferAddress))
79727927
: module.i32(i64_low(bufferAddress))
7973-
], reportNode);
7928+
], expression);
79747929
this.currentType = arrayType;
79757930
expr = this.makeRetain(expr);
79767931
if (arrayType.isManaged) {
@@ -7985,13 +7940,13 @@ export class Compiler extends DiagnosticEmitter {
79857940
}
79867941

79877942
// otherwise compile an explicit instantiation with indexed sets
7988-
var setter = arrayInstance.lookupOverload(OperatorKind.INDEXED_SET, true);
7943+
var setter = (<Class>arrayInstance).lookupOverload(OperatorKind.INDEXED_SET, true);
79897944
if (!setter) {
79907945
flow.freeTempLocal(tempThis);
79917946
flow.freeTempLocal(tempDataStart);
79927947
this.error(
79937948
DiagnosticCode.Index_signature_in_type_0_only_permits_reading,
7994-
reportNode.range, arrayInstance.internalName
7949+
expression.range, arrayInstance.internalName
79957950
);
79967951
this.currentType = arrayType;
79977952
return module.unreachable();
@@ -8008,11 +7963,11 @@ export class Compiler extends DiagnosticEmitter {
80087963
program.options.isWasm64
80097964
? module.i64(elementType.alignLog2)
80107965
: module.i32(elementType.alignLog2),
8011-
module.i32(arrayInstance.id),
7966+
module.i32((<Class>arrayInstance).id),
80127967
program.options.isWasm64
80137968
? module.i64(0)
80147969
: module.i32(0)
8015-
], reportNode)
7970+
], expression)
80167971
)
80177972
)
80187973
);

src/diagnosticMessages.generated.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ export enum DiagnosticCode {
3737
_0_must_be_a_power_of_two = 223,
3838
_0_is_not_a_valid_operator = 224,
3939
Expression_cannot_be_represented_by_a_type = 225,
40+
Expression_resolves_to_unusual_type_0 = 226,
4041
Type_0_is_cyclic_Module_will_include_deferred_garbage_collection = 900,
4142
Importing_the_table_disables_some_indirect_call_optimizations = 901,
4243
Exporting_the_table_disables_some_indirect_call_optimizations = 902,
@@ -65,6 +66,7 @@ export enum DiagnosticCode {
6566
An_accessor_cannot_have_type_parameters = 1094,
6667
A_set_accessor_cannot_have_a_return_type_annotation = 1095,
6768
Type_parameter_list_cannot_be_empty = 1098,
69+
Type_argument_list_cannot_be_empty = 1099,
6870
A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement = 1104,
6971
A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement = 1105,
7072
A_return_statement_can_only_be_used_within_a_function_body = 1108,
@@ -186,6 +188,7 @@ export function diagnosticCodeToString(code: DiagnosticCode): string {
186188
case 223: return "'{0}' must be a power of two.";
187189
case 224: return "'{0}' is not a valid operator.";
188190
case 225: return "Expression cannot be represented by a type.";
191+
case 226: return "Expression resolves to unusual type '{0}'.";
189192
case 900: return "Type '{0}' is cyclic. Module will include deferred garbage collection.";
190193
case 901: return "Importing the table disables some indirect call optimizations.";
191194
case 902: return "Exporting the table disables some indirect call optimizations.";
@@ -214,6 +217,7 @@ export function diagnosticCodeToString(code: DiagnosticCode): string {
214217
case 1094: return "An accessor cannot have type parameters.";
215218
case 1095: return "A 'set' accessor cannot have a return type annotation.";
216219
case 1098: return "Type parameter list cannot be empty.";
220+
case 1099: return "Type argument list cannot be empty.";
217221
case 1104: return "A 'continue' statement can only be used within an enclosing iteration statement.";
218222
case 1105: return "A 'break' statement can only be used within an enclosing iteration or switch statement.";
219223
case 1108: return "A 'return' statement can only be used within a function body.";

src/diagnosticMessages.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"'{0}' must be a power of two.": 223,
3131
"'{0}' is not a valid operator.": 224,
3232
"Expression cannot be represented by a type.": 225,
33+
"Expression resolves to unusual type '{0}'.": 226,
3334

3435
"Type '{0}' is cyclic. Module will include deferred garbage collection.": 900,
3536
"Importing the table disables some indirect call optimizations.": 901,
@@ -60,6 +61,7 @@
6061
"An accessor cannot have type parameters.": 1094,
6162
"A 'set' accessor cannot have a return type annotation.": 1095,
6263
"Type parameter list cannot be empty.": 1098,
64+
"Type argument list cannot be empty.": 1099,
6365
"A 'continue' statement can only be used within an enclosing iteration statement.": 1104,
6466
"A 'break' statement can only be used within an enclosing iteration or switch statement.": 1105,
6567
"A 'return' statement can only be used within a function body.": 1108,

src/diagnostics.ts

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
*//***/
66

77
import {
8-
Range
8+
Range,
9+
Source
910
} from "./ast";
1011

1112
import {
@@ -241,7 +242,7 @@ export abstract class DiagnosticEmitter {
241242
/** Diagnostic messages emitted so far. */
242243
diagnostics: DiagnosticMessage[];
243244
/** Diagnostic messages already seen, by range. */
244-
private seen: Map<Range,Set<DiagnosticCode>> = new Map();
245+
private seen: Map<Source,Map<i32,i32[]>> = new Map();
245246

246247
/** Initializes this diagnostic emitter. */
247248
protected constructor(diagnostics: DiagnosticMessage[] | null = null) {
@@ -260,17 +261,23 @@ export abstract class DiagnosticEmitter {
260261
): void {
261262
// It is possible that the same diagnostic is emitted twice, for example
262263
// when compiling generics with different types or when recompiling a loop
263-
// because our initial assumptions didn't hold. Deduplicate these.
264+
// because our initial assumptions didn't hold. It is even possible to get
265+
// multiple instances of the same range during parsing. Deduplicate these.
264266
if (range) {
265267
let seen = this.seen;
266-
if (seen.has(range)) {
267-
let codes = seen.get(range)!;
268-
if (codes.has(code)) return;
269-
codes.add(code);
268+
if (seen.has(range.source)) {
269+
let seenInSource = seen.get(range.source)!;
270+
if (seenInSource.has(range.start)) {
271+
let seenCodesAtPos = seenInSource.get(range.start)!;
272+
if (seenCodesAtPos.includes(code)) return;
273+
seenCodesAtPos.push(code);
274+
} else {
275+
seenInSource.set(range.start, [ code ]);
276+
}
270277
} else {
271-
let codes = new Set<DiagnosticCode>();
272-
codes.add(code);
273-
seen.set(range, codes);
278+
let seenInSource = new Map();
279+
seenInSource.set(range.start, [ code ]);
280+
seen.set(range.source, seenInSource);
274281
}
275282
}
276283
var message = DiagnosticMessage.create(code, category, arg0, arg1, arg2);

src/glue/binaryen.d.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -781,7 +781,7 @@ export declare function _BinaryenSideEffectImplicitTrap(): BinaryenSideEffects;
781781
export declare function _BinaryenSideEffectIsAtomic(): BinaryenSideEffects;
782782
export declare function _BinaryenSideEffectAny(): BinaryenSideEffects;
783783

784-
export declare function _BinaryenExpressionGetSideEffects(expr: BinaryenExpressionRef): BinaryenSideEffects;
784+
export declare function _BinaryenExpressionGetSideEffects(expr: BinaryenExpressionRef, features: BinaryenFeatureFlags): BinaryenSideEffects;
785785

786786
type BinaryenRelooperRef = usize;
787787
type BinaryenRelooperBlockRef = usize;
@@ -799,5 +799,10 @@ export declare function _BinaryenGetShrinkLevel(): i32;
799799
export declare function _BinaryenSetShrinkLevel(level: i32): void;
800800
export declare function _BinaryenGetDebugInfo(): bool;
801801
export declare function _BinaryenSetDebugInfo(on: bool): void;
802+
export declare function _BinaryenGetLowMemoryUnused(): bool;
803+
export declare function _BinaryenSetLowMemoryUnused(on: bool): void;
804+
export declare function _BinaryenGetPassArgument(key: usize): usize;
805+
export declare function _BinaryenSetPassArgument(key: usize, value: usize): void;
806+
export declare function _BinaryenClearPassArguments(): void;
802807

803808
export declare function _BinaryenSetAPITracing(on: bool): void;

0 commit comments

Comments
 (0)