mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-06-20 02:11:31 +00:00
bleeding edge binaryen
This commit is contained in:
@ -1997,7 +1997,7 @@ export function compileCall(
|
||||
checkTypeAbsent(typeArguments, reportNode, prototype) |
|
||||
checkArgsRequired(operands, 0, reportNode, compiler)
|
||||
) return module.createUnreachable();
|
||||
return module.createHost(HostOp.CurrentMemory);
|
||||
return module.createHost(HostOp.MemorySize);
|
||||
}
|
||||
case BuiltinSymbols.memory_grow: { // memory.grow(pages: i32) -> i32
|
||||
compiler.currentType = Type.i32;
|
||||
@ -2005,7 +2005,7 @@ export function compileCall(
|
||||
checkTypeAbsent(typeArguments, reportNode, prototype) |
|
||||
checkArgsRequired(operands, 1, reportNode, compiler)
|
||||
) return module.createUnreachable();
|
||||
return module.createHost(HostOp.GrowMemory, null, [
|
||||
return module.createHost(HostOp.MemoryGrow, null, [
|
||||
compiler.compileExpression(operands[0], Type.i32, ContextualFlags.IMPLICIT)
|
||||
]);
|
||||
}
|
||||
|
@ -2173,7 +2173,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
// of retaining it as the return value and releasing it as a variable
|
||||
if (!this.skippedAutoreleases.has(expr)) {
|
||||
if (returnType.isManaged) {
|
||||
if (getExpressionId(expr) == ExpressionId.GetLocal) {
|
||||
if (getExpressionId(expr) == ExpressionId.LocalGet) {
|
||||
if (flow.isAnyLocalFlag(getGetLocalIndex(expr), LocalFlags.ANY_RETAINED)) {
|
||||
flow.unsetLocalFlag(getGetLocalIndex(expr), LocalFlags.ANY_RETAINED);
|
||||
this.skippedAutoreleases.add(expr);
|
||||
@ -6222,7 +6222,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
if (thisArg) {
|
||||
let classInstance = assert(instance.parent); assert(classInstance.kind == ElementKind.CLASS);
|
||||
let thisType = assert(instance.signature.thisType);
|
||||
if (canAlias && getExpressionId(thisArg) == ExpressionId.GetLocal) {
|
||||
if (canAlias && getExpressionId(thisArg) == ExpressionId.LocalGet) {
|
||||
flow.addScopedAlias(CommonSymbols.this_, thisType, getGetLocalIndex(thisArg));
|
||||
let baseInstance = (<Class>classInstance).base;
|
||||
if (baseInstance) flow.addScopedAlias(CommonSymbols.super_, baseInstance.type, getGetLocalIndex(thisArg));
|
||||
@ -6244,7 +6244,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
for (let i = 0; i < numArguments; ++i) {
|
||||
let paramExpr = args[i];
|
||||
let paramType = parameterTypes[i];
|
||||
if (canAlias && getExpressionId(paramExpr) == ExpressionId.GetLocal) {
|
||||
if (canAlias && getExpressionId(paramExpr) == ExpressionId.LocalGet) {
|
||||
flow.addScopedAlias(signature.getParameterName(i), paramType, getGetLocalIndex(paramExpr));
|
||||
} else {
|
||||
let argumentLocal = flow.addScopedLocal(
|
||||
@ -6277,7 +6277,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
initType,
|
||||
ContextualFlags.IMPLICIT
|
||||
);
|
||||
if (canAlias && getExpressionId(initExpr) == ExpressionId.GetLocal) {
|
||||
if (canAlias && getExpressionId(initExpr) == ExpressionId.LocalGet) {
|
||||
flow.addScopedAlias(signature.getParameterName(i), initType, getGetLocalIndex(initExpr));
|
||||
} else {
|
||||
let argumentLocal = flow.addScopedLocal(
|
||||
@ -6537,7 +6537,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
// and a child of something else. Preventing the final release however should
|
||||
// make it optimize away.
|
||||
switch (getExpressionId(expr)) {
|
||||
case ExpressionId.SetLocal: { // local.tee(__retain(expr))
|
||||
case ExpressionId.LocalSet: { // local.tee(__retain(expr))
|
||||
if (isTeeLocal(expr)) {
|
||||
let index = getSetLocalIndex(expr);
|
||||
if (flow.isAnyLocalFlag(index, LocalFlags.ANY_RETAINED)) {
|
||||
|
@ -173,20 +173,20 @@ export class Decompiler {
|
||||
case ExpressionId.CallIndirect: {
|
||||
throw new Error("not implemented");
|
||||
}
|
||||
case ExpressionId.GetLocal: {
|
||||
case ExpressionId.LocalGet: {
|
||||
this.push("$");
|
||||
this.push(getGetLocalIndex(expr).toString(10));
|
||||
return;
|
||||
}
|
||||
case ExpressionId.SetLocal: {
|
||||
case ExpressionId.LocalSet: {
|
||||
this.push("$");
|
||||
this.push(getSetLocalIndex(expr).toString(10));
|
||||
this.push(" = ");
|
||||
this.decompileExpression(getSetLocalValue(expr));
|
||||
return;
|
||||
}
|
||||
case ExpressionId.GetGlobal:
|
||||
case ExpressionId.SetGlobal: {
|
||||
case ExpressionId.GlobalGet:
|
||||
case ExpressionId.GlobalSet: {
|
||||
throw new Error("not implemented");
|
||||
}
|
||||
case ExpressionId.Load: {
|
||||
@ -832,11 +832,11 @@ export class Decompiler {
|
||||
}
|
||||
case ExpressionId.Host: {
|
||||
switch (getHostOp(expr)) {
|
||||
case HostOp.CurrentMemory: {
|
||||
case HostOp.MemorySize: {
|
||||
this.push("memory.size()");
|
||||
return;
|
||||
}
|
||||
case HostOp.GrowMemory: {
|
||||
case HostOp.MemoryGrow: {
|
||||
this.push("memory.grow(");
|
||||
this.decompileExpression(getHostOperand(expr, 0));
|
||||
this.push(")");
|
||||
|
14
src/flow.ts
14
src/flow.ts
@ -641,12 +641,12 @@ export class Flow {
|
||||
// depend on a dynamic nullable state (flag = LocalFlags.NONNULL), while everything else
|
||||
// has already been handled by the nullable type check above.
|
||||
switch (getExpressionId(expr)) {
|
||||
case ExpressionId.SetLocal: {
|
||||
case ExpressionId.LocalSet: {
|
||||
if (!isTeeLocal(expr)) break;
|
||||
let local = this.parentFunction.localsByIndex[getSetLocalIndex(expr)];
|
||||
return !local.type.is(TypeFlags.NULLABLE) || this.isLocalFlag(local.index, LocalFlags.NONNULL, false);
|
||||
}
|
||||
case ExpressionId.GetLocal: {
|
||||
case ExpressionId.LocalGet: {
|
||||
let local = this.parentFunction.localsByIndex[getGetLocalIndex(expr)];
|
||||
return !local.type.is(TypeFlags.NULLABLE) || this.isLocalFlag(local.index, LocalFlags.NONNULL, false);
|
||||
}
|
||||
@ -658,14 +658,14 @@ export class Flow {
|
||||
inheritNonnullIfTrue(expr: ExpressionRef): void {
|
||||
// A: `expr` is true-ish -> Q: how did that happen?
|
||||
switch (getExpressionId(expr)) {
|
||||
case ExpressionId.SetLocal: {
|
||||
case ExpressionId.LocalSet: {
|
||||
if (!isTeeLocal(expr)) break;
|
||||
let local = this.parentFunction.localsByIndex[getSetLocalIndex(expr)];
|
||||
this.setLocalFlag(local.index, LocalFlags.NONNULL);
|
||||
this.inheritNonnullIfTrue(getSetLocalValue(expr)); // must have been true-ish as well
|
||||
break;
|
||||
}
|
||||
case ExpressionId.GetLocal: {
|
||||
case ExpressionId.LocalGet: {
|
||||
let local = this.parentFunction.localsByIndex[getGetLocalIndex(expr)];
|
||||
this.setLocalFlag(local.index, LocalFlags.NONNULL);
|
||||
break;
|
||||
@ -854,20 +854,20 @@ export class Flow {
|
||||
switch (getExpressionId(expr)) {
|
||||
|
||||
// overflows if the local isn't wrapped or the conversion does
|
||||
case ExpressionId.GetLocal: {
|
||||
case ExpressionId.LocalGet: {
|
||||
let local = this.parentFunction.localsByIndex[getGetLocalIndex(expr)];
|
||||
return !this.isLocalFlag(local.index, LocalFlags.WRAPPED, true)
|
||||
|| canConversionOverflow(local.type, type);
|
||||
}
|
||||
|
||||
// overflows if the value does
|
||||
case ExpressionId.SetLocal: { // tee
|
||||
case ExpressionId.LocalSet: { // tee
|
||||
assert(isTeeLocal(expr));
|
||||
return this.canOverflow(getSetLocalValue(expr), type);
|
||||
}
|
||||
|
||||
// overflows if the conversion does (globals are wrapped on set)
|
||||
case ExpressionId.GetGlobal: {
|
||||
case ExpressionId.GlobalGet: {
|
||||
// TODO: this is inefficient because it has to read a string
|
||||
let global = assert(this.parentFunction.program.elementsByName.get(assert(getGetGlobalName(expr))));
|
||||
assert(global.kind == ElementKind.GLOBAL);
|
||||
|
40
src/glue/binaryen.d.ts
vendored
40
src/glue/binaryen.d.ts
vendored
@ -42,10 +42,10 @@ declare function _BinaryenBreakId(): BinaryenExpressionId;
|
||||
declare function _BinaryenSwitchId(): BinaryenExpressionId;
|
||||
declare function _BinaryenCallId(): BinaryenExpressionId;
|
||||
declare function _BinaryenCallIndirectId(): BinaryenExpressionId;
|
||||
declare function _BinaryenGetLocalId(): BinaryenExpressionId;
|
||||
declare function _BinaryenSetLocalId(): BinaryenExpressionId;
|
||||
declare function _BinaryenGetGlobalId(): BinaryenExpressionId;
|
||||
declare function _BinaryenSetGlobalId(): BinaryenExpressionId;
|
||||
declare function _BinaryenLocalGetId(): BinaryenExpressionId;
|
||||
declare function _BinaryenLocalSetId(): BinaryenExpressionId;
|
||||
declare function _BinaryenGlobalGetId(): BinaryenExpressionId;
|
||||
declare function _BinaryenGlobalSetId(): BinaryenExpressionId;
|
||||
declare function _BinaryenLoadId(): BinaryenExpressionId;
|
||||
declare function _BinaryenStoreId(): BinaryenExpressionId;
|
||||
declare function _BinaryenConstId(): BinaryenExpressionId;
|
||||
@ -221,8 +221,8 @@ declare function _BinaryenGeFloat64(): BinaryenOp;
|
||||
|
||||
declare type BinaryenHostOp = BinaryenOp;
|
||||
|
||||
declare function _BinaryenCurrentMemory(): BinaryenHostOp;
|
||||
declare function _BinaryenGrowMemory(): BinaryenHostOp;
|
||||
declare function _BinaryenMemorySize(): BinaryenHostOp;
|
||||
declare function _BinaryenMemoryGrow(): BinaryenHostOp;
|
||||
|
||||
declare type BinaryenAtomicRMWOp = BinaryenOp;
|
||||
|
||||
@ -380,11 +380,11 @@ declare function _BinaryenBreak(module: BinaryenModuleRef, name: usize, conditio
|
||||
declare function _BinaryenSwitch(module: BinaryenModuleRef, names: usize, numNames: BinaryenIndex, defaultName: usize, condition: BinaryenExpressionRef, value: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
declare function _BinaryenCall(module: BinaryenModuleRef, target: usize, operands: usize, numOperands: BinaryenIndex, returnType: BinaryenType): BinaryenExpressionRef;
|
||||
declare function _BinaryenCallIndirect(module: BinaryenModuleRef, target: BinaryenExpressionRef, operands: usize, numOperands: BinaryenIndex, type: usize): BinaryenExpressionRef;
|
||||
declare function _BinaryenGetLocal(module: BinaryenModuleRef, index: BinaryenIndex, type: BinaryenType): BinaryenExpressionRef;
|
||||
declare function _BinaryenSetLocal(module: BinaryenModuleRef, index: BinaryenIndex, value: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
declare function _BinaryenTeeLocal(module: BinaryenModuleRef, index: BinaryenIndex, value: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
declare function _BinaryenGetGlobal(module: BinaryenModuleRef, name: usize, type: BinaryenType): BinaryenExpressionRef;
|
||||
declare function _BinaryenSetGlobal(module: BinaryenModuleRef, name: usize, value: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
declare function _BinaryenLocalGet(module: BinaryenModuleRef, index: BinaryenIndex, type: BinaryenType): BinaryenExpressionRef;
|
||||
declare function _BinaryenLocalSet(module: BinaryenModuleRef, index: BinaryenIndex, value: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
declare function _BinaryenLocalTee(module: BinaryenModuleRef, index: BinaryenIndex, value: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
declare function _BinaryenGlobalGet(module: BinaryenModuleRef, name: usize, type: BinaryenType): BinaryenExpressionRef;
|
||||
declare function _BinaryenGlobalSet(module: BinaryenModuleRef, name: usize, value: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
declare function _BinaryenLoad(module: BinaryenModuleRef, bytes: u32, signed: i8, offset: u32, align: u32, type: BinaryenType, ptr: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
declare function _BinaryenStore(module: BinaryenModuleRef, bytes: u32, offset: u32, align: u32, ptr: BinaryenExpressionRef, value: BinaryenExpressionRef, type: BinaryenType): BinaryenExpressionRef;
|
||||
declare function _BinaryenConst(module: BinaryenModuleRef, value: usize): BinaryenExpressionRef;
|
||||
@ -448,16 +448,16 @@ declare function _BinaryenCallIndirectGetTarget(expr: BinaryenExpressionRef): Bi
|
||||
declare function _BinaryenCallIndirectGetNumOperands(expr: BinaryenExpressionRef): BinaryenIndex;
|
||||
declare function _BinaryenCallIndirectGetOperand(expr: BinaryenExpressionRef, index: BinaryenIndex): BinaryenExpressionRef;
|
||||
|
||||
declare function _BinaryenGetLocalGetIndex(expr: BinaryenExpressionRef): BinaryenIndex;
|
||||
declare function _BinaryenLocalGetGetIndex(expr: BinaryenExpressionRef): BinaryenIndex;
|
||||
|
||||
declare function _BinaryenSetLocalIsTee(expr: BinaryenExpressionRef): bool;
|
||||
declare function _BinaryenSetLocalGetIndex(expr: BinaryenExpressionRef): BinaryenIndex;
|
||||
declare function _BinaryenSetLocalGetValue(expr: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
declare function _BinaryenLocalSetIsTee(expr: BinaryenExpressionRef): bool;
|
||||
declare function _BinaryenLocalSetGetIndex(expr: BinaryenExpressionRef): BinaryenIndex;
|
||||
declare function _BinaryenLocalSetGetValue(expr: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
|
||||
declare function _BinaryenGetGlobalGetName(expr: BinaryenExpressionRef): usize;
|
||||
declare function _BinaryenGlobalGetGetName(expr: BinaryenExpressionRef): usize;
|
||||
|
||||
declare function _BinaryenSetGlobalGetName(expr: BinaryenExpressionRef): usize;
|
||||
declare function _BinaryenSetGlobalGetValue(expr: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
declare function _BinaryenGlobalSetGetName(expr: BinaryenExpressionRef): usize;
|
||||
declare function _BinaryenGlobalSetGetValue(expr: BinaryenExpressionRef): BinaryenExpressionRef;
|
||||
|
||||
declare function _BinaryenHostGetOp(expr: BinaryenExpressionRef): BinaryenOp;
|
||||
declare function _BinaryenHostGetNameOperand(expr: BinaryenExpressionRef): usize;
|
||||
@ -622,8 +622,8 @@ declare function _BinaryenModuleRead(input: usize, inputSize: usize): BinaryenMo
|
||||
declare function _BinaryenModuleInterpret(module: BinaryenModuleRef): void;
|
||||
declare function _BinaryenModuleAddDebugInfoFileName(module: BinaryenModuleRef, filename: usize): BinaryenIndex;
|
||||
declare function _BinaryenModuleGetDebugInfoFileName(module: BinaryenModuleRef, index: BinaryenIndex): usize;
|
||||
declare function _BinaryenGetFeatures(module: BinaryenModuleRef): BinaryenFeatureFlags;
|
||||
declare function _BinaryenSetFeatures(module: BinaryenModuleRef, featureFlags: BinaryenFeatureFlags): void;
|
||||
declare function _BinaryenModuleGetFeatures(module: BinaryenModuleRef): BinaryenFeatureFlags;
|
||||
declare function _BinaryenModuleSetFeatures(module: BinaryenModuleRef, featureFlags: BinaryenFeatureFlags): void;
|
||||
|
||||
declare type BinaryenRelooperRef = usize;
|
||||
declare type BinaryenRelooperBlockRef = usize;
|
||||
|
222
src/module.ts
222
src/module.ts
@ -46,10 +46,10 @@ export enum ExpressionId {
|
||||
Switch = _BinaryenSwitchId(),
|
||||
Call = _BinaryenCallId(),
|
||||
CallIndirect = _BinaryenCallIndirectId(),
|
||||
GetLocal = _BinaryenGetLocalId(),
|
||||
SetLocal = _BinaryenSetLocalId(),
|
||||
GetGlobal = _BinaryenGetGlobalId(),
|
||||
SetGlobal = _BinaryenSetGlobalId(),
|
||||
LocalGet = _BinaryenLocalGetId(),
|
||||
LocalSet = _BinaryenLocalSetId(),
|
||||
GlobalGet = _BinaryenGlobalGetId(),
|
||||
GlobalSet = _BinaryenGlobalSetId(),
|
||||
Load = _BinaryenLoadId(),
|
||||
Store = _BinaryenStoreId(),
|
||||
Const = _BinaryenConstId(),
|
||||
@ -336,8 +336,8 @@ export enum BinaryOp {
|
||||
}
|
||||
|
||||
export enum HostOp {
|
||||
CurrentMemory = _BinaryenCurrentMemory(),
|
||||
GrowMemory = _BinaryenGrowMemory(),
|
||||
MemorySize = _BinaryenMemorySize(),
|
||||
MemoryGrow = _BinaryenMemoryGrow(),
|
||||
}
|
||||
|
||||
export enum AtomicRMWOp {
|
||||
@ -526,14 +526,14 @@ export class Module {
|
||||
index: i32,
|
||||
type: NativeType
|
||||
): ExpressionRef {
|
||||
return _BinaryenGetLocal(this.ref, index, type);
|
||||
return _BinaryenLocalGet(this.ref, index, type);
|
||||
}
|
||||
|
||||
createTeeLocal(
|
||||
index: i32,
|
||||
value: ExpressionRef
|
||||
): ExpressionRef {
|
||||
return _BinaryenTeeLocal(this.ref, index, value);
|
||||
return _BinaryenLocalTee(this.ref, index, value);
|
||||
}
|
||||
|
||||
createGetGlobal(
|
||||
@ -541,7 +541,7 @@ export class Module {
|
||||
type: NativeType
|
||||
): ExpressionRef {
|
||||
var cStr = this.allocStringCached(name);
|
||||
return _BinaryenGetGlobal(this.ref, cStr, type);
|
||||
return _BinaryenGlobalGet(this.ref, cStr, type);
|
||||
}
|
||||
|
||||
createLoad(
|
||||
@ -630,7 +630,7 @@ export class Module {
|
||||
index: Index,
|
||||
value: ExpressionRef
|
||||
): ExpressionRef {
|
||||
return _BinaryenSetLocal(this.ref, index, value);
|
||||
return _BinaryenLocalSet(this.ref, index, value);
|
||||
}
|
||||
|
||||
createSetGlobal(
|
||||
@ -638,7 +638,7 @@ export class Module {
|
||||
value: ExpressionRef
|
||||
): ExpressionRef {
|
||||
var cStr = this.allocStringCached(name);
|
||||
return _BinaryenSetGlobal(this.ref, cStr, value);
|
||||
return _BinaryenGlobalSet(this.ref, cStr, value);
|
||||
}
|
||||
|
||||
createBlock(
|
||||
@ -1056,11 +1056,11 @@ export class Module {
|
||||
}
|
||||
|
||||
getFeatures(): BinaryenFeatureFlags {
|
||||
return _BinaryenGetFeatures(this.ref);
|
||||
return _BinaryenModuleGetFeatures(this.ref);
|
||||
}
|
||||
|
||||
setFeatures(featureFlags: BinaryenFeatureFlags): void {
|
||||
_BinaryenSetFeatures(this.ref, featureFlags);
|
||||
_BinaryenModuleSetFeatures(this.ref, featureFlags);
|
||||
}
|
||||
|
||||
optimize(func: FunctionRef = 0): void {
|
||||
@ -1221,16 +1221,16 @@ export class Module {
|
||||
}
|
||||
}
|
||||
}
|
||||
case ExpressionId.GetLocal: {
|
||||
return _BinaryenGetLocal(this.ref,
|
||||
_BinaryenGetLocalGetIndex(expr),
|
||||
case ExpressionId.LocalGet: {
|
||||
return _BinaryenLocalGet(this.ref,
|
||||
_BinaryenLocalGetGetIndex(expr),
|
||||
_BinaryenExpressionGetType(expr)
|
||||
);
|
||||
}
|
||||
case ExpressionId.GetGlobal: {
|
||||
let globalName = _BinaryenGetGlobalGetName(expr);
|
||||
case ExpressionId.GlobalGet: {
|
||||
let globalName = _BinaryenGlobalGetGetName(expr);
|
||||
if (!globalName) break;
|
||||
return _BinaryenGetGlobal(this.ref, globalName, _BinaryenExpressionGetType(expr));
|
||||
return _BinaryenGlobalGet(this.ref, globalName, _BinaryenExpressionGetType(expr));
|
||||
}
|
||||
case ExpressionId.Load: {
|
||||
if (!(nested1 = this.cloneExpression(_BinaryenLoadGetPtr(expr), noSideEffects, maxDepth))) {
|
||||
@ -1330,23 +1330,23 @@ export function getConstValueF64(expr: ExpressionRef): f32 {
|
||||
}
|
||||
|
||||
export function getGetLocalIndex(expr: ExpressionRef): Index {
|
||||
return _BinaryenGetLocalGetIndex(expr);
|
||||
return _BinaryenLocalGetGetIndex(expr);
|
||||
}
|
||||
|
||||
export function getSetLocalIndex(expr: ExpressionRef): Index {
|
||||
return _BinaryenSetLocalGetIndex(expr);
|
||||
return _BinaryenLocalSetGetIndex(expr);
|
||||
}
|
||||
|
||||
export function getSetLocalValue(expr: ExpressionRef): ExpressionRef {
|
||||
return _BinaryenSetLocalGetValue(expr);
|
||||
return _BinaryenLocalSetGetValue(expr);
|
||||
}
|
||||
|
||||
export function isTeeLocal(expr: ExpressionRef): bool {
|
||||
return _BinaryenSetLocalIsTee(expr);
|
||||
return _BinaryenLocalSetIsTee(expr);
|
||||
}
|
||||
|
||||
export function getGetGlobalName(expr: ExpressionRef): string | null {
|
||||
return readString(_BinaryenGetGlobalGetName(expr));
|
||||
return readString(_BinaryenGlobalGetGetName(expr));
|
||||
}
|
||||
|
||||
export function getBinaryOp(expr: ExpressionRef): BinaryOp {
|
||||
@ -1790,3 +1790,177 @@ export function needsExplicitUnreachable(expr: ExpressionRef): bool {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Traverses all expression members of an expression, calling the given visitor. */
|
||||
export function traverse(expr: ExpressionRef, visit: (expr: ExpressionRef) => bool): bool {
|
||||
switch (getExpressionId(expr)) {
|
||||
case ExpressionId.Block: {
|
||||
for (let i = 0, n = _BinaryenBlockGetNumChildren(expr); i < n; ++i) {
|
||||
if (!visit(_BinaryenBlockGetChild(expr, i))) return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ExpressionId.If: {
|
||||
if (!visit(_BinaryenIfGetCondition(expr))) return false;
|
||||
if (!visit(_BinaryenIfGetIfTrue(expr))) return false;
|
||||
let ifFalse = _BinaryenIfGetIfFalse(expr);
|
||||
if (ifFalse) if (!visit(ifFalse)) return false;
|
||||
break;
|
||||
}
|
||||
case ExpressionId.Loop: {
|
||||
if (!visit(_BinaryenLoopGetBody(expr))) return false;
|
||||
break;
|
||||
}
|
||||
case ExpressionId.Break: {
|
||||
let condition = _BinaryenBreakGetCondition(expr);
|
||||
if (condition) if (!visit(condition)) return false;
|
||||
break;
|
||||
}
|
||||
case ExpressionId.Switch: {
|
||||
if (!visit(_BinaryenSwitchGetCondition(expr))) return false;
|
||||
break;
|
||||
}
|
||||
case ExpressionId.Call: {
|
||||
for (let i = 0, n = _BinaryenCallGetNumOperands(expr); i < n; ++i) {
|
||||
if (!visit(_BinaryenCallGetOperand(expr, i))) return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ExpressionId.CallIndirect: {
|
||||
for (let i = 0, n = _BinaryenCallIndirectGetNumOperands(expr); i < n; ++i) {
|
||||
if (!visit(_BinaryenCallIndirectGetOperand(expr, i))) return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ExpressionId.LocalGet: {
|
||||
break;
|
||||
}
|
||||
case ExpressionId.LocalSet: {
|
||||
if (!visit(_BinaryenLocalSetGetValue(expr))) return false;
|
||||
break;
|
||||
}
|
||||
case ExpressionId.GlobalGet: {
|
||||
break;
|
||||
}
|
||||
case ExpressionId.GlobalSet: {
|
||||
if (!visit(_BinaryenGlobalSetGetValue(expr))) return false;
|
||||
break;
|
||||
}
|
||||
case ExpressionId.Load: {
|
||||
if (!visit(_BinaryenLoadGetPtr(expr))) return false;
|
||||
break;
|
||||
}
|
||||
case ExpressionId.Store: {
|
||||
if (!visit(_BinaryenStoreGetPtr(expr))) return false;
|
||||
if (!visit(_BinaryenStoreGetValue(expr))) return false;
|
||||
break;
|
||||
}
|
||||
case ExpressionId.AtomicRMW: {
|
||||
if (!visit(_BinaryenAtomicRMWGetPtr(expr))) return false;
|
||||
if (!visit(_BinaryenAtomicRMWGetValue(expr))) return false;
|
||||
break;
|
||||
}
|
||||
case ExpressionId.AtomicCmpxchg: {
|
||||
if (!visit(_BinaryenAtomicCmpxchgGetPtr(expr))) return false;
|
||||
if (!visit(_BinaryenAtomicCmpxchgGetExpected(expr))) return false;
|
||||
if (!visit(_BinaryenAtomicCmpxchgGetReplacement(expr))) return false;
|
||||
break;
|
||||
}
|
||||
case ExpressionId.AtomicWait: {
|
||||
if (!visit(_BinaryenAtomicWaitGetPtr(expr))) return false;
|
||||
if (!visit(_BinaryenAtomicWaitGetExpected(expr))) return false;
|
||||
if (!visit(_BinaryenAtomicWaitGetTimeout(expr))) return false;
|
||||
break;
|
||||
}
|
||||
case ExpressionId.AtomicNotify: {
|
||||
if (!visit(_BinaryenAtomicNotifyGetPtr(expr))) return false;
|
||||
break;
|
||||
}
|
||||
case ExpressionId.SIMDExtract: {
|
||||
if (!visit(_BinaryenSIMDExtractGetVec(expr))) return false;
|
||||
break;
|
||||
}
|
||||
case ExpressionId.SIMDReplace: {
|
||||
if (!visit(_BinaryenSIMDReplaceGetVec(expr))) return false;
|
||||
if (!visit(_BinaryenSIMDReplaceGetValue(expr))) return false;
|
||||
break;
|
||||
}
|
||||
case ExpressionId.SIMDShuffle: {
|
||||
if (!visit(_BinaryenSIMDShuffleGetLeft(expr))) return false;
|
||||
if (!visit(_BinaryenSIMDShuffleGetRight(expr))) return false;
|
||||
break;
|
||||
}
|
||||
case ExpressionId.SIMDBitselect: {
|
||||
if (!visit(_BinaryenSIMDBitselectGetLeft(expr))) return false;
|
||||
if (!visit(_BinaryenSIMDBitselectGetRight(expr))) return false;
|
||||
if (!visit(_BinaryenSIMDBitselectGetCond(expr))) return false;
|
||||
break;
|
||||
}
|
||||
case ExpressionId.SIMDShift: {
|
||||
if (!visit(_BinaryenSIMDShiftGetVec(expr))) return false;
|
||||
if (!visit(_BinaryenSIMDShiftGetShift(expr))) return false;
|
||||
break;
|
||||
}
|
||||
case ExpressionId.MemoryInit: {
|
||||
if (!visit(_BinaryenMemoryInitGetDest(expr))) return false;
|
||||
if (!visit(_BinaryenMemoryInitGetOffset(expr))) return false;
|
||||
if (!visit(_BinaryenMemoryInitGetSize(expr))) return false;
|
||||
break;
|
||||
}
|
||||
case ExpressionId.DataDrop: {
|
||||
break;
|
||||
}
|
||||
case ExpressionId.MemoryCopy: {
|
||||
if (!visit(_BinaryenMemoryCopyGetDest(expr))) return false;
|
||||
if (!visit(_BinaryenMemoryCopyGetSource(expr))) return false;
|
||||
if (!visit(_BinaryenMemoryCopyGetSize(expr))) return false;
|
||||
break;
|
||||
}
|
||||
case ExpressionId.MemoryFill: {
|
||||
if (!visit(_BinaryenMemoryFillGetDest(expr))) return false;
|
||||
if (!visit(_BinaryenMemoryFillGetValue(expr))) return false;
|
||||
if (!visit(_BinaryenMemoryFillGetSize(expr))) return false;
|
||||
break;
|
||||
}
|
||||
case ExpressionId.Const: {
|
||||
break;
|
||||
}
|
||||
case ExpressionId.Unary: {
|
||||
if (!visit(_BinaryenUnaryGetValue(expr))) return false;
|
||||
break;
|
||||
}
|
||||
case ExpressionId.Binary: {
|
||||
if (!visit(_BinaryenBinaryGetLeft(expr))) return false;
|
||||
if (!visit(_BinaryenBinaryGetRight(expr))) return false;
|
||||
break;
|
||||
}
|
||||
case ExpressionId.Select: {
|
||||
if (!visit(_BinaryenSelectGetIfTrue(expr))) return false;
|
||||
if (!visit(_BinaryenSelectGetIfFalse(expr))) return false;
|
||||
if (!visit(_BinaryenSelectGetCondition(expr))) return false;
|
||||
break;
|
||||
}
|
||||
case ExpressionId.Drop: {
|
||||
if (!visit(_BinaryenDropGetValue(expr))) return false;
|
||||
break;
|
||||
}
|
||||
case ExpressionId.Return: {
|
||||
if (!visit(_BinaryenReturnGetValue(expr))) return false;
|
||||
break;
|
||||
}
|
||||
case ExpressionId.Host: {
|
||||
for (let i = 0, n = _BinaryenHostGetNumOperands(expr); i < n; ++i) {
|
||||
if (!visit(_BinaryenHostGetOperand(expr, i))) return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ExpressionId.Nop: {
|
||||
break;
|
||||
}
|
||||
case ExpressionId.Unreachable: {
|
||||
break;
|
||||
}
|
||||
default: assert(false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
Reference in New Issue
Block a user