mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-06-21 02:31:41 +00:00
Update binaryen.js and enable tee optimizations
This commit is contained in:
100
src/ast.ts
100
src/ast.ts
@ -1028,7 +1028,7 @@ export class StringLiteralExpression extends LiteralExpression {
|
||||
value: string;
|
||||
|
||||
serialize(sb: string[]): void {
|
||||
sb.push(escapeString(this.value));
|
||||
sb.push(stringToLiteral(this.value));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2181,19 +2181,93 @@ function builderEndsWith(sb: string[], code: CharCode): bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Escapes a string to a string literal. */
|
||||
export function escapeString(str: string): string {
|
||||
var k = str.length;
|
||||
var ret = new Array<string>(k);
|
||||
for (var i = 0, c: string; i < k; ++i) {
|
||||
switch (c = str.charAt(i)) {
|
||||
case "\\": ret[i] = "\\\\"; break;
|
||||
case "\"": ret[i] = "\\\""; break;
|
||||
case "\r": ret[i] = "\\r"; break;
|
||||
case "\n": ret[i] = "\\n"; break;
|
||||
case "\0": ret[i] = "\\0"; break;
|
||||
default: ret[i] = c;
|
||||
/** Converts a string to its literal representation including quotes. */
|
||||
export function stringToLiteral(str: string): string {
|
||||
var ret = new Array<string>();
|
||||
var off = 0;
|
||||
for (var i = 0, k = str.length; i < k;) {
|
||||
switch (str.charCodeAt(i)) {
|
||||
|
||||
case CharCode.NULL:
|
||||
if (i > off)
|
||||
ret.push(str.substring(off, off = i + 1));
|
||||
ret.push("\\0");
|
||||
off = ++i;
|
||||
break;
|
||||
|
||||
case CharCode.BACKSPACE:
|
||||
if (i > off)
|
||||
ret.push(str.substring(off, i));
|
||||
off = ++i;
|
||||
ret.push("\\b");
|
||||
break;
|
||||
|
||||
case CharCode.TAB:
|
||||
if (i > off)
|
||||
ret.push(str.substring(off, i));
|
||||
off = ++i;
|
||||
ret.push("\\t");
|
||||
break;
|
||||
|
||||
case CharCode.LINEFEED:
|
||||
if (i > off)
|
||||
ret.push(str.substring(off, i));
|
||||
off = ++i;
|
||||
ret.push("\\n");
|
||||
break;
|
||||
|
||||
case CharCode.VERTICALTAB:
|
||||
if (i > off)
|
||||
ret.push(str.substring(off, i));
|
||||
off = ++i;
|
||||
ret.push("\\v");
|
||||
break;
|
||||
|
||||
case CharCode.FORMFEED:
|
||||
if (i > off)
|
||||
ret.push(str.substring(off, i));
|
||||
off = ++i;
|
||||
ret.push("\\f");
|
||||
break;
|
||||
|
||||
case CharCode.CARRIAGERETURN:
|
||||
if (i > off)
|
||||
ret.push(str.substring(off, i));
|
||||
ret.push("\\r");
|
||||
off = ++i;
|
||||
break;
|
||||
|
||||
case CharCode.DOUBLEQUOTE:
|
||||
if (i > off)
|
||||
ret.push(str.substring(off, i));
|
||||
ret.push("\\\"");
|
||||
off = ++i;
|
||||
break;
|
||||
|
||||
case CharCode.SINGLEQUOTE:
|
||||
if (i > off)
|
||||
ret.push(str.substring(off, i));
|
||||
ret.push("\\'");
|
||||
off = ++i;
|
||||
break;
|
||||
|
||||
case CharCode.BACKSLASH:
|
||||
if (i > off)
|
||||
ret.push(str.substring(off, i));
|
||||
ret.push("\\\\");
|
||||
off = ++i;
|
||||
break;
|
||||
|
||||
default:
|
||||
++i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (off == 0) {
|
||||
assert(ret.length == 0);
|
||||
return "\"" + str + "\"";
|
||||
}
|
||||
if (i > off)
|
||||
ret.push(str.substring(off, i));
|
||||
return "\"" + ret.join("") + "\"";
|
||||
}
|
||||
|
@ -1573,19 +1573,19 @@ export class Compiler extends DiagnosticEmitter {
|
||||
left = this.compileExpression(expression.left, contextualType, ConversionKind.NONE);
|
||||
right = this.compileExpression(expression.right, this.currentType);
|
||||
|
||||
// simplify if left is free of side effects while tolerating two levels of nesting, e.g., i32.load(i32.load(i32.const))
|
||||
// if (condition = this.module.cloneExpression(left, true, 2))
|
||||
// return this.module.createIf(
|
||||
// this.currentType.isLongInteger
|
||||
// ? this.module.createBinary(BinaryOp.NeI64, condition, this.module.createI64(0, 0))
|
||||
// : this.currentType == Type.f64
|
||||
// ? this.module.createBinary(BinaryOp.NeF64, condition, this.module.createF64(0))
|
||||
// : this.currentType == Type.f32
|
||||
// ? this.module.createBinary(BinaryOp.NeF32, condition, this.module.createF32(0))
|
||||
// : condition, // usual case: saves one EQZ when not using EQZ above
|
||||
// right,
|
||||
// left
|
||||
// );
|
||||
// simplify if left is free of side effects while tolerating one level of nesting, e.g., i32.load(i32.const)
|
||||
if (condition = this.module.cloneExpression(left, true, 1))
|
||||
return this.module.createIf(
|
||||
this.currentType.isLongInteger
|
||||
? this.module.createBinary(BinaryOp.NeI64, condition, this.module.createI64(0, 0))
|
||||
: this.currentType == Type.f64
|
||||
? this.module.createBinary(BinaryOp.NeF64, condition, this.module.createF64(0))
|
||||
: this.currentType == Type.f32
|
||||
? this.module.createBinary(BinaryOp.NeF32, condition, this.module.createF32(0))
|
||||
: condition, // usual case: saves one EQZ when not using EQZ above
|
||||
right,
|
||||
left
|
||||
);
|
||||
|
||||
// otherwise use a temporary local for the intermediate value
|
||||
tempLocal = this.currentFunction.getAndFreeTempLocal(this.currentType);
|
||||
@ -1606,19 +1606,19 @@ export class Compiler extends DiagnosticEmitter {
|
||||
left = this.compileExpression(expression.left, contextualType, ConversionKind.NONE);
|
||||
right = this.compileExpression(expression.right, this.currentType);
|
||||
|
||||
// simplify if left is free of side effects while tolerating two levels of nesting
|
||||
// if (condition = this.module.cloneExpression(left, true, 2))
|
||||
// return this.module.createIf(
|
||||
// this.currentType.isLongInteger
|
||||
// ? this.module.createBinary(BinaryOp.NeI64, condition, this.module.createI64(0, 0))
|
||||
// : this.currentType == Type.f64
|
||||
// ? this.module.createBinary(BinaryOp.NeF64, condition, this.module.createF64(0))
|
||||
// : this.currentType == Type.f32
|
||||
// ? this.module.createBinary(BinaryOp.NeF32, condition, this.module.createF32(0))
|
||||
// : condition, // usual case: saves one EQZ when not using EQZ above
|
||||
// left,
|
||||
// right
|
||||
// );
|
||||
// simplify if left is free of side effects while tolerating one level of nesting
|
||||
if (condition = this.module.cloneExpression(left, true, 1))
|
||||
return this.module.createIf(
|
||||
this.currentType.isLongInteger
|
||||
? this.module.createBinary(BinaryOp.NeI64, condition, this.module.createI64(0, 0))
|
||||
: this.currentType == Type.f64
|
||||
? this.module.createBinary(BinaryOp.NeF64, condition, this.module.createF64(0))
|
||||
: this.currentType == Type.f32
|
||||
? this.module.createBinary(BinaryOp.NeF32, condition, this.module.createF32(0))
|
||||
: condition, // usual case: saves one EQZ when not using EQZ above
|
||||
left,
|
||||
right
|
||||
);
|
||||
|
||||
// otherwise use a temporary local for the intermediate value
|
||||
tempLocal = this.currentFunction.getAndFreeTempLocal(this.currentType);
|
||||
|
@ -15,33 +15,15 @@ export type ImportRef = usize;
|
||||
export type ExportRef = usize;
|
||||
export type Index = u32;
|
||||
|
||||
// snip...
|
||||
declare function _BinaryenNone(): NativeType;
|
||||
declare function _BinaryenInt32(): NativeType;
|
||||
declare function _BinaryenInt64(): NativeType;
|
||||
declare function _BinaryenFloat32(): NativeType;
|
||||
declare function _BinaryenFloat64(): NativeType;
|
||||
declare function _BinaryenUndefined(): NativeType;
|
||||
export enum NativeType {
|
||||
None = _BinaryenNone(),
|
||||
I32 = _BinaryenInt32(),
|
||||
I64 = _BinaryenInt64(),
|
||||
F32 = _BinaryenFloat32(),
|
||||
F64 = _BinaryenFloat64(),
|
||||
Unreachable = 5,
|
||||
Auto = _BinaryenUndefined()
|
||||
export enum NativeType {
|
||||
None = _BinaryenTypeNone(),
|
||||
I32 = _BinaryenTypeInt32(),
|
||||
I64 = _BinaryenTypeInt64(),
|
||||
F32 = _BinaryenTypeFloat32(),
|
||||
F64 = _BinaryenTypeFloat64(),
|
||||
Unreachable = _BinaryenTypeUnreachable(),
|
||||
Auto = _BinaryenTypeAuto()
|
||||
}
|
||||
// ...snap, once binaryen is updated
|
||||
|
||||
// export enum NativeType {
|
||||
// None = _BinaryenTypeNone(),
|
||||
// I32 = _BinaryenTypeInt32(),
|
||||
// I64 = _BinaryenTypeInt64(),
|
||||
// F32 = _BinaryenTypeFloat32(),
|
||||
// F64 = _BinaryenTypeFloat64(),
|
||||
// Unreachable = _BinaryenTypeUnreachable(),
|
||||
// Auto = _BinaryenTypeAuto()
|
||||
// }
|
||||
|
||||
export enum ExpressionId {
|
||||
Invalid = _BinaryenInvalidId(),
|
||||
@ -828,28 +810,35 @@ export class Module {
|
||||
case NativeType.I64: return this.createI64(_BinaryenConstGetValueI64Low(expr), _BinaryenConstGetValueI64High(expr));
|
||||
case NativeType.F32: return this.createF32(_BinaryenConstGetValueF32(expr));
|
||||
case NativeType.F64: return this.createF64(_BinaryenConstGetValueF64(expr));
|
||||
default: throw new Error("unexpected constant type");
|
||||
default: throw new Error("concrete type expected");
|
||||
}
|
||||
|
||||
case ExpressionId.GetLocal:
|
||||
return _BinaryenGetLocal(this.ref, _BinaryenGetLocalGetIndex(expr), _BinaryenExpressionGetType(expr));
|
||||
|
||||
// case ExpressionId.GetGlobal: explodes if it doesn't have a name
|
||||
// return _BinaryenGetGlobal(this.ref, _BinaryenGetGlobalGetName(expr), _BinaryenExpressionGetType(expr));
|
||||
case ExpressionId.GetGlobal:
|
||||
var globalName = _BinaryenGetGlobalGetName(expr);
|
||||
if (!globalName)
|
||||
break;
|
||||
return _BinaryenGetGlobal(this.ref, globalName, _BinaryenExpressionGetType(expr));
|
||||
|
||||
case ExpressionId.Load:
|
||||
if (!(nested1 = this.cloneExpression(_BinaryenLoadGetPtr(expr), noSideEffects, maxDepth - 1))) break;
|
||||
if (!(nested1 = this.cloneExpression(_BinaryenLoadGetPtr(expr), noSideEffects, maxDepth - 1)))
|
||||
break;
|
||||
return _BinaryenLoadIsAtomic(expr)
|
||||
? _BinaryenAtomicLoad(this.ref, _BinaryenLoadGetBytes(expr), _BinaryenLoadGetOffset(expr), _BinaryenExpressionGetType(expr), nested1)
|
||||
: _BinaryenLoad(this.ref, _BinaryenLoadGetBytes(expr), _BinaryenLoadIsSigned(expr) ? 1 : 0, _BinaryenLoadGetOffset(expr), _BinaryenLoadGetAlign(expr), _BinaryenExpressionGetType(expr), nested1);
|
||||
|
||||
case ExpressionId.Unary:
|
||||
if (!(nested1 = this.cloneExpression(_BinaryenUnaryGetValue(expr), noSideEffects, maxDepth - 1))) break;
|
||||
if (!(nested1 = this.cloneExpression(_BinaryenUnaryGetValue(expr), noSideEffects, maxDepth - 1)))
|
||||
break;
|
||||
return _BinaryenUnary(this.ref, _BinaryenUnaryGetOp(expr), nested1);
|
||||
|
||||
case ExpressionId.Binary:
|
||||
if (!(nested1 = this.cloneExpression(_BinaryenBinaryGetLeft(expr), noSideEffects, maxDepth - 1))) break;
|
||||
if (!(nested2 = this.cloneExpression(_BinaryenBinaryGetRight(expr), noSideEffects, maxDepth - 1))) break;
|
||||
if (!(nested1 = this.cloneExpression(_BinaryenBinaryGetLeft(expr), noSideEffects, maxDepth - 1)))
|
||||
break;
|
||||
if (!(nested2 = this.cloneExpression(_BinaryenBinaryGetRight(expr), noSideEffects, maxDepth - 1)))
|
||||
break;
|
||||
return _BinaryenBinary(this.ref, _BinaryenBinaryGetOp(expr), nested1, nested2);
|
||||
}
|
||||
return 0;
|
||||
|
Reference in New Issue
Block a user