public int YieldToCurrentContinuation() { RuntimeLabel target = Interpreter._labels[_continuations[_continuationIndex - 1]]; SetStackDepth(target.StackDepth); return(target.Index - InstructionIndex); }
internal InstructionArray(int maxStackDepth, int maxContinuationDepth, Instruction[] instructions, object[] objects, RuntimeLabel[] labels, List<KeyValuePair<int, object>> debugCookies) { MaxStackDepth = maxStackDepth; MaxContinuationDepth = maxContinuationDepth; Instructions = instructions; DebugCookies = debugCookies; Objects = objects; Labels = labels; }
private RuntimeLabel[] BuildRuntimeLabels() { if (_runtimeLabelCount == 0) { return(s_emptyRuntimeLabels); } var result = new RuntimeLabel[_runtimeLabelCount + 1]; foreach (BranchLabel label in _labels) { if (label.HasRuntimeLabel) { result[label.LabelIndex] = label.ToRuntimeLabel(); } } // "return and rethrow" label: result[result.Length - 1] = new RuntimeLabel(Interpreter.RethrowOnReturn, 0, 0); return(result); }
public int Goto(int labelIndex, object value, bool gotoExceptionHandler) { // TODO: we know this at compile time (except for compiled loop): RuntimeLabel target = Interpreter._labels[labelIndex]; Debug.Assert(!gotoExceptionHandler || (gotoExceptionHandler && _continuationIndex == target.ContinuationStackDepth), "When it's time to jump to the exception handler, all previous finally blocks should already be processed"); if (_continuationIndex == target.ContinuationStackDepth) { SetStackDepth(target.StackDepth); if (value != Interpreter.NoValue) { Data[StackIndex - 1] = value; } return(target.Index - InstructionIndex); } // if we are in the middle of executing jump we forget the previous target and replace it by a new one: _pendingContinuation = labelIndex; _pendingValue = value; return(YieldToCurrentContinuation()); }
/// <summary> /// Get called from the LeaveFinallyInstruction /// </summary> public int YieldToPendingContinuation() { Debug.Assert(_pendingContinuation >= 0); RuntimeLabel pendingTarget = Interpreter._labels[_pendingContinuation]; // the current continuation might have higher priority (continuationIndex is the depth of the current continuation): if (pendingTarget.ContinuationStackDepth < _continuationIndex) { RuntimeLabel currentTarget = Interpreter._labels[_continuations[_continuationIndex - 1]]; SetStackDepth(currentTarget.StackDepth); return(currentTarget.Index - InstructionIndex); } SetStackDepth(pendingTarget.StackDepth); if (_pendingValue != Interpreter.NoValue) { Data[StackIndex - 1] = _pendingValue; } // Set the _pendingContinuation and _pendingValue to the default values if we finally gets to the Goto target _pendingContinuation = -1; _pendingValue = Interpreter.NoValue; return(pendingTarget.Index - InstructionIndex); }
private RuntimeLabel[] BuildRuntimeLabels() { if (_runtimeLabelCount == 0) { return s_emptyRuntimeLabels; } var result = new RuntimeLabel[_runtimeLabelCount + 1]; foreach (BranchLabel label in _labels) { if (label.HasRuntimeLabel) { result[label.LabelIndex] = label.ToRuntimeLabel(); } } // "return and rethrow" label: result[result.Length - 1] = new RuntimeLabel(Interpreter.RethrowOnReturn, 0, 0); return result; }