Skip to content

Commit c629b1d

Browse files
authored
Refactor cloneExpression to reuse copyExpression (AssemblyScript#2079)
1 parent 250dc70 commit c629b1d

File tree

2 files changed

+17
-107
lines changed

2 files changed

+17
-107
lines changed

src/compiler.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4645,8 +4645,8 @@ export class Compiler extends DiagnosticEmitter {
46454645
rightFlow.freeScopedLocals();
46464646
this.currentFlow = flow;
46474647

4648-
// simplify if cloning left without side effects is possible
4649-
if (expr = module.cloneExpression(leftExpr, true, 0)) {
4648+
// simplify if copying left is trivial
4649+
if (expr = module.tryCopyTrivialExpression(leftExpr)) {
46504650
expr = module.if(
46514651
this.makeIsTrueish(leftExpr, this.currentType, left),
46524652
rightExpr,
@@ -4709,8 +4709,8 @@ export class Compiler extends DiagnosticEmitter {
47094709
rightFlow.freeScopedLocals();
47104710
this.currentFlow = flow;
47114711

4712-
// simplify if cloning left without side effects is possible
4713-
if (expr = module.cloneExpression(leftExpr, true, 0)) {
4712+
// simplify if copying left is trivial
4713+
if (expr = module.tryCopyTrivialExpression(leftExpr)) {
47144714
expr = module.if(
47154715
this.makeIsTrueish(leftExpr, leftType, left),
47164716
expr,

src/module.ts

Lines changed: 13 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -2484,115 +2484,25 @@ export class Module {
24842484
return Relooper.create(this);
24852485
}
24862486

2487-
cloneExpression(
2488-
expr: ExpressionRef,
2489-
noSideEffects: bool = false,
2490-
maxDepth: i32 = i32.MAX_VALUE
2491-
): ExpressionRef { // currently supports side effect free expressions only
2492-
if (maxDepth < 0) return 0;
2493-
maxDepth -= 1;
2494-
2495-
var nested1: ExpressionRef,
2496-
nested2: ExpressionRef;
2497-
2487+
/** Makes a copy of a trivial expression (doesn't contain subexpressions). Returns `0` if non-trivial. */
2488+
tryCopyTrivialExpression(expr: ExpressionRef): ExpressionRef {
24982489
switch (binaryen._BinaryenExpressionGetId(expr)) {
2499-
case ExpressionId.Const: {
2500-
switch (<u32>binaryen._BinaryenExpressionGetType(expr)) {
2501-
case <u32>TypeRef.I32: {
2502-
return this.i32(binaryen._BinaryenConstGetValueI32(expr));
2503-
}
2504-
case <u32>TypeRef.I64: {
2505-
return this.i64(
2506-
binaryen._BinaryenConstGetValueI64Low(expr),
2507-
binaryen._BinaryenConstGetValueI64High(expr)
2508-
);
2509-
}
2510-
case <u32>TypeRef.F32: {
2511-
return this.f32(binaryen._BinaryenConstGetValueF32(expr));
2512-
}
2513-
case <u32>TypeRef.F64: {
2514-
return this.f64(binaryen._BinaryenConstGetValueF64(expr));
2515-
}
2516-
case <u32>TypeRef.V128: {
2517-
// TODO
2518-
return 0;
2519-
}
2520-
// Not possible to clone an externref as it is opaque
2521-
case <u32>TypeRef.Externref: {
2522-
return 0;
2523-
}
2524-
default: {
2525-
throw new Error("concrete type expected");
2526-
}
2527-
}
2528-
}
2529-
case ExpressionId.LocalGet: {
2530-
return binaryen._BinaryenLocalGet(this.ref,
2531-
binaryen._BinaryenLocalGetGetIndex(expr),
2532-
binaryen._BinaryenExpressionGetType(expr)
2533-
);
2534-
}
2535-
case ExpressionId.GlobalGet: {
2536-
let globalName = binaryen._BinaryenGlobalGetGetName(expr);
2537-
if (!globalName) break;
2538-
return binaryen._BinaryenGlobalGet(
2539-
this.ref, globalName, binaryen._BinaryenExpressionGetType(expr)
2540-
);
2541-
}
2542-
case ExpressionId.Load: {
2543-
if (!(nested1 = this.cloneExpression(
2544-
binaryen._BinaryenLoadGetPtr(expr), noSideEffects, maxDepth)
2545-
)) {
2546-
break;
2547-
}
2548-
return (
2549-
binaryen._BinaryenLoadIsAtomic(expr)
2550-
? binaryen._BinaryenAtomicLoad(this.ref,
2551-
binaryen._BinaryenLoadGetBytes(expr),
2552-
binaryen._BinaryenLoadGetOffset(expr),
2553-
binaryen._BinaryenExpressionGetType(expr),
2554-
nested1
2555-
)
2556-
: binaryen._BinaryenLoad(this.ref,
2557-
binaryen._BinaryenLoadGetBytes(expr),
2558-
binaryen._BinaryenLoadIsSigned(expr),
2559-
binaryen._BinaryenLoadGetOffset(expr),
2560-
binaryen._BinaryenLoadGetAlign(expr),
2561-
binaryen._BinaryenExpressionGetType(expr),
2562-
nested1
2563-
)
2564-
);
2565-
}
2566-
case ExpressionId.Unary: {
2567-
if (!(nested1 = this.cloneExpression(
2568-
binaryen._BinaryenUnaryGetValue(expr), noSideEffects, maxDepth)
2569-
)) {
2570-
break;
2571-
}
2572-
return binaryen._BinaryenUnary(
2573-
this.ref, binaryen._BinaryenUnaryGetOp(expr), nested1
2574-
);
2575-
}
2576-
case ExpressionId.Binary: {
2577-
if (!(nested1 = this.cloneExpression(
2578-
binaryen._BinaryenBinaryGetLeft(expr), noSideEffects, maxDepth)
2579-
)) {
2580-
break;
2581-
}
2582-
if (!(nested2 = this.cloneExpression(
2583-
binaryen._BinaryenBinaryGetRight(expr), noSideEffects, maxDepth)
2584-
)) {
2585-
break;
2586-
}
2587-
return binaryen._BinaryenBinary(
2588-
this.ref, binaryen._BinaryenBinaryGetOp(expr), nested1, nested2
2589-
);
2590-
}
2490+
case ExpressionId.LocalGet:
2491+
case ExpressionId.GlobalGet:
2492+
case ExpressionId.Const:
2493+
case ExpressionId.MemorySize:
2494+
case ExpressionId.Nop:
2495+
case ExpressionId.Unreachable:
2496+
case ExpressionId.DataDrop:
2497+
case ExpressionId.RefNull:
2498+
case ExpressionId.RttCanon: return this.copyExpression(expr);
25912499
}
25922500
return 0;
25932501
}
25942502

2503+
/** Makes a copy of any expression including all subexpressions. */
25952504
copyExpression(expr: ExpressionRef): ExpressionRef {
2505+
// TODO: Copy debug location as well (needs Binaryen support)
25962506
return binaryen._BinaryenExpressionCopy(expr, this.ref);
25972507
}
25982508

0 commit comments

Comments
 (0)