Extract portable AS to its own definition and polyfill; Try running flatten/ssa before default optimizations, see WebAssembly/binaryen#1331

This commit is contained in:
dcodeIO
2017-12-08 19:08:03 +01:00
parent d6b94d4c33
commit 0ebb99a33c
23 changed files with 1515 additions and 1231 deletions

View File

@ -1424,6 +1424,7 @@ export class Compiler extends DiagnosticEmitter {
case Token.AMPERSAND_AMPERSAND: // left && right
left = this.compileExpression(expression.left, contextualType, contextualType == Type.void ? ConversionKind.NONE : ConversionKind.IMPLICIT);
right = this.compileExpression(expression.right, this.currentType);
// TODO: once it's possible to clone 'left', we could check if it is a Const, GetLocal, GetGlobal or Load and avoid the tempLocal
tempLocal = this.currentFunction.addLocal(this.currentType);
return this.module.createIf(
this.currentType.isLongInteger
@ -1440,6 +1441,7 @@ export class Compiler extends DiagnosticEmitter {
case Token.BAR_BAR: // left || right
left = this.compileExpression(expression.left, contextualType, contextualType == Type.void ? ConversionKind.NONE : ConversionKind.IMPLICIT);
right = this.compileExpression(expression.right, this.currentType);
// TODO: same as above
tempLocal = this.currentFunction.addLocal(this.currentType);
return this.module.createIf(
this.currentType.isLongInteger

20
src/glue/js.d.ts vendored
View File

@ -1,20 +1,6 @@
// Aliased AssemblyScript types. Beware of semantic differences.
declare type i8 = number;
declare type u8 = number;
declare type i16 = number;
declare type u16 = number;
declare type i32 = number;
declare type u32 = number;
declare type isize = number;
declare type usize = number;
declare type f32 = number;
declare type f64 = number;
declare type bool = boolean;
/// <reference path="../../portable-assembly.d.ts" />
/// <reference path="./binaryen-c.d.ts" />
// Raw memory access (here: Binaryen memory)
// Raw memory accesses to Binaryen memory
declare function store<T = u8>(ptr: usize, val: T): void;
declare function load<T = u8>(ptr: usize): T;
declare function assert(isTrue: bool): void;
// Other things that might or might not be useful
declare function select<T>(ifTrue: T, ifFalse: T, condition: bool): T;

42
src/glue/js.js Normal file
View File

@ -0,0 +1,42 @@
require("../../portable-assembly");
var globalScope = typeof window !== "undefined" && window || typeof global !== "undefined" && global || self;
var binaryen;
try {
binaryen = require("binaryen");
} catch (e) {
binaryen = globalScope["Binaryen"];
}
for (var key in binaryen)
if (/^_(?:Binaryen|Relooper|malloc$|free$)/.test(key))
globalScope[key] = binaryen[key];
globalScope["store"] = function store(ptr, val) {
binaryen.HEAPU8[ptr] = val;
};
globalScope["load"] = function load_u8(ptr) {
return binaryen.HEAPU8[ptr];
};
var Module = require("../module").Module;
Module.prototype.toBinary = function toBinary(bufferSize) {
if (!bufferSize) bufferSize = 1024 * 1024;
var ptr = _malloc(bufferSize);
var len = this.write(ptr, bufferSize);
var ret = new Uint8Array(len);
ret.set(binaryen.HEAPU8.subarray(ptr, ptr + len));
_free(ptr);
return ret;
}
Module.prototype.toText = function toText() {
var previousPrint = binaryen.print;
var ret = "";
binaryen.print = function print(x) { ret += x + "\n" };
this.print();
binaryen.print = previousPrint;
return ret;
}

View File

@ -1,47 +0,0 @@
const globalScope: any = typeof window !== "undefined" && window || typeof global !== "undefined" && global || self;
globalScope["store"] = function store_u8(ptr: number, val: number) {
binaryen.HEAPU8[ptr] = val;
};
globalScope["load"] = function load_u8(ptr: number) {
return binaryen.HEAPU8[ptr];
};
globalScope["select"] = function select<T>(ifTrue: T, ifFalse: T, condition: bool): T {
return condition ? ifTrue : ifFalse;
};
globalScope["assert"] = function(isTrue: bool): void {
if (!isTrue) throw new Error("assertion failed");
};
let binaryen: any;
try {
binaryen = require("binaryen");
} catch (e) {
binaryen = globalScope["Binaryen"];
}
for (const key in binaryen)
if (/^_(?:Binaryen|Relooper|malloc$|free$)/.test(key))
globalScope[key] = binaryen[key];
import { Module } from "../module";
Module.prototype.toBinary = function(bufferSize = 1048576): Uint8Array {
const ptr = _malloc(bufferSize);
const len = this.write(ptr, bufferSize);
const ret = new Uint8Array(len);
ret.set(binaryen.HEAPU8.subarray(ptr, ptr + len));
_free(ptr);
return ret;
}
Module.prototype.toText = function(): string {
let previousPrint: any = (<any>binaryen)["print"];
let ret: string = "";
binaryen["print"] = function(x: string): void { ret += x + "\n" };
this.print();
binaryen["print"] = previousPrint;
return ret;
}

View File

View File

@ -701,10 +701,13 @@ export class Module {
}
optimize(func: FunctionRef = 0): void {
if (func)
// see: https://github.com/WebAssembly/binaryen/issues/1331#issuecomment-350328175
this.runPasses([ "flatten", "ssa" ], func);
if (func) {
_BinaryenFunctionOptimize(func, this.ref);
else
} else {
_BinaryenModuleOptimize(this.ref);
}
}
runPasses(passes: string[], func: FunctionRef = 0): void {

View File

@ -27,9 +27,7 @@
"diagnosticMessages.generated.ts",
"diagnostics.ts",
"evaluator.ts",
"glue/binaryen.d.ts",
"glue/js.d.ts",
"glue/js.ts",
"index.ts",
"module.ts",
"parser.ts",
@ -43,11 +41,7 @@
],
"assembly": {
"exclude": [
"glue/js.d.ts",
"glue/js.ts"
],
"include": [
"glue/wasm.ts"
"glue/js.d.ts"
]
}
}