diff --git a/WasmLib/Decompilation/GenericDecompiler.cs b/WasmLib/Decompilation/GenericDecompiler.cs index 102a11a..4a4b948 100644 --- a/WasmLib/Decompilation/GenericDecompiler.cs +++ b/WasmLib/Decompilation/GenericDecompiler.cs @@ -112,9 +112,9 @@ namespace WasmLib.Decompilation for (int i = 0; i < parameterEdges.Length; i++) { var edge = parameterEdges[i]; var variableNode = edge.Source; - var isPure = !graph.Nodes.OfType().Any(x => !x.IsPure & x.Index > variableNode.Index && x.Index < currentNode.Index); + var doesNotSkipImpure = !graph.Nodes.OfType().Any(x => !x.IsPure & x.Index > variableNode.Index && x.Index < currentNode.Index); - if (isPure) { // TODO: and instruction can be inlined + if (doesNotSkipImpure && variableNode.Instruction.CanBeInlined) { parameters[i] = statements[variableNode.Index]; statements.Remove(variableNode.Index); } diff --git a/WasmLib/Decompilation/Intermediate/Instructions/CallInstruction.cs b/WasmLib/Decompilation/Intermediate/Instructions/CallInstruction.cs index f2fbab6..a360dc8 100644 --- a/WasmLib/Decompilation/Intermediate/Instructions/CallInstruction.cs +++ b/WasmLib/Decompilation/Intermediate/Instructions/CallInstruction.cs @@ -13,6 +13,7 @@ namespace WasmLib.Decompilation.Intermediate.Instructions public bool IsIndirect { get; } public FunctionSignature Signature { get; } public override bool IsPure => false; // TODO: could be optimized by checking if referenced function is pure + public override bool CanBeInlined => false; // only for readability public override ValueKind[] PopTypes => (IsIndirect ? new[] {ValueKind.I32} : new ValueKind[0]).Concat(Signature.Parameters.Reverse()).ToArray(); public override ValueKind[] PushTypes => Signature.ReturnParameter.Reverse().ToArray(); diff --git a/WasmLib/Decompilation/Intermediate/Instructions/ControlBlockInstruction.cs b/WasmLib/Decompilation/Intermediate/Instructions/ControlBlockInstruction.cs index 96ab8e0..2446fb8 100644 --- a/WasmLib/Decompilation/Intermediate/Instructions/ControlBlockInstruction.cs +++ b/WasmLib/Decompilation/Intermediate/Instructions/ControlBlockInstruction.cs @@ -11,6 +11,7 @@ namespace WasmLib.Decompilation.Intermediate.Instructions public ControlBlockKind Kind { get; } public ValueKind ValueKind { get; } public override bool IsPure => false; // TODO: could be optimized by checking if control blocks are pure + public override bool CanBeInlined => false; public ControlBlockInstruction(in Instruction instruction, IReadOnlyList block1, IReadOnlyList? block2) { diff --git a/WasmLib/Decompilation/Intermediate/Instructions/DropInstruction.cs b/WasmLib/Decompilation/Intermediate/Instructions/DropInstruction.cs index b7f299d..aed0a2a 100644 --- a/WasmLib/Decompilation/Intermediate/Instructions/DropInstruction.cs +++ b/WasmLib/Decompilation/Intermediate/Instructions/DropInstruction.cs @@ -8,5 +8,6 @@ namespace WasmLib.Decompilation.Intermediate.Instructions public override ValueKind[] PushTypes => new ValueKind[0]; public override string OperationStringFormat => "// drop {0}"; public override bool IsPure => true; + public override bool CanBeInlined => false; // inlined behavior would be part of the comment } } \ No newline at end of file diff --git a/WasmLib/Decompilation/Intermediate/Instructions/MemoryInstruction.cs b/WasmLib/Decompilation/Intermediate/Instructions/MemoryInstruction.cs index d8df9bc..29ee3d2 100644 --- a/WasmLib/Decompilation/Intermediate/Instructions/MemoryInstruction.cs +++ b/WasmLib/Decompilation/Intermediate/Instructions/MemoryInstruction.cs @@ -13,9 +13,8 @@ namespace WasmLib.Decompilation.Intermediate.Instructions public uint Offset { get; } public uint Alignment { get; } - - // inlining loads would be ugly - // public override bool IsPure => Action == ActionKind.Load; + + public override bool IsPure => false; public MemoryInstruction(in Instruction instruction) { diff --git a/WasmLib/Decompilation/Intermediate/Instructions/UnreachableInstruction.cs b/WasmLib/Decompilation/Intermediate/Instructions/UnreachableInstruction.cs index d52dbd4..80ec88c 100644 --- a/WasmLib/Decompilation/Intermediate/Instructions/UnreachableInstruction.cs +++ b/WasmLib/Decompilation/Intermediate/Instructions/UnreachableInstruction.cs @@ -9,5 +9,7 @@ namespace WasmLib.Decompilation.Intermediate.Instructions public override string OperationStringFormat => "// UNREACHABLE"; public override bool RestOfBlockUnreachable => true; + public override bool IsPure => false; + public override bool CanBeInlined => false; } } \ No newline at end of file diff --git a/WasmLib/Decompilation/Intermediate/Instructions/VariableInstruction.cs b/WasmLib/Decompilation/Intermediate/Instructions/VariableInstruction.cs index 6362c39..b54cc44 100644 --- a/WasmLib/Decompilation/Intermediate/Instructions/VariableInstruction.cs +++ b/WasmLib/Decompilation/Intermediate/Instructions/VariableInstruction.cs @@ -15,6 +15,7 @@ namespace WasmLib.Decompilation.Intermediate.Instructions public uint Index { get; } public ValueKind Type => Target == TargetKind.Local ? GetLocal(Index) : GetGlobal(Index); public override bool IsPure => Action == ActionKind.Get; + public override bool CanBeInlined => Action != ActionKind.Tee; private readonly WasmModule module; private readonly FunctionBody body; diff --git a/WasmLib/Decompilation/Intermediate/IntermediateInstruction.cs b/WasmLib/Decompilation/Intermediate/IntermediateInstruction.cs index 4d8df0a..e0a4f80 100644 --- a/WasmLib/Decompilation/Intermediate/IntermediateInstruction.cs +++ b/WasmLib/Decompilation/Intermediate/IntermediateInstruction.cs @@ -9,6 +9,7 @@ namespace WasmLib.Decompilation.Intermediate public abstract ValueKind[] PushTypes { get; } public virtual bool RestOfBlockUnreachable => false; public virtual bool IsPure => false; + public virtual bool CanBeInlined => true; // only matters if PushTypes has items public virtual bool IsImplicit => false; public bool HasBlock => Block1 != null;