private void Exit(uint l) { if (ctx.labels.Count() < l + 1) { Trap("Function corrupt"); } // Stack appears to consider ElementAt from the front of the list rather than the back // So paradoxically, it actually counts up (0th element = latest, 1st = second, etc) LabelObject label = ctx.labels.ElementAt((int)l); uint n = label.arity; logger.ConditionalTrace($"Exiting to label: {label}."); /* * Pop the values val^n from the stack. * Repeat l+1 times: * While the top of the stack is a value, do: * Pop the value from the stack. * Assert: due to validation, the top of the stack now is a label. * Pop the label from the stack. * Push the values val^n to the stack. */ Stack <ValueObject> values = new Stack <ValueObject>(); for (uint i = 0; i < n; i++) { values.Push(GetValueOrFail()); } for (uint i = 0; i < l + 1; i++) { while (ctx.Peek() == WebAssemblyStackObjectType.ValueObject) { ctx.PopValue(); } if (ctx.Peek() != WebAssemblyStackObjectType.LabelObject) { Trap("Corrupt function"); } ctx.PopLabel(); } for (uint i = 0; i < n; i++) { ctx.Push(values.Pop()); } logger.ConditionalTrace($"Jumping to {label.branch_target}."); ctx.GetCurrentFunction().pc = label.branch_target; }
public void Push(LabelObject obj) { stack_objects.Push(WebAssemblyStackObjectType.LabelObject); labels.Push(obj); logger.ConditionalTrace($"Pushed Label: {obj}."); }
private void Enter(LabelObject obj) { ctx.Push(obj); }