IEnumerable <LazyString> Impl_Call_CustomMethod(MethodInfo method, Instruction instruction, MethodDefinition targetMethod) { // pop the parameters off the variable stack and onto the parameter stack var paramsVal = ArraySlice( GetGlobal(Variables.VariableStack), () => "0", () => targetMethod.Parameters.Count.ToString()); foreach (var action in ParameterStack.Push(paramsVal)) { yield return(action); } foreach (var action in VariableStack.Pop(targetMethod.Parameters.Count)) { yield return(action); } foreach (var action in JumpOffsetStack.Push(GetJumpId(method, instruction.Next))) { yield return(action); } foreach (var action in JumpOffsetStack.Push(() => "0")) { yield return(action); } foreach (var action in Impl_Call_CustomMethod_Direct(targetMethod)) { yield return(action); } yield return(() => "Loop;"); }
IEnumerable <LazyString> MethodHeaderActions(MethodInfo method) { var firstActions = new LazyString[] { () => $"Abort If (Not({FunctionCondition(method)()}));", () => "Wait(0, Abort When False);", SetGlobal(Variables.Temporary, JumpOffsetStack.GetLastElement(0)), }; LazyString actionCountStr = () => { var instruction = method.Instructions.First(); var nextInChain = FindNextSkipChain(method, instruction); var actionCount = nextInChain == null ? 99999999 : CalcNumActionsToSkip(method, nextInChain) - CalcNumActionsToSkip(method, instruction); return(actionCount.ToString()); }; var jumpToTarget = new[] { SetGlobal(Variables.Temporary2, GetGlobal(Variables.Temporary)), SetGlobal(Variables.Temporary, Subtract(GetGlobal(Variables.Temporary), Add(actionCountStr, () => "4"))), SkipIf( NotEqual(GetGlobal(Variables.Temporary2), () => "0"), Min(GetGlobal(Variables.Temporary2), Add(actionCountStr, () => "1"))), }; return(firstActions.Concat(JumpOffsetStack.Pop(1)).Concat(jumpToTarget)); }
IEnumerable <LazyString> Impl_Jump_If(MethodInfo method, Instruction instruction, int valuesToPop, LazyString condition) { yield return(SetGlobal(Variables.Temporary, ArraySlice( GetGlobal(Variables.VariableStack), () => "0", () => valuesToPop.ToString()))); foreach (var action in VariableStack.Pop(valuesToPop)) { yield return(action); } yield return(SkipIf(Not(condition), () => (JumpOffsetStack.Push(() => "").Count() + 1).ToString())); foreach (var action in JumpOffsetStack.Push(GetJumpId(method, (Instruction)instruction.Operand))) { yield return(action); } yield return(() => "Loop;"); }