Skip to content

Commit fa05a90

Browse files
committed
Merge remote-tracking branch 'origin/master' into release
2 parents d8c8828 + 60c0d83 commit fa05a90

20 files changed

+199
-77
lines changed

examples/sdk/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Browser SDK
2+
===========
3+
4+
An [AssemblyScript](http://assemblyscript.org) example using the [AssemblyScript browser SDK](https://github.com/AssemblyScript/assemblyscript/tree/master/lib/sdk).
5+
6+
Instructions
7+
------------
8+
9+
Open [index.html](./index.html) in a browser and see the console. View the source to learn how it works.

examples/sdk/index.html

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.min.js"></script>
2+
<script>
3+
require([ "https://cdn.jsdelivr.net/npm/assemblyscript@latest/dist/sdk.js" ], function(sdk) {
4+
const { asc } = sdk;
5+
asc.ready.then(() => {
6+
console.log("Running simple example...");
7+
simpleExample(asc);
8+
console.log("\nRunning extended example...");
9+
extendedExample(asc);
10+
});
11+
});
12+
13+
// This uses `asc.compileString`, a convenience API useful if all one wants to
14+
// do is to quickly compile a single source string to WebAssembly.
15+
function simpleExample(asc) {
16+
const { text, binary } = asc.compileString(`export function test(): void {}`, {
17+
optimizeLevel: 3,
18+
runtime: "none"
19+
});
20+
console.log(">>> TEXT >>>\n" + text);
21+
console.log(">>> BINARY >>>\n" + binary.length + " bytes");
22+
}
23+
24+
// The full API works very much like asc on the command line, with additional
25+
// environment bindings being provided to access the (virtual) file system.
26+
function extendedExample(asc) {
27+
const stdout = asc.createMemoryStream();
28+
const stderr = asc.createMemoryStream();
29+
asc.main([
30+
"module.ts",
31+
"-O3",
32+
"--runtime", "none",
33+
"--binaryFile", "module.wasm",
34+
"--textFile", "module.wat",
35+
"--sourceMap"
36+
], {
37+
stdout: stdout,
38+
stderr: stderr,
39+
readFile: (name, baseDir) => {
40+
if (name === "module.ts") return `export function test(): void {}`;
41+
return null;
42+
},
43+
writeFile: (name, data, baseDir) => {
44+
console.log(">>> WRITE:" + name + " >>>\n" + data.length);
45+
},
46+
listFiles: (dirname, baseDir) => {
47+
return [];
48+
}
49+
}, err => {
50+
console.log(">>> STDOUT >>>\n" + stdout.toString());
51+
console.log(">>> STDERR >>>\n" + stderr.toString());
52+
if (err) {
53+
console.log(">>> THROWN >>>");
54+
console.log(err);
55+
}
56+
});
57+
}
58+
</script>
59+
<p>See the browser console!</p>

lib/sdk/README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ Exports
1515
* **binaryen**<br />
1616
The version of binaryen required by the compiler.
1717

18+
* **long**<br />
19+
The version of long.js required by the compiler.
20+
1821
* **assemblyscript**<br />
1922
The AssemblyScript compiler as a library.
2023

@@ -27,12 +30,14 @@ Example usage
2730

2831
```js
2932
require(
30-
["https://cdn.jsdelivr.net/npm/assemblyscript@nightly/dist/sdk"],
33+
["https://cdn.jsdelivr.net/npm/assemblyscript@latest/dist/sdk"],
3134
function(sdk) {
32-
const { binaryen, assemblyscript, asc } = sdk;
35+
const { asc } = sdk;
3336
asc.ready.then(() => {
3437
asc.main(...);
3538
});
3639
}
3740
);
3841
```
42+
43+
There is also the [SDK example](https://github.com/AssemblyScript/assemblyscript/tree/master/examples/sdk) showing how to compile some actual code.

lib/sdk/index.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,22 @@
11
const BINARYEN_VERSION = "nightly";
2+
const LONG_VERSION = "latest";
23
const ASSEMBLYSCRIPT_VERSION = "nightly";
34

45
// AMD/require.js (browser)
56
if (typeof define === "function" && define.amd) {
67
const paths = {
78
"binaryen": "https://cdn.jsdelivr.net/npm/binaryen@" + BINARYEN_VERSION + "/index",
9+
"long": "https://cdn.jsdelivr.net/npm/long@" + LONG_VERSION + "/dist/long",
810
"assemblyscript": "https://cdn.jsdelivr.net/npm/assemblyscript@" + ASSEMBLYSCRIPT_VERSION + "/dist/assemblyscript",
911
"assemblyscript/cli/asc": "https://cdn.jsdelivr.net/npm/assemblyscript@" + ASSEMBLYSCRIPT_VERSION + "/dist/asc",
1012
};
1113
require.config({ paths });
12-
define(Object.keys(paths), (binaryen, assemblyscript, asc) => ({
14+
define(Object.keys(paths), (binaryen, long, assemblyscript, asc) => ({
1315
BINARYEN_VERSION,
16+
LONG_VERSION,
1417
ASSEMBLYSCRIPT_VERSION,
1518
binaryen,
19+
long,
1620
assemblyscript,
1721
asc
1822
}));
@@ -21,8 +25,10 @@ if (typeof define === "function" && define.amd) {
2125
} else if (typeof module === "object" && module.exports) {
2226
module.exports = {
2327
BINARYEN_VERSION,
28+
LONG_VERSION,
2429
ASSEMBLYSCRIPT_VERSION,
2530
binaryen: require("binaryen"),
31+
long: require("long"),
2632
assemblyscript: require("assemblyscript"),
2733
asc: require("assemblyscript/cli/asc")
2834
};

lib/sdk/tests/index.html

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,15 @@
44
if (!x) throw Error("assertion failed");
55
}
66
require(["../index"], function(sdk) {
7-
const { BINARYEN_VERSION, ASSEMBLYSCRIPT_VERSION, binaryen, assemblyscript, asc } = sdk;
7+
const { BINARYEN_VERSION, LONG_VERSION, ASSEMBLYSCRIPT_VERSION, binaryen, long, assemblyscript, asc } = sdk;
88
assert(typeof BINARYEN_VERSION === "string");
9+
assert(typeof LONG_VERSION === "string");
910
assert(typeof ASSEMBLYSCRIPT_VERSION === "string");
1011
console.log("Binaryen@" + BINARYEN_VERSION);
12+
console.log("Long@" + LONG_VERSION);
1113
console.log("AssemblyScript@" + ASSEMBLYSCRIPT_VERSION);
1214
assert(typeof binaryen === "object" && binaryen && typeof binaryen._BinaryenTypeNone === "function");
15+
assert(typeof long === "function" && long && typeof long.fromInt === "function");
1316
assert(typeof assemblyscript === "object" && assemblyscript && typeof assemblyscript.parse === "function");
1417
assert(typeof asc === "object" && asc && typeof asc.main === "function");
1518
asc.ready.then(() => console.log("ready", sdk));

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.20200111",
24+
"binaryen": "90.0.0-nightly.20200128",
2525
"long": "^4.0.0",
2626
"source-map-support": "^0.5.16",
2727
"ts-node": "^6.2.0"

scripts/build-sdk.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
const path = require("path");
22
const fs = require("fs");
3-
const pkg = require("../package.json");
3+
const pkg = require("../package-lock.json");
44

55
fs.readFile(path.join(__dirname, "..", "lib", "sdk", "index.js"), "utf8", function(err, data) {
66
if (err) throw err;
77
data = data
8-
.replace(/BINARYEN_VERSION = "nightly"/, "BINARYEN_VERSION = " + JSON.stringify(pkg.dependencies.binaryen))
8+
.replace(/BINARYEN_VERSION = "nightly"/, "BINARYEN_VERSION = " + JSON.stringify(pkg.dependencies.binaryen.version))
9+
.replace(/LONG_VERSION = "latest"/, "LONG_VERSION = " + JSON.stringify(pkg.dependencies.long.version))
910
.replace(/ASSEMBLYSCRIPT_VERSION = "nightly"/, "ASSEMBLYSCRIPT_VERSION = " + JSON.stringify(pkg.version));
1011
fs.writeFile(path.join(__dirname, "..", "dist", "sdk.js"), data, function(err) {
1112
if (err) throw err;

src/compiler.ts

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,7 @@ export class Compiler extends DiagnosticEmitter {
428428
if (cyclicClasses.size) {
429429
if (options.pedantic) {
430430
for (let classInstance of cyclicClasses) {
431-
this.info(
431+
this.pedantic(
432432
DiagnosticCode.Type_0_is_cyclic_Module_will_include_deferred_garbage_collection,
433433
classInstance.identifierNode.range, classInstance.internalName
434434
);
@@ -504,7 +504,7 @@ export class Compiler extends DiagnosticEmitter {
504504
if (options.importTable) {
505505
module.addTableImport("0", "env", "table");
506506
if (options.pedantic && options.willOptimize) {
507-
this.warning(
507+
this.pedantic(
508508
DiagnosticCode.Importing_the_table_disables_some_indirect_call_optimizations,
509509
null
510510
);
@@ -513,7 +513,7 @@ export class Compiler extends DiagnosticEmitter {
513513
if (options.exportTable) {
514514
module.addTableExport("0", ExportNames.table);
515515
if (options.pedantic && options.willOptimize) {
516-
this.warning(
516+
this.pedantic(
517517
DiagnosticCode.Exporting_the_table_disables_some_indirect_call_optimizations,
518518
null
519519
);
@@ -5578,6 +5578,12 @@ export class Compiler extends DiagnosticEmitter {
55785578
assert(indexedSet.signature.parameterTypes.length == 2); // parser must guarantee this
55795579
targetType = indexedSet.signature.parameterTypes[1]; // 2nd parameter is the element
55805580
if (indexedSet.hasDecorator(DecoratorFlags.UNSAFE)) this.checkUnsafe(expression);
5581+
if (!isUnchecked && this.options.pedantic) {
5582+
this.pedantic(
5583+
DiagnosticCode.Indexed_access_may_involve_bounds_checking,
5584+
expression.range
5585+
);
5586+
}
55815587
break;
55825588
}
55835589
default: {
@@ -7220,11 +7226,18 @@ export class Compiler extends DiagnosticEmitter {
72207226
if (targetType.is(TypeFlags.REFERENCE)) {
72217227
let classReference = targetType.classReference;
72227228
if (classReference) {
7223-
let indexedGet = classReference.lookupOverload(OperatorKind.INDEXED_GET, this.currentFlow.is(FlowFlags.UNCHECKED_CONTEXT));
7229+
let isUnchecked = this.currentFlow.is(FlowFlags.UNCHECKED_CONTEXT);
7230+
let indexedGet = classReference.lookupOverload(OperatorKind.INDEXED_GET, isUnchecked);
72247231
if (indexedGet) {
72257232
let thisArg = this.compileExpression(targetExpression, classReference.type,
72267233
Constraints.CONV_IMPLICIT
72277234
);
7235+
if (!isUnchecked && this.options.pedantic) {
7236+
this.pedantic(
7237+
DiagnosticCode.Indexed_access_may_involve_bounds_checking,
7238+
expression.range
7239+
);
7240+
}
72287241
return this.compileCallDirect(indexedGet, [
72297242
expression.elementExpression
72307243
], expression, thisArg, constraints);
@@ -7671,6 +7684,12 @@ export class Compiler extends DiagnosticEmitter {
76717684
], expression)
76727685
);
76737686
flow.freeTempLocal(temp);
7687+
if (this.options.pedantic) {
7688+
this.pedantic(
7689+
DiagnosticCode.Expression_compiles_to_a_dynamic_check_at_runtime,
7690+
expression.range
7691+
);
7692+
}
76747693
return ret;
76757694
} else {
76767695
this.error(

src/diagnosticMessages.generated.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ export enum DiagnosticCode {
4040
Type_0_is_cyclic_Module_will_include_deferred_garbage_collection = 900,
4141
Importing_the_table_disables_some_indirect_call_optimizations = 901,
4242
Exporting_the_table_disables_some_indirect_call_optimizations = 902,
43+
Expression_compiles_to_a_dynamic_check_at_runtime = 903,
44+
Indexed_access_may_involve_bounds_checking = 904,
4345
Unterminated_string_literal = 1002,
4446
Identifier_expected = 1003,
4547
_0_expected = 1005,
@@ -187,6 +189,8 @@ export function diagnosticCodeToString(code: DiagnosticCode): string {
187189
case 900: return "Type '{0}' is cyclic. Module will include deferred garbage collection.";
188190
case 901: return "Importing the table disables some indirect call optimizations.";
189191
case 902: return "Exporting the table disables some indirect call optimizations.";
192+
case 903: return "Expression compiles to a dynamic check at runtime.";
193+
case 904: return "Indexed access may involve bounds checking.";
190194
case 1002: return "Unterminated string literal.";
191195
case 1003: return "Identifier expected.";
192196
case 1005: return "'{0}' expected.";

src/diagnosticMessages.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
"Type '{0}' is cyclic. Module will include deferred garbage collection.": 900,
3535
"Importing the table disables some indirect call optimizations.": 901,
3636
"Exporting the table disables some indirect call optimizations.": 902,
37+
"Expression compiles to a dynamic check at runtime.": 903,
38+
"Indexed access may involve bounds checking.": 904,
3739

3840
"Unterminated string literal.": 1002,
3941
"Identifier expected.": 1003,

src/diagnostics.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ export {
2424

2525
/** Indicates the category of a {@link DiagnosticMessage}. */
2626
export enum DiagnosticCategory {
27+
/** Overly pedantic message. */
28+
PEDANTIC,
2729
/** Informatory message. */
2830
INFO,
2931
/** Warning message. */
@@ -35,6 +37,7 @@ export enum DiagnosticCategory {
3537
/** Returns the string representation of the specified diagnostic category. */
3638
export function diagnosticCategoryToString(category: DiagnosticCategory): string {
3739
switch (category) {
40+
case DiagnosticCategory.PEDANTIC: return "PEDANTIC";
3841
case DiagnosticCategory.INFO: return "INFO";
3942
case DiagnosticCategory.WARNING: return "WARNING";
4043
case DiagnosticCategory.ERROR: return "ERROR";
@@ -51,12 +54,15 @@ export const COLOR_BLUE: string = "\u001b[96m";
5154
export const COLOR_YELLOW: string = "\u001b[93m";
5255
/** ANSI escape sequence for red foreground. */
5356
export const COLOR_RED: string = "\u001b[91m";
57+
/** ANSI escape sequence for magenta foreground. */
58+
export const COLOR_MAGENTA: string = "\u001b[95m";
5459
/** ANSI escape sequence to reset the foreground color. */
5560
export const COLOR_RESET: string = "\u001b[0m";
5661

5762
/** Returns the ANSI escape sequence for the specified category. */
5863
export function diagnosticCategoryToColor(category: DiagnosticCategory): string {
5964
switch (category) {
65+
case DiagnosticCategory.PEDANTIC: return COLOR_MAGENTA;
6066
case DiagnosticCategory.INFO: return COLOR_BLUE;
6167
case DiagnosticCategory.WARNING: return COLOR_YELLOW;
6268
case DiagnosticCategory.ERROR: return COLOR_RED;
@@ -275,6 +281,29 @@ export abstract class DiagnosticEmitter {
275281
// console.log(<string>new Error("stack").stack);
276282
}
277283

284+
/** Emits an overly pedantic diagnostic message. */
285+
pedantic(
286+
code: DiagnosticCode,
287+
range: Range | null,
288+
arg0: string | null = null,
289+
arg1: string | null = null,
290+
arg2: string | null = null
291+
): void {
292+
this.emitDiagnostic(code, DiagnosticCategory.PEDANTIC, range, null, arg0, arg1, arg2);
293+
}
294+
295+
/** Emits an overly pedantic diagnostic message with a related range. */
296+
pedanticRelated(
297+
code: DiagnosticCode,
298+
range: Range,
299+
relatedRange: Range,
300+
arg0: string | null = null,
301+
arg1: string | null = null,
302+
arg2: string | null = null
303+
): void {
304+
this.emitDiagnostic(code, DiagnosticCategory.PEDANTIC, range, relatedRange, arg0, arg1, arg2);
305+
}
306+
278307
/** Emits an informatory diagnostic message. */
279308
info(
280309
code: DiagnosticCode,

src/glue/binaryen.d.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,23 @@ export declare function _BinaryenModuleSetFeatures(module: BinaryenModuleRef, fe
766766

767767
export declare function _BinaryenAddCustomSection(module: BinaryenModuleRef, name: usize, contents: usize, contentsSize: BinaryenIndex): void;
768768

769+
type BinaryenSideEffects = u32;
770+
771+
export declare function _BinaryenSideEffectNone(): BinaryenSideEffects;
772+
export declare function _BinaryenSideEffectBranches(): BinaryenSideEffects;
773+
export declare function _BinaryenSideEffectCalls(): BinaryenSideEffects;
774+
export declare function _BinaryenSideEffectReadsLocal(): BinaryenSideEffects;
775+
export declare function _BinaryenSideEffectWritesLocal(): BinaryenSideEffects;
776+
export declare function _BinaryenSideEffectReadsGlobal(): BinaryenSideEffects;
777+
export declare function _BinaryenSideEffectWritesGlobal(): BinaryenSideEffects;
778+
export declare function _BinaryenSideEffectReadsMemory(): BinaryenSideEffects;
779+
export declare function _BinaryenSideEffectWritesMemory(): BinaryenSideEffects;
780+
export declare function _BinaryenSideEffectImplicitTrap(): BinaryenSideEffects;
781+
export declare function _BinaryenSideEffectIsAtomic(): BinaryenSideEffects;
782+
export declare function _BinaryenSideEffectAny(): BinaryenSideEffects;
783+
784+
export declare function _BinaryenExpressionGetSideEffects(expr: BinaryenExpressionRef): BinaryenSideEffects;
785+
769786
type BinaryenRelooperRef = usize;
770787
type BinaryenRelooperBlockRef = usize;
771788

0 commit comments

Comments
 (0)