mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-04-25 23:12:19 +00:00
Fix unsigned ops; Fix parenthesized conversion; Minor restructure
This commit is contained in:
parent
b5ffaf36cd
commit
b5cc2f9924
@ -14,6 +14,11 @@ Development status
|
||||
|
||||
This version of the compiler (0.5.0, NEXT) is relatively new and does not yet support some features a TypeScript programmer might expect, e.g., strings, arrays and classes. For now, you can see the [compiler tests](https://github.com/AssemblyScript/next/tree/master/tests/compiler) for an overview of what's supposed to be working already.
|
||||
|
||||
A few early examples to get an idea:
|
||||
|
||||
* [memcpy](./tests/compiler/memcpy.ts) using load/store derived from [musl](http://www.musl-libc.org)
|
||||
* Conway's [Game of Life](./tests/compiler/game-of-life.ts) ([html](./tests/compiler/game-of-life.html)) as seen on [dcode.io](http://dcode.io)
|
||||
|
||||
Getting started
|
||||
---------------
|
||||
|
||||
@ -25,7 +30,7 @@ $> cd next
|
||||
$> npm install
|
||||
```
|
||||
|
||||
Author your module in AssemblyScript ([definitions](./assembly.d.ts)) or portable AssemblyScript ([definitions](./portable-assembly.d.ts)) and run:
|
||||
Author your module in AssemblyScript ([definitions](./assembly.d.ts), [base config](./assembly.json)) or portable AssemblyScript ([definitions](./portable.d.ts), [base config](./portable.json) and run:
|
||||
|
||||
```
|
||||
$> node bin\asc yourModule.ts
|
||||
|
1
portable-assembly.d.ts → portable.d.ts
vendored
1
portable-assembly.d.ts → portable.d.ts
vendored
@ -108,6 +108,7 @@ declare interface IArguments {}
|
||||
declare class Error {
|
||||
constructor(message: string);
|
||||
message: string;
|
||||
stack: string | null;
|
||||
}
|
||||
|
||||
declare class Symbol {
|
@ -14,8 +14,8 @@
|
||||
"allowJs": true
|
||||
},
|
||||
"files": [
|
||||
"./portable-assembly.d.ts",
|
||||
"./portable-assembly.js",
|
||||
"./portable.d.ts",
|
||||
"./portable.js",
|
||||
"./std/portable/heap.d.ts",
|
||||
"./std/portable/heap.js"
|
||||
]
|
@ -1277,9 +1277,9 @@ export class Compiler extends DiagnosticEmitter {
|
||||
|
||||
compileAssertionExpression(expression: AssertionExpression, contextualType: Type): ExpressionRef {
|
||||
const toType: Type | null = this.program.resolveType(expression.toType, this.currentFunction.contextualTypeArguments); // reports
|
||||
return toType && toType != contextualType
|
||||
? this.compileExpression(expression.expression, <Type>toType, ConversionKind.EXPLICIT)
|
||||
: this.compileExpression(expression.expression, contextualType);
|
||||
if (!toType)
|
||||
return this.module.createUnreachable();
|
||||
return this.compileExpression(expression.expression, toType, ConversionKind.EXPLICIT);
|
||||
}
|
||||
|
||||
compileBinaryExpression(expression: BinaryExpression, contextualType: Type): ExpressionRef {
|
||||
@ -1300,9 +1300,13 @@ export class Compiler extends DiagnosticEmitter {
|
||||
? BinaryOp.LtF32
|
||||
: this.currentType == Type.f64
|
||||
? BinaryOp.LtF64
|
||||
: this.currentType.isLongInteger
|
||||
: this.currentType.isSignedInteger
|
||||
? this.currentType.isLongInteger
|
||||
? BinaryOp.LtI64
|
||||
: BinaryOp.LtI32;
|
||||
: BinaryOp.LtI32
|
||||
: this.currentType.isLongInteger
|
||||
? BinaryOp.LtU64
|
||||
: BinaryOp.LtU32;
|
||||
this.currentType = Type.bool;
|
||||
break;
|
||||
|
||||
@ -1313,9 +1317,13 @@ export class Compiler extends DiagnosticEmitter {
|
||||
? BinaryOp.GtF32
|
||||
: this.currentType == Type.f64
|
||||
? BinaryOp.GtF64
|
||||
: this.currentType.isLongInteger
|
||||
: this.currentType.isSignedInteger
|
||||
? this.currentType.isLongInteger
|
||||
? BinaryOp.GtI64
|
||||
: BinaryOp.GtI32;
|
||||
: BinaryOp.GtI32
|
||||
: this.currentType.isLongInteger
|
||||
? BinaryOp.GtU64
|
||||
: BinaryOp.GtU32;
|
||||
this.currentType = Type.bool;
|
||||
break;
|
||||
|
||||
@ -1326,9 +1334,13 @@ export class Compiler extends DiagnosticEmitter {
|
||||
? BinaryOp.LeF32
|
||||
: this.currentType == Type.f64
|
||||
? BinaryOp.LeF64
|
||||
: this.currentType.isLongInteger
|
||||
: this.currentType.isSignedInteger
|
||||
? this.currentType.isLongInteger
|
||||
? BinaryOp.LeI64
|
||||
: BinaryOp.LeI32;
|
||||
: BinaryOp.LeI32
|
||||
: this.currentType.isLongInteger
|
||||
? BinaryOp.LeU64
|
||||
: BinaryOp.LeU32;
|
||||
this.currentType = Type.bool;
|
||||
break;
|
||||
|
||||
@ -1339,9 +1351,13 @@ export class Compiler extends DiagnosticEmitter {
|
||||
? BinaryOp.GeF32
|
||||
: this.currentType == Type.f64
|
||||
? BinaryOp.GeF64
|
||||
: this.currentType.isLongInteger
|
||||
: this.currentType.isSignedInteger
|
||||
? this.currentType.isLongInteger
|
||||
? BinaryOp.GeI64
|
||||
: BinaryOp.GeI32;
|
||||
: BinaryOp.GeI32
|
||||
: this.currentType.isLongInteger
|
||||
? BinaryOp.GeU64
|
||||
: BinaryOp.GeU32;
|
||||
this.currentType = Type.bool;
|
||||
break;
|
||||
|
||||
@ -1427,9 +1443,13 @@ export class Compiler extends DiagnosticEmitter {
|
||||
? BinaryOp.DivF32
|
||||
: this.currentType == Type.f64
|
||||
? BinaryOp.DivF64
|
||||
: this.currentType.isLongInteger
|
||||
: this.currentType.isSignedInteger
|
||||
? this.currentType.isLongInteger
|
||||
? BinaryOp.DivI64
|
||||
: BinaryOp.DivI32;
|
||||
: BinaryOp.DivI32
|
||||
: this.currentType.isLongInteger
|
||||
? BinaryOp.DivU64
|
||||
: BinaryOp.DivU32;
|
||||
break;
|
||||
|
||||
case Token.PERCENT_EQUALS:
|
||||
@ -1439,15 +1459,19 @@ export class Compiler extends DiagnosticEmitter {
|
||||
right = this.compileExpression(expression.right, this.currentType);
|
||||
if (this.currentType.isAnyFloat)
|
||||
throw new Error("not implemented"); // TODO: internal fmod, possibly simply imported from JS
|
||||
op = this.currentType.isLongInteger
|
||||
op = this.currentType.isSignedInteger
|
||||
? this.currentType.isLongInteger
|
||||
? BinaryOp.RemI64
|
||||
: BinaryOp.RemI32;
|
||||
: BinaryOp.RemI32
|
||||
: this.currentType.isLongInteger
|
||||
? BinaryOp.RemU64
|
||||
: BinaryOp.RemU32;
|
||||
break;
|
||||
|
||||
case Token.LESSTHAN_LESSTHAN_EQUALS:
|
||||
compound = Token.EQUALS;
|
||||
case Token.LESSTHAN_LESSTHAN:
|
||||
left = this.compileExpression(expression.left, contextualType.isAnyFloat ? Type.i64 : contextualType, contextualType == Type.void ? ConversionKind.NONE : ConversionKind.IMPLICIT);
|
||||
left = this.compileExpression(expression.left, contextualType.isAnyFloat ? Type.i64 : contextualType, ConversionKind.NONE);
|
||||
right = this.compileExpression(expression.right, this.currentType);
|
||||
op = this.currentType.isLongInteger
|
||||
? BinaryOp.ShlI64
|
||||
@ -1457,7 +1481,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
case Token.GREATERTHAN_GREATERTHAN_EQUALS:
|
||||
compound = Token.EQUALS;
|
||||
case Token.GREATERTHAN_GREATERTHAN:
|
||||
left = this.compileExpression(expression.left, contextualType.isAnyFloat ? Type.i64 : contextualType, contextualType == Type.void ? ConversionKind.NONE : ConversionKind.IMPLICIT);
|
||||
left = this.compileExpression(expression.left, contextualType.isAnyFloat ? Type.i64 : contextualType, ConversionKind.NONE);
|
||||
right = this.compileExpression(expression.right, this.currentType);
|
||||
op = this.currentType.isSignedInteger
|
||||
? this.currentType.isLongInteger
|
||||
@ -1471,7 +1495,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
case Token.GREATERTHAN_GREATERTHAN_GREATERTHAN_EQUALS:
|
||||
compound = Token.EQUALS;
|
||||
case Token.GREATERTHAN_GREATERTHAN_GREATERTHAN:
|
||||
left = this.compileExpression(expression.left, contextualType.isAnyFloat ? Type.u64 : contextualType, contextualType == Type.void ? ConversionKind.NONE : ConversionKind.IMPLICIT);
|
||||
left = this.compileExpression(expression.left, contextualType.isAnyFloat ? Type.u64 : contextualType, ConversionKind.NONE);
|
||||
right = this.compileExpression(expression.right, this.currentType);
|
||||
op = this.currentType.isLongInteger
|
||||
? BinaryOp.ShrU64
|
||||
@ -1481,7 +1505,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
case Token.AMPERSAND_EQUALS:
|
||||
compound = Token.EQUALS;
|
||||
case Token.AMPERSAND:
|
||||
left = this.compileExpression(expression.left, contextualType.isAnyFloat ? Type.i64 : contextualType, contextualType == Type.void ? ConversionKind.NONE : ConversionKind.IMPLICIT);
|
||||
left = this.compileExpression(expression.left, contextualType.isAnyFloat ? Type.i64 : contextualType, ConversionKind.NONE);
|
||||
right = this.compileExpression(expression.right, this.currentType);
|
||||
op = this.currentType.isLongInteger
|
||||
? BinaryOp.AndI64
|
||||
@ -1491,7 +1515,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
case Token.BAR_EQUALS:
|
||||
compound = Token.EQUALS;
|
||||
case Token.BAR:
|
||||
left = this.compileExpression(expression.left, contextualType.isAnyFloat ? Type.i64 : contextualType, contextualType == Type.void ? ConversionKind.NONE : ConversionKind.IMPLICIT);
|
||||
left = this.compileExpression(expression.left, contextualType.isAnyFloat ? Type.i64 : contextualType, ConversionKind.NONE);
|
||||
right = this.compileExpression(expression.right, this.currentType);
|
||||
op = this.currentType.isLongInteger
|
||||
? BinaryOp.OrI64
|
||||
@ -1501,7 +1525,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
case Token.CARET_EQUALS:
|
||||
compound = Token.EQUALS;
|
||||
case Token.CARET:
|
||||
left = this.compileExpression(expression.left, contextualType.isAnyFloat ? Type.i64 : contextualType, contextualType == Type.void ? ConversionKind.NONE : ConversionKind.IMPLICIT);
|
||||
left = this.compileExpression(expression.left, contextualType.isAnyFloat ? Type.i64 : contextualType, ConversionKind.NONE);
|
||||
right = this.compileExpression(expression.right, this.currentType);
|
||||
op = this.currentType.isLongInteger
|
||||
? BinaryOp.XorI64
|
||||
@ -1509,7 +1533,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
break;
|
||||
|
||||
case Token.AMPERSAND_AMPERSAND: // left && right
|
||||
left = this.compileExpression(expression.left, contextualType, contextualType == Type.void ? ConversionKind.NONE : ConversionKind.IMPLICIT);
|
||||
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))
|
||||
@ -1542,7 +1566,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);
|
||||
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
|
||||
@ -1782,16 +1806,15 @@ export class Compiler extends DiagnosticEmitter {
|
||||
// local
|
||||
if (element.kind == ElementKind.LOCAL) {
|
||||
this.currentType = (<Local>element).type;
|
||||
return this.module.createGetLocal((<Local>element).index, typeToNativeType(this.currentType = (<Local>element).type));
|
||||
return this.module.createGetLocal((<Local>element).index, typeToNativeType(this.currentType));
|
||||
}
|
||||
|
||||
// global
|
||||
if (element.kind == ElementKind.GLOBAL) {
|
||||
const global: Global = <Global>element;
|
||||
if (global.type)
|
||||
this.currentType = <Type>global.type;
|
||||
if (!this.compileGlobal(global)) // reports
|
||||
return this.module.createUnreachable();
|
||||
this.currentType = <Type>global.type;
|
||||
if (global.hasConstantValue) {
|
||||
if (global.type == Type.f32)
|
||||
return this.module.createF32((<Global>element).constantFloatValue);
|
||||
@ -1804,7 +1827,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
else
|
||||
throw new Error("unexpected global type");
|
||||
} else
|
||||
return this.module.createGetGlobal((<Global>element).internalName, typeToNativeType(this.currentType = <Type>(<Global>element).type));
|
||||
return this.module.createGetGlobal((<Global>element).internalName, typeToNativeType(this.currentType));
|
||||
}
|
||||
|
||||
// field
|
||||
@ -1859,7 +1882,8 @@ export class Compiler extends DiagnosticEmitter {
|
||||
}
|
||||
|
||||
compileParenthesizedExpression(expression: ParenthesizedExpression, contextualType: Type): ExpressionRef {
|
||||
return this.compileExpression(expression.expression, contextualType);
|
||||
// does not change types, just order
|
||||
return this.compileExpression(expression.expression, contextualType, ConversionKind.NONE);
|
||||
}
|
||||
|
||||
compilePropertyAccessExpression(expression: PropertyAccessExpression, contextualType: Type): ExpressionRef {
|
||||
|
167
src/decompiler.ts
Normal file
167
src/decompiler.ts
Normal file
@ -0,0 +1,167 @@
|
||||
import {
|
||||
Module,
|
||||
NativeType,
|
||||
ExpressionId,
|
||||
UnaryOp,
|
||||
BinaryOp,
|
||||
HostOp,
|
||||
FunctionTypeRef,
|
||||
FunctionRef,
|
||||
ExpressionRef,
|
||||
|
||||
getFunctionBody,
|
||||
getExpressionId,
|
||||
getExpressionType,
|
||||
getUnaryOp,
|
||||
getUnaryValue,
|
||||
getBinaryOp,
|
||||
getBinaryLeft,
|
||||
getBinaryRight,
|
||||
getSelectIfTrue,
|
||||
getSelectIfFalse,
|
||||
getSelectCondition,
|
||||
getHostOp,
|
||||
getHostNameOperand,
|
||||
getHostOperands,
|
||||
getConstValueI32,
|
||||
getConstValueI64Low,
|
||||
getConstValueI64High,
|
||||
getConstValueF32,
|
||||
getConstValueF64,
|
||||
getReturnValue,
|
||||
getDropValue
|
||||
} from "./module";
|
||||
import { I64 } from "./util";
|
||||
|
||||
// TODO :-)
|
||||
|
||||
class Decompiler {
|
||||
|
||||
name: string;
|
||||
text: string[] = [];
|
||||
|
||||
private tempI64: I64 = new I64();
|
||||
|
||||
// Decide whether to decompile to an AST or to text directly.
|
||||
// AST is a bit more useful, text a lot more efficient.
|
||||
|
||||
constructor(name: string = "module.ts") {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/** Decompiles a module to an AST that can then be serialized. */
|
||||
decompile(module: Module) {
|
||||
throw new Error("not implemented");
|
||||
}
|
||||
|
||||
decompileFunction(func: FunctionRef): void {
|
||||
const body: ExpressionRef = getFunctionBody(func);
|
||||
throw new Error("not implemented");
|
||||
}
|
||||
|
||||
decompileExpression(expr: ExpressionRef): void {
|
||||
const id: ExpressionId = getExpressionId(expr);
|
||||
const type: NativeType = getExpressionType(expr);
|
||||
|
||||
switch (id) {
|
||||
case ExpressionId.Block:
|
||||
case ExpressionId.If:
|
||||
case ExpressionId.Loop:
|
||||
case ExpressionId.Break:
|
||||
case ExpressionId.Switch:
|
||||
case ExpressionId.Call:
|
||||
case ExpressionId.CallImport:
|
||||
case ExpressionId.CallIndirect:
|
||||
case ExpressionId.GetLocal:
|
||||
case ExpressionId.SetLocal:
|
||||
case ExpressionId.GetGlobal:
|
||||
case ExpressionId.SetGlobal:
|
||||
case ExpressionId.Load:
|
||||
case ExpressionId.Store:
|
||||
case ExpressionId.Const:
|
||||
switch (type) {
|
||||
case NativeType.I32:
|
||||
this.text.push(getConstValueI32(expr).toString(10));
|
||||
return;
|
||||
case NativeType.I64:
|
||||
this.tempI64.lo = getConstValueI64Low(expr);
|
||||
this.tempI64.hi = getConstValueI64High(expr);
|
||||
this.text.push(this.tempI64.toString());
|
||||
return;
|
||||
case NativeType.F32:
|
||||
this.text.push(getConstValueF32(expr).toString(10));
|
||||
return;
|
||||
case NativeType.F64:
|
||||
this.text.push(getConstValueF64(expr).toString(10));
|
||||
return;
|
||||
default:
|
||||
throw new Error("unexpected const type");
|
||||
}
|
||||
case ExpressionId.Unary:
|
||||
switch (getUnaryOp(expr)) {
|
||||
// TODO
|
||||
}
|
||||
this.decompileExpression(getUnaryValue(expr));
|
||||
return;
|
||||
case ExpressionId.Binary:
|
||||
this.decompileExpression(getBinaryLeft(expr));
|
||||
switch (getBinaryOp(expr)) {
|
||||
// TODO
|
||||
}
|
||||
this.decompileExpression(getBinaryRight(expr));
|
||||
return;
|
||||
case ExpressionId.Select:
|
||||
this.text.push("select<");
|
||||
this.text.push(nativeTypeToType(type));
|
||||
this.text.push(">(");
|
||||
this.decompileExpression(getSelectIfTrue(expr));
|
||||
this.text.push(", ");
|
||||
this.decompileExpression(getSelectIfFalse(expr));
|
||||
this.text.push(", ");
|
||||
this.decompileExpression(getSelectCondition(expr));
|
||||
this.text.push(");");
|
||||
return;
|
||||
case ExpressionId.Drop:
|
||||
this.decompileExpression(getDropValue(expr));
|
||||
this.text.push(";");
|
||||
return;
|
||||
case ExpressionId.Return:
|
||||
if (type == NativeType.None) {
|
||||
this.text.push("return;");
|
||||
} else {
|
||||
this.text.push("return ");
|
||||
this.decompileExpression(getReturnValue(expr));
|
||||
this.text.push(";");
|
||||
}
|
||||
return;
|
||||
case ExpressionId.Host:
|
||||
switch (getHostOp(expr)) {
|
||||
case HostOp.CurrentMemory:
|
||||
case HostOp.GrowMemory:
|
||||
}
|
||||
break;
|
||||
case ExpressionId.Nop:
|
||||
this.text.push(";");
|
||||
return;
|
||||
case ExpressionId.Unreachable:
|
||||
this.text.push("unreachable()");
|
||||
return;
|
||||
case ExpressionId.AtomicCmpxchg:
|
||||
case ExpressionId.AtomicRMW:
|
||||
case ExpressionId.AtomicWait:
|
||||
case ExpressionId.AtomicWake:
|
||||
}
|
||||
throw new Error("not implemented")
|
||||
}
|
||||
}
|
||||
|
||||
function nativeTypeToType(type: NativeType): string {
|
||||
switch (type) {
|
||||
case NativeType.None: return "void";
|
||||
case NativeType.I32: return "i32";
|
||||
case NativeType.I64: return "i64";
|
||||
case NativeType.F32: return "f32";
|
||||
case NativeType.F64: return "f64";
|
||||
default: throw new Error("unexpected type");
|
||||
}
|
||||
}
|
3
src/glue/js.d.ts
vendored
3
src/glue/js.d.ts
vendored
@ -1,3 +0,0 @@
|
||||
// Raw memory accesses to Binaryen memory
|
||||
declare function store<T = u8>(ptr: usize, val: T): void;
|
||||
declare function load<T = u8>(ptr: usize): T;
|
@ -1,4 +1,4 @@
|
||||
require("../../portable-assembly");
|
||||
require("../../portable");
|
||||
|
||||
// Copy Binaryen exports to global scope
|
||||
var globalScope = typeof window !== "undefined" && window || typeof global !== "undefined" && global || self;
|
||||
|
@ -859,6 +859,41 @@ export function getBinaryRight(expr: ExpressionRef): ExpressionRef {
|
||||
return _BinaryenBinaryGetRight(expr);
|
||||
}
|
||||
|
||||
export function getSelectIfTrue(expr: ExpressionRef): ExpressionRef {
|
||||
return _BinaryenSelectGetIfTrue(expr);
|
||||
}
|
||||
|
||||
export function getSelectIfFalse(expr: ExpressionRef): ExpressionRef {
|
||||
return _BinaryenSelectGetIfFalse(expr);
|
||||
}
|
||||
|
||||
export function getSelectCondition(expr: ExpressionRef): ExpressionRef {
|
||||
return _BinaryenSelectGetCondition(expr);
|
||||
}
|
||||
|
||||
export function getReturnValue(expr: ExpressionRef): ExpressionRef {
|
||||
return _BinaryenReturnGetValue(expr);
|
||||
}
|
||||
|
||||
export function getDropValue(expr: ExpressionRef): ExpressionRef {
|
||||
return _BinaryenDropGetValue(expr);
|
||||
}
|
||||
|
||||
export function getHostOp(expr: ExpressionRef): HostOp {
|
||||
return _BinaryenHostGetOp(expr);
|
||||
}
|
||||
|
||||
export function getHostNameOperand(expr: ExpressionRef): string {
|
||||
return readString(_BinaryenHostGetNameOperand(expr));
|
||||
}
|
||||
|
||||
export function getHostOperands(expr: ExpressionRef): BinaryenExpressionRef[] {
|
||||
const num: Index = _BinaryenHostGetNumOperands(expr);
|
||||
const arr: BinaryenExpressionRef[] = new Array(num);
|
||||
for (let i: Index = 0; i < num; ++i) arr[i] = _BinaryenHostGetOperand(expr, i);
|
||||
return arr;
|
||||
}
|
||||
|
||||
export class Relooper {
|
||||
|
||||
module: Module;
|
||||
|
@ -306,6 +306,10 @@ export class Range {
|
||||
|
||||
get atStart(): Range { return new Range(this.source, this.start, this.start); }
|
||||
get atEnd(): Range { return new Range(this.source, this.end, this.end); }
|
||||
|
||||
toString(): string {
|
||||
return this.source.text.substring(this.start, this.end);
|
||||
}
|
||||
}
|
||||
|
||||
export class Tokenizer extends DiagnosticEmitter {
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"extends": "../portable-assembly.json",
|
||||
"extends": "../portable.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../out",
|
||||
"sourceMap": true
|
||||
|
36
std/assembly/array.ts
Normal file
36
std/assembly/array.ts
Normal file
@ -0,0 +1,36 @@
|
||||
// Multiple options:
|
||||
// 1. C-like with no 'length' or 'push'
|
||||
// 2. Descriptors that can be constructed from lower level arrays
|
||||
|
||||
class Array<T> {
|
||||
|
||||
readonly capacity: i32;
|
||||
length: i32;
|
||||
ptr: usize;
|
||||
|
||||
static fromPtr<T>(ptr: usize, capacity: i32): Array<T> {
|
||||
assert(capacity >= 0);
|
||||
const arr: Array<T> = new Array(0);
|
||||
store<i32>(changetype<Array<T>, usize>(arr), capacity);
|
||||
arr.length = ptr;
|
||||
arr.ptr = ptr;
|
||||
return arr;
|
||||
}
|
||||
|
||||
constructor(capacity: i32 = 0) {
|
||||
assert(capacity >= 0);
|
||||
this.capacity = this.length = capacity;
|
||||
if (capacity > 0) {
|
||||
this.ptr = Heap.allocate(<usize>capacity);
|
||||
} else {
|
||||
this.ptr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
store<i64>(changetype<this,usize>(this), 0);
|
||||
Heap.dispose(this.ptr);
|
||||
this.ptr = 0;
|
||||
Heap.dispose(changetype<this,usize>(this));
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
var globalScope = typeof window !== "undefined" && window || typeof global !== "undefined" && global || self;
|
||||
|
||||
var HEAP = new Uint8Array(65536);
|
||||
var HEAP = new Uint8Array(0);
|
||||
var HEAP_OFFSET = 0;
|
||||
|
||||
Object.defineProperties(globalScope["Heap"] = {
|
||||
@ -8,7 +8,7 @@ Object.defineProperties(globalScope["Heap"] = {
|
||||
if (!size) return 0;
|
||||
if (HEAP_OFFSET + size > HEAP.length) {
|
||||
var oldHeap = HEAP;
|
||||
HEAP = new Uint8Array(Math.max(HEAP.length + size, HEAP.length * 2));
|
||||
HEAP = new Uint8Array(Math.max(65536, HEAP.length + size, HEAP.length * 2));
|
||||
HEAP.set(oldHeap);
|
||||
}
|
||||
var ptr = HEAP_OFFSET;
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"extends": "../../portable-assembly.json",
|
||||
"extends": "../../portable.json",
|
||||
"compilerOptions": {
|
||||
"diagnostics": true
|
||||
},
|
||||
|
@ -48,7 +48,7 @@
|
||||
)
|
||||
(loop $continue|0
|
||||
(if
|
||||
(i32.lt_s
|
||||
(i32.lt_u
|
||||
(get_local $0)
|
||||
(get_global $game-of-life/h)
|
||||
)
|
||||
@ -81,7 +81,7 @@
|
||||
)
|
||||
(loop $continue|1
|
||||
(if
|
||||
(i32.lt_s
|
||||
(i32.lt_u
|
||||
(get_local $1)
|
||||
(get_global $game-of-life/w)
|
||||
)
|
||||
@ -208,13 +208,13 @@
|
||||
(if
|
||||
(if (result i32)
|
||||
(tee_local $3
|
||||
(i32.lt_s
|
||||
(i32.lt_u
|
||||
(get_local $2)
|
||||
(i32.const 2)
|
||||
)
|
||||
)
|
||||
(get_local $3)
|
||||
(i32.gt_s
|
||||
(i32.gt_u
|
||||
(get_local $2)
|
||||
(i32.const 3)
|
||||
)
|
||||
|
@ -63,7 +63,7 @@
|
||||
)
|
||||
(loop $continue|0
|
||||
(if
|
||||
(i32.lt_s
|
||||
(i32.lt_u
|
||||
(get_local $0)
|
||||
(get_global $game-of-life/h)
|
||||
)
|
||||
@ -101,7 +101,7 @@
|
||||
)
|
||||
(loop $continue|1
|
||||
(if
|
||||
(i32.lt_s
|
||||
(i32.lt_u
|
||||
(get_local $3)
|
||||
(get_global $game-of-life/w)
|
||||
)
|
||||
@ -237,13 +237,13 @@
|
||||
(if
|
||||
(if (result i32)
|
||||
(tee_local $11
|
||||
(i32.lt_s
|
||||
(i32.lt_u
|
||||
(get_local $8)
|
||||
(i32.const 2)
|
||||
)
|
||||
)
|
||||
(get_local $11)
|
||||
(i32.gt_s
|
||||
(i32.gt_u
|
||||
(get_local $8)
|
||||
(i32.const 3)
|
||||
)
|
||||
|
301
tests/compiler/i64.optimized.wast
Normal file
301
tests/compiler/i64.optimized.wast
Normal file
@ -0,0 +1,301 @@
|
||||
(module
|
||||
(type $iiiiv (func (param i32 i32 i32 i32)))
|
||||
(global $i64/lo (mut i32) (i32.const 0))
|
||||
(global $i64/hi (mut i32) (i32.const 0))
|
||||
(memory $0 1)
|
||||
(export "add" (func $i64/add))
|
||||
(export "sub" (func $i64/sub))
|
||||
(export "mul" (func $i64/mul))
|
||||
(export "div_s" (func $i64/div_s))
|
||||
(export "div_u" (func $i64/div_u))
|
||||
(export "rem_s" (func $i64/rem_s))
|
||||
(export "rem_u" (func $i64/rem_u))
|
||||
(export "memory" (memory $0))
|
||||
(func $i64/add (; 0 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
|
||||
(local $4 i64)
|
||||
(set_global $i64/lo
|
||||
(i32.wrap/i64
|
||||
(tee_local $4
|
||||
(i64.add
|
||||
(i64.or
|
||||
(i64.extend_s/i32
|
||||
(get_local $0)
|
||||
)
|
||||
(i64.shl
|
||||
(i64.extend_s/i32
|
||||
(get_local $1)
|
||||
)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
(i64.or
|
||||
(i64.extend_s/i32
|
||||
(get_local $2)
|
||||
)
|
||||
(i64.shl
|
||||
(i64.extend_s/i32
|
||||
(get_local $3)
|
||||
)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set_global $i64/hi
|
||||
(i32.wrap/i64
|
||||
(i64.shr_u
|
||||
(get_local $4)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(func $i64/sub (; 1 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
|
||||
(local $4 i64)
|
||||
(set_global $i64/lo
|
||||
(i32.wrap/i64
|
||||
(tee_local $4
|
||||
(i64.sub
|
||||
(i64.or
|
||||
(i64.extend_s/i32
|
||||
(get_local $0)
|
||||
)
|
||||
(i64.shl
|
||||
(i64.extend_s/i32
|
||||
(get_local $1)
|
||||
)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
(i64.or
|
||||
(i64.extend_s/i32
|
||||
(get_local $2)
|
||||
)
|
||||
(i64.shl
|
||||
(i64.extend_s/i32
|
||||
(get_local $3)
|
||||
)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set_global $i64/hi
|
||||
(i32.wrap/i64
|
||||
(i64.shr_u
|
||||
(get_local $4)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(func $i64/mul (; 2 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
|
||||
(local $4 i64)
|
||||
(set_global $i64/lo
|
||||
(i32.wrap/i64
|
||||
(tee_local $4
|
||||
(i64.mul
|
||||
(i64.or
|
||||
(i64.extend_s/i32
|
||||
(get_local $0)
|
||||
)
|
||||
(i64.shl
|
||||
(i64.extend_s/i32
|
||||
(get_local $1)
|
||||
)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
(i64.or
|
||||
(i64.extend_s/i32
|
||||
(get_local $2)
|
||||
)
|
||||
(i64.shl
|
||||
(i64.extend_s/i32
|
||||
(get_local $3)
|
||||
)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set_global $i64/hi
|
||||
(i32.wrap/i64
|
||||
(i64.shr_u
|
||||
(get_local $4)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(func $i64/div_s (; 3 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
|
||||
(local $4 i64)
|
||||
(set_global $i64/lo
|
||||
(i32.wrap/i64
|
||||
(tee_local $4
|
||||
(i64.div_s
|
||||
(i64.or
|
||||
(i64.extend_s/i32
|
||||
(get_local $0)
|
||||
)
|
||||
(i64.shl
|
||||
(i64.extend_s/i32
|
||||
(get_local $1)
|
||||
)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
(i64.or
|
||||
(i64.extend_s/i32
|
||||
(get_local $2)
|
||||
)
|
||||
(i64.shl
|
||||
(i64.extend_s/i32
|
||||
(get_local $3)
|
||||
)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set_global $i64/hi
|
||||
(i32.wrap/i64
|
||||
(i64.shr_u
|
||||
(get_local $4)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(func $i64/div_u (; 4 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
|
||||
(local $4 i64)
|
||||
(set_global $i64/lo
|
||||
(i32.wrap/i64
|
||||
(tee_local $4
|
||||
(i64.div_u
|
||||
(i64.or
|
||||
(i64.extend_u/i32
|
||||
(get_local $0)
|
||||
)
|
||||
(i64.shl
|
||||
(i64.extend_u/i32
|
||||
(get_local $1)
|
||||
)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
(i64.or
|
||||
(i64.extend_u/i32
|
||||
(get_local $2)
|
||||
)
|
||||
(i64.shl
|
||||
(i64.extend_u/i32
|
||||
(get_local $3)
|
||||
)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set_global $i64/hi
|
||||
(i32.wrap/i64
|
||||
(i64.shr_u
|
||||
(get_local $4)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(func $i64/rem_s (; 5 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
|
||||
(local $4 i64)
|
||||
(set_global $i64/lo
|
||||
(i32.wrap/i64
|
||||
(tee_local $4
|
||||
(i64.rem_s
|
||||
(i64.or
|
||||
(i64.extend_s/i32
|
||||
(get_local $0)
|
||||
)
|
||||
(i64.shl
|
||||
(i64.extend_s/i32
|
||||
(get_local $1)
|
||||
)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
(i64.or
|
||||
(i64.extend_s/i32
|
||||
(get_local $2)
|
||||
)
|
||||
(i64.shl
|
||||
(i64.extend_s/i32
|
||||
(get_local $3)
|
||||
)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set_global $i64/hi
|
||||
(i32.wrap/i64
|
||||
(i64.shr_u
|
||||
(get_local $4)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(func $i64/rem_u (; 6 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
|
||||
(local $4 i64)
|
||||
(set_global $i64/lo
|
||||
(i32.wrap/i64
|
||||
(tee_local $4
|
||||
(i64.rem_u
|
||||
(i64.or
|
||||
(i64.extend_u/i32
|
||||
(get_local $0)
|
||||
)
|
||||
(i64.shl
|
||||
(i64.extend_u/i32
|
||||
(get_local $1)
|
||||
)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
(i64.or
|
||||
(i64.extend_u/i32
|
||||
(get_local $2)
|
||||
)
|
||||
(i64.shl
|
||||
(i64.extend_u/i32
|
||||
(get_local $3)
|
||||
)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set_global $i64/hi
|
||||
(i32.wrap/i64
|
||||
(i64.shr_u
|
||||
(get_local $4)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
44
tests/compiler/i64.ts
Normal file
44
tests/compiler/i64.ts
Normal file
@ -0,0 +1,44 @@
|
||||
let lo: u32;
|
||||
let hi: u32;
|
||||
|
||||
export function add(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void {
|
||||
const ret: i64 = (<i64>loLeft | <i64>hiLeft << 32) + (<i64>loRight | <i64>hiRight << 32);
|
||||
lo = <u32>ret;
|
||||
hi = <u32>(ret >>> 32);
|
||||
}
|
||||
|
||||
export function sub(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void {
|
||||
const ret: i64 = (<i64>loLeft | <i64>hiLeft << 32) - (<i64>loRight | <i64>hiRight << 32);
|
||||
lo = <u32>ret;
|
||||
hi = <u32>(ret >>> 32);
|
||||
}
|
||||
|
||||
export function mul(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void {
|
||||
const ret: i64 = (<i64>loLeft | <i64>hiLeft << 32) * (<i64>loRight | <i64>hiRight << 32);
|
||||
lo = <u32>ret;
|
||||
hi = <u32>(ret >>> 32);
|
||||
}
|
||||
|
||||
export function div_s(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void {
|
||||
const ret: i64 = (<i64>loLeft | <i64>hiLeft << 32) / (<i64>loRight | <i64>hiRight << 32);
|
||||
lo = <u32>ret;
|
||||
hi = <u32>(ret >>> 32);
|
||||
}
|
||||
|
||||
export function div_u(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void {
|
||||
const ret: u64 = (<u64>loLeft | <u64>hiLeft << 32) / (<u64>loRight | <u64>hiRight << 32);
|
||||
lo = <u32>ret;
|
||||
hi = <u32>(ret >>> 32);
|
||||
}
|
||||
|
||||
export function rem_s(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void {
|
||||
const ret: i64 = (<i64>loLeft | <i64>hiLeft << 32) % (<i64>loRight | <i64>hiRight << 32);
|
||||
lo = <u32>ret;
|
||||
hi = <u32>(ret >>> 32);
|
||||
}
|
||||
|
||||
export function rem_u(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void {
|
||||
const ret: u64 = (<u64>loLeft | <u64>hiLeft << 32) % (<u64>loRight | <u64>hiRight << 32);
|
||||
lo = <u32>ret;
|
||||
hi = <u32>(ret >>> 32);
|
||||
}
|
369
tests/compiler/i64.wast
Normal file
369
tests/compiler/i64.wast
Normal file
@ -0,0 +1,369 @@
|
||||
(module
|
||||
(type $iiiiv (func (param i32 i32 i32 i32)))
|
||||
(global $i64/lo (mut i32) (i32.const 0))
|
||||
(global $i64/hi (mut i32) (i32.const 0))
|
||||
(global $HEAP_START i32 (i32.const 4))
|
||||
(memory $0 1)
|
||||
(export "add" (func $i64/add))
|
||||
(export "sub" (func $i64/sub))
|
||||
(export "mul" (func $i64/mul))
|
||||
(export "div_s" (func $i64/div_s))
|
||||
(export "div_u" (func $i64/div_u))
|
||||
(export "rem_s" (func $i64/rem_s))
|
||||
(export "rem_u" (func $i64/rem_u))
|
||||
(export "memory" (memory $0))
|
||||
(func $i64/add (; 0 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
|
||||
(local $4 i64)
|
||||
(block
|
||||
(set_local $4
|
||||
(i64.add
|
||||
(i64.or
|
||||
(i64.extend_s/i32
|
||||
(get_local $0)
|
||||
)
|
||||
(i64.shl
|
||||
(i64.extend_s/i32
|
||||
(get_local $1)
|
||||
)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
(i64.or
|
||||
(i64.extend_s/i32
|
||||
(get_local $2)
|
||||
)
|
||||
(i64.shl
|
||||
(i64.extend_s/i32
|
||||
(get_local $3)
|
||||
)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set_global $i64/lo
|
||||
(i32.wrap/i64
|
||||
(get_local $4)
|
||||
)
|
||||
)
|
||||
(set_global $i64/hi
|
||||
(i32.wrap/i64
|
||||
(i64.shr_u
|
||||
(get_local $4)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(func $i64/sub (; 1 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
|
||||
(local $4 i64)
|
||||
(block
|
||||
(set_local $4
|
||||
(i64.sub
|
||||
(i64.or
|
||||
(i64.extend_s/i32
|
||||
(get_local $0)
|
||||
)
|
||||
(i64.shl
|
||||
(i64.extend_s/i32
|
||||
(get_local $1)
|
||||
)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
(i64.or
|
||||
(i64.extend_s/i32
|
||||
(get_local $2)
|
||||
)
|
||||
(i64.shl
|
||||
(i64.extend_s/i32
|
||||
(get_local $3)
|
||||
)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set_global $i64/lo
|
||||
(i32.wrap/i64
|
||||
(get_local $4)
|
||||
)
|
||||
)
|
||||
(set_global $i64/hi
|
||||
(i32.wrap/i64
|
||||
(i64.shr_u
|
||||
(get_local $4)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(func $i64/mul (; 2 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
|
||||
(local $4 i64)
|
||||
(block
|
||||
(set_local $4
|
||||
(i64.mul
|
||||
(i64.or
|
||||
(i64.extend_s/i32
|
||||
(get_local $0)
|
||||
)
|
||||
(i64.shl
|
||||
(i64.extend_s/i32
|
||||
(get_local $1)
|
||||
)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
(i64.or
|
||||
(i64.extend_s/i32
|
||||
(get_local $2)
|
||||
)
|
||||
(i64.shl
|
||||
(i64.extend_s/i32
|
||||
(get_local $3)
|
||||
)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set_global $i64/lo
|
||||
(i32.wrap/i64
|
||||
(get_local $4)
|
||||
)
|
||||
)
|
||||
(set_global $i64/hi
|
||||
(i32.wrap/i64
|
||||
(i64.shr_u
|
||||
(get_local $4)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(func $i64/div_s (; 3 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
|
||||
(local $4 i64)
|
||||
(block
|
||||
(set_local $4
|
||||
(i64.div_s
|
||||
(i64.or
|
||||
(i64.extend_s/i32
|
||||
(get_local $0)
|
||||
)
|
||||
(i64.shl
|
||||
(i64.extend_s/i32
|
||||
(get_local $1)
|
||||
)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
(i64.or
|
||||
(i64.extend_s/i32
|
||||
(get_local $2)
|
||||
)
|
||||
(i64.shl
|
||||
(i64.extend_s/i32
|
||||
(get_local $3)
|
||||
)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set_global $i64/lo
|
||||
(i32.wrap/i64
|
||||
(get_local $4)
|
||||
)
|
||||
)
|
||||
(set_global $i64/hi
|
||||
(i32.wrap/i64
|
||||
(i64.shr_u
|
||||
(get_local $4)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(func $i64/div_u (; 4 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
|
||||
(local $4 i64)
|
||||
(block
|
||||
(set_local $4
|
||||
(i64.div_u
|
||||
(i64.or
|
||||
(i64.extend_u/i32
|
||||
(get_local $0)
|
||||
)
|
||||
(i64.shl
|
||||
(i64.extend_u/i32
|
||||
(get_local $1)
|
||||
)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
(i64.or
|
||||
(i64.extend_u/i32
|
||||
(get_local $2)
|
||||
)
|
||||
(i64.shl
|
||||
(i64.extend_u/i32
|
||||
(get_local $3)
|
||||
)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set_global $i64/lo
|
||||
(i32.wrap/i64
|
||||
(get_local $4)
|
||||
)
|
||||
)
|
||||
(set_global $i64/hi
|
||||
(i32.wrap/i64
|
||||
(i64.shr_u
|
||||
(get_local $4)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(func $i64/rem_s (; 5 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
|
||||
(local $4 i64)
|
||||
(block
|
||||
(set_local $4
|
||||
(i64.rem_s
|
||||
(i64.or
|
||||
(i64.extend_s/i32
|
||||
(get_local $0)
|
||||
)
|
||||
(i64.shl
|
||||
(i64.extend_s/i32
|
||||
(get_local $1)
|
||||
)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
(i64.or
|
||||
(i64.extend_s/i32
|
||||
(get_local $2)
|
||||
)
|
||||
(i64.shl
|
||||
(i64.extend_s/i32
|
||||
(get_local $3)
|
||||
)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set_global $i64/lo
|
||||
(i32.wrap/i64
|
||||
(get_local $4)
|
||||
)
|
||||
)
|
||||
(set_global $i64/hi
|
||||
(i32.wrap/i64
|
||||
(i64.shr_u
|
||||
(get_local $4)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(func $i64/rem_u (; 6 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
|
||||
(local $4 i64)
|
||||
(block
|
||||
(set_local $4
|
||||
(i64.rem_u
|
||||
(i64.or
|
||||
(i64.extend_u/i32
|
||||
(get_local $0)
|
||||
)
|
||||
(i64.shl
|
||||
(i64.extend_u/i32
|
||||
(get_local $1)
|
||||
)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
(i64.or
|
||||
(i64.extend_u/i32
|
||||
(get_local $2)
|
||||
)
|
||||
(i64.shl
|
||||
(i64.extend_u/i32
|
||||
(get_local $3)
|
||||
)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set_global $i64/lo
|
||||
(i32.wrap/i64
|
||||
(get_local $4)
|
||||
)
|
||||
)
|
||||
(set_global $i64/hi
|
||||
(i32.wrap/i64
|
||||
(i64.shr_u
|
||||
(get_local $4)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(;
|
||||
[program.elements]
|
||||
clz
|
||||
ctz
|
||||
popcnt
|
||||
rotl
|
||||
rotr
|
||||
abs
|
||||
ceil
|
||||
copysign
|
||||
floor
|
||||
max
|
||||
min
|
||||
nearest
|
||||
sqrt
|
||||
trunc
|
||||
current_memory
|
||||
grow_memory
|
||||
unreachable
|
||||
load
|
||||
store
|
||||
reinterpret
|
||||
select
|
||||
sizeof
|
||||
changetype
|
||||
isNaN
|
||||
isFinite
|
||||
assert
|
||||
i64/lo
|
||||
i64/hi
|
||||
i64/add
|
||||
i64/sub
|
||||
i64/mul
|
||||
i64/div_s
|
||||
i64/div_u
|
||||
i64/rem_s
|
||||
i64/rem_u
|
||||
[program.exports]
|
||||
i64/add
|
||||
i64/sub
|
||||
i64/mul
|
||||
i64/div_s
|
||||
i64/div_u
|
||||
i64/rem_s
|
||||
i64/rem_u
|
||||
;)
|
@ -19,7 +19,7 @@
|
||||
(tee_local $3
|
||||
(get_local $2)
|
||||
)
|
||||
(i32.rem_s
|
||||
(i32.rem_u
|
||||
(get_local $1)
|
||||
(i32.const 4)
|
||||
)
|
||||
@ -62,7 +62,7 @@
|
||||
)
|
||||
(if
|
||||
(i32.eqz
|
||||
(i32.rem_s
|
||||
(i32.rem_u
|
||||
(get_local $4)
|
||||
(i32.const 4)
|
||||
)
|
||||
@ -70,7 +70,7 @@
|
||||
(block
|
||||
(loop $continue|1
|
||||
(if
|
||||
(i32.ge_s
|
||||
(i32.ge_u
|
||||
(get_local $2)
|
||||
(i32.const 16)
|
||||
)
|
||||
@ -247,7 +247,7 @@
|
||||
)
|
||||
)
|
||||
(if
|
||||
(i32.ge_s
|
||||
(i32.ge_u
|
||||
(get_local $2)
|
||||
(i32.const 32)
|
||||
)
|
||||
@ -258,7 +258,7 @@
|
||||
(block $tablify|0
|
||||
(br_table $case0|2 $case1|2 $case2|2 $tablify|0
|
||||
(i32.sub
|
||||
(i32.rem_s
|
||||
(i32.rem_u
|
||||
(get_local $4)
|
||||
(i32.const 4)
|
||||
)
|
||||
@ -353,7 +353,7 @@
|
||||
)
|
||||
(loop $continue|3
|
||||
(if
|
||||
(i32.ge_s
|
||||
(i32.ge_u
|
||||
(get_local $2)
|
||||
(i32.const 17)
|
||||
)
|
||||
@ -532,7 +532,7 @@
|
||||
)
|
||||
(loop $continue|4
|
||||
(if
|
||||
(i32.ge_s
|
||||
(i32.ge_u
|
||||
(get_local $2)
|
||||
(i32.const 18)
|
||||
)
|
||||
@ -687,7 +687,7 @@
|
||||
)
|
||||
(loop $continue|5
|
||||
(if
|
||||
(i32.ge_s
|
||||
(i32.ge_u
|
||||
(get_local $2)
|
||||
(i32.const 19)
|
||||
)
|
||||
|
@ -110,7 +110,7 @@
|
||||
(tee_local $7
|
||||
(get_local $2)
|
||||
)
|
||||
(i32.rem_s
|
||||
(i32.rem_u
|
||||
(get_local $4)
|
||||
(i32.const 4)
|
||||
)
|
||||
@ -168,7 +168,7 @@
|
||||
)
|
||||
(if
|
||||
(i32.eq
|
||||
(i32.rem_s
|
||||
(i32.rem_u
|
||||
(get_local $3)
|
||||
(i32.const 4)
|
||||
)
|
||||
@ -178,7 +178,7 @@
|
||||
(block $break|1
|
||||
(loop $continue|1
|
||||
(if
|
||||
(i32.ge_s
|
||||
(i32.ge_u
|
||||
(get_local $2)
|
||||
(i32.const 16)
|
||||
)
|
||||
@ -380,7 +380,7 @@
|
||||
)
|
||||
)
|
||||
(if
|
||||
(i32.ge_s
|
||||
(i32.ge_u
|
||||
(get_local $2)
|
||||
(i32.const 32)
|
||||
)
|
||||
@ -389,7 +389,7 @@
|
||||
(block $case1|2
|
||||
(block $case0|2
|
||||
(set_local $13
|
||||
(i32.rem_s
|
||||
(i32.rem_u
|
||||
(get_local $3)
|
||||
(i32.const 4)
|
||||
)
|
||||
@ -512,7 +512,7 @@
|
||||
(block $break|3
|
||||
(loop $continue|3
|
||||
(if
|
||||
(i32.ge_s
|
||||
(i32.ge_u
|
||||
(get_local $2)
|
||||
(i32.const 17)
|
||||
)
|
||||
@ -707,7 +707,7 @@
|
||||
(block $break|4
|
||||
(loop $continue|4
|
||||
(if
|
||||
(i32.ge_s
|
||||
(i32.ge_u
|
||||
(get_local $2)
|
||||
(i32.const 18)
|
||||
)
|
||||
@ -874,7 +874,7 @@
|
||||
(block $break|5
|
||||
(loop $continue|5
|
||||
(if
|
||||
(i32.ge_s
|
||||
(i32.ge_u
|
||||
(get_local $2)
|
||||
(i32.const 19)
|
||||
)
|
||||
|
@ -32,14 +32,14 @@
|
||||
)
|
||||
(func $tlsf/control$set_block (; 2 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
|
||||
(if
|
||||
(i32.ge_s
|
||||
(i32.ge_u
|
||||
(get_local $1)
|
||||
(i32.const 23)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
(if
|
||||
(i32.ge_s
|
||||
(i32.ge_u
|
||||
(get_local $2)
|
||||
(i32.const 32)
|
||||
)
|
||||
@ -133,7 +133,7 @@
|
||||
)
|
||||
(loop $continue|0
|
||||
(if
|
||||
(i32.lt_s
|
||||
(i32.lt_u
|
||||
(get_local $1)
|
||||
(i32.const 23)
|
||||
)
|
||||
@ -151,7 +151,7 @@
|
||||
)
|
||||
(block
|
||||
(if
|
||||
(i32.ge_s
|
||||
(i32.ge_u
|
||||
(get_local $10)
|
||||
(i32.const 23)
|
||||
)
|
||||
@ -178,7 +178,7 @@
|
||||
)
|
||||
(loop $continue|1
|
||||
(if
|
||||
(i32.lt_s
|
||||
(i32.lt_u
|
||||
(get_local $2)
|
||||
(i32.const 32)
|
||||
)
|
||||
|
@ -59,7 +59,7 @@
|
||||
)
|
||||
(func $tlsf/control$set_sl_bitmap (; 5 ;) (type $iiiv) (param $0 i32) (param $1 i32) (param $2 i32)
|
||||
(if
|
||||
(i32.ge_s
|
||||
(i32.ge_u
|
||||
(get_local $1)
|
||||
(i32.const 23)
|
||||
)
|
||||
@ -81,14 +81,14 @@
|
||||
)
|
||||
(func $tlsf/control$set_block (; 6 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
|
||||
(if
|
||||
(i32.ge_s
|
||||
(i32.ge_u
|
||||
(get_local $1)
|
||||
(i32.const 23)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
(if
|
||||
(i32.ge_s
|
||||
(i32.ge_u
|
||||
(get_local $2)
|
||||
(i32.const 32)
|
||||
)
|
||||
@ -134,7 +134,7 @@
|
||||
)
|
||||
(loop $continue|0
|
||||
(if
|
||||
(i32.lt_s
|
||||
(i32.lt_u
|
||||
(get_local $1)
|
||||
(i32.const 23)
|
||||
)
|
||||
@ -149,7 +149,7 @@
|
||||
)
|
||||
(loop $continue|1
|
||||
(if
|
||||
(i32.lt_s
|
||||
(i32.lt_u
|
||||
(get_local $2)
|
||||
(i32.const 32)
|
||||
)
|
||||
|
@ -91,7 +91,7 @@
|
||||
(func $tlsf/control$set_sl_bitmap (; 5 ;) (type $iiiv) (param $0 i32) (param $1 i32) (param $2 i32)
|
||||
(if
|
||||
(i32.eqz
|
||||
(i32.lt_s
|
||||
(i32.lt_u
|
||||
(get_local $1)
|
||||
(i32.const 23)
|
||||
)
|
||||
@ -115,7 +115,7 @@
|
||||
(func $tlsf/control$set_block (; 6 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
|
||||
(if
|
||||
(i32.eqz
|
||||
(i32.lt_s
|
||||
(i32.lt_u
|
||||
(get_local $1)
|
||||
(i32.const 23)
|
||||
)
|
||||
@ -124,7 +124,7 @@
|
||||
)
|
||||
(if
|
||||
(i32.eqz
|
||||
(i32.lt_s
|
||||
(i32.lt_u
|
||||
(get_local $2)
|
||||
(i32.const 32)
|
||||
)
|
||||
@ -174,7 +174,7 @@
|
||||
)
|
||||
(loop $continue|0
|
||||
(if
|
||||
(i32.lt_s
|
||||
(i32.lt_u
|
||||
(get_local $1)
|
||||
(i32.const 23)
|
||||
)
|
||||
@ -193,7 +193,7 @@
|
||||
)
|
||||
(loop $continue|1
|
||||
(if
|
||||
(i32.lt_s
|
||||
(i32.lt_u
|
||||
(get_local $2)
|
||||
(i32.const 32)
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user