diff --git a/Wacs.Core/Instructions/Control.cs b/Wacs.Core/Instructions/Control.cs index 6a3a562..c2038bb 100644 --- a/Wacs.Core/Instructions/Control.cs +++ b/Wacs.Core/Instructions/Control.cs @@ -89,8 +89,7 @@ public override void Validate(IWasmValidationContext context) context.Assert(funcType, "Invalid BlockType: {0}",Block.Type); //Check the parameters [t1*] and discard - context.OpStack.PopValues(funcType.ParameterTypes, ref _aside); - _aside.Clear(); + context.OpStack.DiscardValues(funcType.ParameterTypes); //ControlStack will push the values back on (Control Frame is our Label) context.PushControlFrame(BlockOp, funcType); @@ -164,8 +163,7 @@ public override void Validate(IWasmValidationContext context) context.Assert(funcType, "Invalid BlockType: {0}",Block.Type); //Check the parameters [t1*] and discard - context.OpStack.PopValues(funcType.ParameterTypes, ref _aside); - _aside.Clear(); + context.OpStack.DiscardValues(funcType.ParameterTypes); //ControlStack will push the values back on (Control Frame is our Label) context.PushControlFrame(LoopOp, funcType); @@ -247,8 +245,7 @@ public override void Validate(IWasmValidationContext context) context.OpStack.PopI32(); //Check the parameters [t1*] and discard - context.OpStack.PopValues(ifType.ParameterTypes, ref _aside); - _aside.Clear(); + context.OpStack.DiscardValues(ifType.ParameterTypes); //ControlStack will push the values back on (Control Frame is our Label) context.PushControlFrame(IfOp, ifType); @@ -444,8 +441,7 @@ public override void Validate(IWasmValidationContext context) var nthFrame = context.ControlStack.PeekAt((int)L.Value); //Validate results, but leave them on the stack - context.OpStack.PopValues(nthFrame.LabelTypes, ref _aside); - _aside.Clear(); + context.OpStack.DiscardValues(nthFrame.LabelTypes); // if (!context.Unreachable) // nthFrame.ConditionallyReachable = true; @@ -544,7 +540,7 @@ public override void Validate(IWasmValidationContext context) // nthFrame.ConditionallyReachable = true; //Pop values like we branch - context.OpStack.PopValues(nthFrame.LabelTypes, ref _aside); + context.OpStack.DiscardValues(nthFrame.LabelTypes); //But actually, we don't, so push them back on. context.OpStack.PushResult(nthFrame.LabelTypes); } @@ -610,7 +606,8 @@ public override void Validate(IWasmValidationContext context) // if (!context.Unreachable) // mthFrame.ConditionallyReachable = true; - + + Stack aside = new(); foreach (var lidx in Ls) { context.Assert(context.ContainsLabel(lidx.Value), @@ -619,16 +616,12 @@ public override void Validate(IWasmValidationContext context) var nthFrame = context.ControlStack.PeekAt((int)lidx.Value); context.Assert(nthFrame.LabelTypes.Arity == arity, "Instruction br_table invalid. Label {0} had different arity {1} =/= {2}", lidx, nthFrame.LabelTypes.Arity,arity); - - // if (!context.Unreachable) - // nthFrame.ConditionallyReachable = true; - context.OpStack.PopValues(nthFrame.LabelTypes, ref _aside); - context.OpStack.PushValues(_aside); + context.OpStack.PopValues(nthFrame.LabelTypes, ref aside); + context.OpStack.PushValues(aside); } - context.OpStack.PopValues(mthFrame.LabelTypes, ref _aside); - _aside.Clear(); + context.OpStack.PopValues(mthFrame.LabelTypes, ref aside); context.SetUnreachable(); } @@ -723,8 +716,9 @@ public sealed class InstReturn : InstructionBase public override void Validate(IWasmValidationContext context) { //keep the results for the block or function to validate - context.OpStack.PopValues(context.ReturnType, ref _aside); - context.OpStack.PushValues(_aside); + Stack aside = new(); + context.OpStack.PopValues(context.ReturnType, ref aside); + context.OpStack.PushValues(aside); context.SetUnreachable(); } @@ -770,8 +764,7 @@ public override void Validate(IWasmValidationContext context) "Instruction call was invalid. Function {0} was not in the Context.",X); var func = context.Funcs[X]; var type = context.Types[func.TypeIndex]; - context.OpStack.PopValues(type.ParameterTypes, ref _aside); - _aside.Clear(); + context.OpStack.DiscardValues(type.ParameterTypes); context.OpStack.PushResult(type.ResultType); } @@ -891,8 +884,7 @@ public override void Validate(IWasmValidationContext context) var funcType = context.Types[Y]; context.OpStack.PopI32(); - context.OpStack.PopValues(funcType.ParameterTypes, ref _aside); - _aside.Clear(); + context.OpStack.DiscardValues(funcType.ParameterTypes); context.OpStack.PushResult(funcType.ResultType); } diff --git a/Wacs.Core/Instructions/InstructionBase.cs b/Wacs.Core/Instructions/InstructionBase.cs index 6790074..e76371e 100644 --- a/Wacs.Core/Instructions/InstructionBase.cs +++ b/Wacs.Core/Instructions/InstructionBase.cs @@ -31,8 +31,6 @@ namespace Wacs.Core.Instructions /// public abstract class InstructionBase { - protected static Stack _aside = new(); - public bool IsAsync = false; public int Size = 1; diff --git a/Wacs.Core/Instructions/TailCall.cs b/Wacs.Core/Instructions/TailCall.cs index e31f23b..ae43eb0 100644 --- a/Wacs.Core/Instructions/TailCall.cs +++ b/Wacs.Core/Instructions/TailCall.cs @@ -53,8 +53,9 @@ public bool IsBound(ExecContext context) public override void Validate(IWasmValidationContext context) { //Return - context.OpStack.PopValues(context.ReturnType, ref _aside); - context.OpStack.PushValues(_aside); + Stack aside = new(); + context.OpStack.PopValues(context.ReturnType, ref aside); + context.OpStack.PushValues(aside); context.SetUnreachable(); //Call @@ -62,8 +63,8 @@ public override void Validate(IWasmValidationContext context) "Instruction call was invalid. Function {0} was not in the Context.",X); var func = context.Funcs[X]; var type = context.Types[func.TypeIndex]; - context.OpStack.PopValues(type.ParameterTypes, ref _aside); - _aside.Clear(); + context.OpStack.PopValues(type.ParameterTypes, ref aside); + aside.Clear(); context.OpStack.PushResult(type.ResultType); } @@ -203,8 +204,9 @@ public bool IsBound(ExecContext context) public override void Validate(IWasmValidationContext context) { //Return - context.OpStack.PopValues(context.ReturnType, ref _aside); - context.OpStack.PushValues(_aside); + Stack aside = new(); + context.OpStack.PopValues(context.ReturnType, ref aside); + context.OpStack.PushValues(aside); context.SetUnreachable(); //Call Indirect @@ -218,8 +220,8 @@ public override void Validate(IWasmValidationContext context) var funcType = context.Types[Y]; context.OpStack.PopI32(); - context.OpStack.PopValues(funcType.ParameterTypes, ref _aside); - _aside.Clear(); + context.OpStack.PopValues(funcType.ParameterTypes, ref aside); + aside.Clear(); context.OpStack.PushResult(funcType.ResultType); } diff --git a/Wacs.Core/Instructions/Transpiler/InstCompoundIf.cs b/Wacs.Core/Instructions/Transpiler/InstCompoundIf.cs index 9648998..45419fa 100644 --- a/Wacs.Core/Instructions/Transpiler/InstCompoundIf.cs +++ b/Wacs.Core/Instructions/Transpiler/InstCompoundIf.cs @@ -74,8 +74,7 @@ public override void Validate(IWasmValidationContext context) // context.OpStack.PopI32(); //Check the parameters [t1*] and discard - context.OpStack.PopValues(ifType.ParameterTypes, ref _aside); - _aside.Clear(); + context.OpStack.DiscardValues(ifType.ParameterTypes); //ControlStack will push the values back on (Control Frame is our Label) context.PushControlFrame(IfOp, ifType); diff --git a/Wacs.Core/Modules/Sections/StackCalculator.cs b/Wacs.Core/Modules/Sections/StackCalculator.cs index d42d927..3807f82 100644 --- a/Wacs.Core/Modules/Sections/StackCalculator.cs +++ b/Wacs.Core/Modules/Sections/StackCalculator.cs @@ -57,6 +57,10 @@ public void PushResult(ResultType types) public void PushValues(Stack vals) { while (vals.Count > 0) _context.Push(vals.Pop().Type); } + + public void DiscardValues(ResultType types) { + foreach (var type in types.Types.Reverse()) PopType(type); + } public Value PopI32() => _context.Pop(ValType.I32); public Value PopI64() => _context.Pop(ValType.I64); diff --git a/Wacs.Core/Modules/Sections/StackRenderer.cs b/Wacs.Core/Modules/Sections/StackRenderer.cs index 4e30e72..caf1444 100644 --- a/Wacs.Core/Modules/Sections/StackRenderer.cs +++ b/Wacs.Core/Modules/Sections/StackRenderer.cs @@ -60,6 +60,10 @@ public void PushResult(ResultType types) public void PushValues(Stack vals) { while (vals.Count > 0) _context.Push(vals.Pop().Type); } + + public void DiscardValues(ResultType types) { + foreach (var type in types.Types.Reverse()) PopType(type); + } public Value PopI32() => _context.Pop(ValType.I32); public Value PopI64() => _context.Pop(ValType.I64); diff --git a/Wacs.Core/Validation/ValidationOpStack.cs b/Wacs.Core/Validation/ValidationOpStack.cs index bed1870..2a4db83 100644 --- a/Wacs.Core/Validation/ValidationOpStack.cs +++ b/Wacs.Core/Validation/ValidationOpStack.cs @@ -46,6 +46,8 @@ public interface IValidationOpStack Value PopAny(); void PopValues(ResultType types, ref Stack aside); + void DiscardValues(ResultType types); + public void ReturnResults(ResultType type); } @@ -258,6 +260,14 @@ public void PopValues(ResultType types, ref Stack aside) aside.Push(PopType(type)); } } + + public void DiscardValues(ResultType types) + { + foreach (var type in types.Types.Reverse()) + { + PopType(type); + } + } public void ReturnResults(ResultType types) {