/// <summary> /// Changes the execution context to the current environment's parent, and then jumps to the /// address on the ReturnAddress stack. In other words, this explicitly closes dynamic scope. /// </summary> /// <param name="vm"></param> /// <param name="i"></param> internal static void Return(VirtualMachine vm, Instruction i) { if (vm.CurrentEnvironment.Parent == null) { // We're at the top of the chain, so end execution. vm.RaiseError("Attempted to return without any parent environment."); return; } if (vm.Stack.Count() > 0) { Value val = vm.Stack.Shift(); vm.CurrentEnvironment.Parent.Stack.Push(val); } vm.PopCurrentEnvironment(); vm.ByteCode.ProgramCounter = vm.ReturnAddresses[vm.ReturnAddresses.Count() - 1]; // Pop off this return address vm.ReturnAddresses.RemoveAt(vm.ReturnAddresses.Count() - 1); // Pop off the CodeBlock saved for this function vm.FunctionCallList.RemoveAt(vm.FunctionCallList.Count() - 1); }