mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-06-22 19:21:47 +00:00
Minor restructure and fixes; README; Proposed binaryen additions
This commit is contained in:
139
src/compiler.ts
139
src/compiler.ts
@ -1,8 +1,56 @@
|
||||
import { compileCall as compileBuiltinCall, initialize } from "./builtins";
|
||||
import { PATH_DELIMITER } from "./constants";
|
||||
import { DiagnosticCode, DiagnosticEmitter } from "./diagnostics";
|
||||
import { Module, MemorySegment, ExpressionRef, UnaryOp, BinaryOp, NativeType, FunctionRef, FunctionTypeRef, getExpressionId, ExpressionId, getExpressionType, getFunctionBody, getConstValueI32, getConstValueI64Low, getConstValueI64High, getConstValueF32, getConstValueF64 } from "./module";
|
||||
import { Program, ClassPrototype, Class, Element, ElementKind, Enum, FunctionPrototype, Function, Global, Local, Namespace, Parameter, EnumValue } from "./program";
|
||||
import {
|
||||
|
||||
Module,
|
||||
MemorySegment,
|
||||
ExpressionRef,
|
||||
UnaryOp,
|
||||
BinaryOp,
|
||||
NativeType,
|
||||
FunctionTypeRef,
|
||||
FunctionRef,
|
||||
ExpressionId,
|
||||
|
||||
getExpressionId,
|
||||
getExpressionType,
|
||||
getFunctionBody,
|
||||
getConstValueI32,
|
||||
getConstValueI64Low,
|
||||
getConstValueI64High,
|
||||
getConstValueF32,
|
||||
getConstValueF64,
|
||||
getGetLocalIndex,
|
||||
getGetGlobalName,
|
||||
isLoadAtomic,
|
||||
isLoadSigned,
|
||||
getLoadBytes,
|
||||
getLoadOffset,
|
||||
getLoadPtr,
|
||||
getUnaryOp,
|
||||
getUnaryValue,
|
||||
getBinaryOp,
|
||||
getBinaryLeft,
|
||||
getBinaryRight
|
||||
|
||||
} from "./module";
|
||||
import {
|
||||
|
||||
Program,
|
||||
ClassPrototype,
|
||||
Class, Element,
|
||||
ElementKind,
|
||||
Enum,
|
||||
FunctionPrototype,
|
||||
Function,
|
||||
Global,
|
||||
Local,
|
||||
Namespace,
|
||||
Parameter,
|
||||
EnumValue
|
||||
|
||||
} from "./program";
|
||||
import { I64, U64, sb } from "./util";
|
||||
import { Token } from "./tokenizer";
|
||||
import {
|
||||
@ -65,6 +113,7 @@ import {
|
||||
UnaryPostfixExpression,
|
||||
UnaryPrefixExpression,
|
||||
|
||||
// utility
|
||||
hasModifier
|
||||
|
||||
} from "./ast";
|
||||
@ -1021,7 +1070,8 @@ export class Compiler extends DiagnosticEmitter {
|
||||
this.module.runPasses([ "precompute" ], funcRef);
|
||||
const ret: ExpressionRef = getFunctionBody(funcRef);
|
||||
this.module.removeFunction("__precompute");
|
||||
// TODO: also remove the function type somehow if no longer used
|
||||
// TODO: also remove the function type somehow if no longer used or make the C-API accept
|
||||
// a `null` typeRef, using an implicit type.
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1190,6 +1240,41 @@ export class Compiler extends DiagnosticEmitter {
|
||||
return expr;
|
||||
}
|
||||
|
||||
cloneExpressionRef(expr: ExpressionRef, noSideEffects: bool = false, maxDepth: i32 = 0x7fffffff): ExpressionRef {
|
||||
// currently supports side effect free expressions only
|
||||
if (maxDepth < 0)
|
||||
return 0;
|
||||
let nested1: ExpressionRef,
|
||||
nested2: ExpressionRef;
|
||||
switch (getExpressionId(expr)) {
|
||||
case ExpressionId.Const:
|
||||
switch (getExpressionType(expr)) {
|
||||
case NativeType.I32: return this.module.createI32(getConstValueI32(expr));
|
||||
case NativeType.I64: return this.module.createI64(getConstValueI64Low(expr), getConstValueI64High(expr));
|
||||
case NativeType.F32: return this.module.createF32(getConstValueF32(expr));
|
||||
case NativeType.F64: return this.module.createF64(getConstValueF64(expr));
|
||||
default: throw new Error("unexpected expression type");
|
||||
}
|
||||
case ExpressionId.GetLocal:
|
||||
return this.module.createGetLocal(getGetLocalIndex(expr), getExpressionType(expr));
|
||||
case ExpressionId.GetGlobal:
|
||||
return this.module.createGetGlobal(getGetGlobalName(expr), getExpressionType(expr));
|
||||
case ExpressionId.Load:
|
||||
if (!(nested1 = this.cloneExpressionRef(getLoadPtr(expr), noSideEffects, maxDepth - 1))) break;
|
||||
return isLoadAtomic(expr)
|
||||
? this.module.createAtomicLoad(getLoadBytes(expr), nested1, getExpressionType(expr), getLoadOffset(expr))
|
||||
: this.module.createLoad(getLoadBytes(expr), isLoadSigned(expr), nested1, getExpressionType(expr), getLoadOffset(expr));
|
||||
case ExpressionId.Unary:
|
||||
if (!(nested1 = this.cloneExpressionRef(getUnaryValue(expr), noSideEffects, maxDepth - 1))) break;
|
||||
return this.module.createUnary(getUnaryOp(expr), nested1);
|
||||
case ExpressionId.Binary:
|
||||
if (!(nested1 = this.cloneExpressionRef(getBinaryLeft(expr), noSideEffects, maxDepth - 1))) break;
|
||||
if (!(nested2 = this.cloneExpressionRef(getBinaryLeft(expr), noSideEffects, maxDepth - 1))) break;
|
||||
return this.module.createBinary(getBinaryOp(expr), nested1, nested2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
compileAssertionExpression(expression: AssertionExpression, contextualType: Type): ExpressionRef {
|
||||
const toType: Type | null = this.program.resolveType(expression.toType, this.currentFunction.contextualTypeArguments); // reports
|
||||
return toType && toType != contextualType
|
||||
@ -1426,15 +1511,31 @@ 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
|
||||
|
||||
// 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.cloneExpressionRef(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
|
||||
// );
|
||||
|
||||
// otherwise use a temporary local for the intermediate value
|
||||
tempLocal = this.currentFunction.addLocal(this.currentType);
|
||||
condition = this.module.createTeeLocal(tempLocal.index, left);
|
||||
return this.module.createIf(
|
||||
this.currentType.isLongInteger
|
||||
? this.module.createBinary(BinaryOp.NeI64, this.module.createTeeLocal(tempLocal.index, left), this.module.createI64(0, 0))
|
||||
? this.module.createBinary(BinaryOp.NeI64, condition, this.module.createI64(0, 0))
|
||||
: this.currentType == Type.f64
|
||||
? this.module.createBinary(BinaryOp.NeF64, this.module.createTeeLocal(tempLocal.index, left), this.module.createF64(0))
|
||||
? this.module.createBinary(BinaryOp.NeF64, condition, this.module.createF64(0))
|
||||
: this.currentType == Type.f32
|
||||
? this.module.createBinary(BinaryOp.NeF32, this.module.createTeeLocal(tempLocal.index, left), this.module.createF32(0))
|
||||
? this.module.createBinary(BinaryOp.NeF32, condition, this.module.createF32(0))
|
||||
: this.module.createTeeLocal(tempLocal.index, left),
|
||||
right,
|
||||
this.module.createGetLocal(tempLocal.index, typeToNativeType(tempLocal.type))
|
||||
@ -1443,15 +1544,31 @@ 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
|
||||
|
||||
// simplify if left is free of side effects while tolerating two levels of nesting
|
||||
// if (condition = this.cloneExpressionRef(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
|
||||
// );
|
||||
|
||||
// otherwise use a temporary local for the intermediate value
|
||||
tempLocal = this.currentFunction.addLocal(this.currentType);
|
||||
condition = this.module.createTeeLocal(tempLocal.index, left);
|
||||
return this.module.createIf(
|
||||
this.currentType.isLongInteger
|
||||
? this.module.createBinary(BinaryOp.NeI64, this.module.createTeeLocal(tempLocal.index, left), this.module.createI64(0, 0))
|
||||
? this.module.createBinary(BinaryOp.NeI64, condition, this.module.createI64(0, 0))
|
||||
: this.currentType == Type.f64
|
||||
? this.module.createBinary(BinaryOp.NeF64, this.module.createTeeLocal(tempLocal.index, left), this.module.createF64(0))
|
||||
? this.module.createBinary(BinaryOp.NeF64, condition, this.module.createF64(0))
|
||||
: this.currentType == Type.f32
|
||||
? this.module.createBinary(BinaryOp.NeF32, this.module.createTeeLocal(tempLocal.index, left), this.module.createF32(0))
|
||||
? this.module.createBinary(BinaryOp.NeF32, condition, this.module.createF32(0))
|
||||
: this.module.createTeeLocal(tempLocal.index, left),
|
||||
this.module.createGetLocal(tempLocal.index, typeToNativeType(tempLocal.type)),
|
||||
right
|
||||
|
120
src/glue/binaryen-c.d.ts
vendored
120
src/glue/binaryen-c.d.ts
vendored
@ -60,13 +60,9 @@ declare type BinaryenModuleRef = usize;
|
||||
declare function _BinaryenModuleCreate(): BinaryenModuleRef;
|
||||
declare function _BinaryenModuleDispose(module: BinaryenModuleRef): void;
|
||||
|
||||
declare type BinaryenFunctionTypeRef = usize;
|
||||
declare type CString = usize;
|
||||
declare type CArray<T> = usize;
|
||||
|
||||
declare function _BinaryenAddFunctionType(module: BinaryenModuleRef, name: CString, result: BinaryenType, paramTypes: CArray<BinaryenType>, numParams: BinaryenIndex): BinaryenFunctionTypeRef;
|
||||
declare function _BinaryenGetFunctionTypeBySignature(module: BinaryenModuleRef, result: BinaryenType, paramTypes: CArray<BinaryenType>, numParams: BinaryenIndex): BinaryenFunctionTypeRef;
|
||||
|
||||
declare type BinaryenLiteral = CArray<u8>;
|
||||
|
||||
// LLVM C ABI with `out` being a buffer of 16 bytes receiving the BinaryenLiteral struct.
|
||||
@ -256,18 +252,134 @@ declare function _BinaryenAtomicWake(module: BinaryenModuleRef, ptr: BinaryenExp
|
||||
declare function _BinaryenExpressionGetId(expr: BinaryenExpressionRef): BinaryenExpressionId;
|
||||
declare function _BinaryenExpressionGetType(expr: BinaryenExpressionRef): BinaryenType;
|
||||
declare function _BinaryenExpressionPrint(expr: BinaryenExpressionRef): void;
|
||||
|
||||
declare function _BinaryenBlockGetName(expr: BinaryenExpressionRef): CString;
|
||||
declare function _BinaryenBlockGetNumChildren(expr: BinaryenExpressionRef): BinaryenIndex;
|
||||
declare function _BinaryenBlockGetChild(expr: BinaryenExpressionRef, index: BinaryenIndex): BinaryenExpressionRef;
|
||||
|
||||
declare function _BinaryenIfGetCondition(expr: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
declare function _BinaryenIfGetIfTrue(expr: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
declare function _BinaryenIfGetIfFalse(expr: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
|
||||
declare function _BinaryenLoopGetName(expr: BinaryenExpressionRef): CString;
|
||||
declare function _BinaryenLoopGetBody(expr: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
|
||||
declare function _BinaryenBreakGetName(expr: BinaryenExpressionRef): CString;
|
||||
declare function _BinaryenBreakGetCondition(expr: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
declare function _BinaryenBreakGetValue(expr: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
|
||||
declare function _BinaryenSwitchGetNumNames(expr: BinaryenExpressionRef): BinaryenIndex;
|
||||
declare function _BinaryenSwitchGetName(expr: BinaryenExpressionRef, index: BinaryenIndex): CString;
|
||||
declare function _BinaryenSwitchGetDefaultName(expr: BinaryenExpressionRef): CString;
|
||||
declare function _BinaryenSwitchGetCondition(expr: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
declare function _BinaryenSwitchGetValue(expr: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
|
||||
declare function _BinaryenCallGetTarget(expr: BinaryenExpressionRef): CString;
|
||||
declare function _BinaryenCallGetNumOperands(expr: BinaryenExpressionRef): BinaryenIndex;
|
||||
declare function _BinaryenCallGetOperand(expr: BinaryenExpressionRef, index: BinaryenIndex): BinaryenExpressionRef;
|
||||
|
||||
declare function _BinaryenCallImportGetTarget(expr: BinaryenExpressionRef): CString;
|
||||
declare function _BinaryenCallImportGetNumOperands(expr: BinaryenExpressionRef): BinaryenIndex;
|
||||
declare function _BinaryenCallImportGetOperand(expr: BinaryenExpressionRef, index: BinaryenIndex): BinaryenExpressionRef;
|
||||
|
||||
declare function _BinaryenCallIndirectGetTarget(expr: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
declare function _BinaryenCallIndirectGetNumOperands(expr: BinaryenExpressionRef): BinaryenIndex;
|
||||
declare function _BinaryenCallIndirectGetOperand(expr: BinaryenExpressionRef, index: BinaryenIndex): BinaryenExpressionRef;
|
||||
|
||||
declare function _BinaryenGetLocalGetIndex(expr: BinaryenExpressionRef): BinaryenIndex;
|
||||
|
||||
declare function _BinaryenSetLocalIsTee(expr: BinaryenExpressionRef): bool;
|
||||
declare function _BinaryenSetLocalGetIndex(expr: BinaryenExpressionRef): BinaryenIndex;
|
||||
declare function _BinaryenSetLocalGetValue(expr: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
|
||||
declare function _BinaryenGetGlobalGetName(expr: BinaryenExpressionRef): CString;
|
||||
|
||||
declare function _BinaryenSetGlobalGetName(expr: BinaryenExpressionRef): CString;
|
||||
declare function _BinaryenSetGlobalGetValue(expr: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
|
||||
declare function _BinaryenHostGetOp(expr: BinaryenExpressionRef): BinaryenOp;
|
||||
declare function _BinaryenHostGetNameOperand(expr: BinaryenExpressionRef): CString;
|
||||
declare function _BinaryenHostGetNumOperands(expr: BinaryenExpressionRef): BinaryenIndex;
|
||||
declare function _BinaryenHostGetOperand(expr: BinaryenExpressionRef, index: BinaryenIndex): BinaryenExpressionRef;
|
||||
|
||||
declare function _BinaryenLoadIsAtomic(expr: BinaryenExpressionRef): bool;
|
||||
declare function _BinaryenLoadIsSigned(expr: BinaryenExpressionRef): bool;
|
||||
declare function _BinaryenLoadGetBytes(expr: BinaryenExpressionRef): u32;
|
||||
declare function _BinaryenLoadGetOffset(expr: BinaryenExpressionRef): u32;
|
||||
declare function _BinaryenLoadGetAlign(expr: BinaryenExpressionRef): u32;
|
||||
declare function _BinaryenLoadGetPtr(expr: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
|
||||
declare function _BinaryenStoreIsAtomic(expr: BinaryenExpressionRef): bool;
|
||||
declare function _BinaryenStoreGetBytes(expr: BinaryenExpressionRef): u32;
|
||||
declare function _BinaryenStoreGetOffset(expr: BinaryenExpressionRef): u32;
|
||||
declare function _BinaryenStoreGetAlign(expr: BinaryenExpressionRef): u32;
|
||||
declare function _BinaryenStoreGetPtr(expr: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
declare function _BinaryenStoreGetValue(expr: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
|
||||
declare function _BinaryenConstGetValueI32(expr: BinaryenExpressionRef): i32;
|
||||
declare function _BinaryenConstGetValueI64Low(expr: BinaryenExpressionRef): i32;
|
||||
declare function _BinaryenConstGetValueI64High(expr: BinaryenExpressionRef): i32;
|
||||
declare function _BinaryenConstGetValueF32(expr: BinaryenExpressionRef): f32;
|
||||
declare function _BinaryenConstGetValueF64(expr: BinaryenExpressionRef): f64;
|
||||
|
||||
declare function _BinaryenUnaryGetOp(expr: BinaryenExpressionRef): BinaryenOp;
|
||||
declare function _BinaryenUnaryGetValue(expr: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
|
||||
declare function _BinaryenBinaryGetOp(expr: BinaryenExpressionRef): BinaryenOp;
|
||||
declare function _BinaryenBinaryGetLeft(expr: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
declare function _BinaryenBinaryGetRight(expr: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
|
||||
declare function _BinaryenSelectGetIfTrue(expr: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
declare function _BinaryenSelectGetIfFalse(expr: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
declare function _BinaryenSelectGetCondition(expr: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
|
||||
declare function _BinaryenDropGetValue(expr: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
|
||||
declare function _BinaryenReturnGetValue(expr: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
|
||||
declare function _BinaryenAtomicRMWGetOp(expr: BinaryenExpressionRef): BinaryenOp;
|
||||
declare function _BinaryenAtomicRMWGetBytes(expr: BinaryenExpressionRef): u32;
|
||||
declare function _BinaryenAtomicRMWGetOffset(expr: BinaryenExpressionRef): u32;
|
||||
declare function _BinaryenAtomicRMWGetPtr(expr: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
declare function _BinaryenAtomicRMWGetValue(expr: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
|
||||
declare function _BinaryenAtomicCmpxchgGetBytes(expr: BinaryenExpressionRef): u32;
|
||||
declare function _BinaryenAtomicCmpxchgGetOffset(expr: BinaryenExpressionRef): u32;
|
||||
declare function _BinaryenAtomicCmpxchgGetPtr(expr: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
declare function _BinaryenAtomicCmpxchgGetExpected(expr: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
declare function _BinaryenAtomicCmpxchgGetReplacement(expr: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
|
||||
declare function _BinaryenAtomicWaitGetPtr(expr: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
declare function _BinaryenAtomicWaitGetExpected(expr: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
declare function _BinaryenAtomicWaitGetTimeout(expr: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
declare function _BinaryenAtomicWaitGetExpectedType(expr: BinaryenExpressionRef): BinaryenType;
|
||||
|
||||
declare function _BinaryenAtomicWakeGetPtr(expr: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
declare function _BinaryenAtomicWakeGetWakeCount(expr: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
|
||||
declare type BinaryenFunctionTypeRef = usize;
|
||||
|
||||
declare function _BinaryenAddFunctionType(module: BinaryenModuleRef, name: CString, result: BinaryenType, paramTypes: CArray<BinaryenType>, numParams: BinaryenIndex): BinaryenFunctionTypeRef;
|
||||
declare function _BinaryenGetFunctionTypeBySignature(module: BinaryenModuleRef, result: BinaryenType, paramTypes: CArray<BinaryenType>, numParams: BinaryenIndex): BinaryenFunctionTypeRef;
|
||||
|
||||
declare function _BinaryenFunctionTypeGetName(ftype: BinaryenFunctionTypeRef): CString;
|
||||
declare function _BinaryenFunctionTypeGetNumParams(ftype: BinaryenFunctionTypeRef): BinaryenIndex;
|
||||
declare function _BinaryenFunctionTypeGetParam(ftype: BinaryenFunctionTypeRef, index: BinaryenIndex): BinaryenType;
|
||||
declare function _BinaryenFunctionTypeGetResult(ftype: BinaryenFunctionTypeRef): BinaryenType;
|
||||
|
||||
declare type BinaryenFunctionRef = usize;
|
||||
|
||||
declare function _BinaryenAddFunction(module: BinaryenModuleRef, name: CString, type: BinaryenFunctionTypeRef, varTypes: CArray<BinaryenType>, numVarTypes: BinaryenIndex, body: BinaryenExpressionRef): BinaryenFunctionRef;
|
||||
declare function _BinaryenGetFunction(module: BinaryenModuleRef, name: CString): BinaryenFunctionRef;
|
||||
declare function _BinaryenRemoveFunction(module: BinaryenModuleRef, name: CString): void;
|
||||
|
||||
declare function _BinaryenFunctionGetName(func: BinaryenFunctionRef): CString;
|
||||
declare function _BinaryenFunctionGetType(func: BinaryenFunctionRef): BinaryenFunctionTypeRef;
|
||||
declare function _BinaryenFunctionGetNumParams(func: BinaryenFunctionRef): BinaryenIndex;
|
||||
declare function _BinaryenFunctionGetParam(func: BinaryenFunctionRef, index: BinaryenIndex): BinaryenType;
|
||||
declare function _BinaryenFunctionGetResult(func: BinaryenFunctionRef): BinaryenType;
|
||||
declare function _BinaryenFunctionGetNumVars(func: BinaryenFunctionRef): BinaryenIndex;
|
||||
declare function _BinaryenFunctionGetVar(func: BinaryenFunctionRef, index: BinaryenIndex): BinaryenType;
|
||||
declare function _BinaryenFunctionGetBody(func: BinaryenFunctionRef): BinaryenExpressionRef;
|
||||
declare function _BinaryenFunctionOptimize(func: BinaryenFunctionRef, module: BinaryenModuleRef): void;
|
||||
declare function _BinaryenFunctionRunPasses(func: BinaryenFunctionRef, module: BinaryenModuleRef, passes: CArray<CString>, numPasses: BinaryenIndex): void;
|
||||
|
@ -807,10 +807,58 @@ export function getConstValueF64(expr: ExpressionRef): f64 {
|
||||
return _BinaryenConstGetValueF64(expr);
|
||||
}
|
||||
|
||||
export function getGetLocalIndex(expr: ExpressionRef): Index {
|
||||
return _BinaryenGetLocalGetIndex(expr);
|
||||
}
|
||||
|
||||
export function getGetGlobalName(expr: ExpressionRef): string {
|
||||
return readString(_BinaryenGetGlobalGetName(expr));
|
||||
}
|
||||
|
||||
export function isLoadAtomic(expr: ExpressionRef): bool {
|
||||
return _BinaryenLoadIsAtomic(expr);
|
||||
}
|
||||
|
||||
export function isLoadSigned(expr: ExpressionRef): bool {
|
||||
return _BinaryenLoadIsSigned(expr);
|
||||
}
|
||||
|
||||
export function getLoadBytes(expr: ExpressionRef): u32 {
|
||||
return _BinaryenLoadGetBytes(expr);
|
||||
}
|
||||
|
||||
export function getLoadOffset(expr: ExpressionRef): u32 {
|
||||
return _BinaryenLoadGetOffset(expr);
|
||||
}
|
||||
|
||||
export function getLoadPtr(expr: ExpressionRef): ExpressionRef {
|
||||
return _BinaryenLoadGetPtr(expr);
|
||||
}
|
||||
|
||||
export function getFunctionBody(func: FunctionRef): ExpressionRef {
|
||||
return _BinaryenFunctionGetBody(func);
|
||||
}
|
||||
|
||||
export function getUnaryOp(expr: ExpressionRef): UnaryOp {
|
||||
return _BinaryenUnaryGetOp(expr);
|
||||
}
|
||||
|
||||
export function getUnaryValue(expr: ExpressionRef): ExpressionRef {
|
||||
return _BinaryenUnaryGetValue(expr);
|
||||
}
|
||||
|
||||
export function getBinaryOp(expr: ExpressionRef): BinaryOp {
|
||||
return _BinaryenBinaryGetOp(expr);
|
||||
}
|
||||
|
||||
export function getBinaryLeft(expr: ExpressionRef): ExpressionRef {
|
||||
return _BinaryenBinaryGetLeft(expr);
|
||||
}
|
||||
|
||||
export function getBinaryRight(expr: ExpressionRef): ExpressionRef {
|
||||
return _BinaryenBinaryGetRight(expr);
|
||||
}
|
||||
|
||||
export class Relooper {
|
||||
|
||||
module: Module;
|
||||
@ -866,9 +914,9 @@ export class Relooper {
|
||||
}
|
||||
}
|
||||
|
||||
// export function setAPITracing(on: bool): void {
|
||||
// _BinaryenSetAPITracing(on ? 1 : 0);
|
||||
// }
|
||||
export function setAPITracing(on: bool): void {
|
||||
_BinaryenSetAPITracing(on ? 1 : 0);
|
||||
}
|
||||
|
||||
// helpers
|
||||
// can't do stack allocation here: STACKTOP is a global in WASM but a hidden variable in asm.js
|
||||
@ -959,3 +1007,47 @@ function allocString(str: string | null): CString {
|
||||
store<u8>(idx, 0);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
function readString(ptr: usize): string {
|
||||
const utf16le: u32[] = [];
|
||||
// the following is based on Emscripten's UTF8ArrayToString
|
||||
let cp: u32;
|
||||
let u1: u32, u2: u32, u3: u32, u4: u32, u5: u32;
|
||||
while (cp = load<u8>(ptr++)) {
|
||||
if (!(cp & 0x80)) {
|
||||
utf16le.push(cp);
|
||||
continue;
|
||||
}
|
||||
u1 = load<u8>(ptr++) & 63;
|
||||
if ((cp & 0xE0) == 0xC0) {
|
||||
utf16le.push(((cp & 31) << 6) | u1);
|
||||
continue;
|
||||
}
|
||||
u2 = load<u8>(ptr++) & 63;
|
||||
if ((cp & 0xF0) == 0xE0) {
|
||||
cp = ((cp & 15) << 12) | (u1 << 6) | u2;
|
||||
} else {
|
||||
u3 = load<u8>(ptr++) & 63;
|
||||
if ((cp & 0xF8) == 0xF0) {
|
||||
cp = ((cp & 7) << 18) | (u1 << 12) | (u2 << 6) | u3;
|
||||
} else {
|
||||
u4 = load<u8>(ptr++) & 63;
|
||||
if ((cp & 0xFC) == 0xF8) {
|
||||
cp = ((cp & 3) << 24) | (u1 << 18) | (u2 << 12) | (u3 << 6) | u4;
|
||||
} else {
|
||||
u5 = load<u8>(ptr++) & 63;
|
||||
cp = ((cp & 1) << 30) | (u1 << 24) | (u2 << 18) | (u3 << 12) | (u4 << 6) | u5;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cp < 0x10000) {
|
||||
utf16le.push(cp);
|
||||
} else {
|
||||
var ch = cp - 0x10000;
|
||||
utf16le.push(0xD800 | (ch >> 10));
|
||||
utf16le.push(0xDC00 | (ch & 0x3FF));
|
||||
}
|
||||
}
|
||||
// FIXME: not portable and prone to stack overflows. Maybe use CString from stdlib?
|
||||
return String.fromCharCode.apply(utf16le);
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ export class Type {
|
||||
constructor(kind: TypeKind, size: i32) {
|
||||
this.kind = kind;
|
||||
this.size = size;
|
||||
this.byteSize = ceil<f64>(<f64>size / 8);
|
||||
this.byteSize = <i32>ceil<f64>(<f64>size / 8);
|
||||
this.classType = null;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user