InvokeOptions GetInvokeOptions(FuncEvalOptions funcEvalOptions) { var options = InvokeOptions.DisableBreakpoints; if (suspendOtherThreads) { options |= InvokeOptions.SingleThreaded; } if ((funcEvalOptions & FuncEvalOptions.ReturnOutThis) != 0) { options |= InvokeOptions.ReturnOutThis; } if ((funcEvalOptions & FuncEvalOptions.ReturnOutArgs) != 0) { options |= InvokeOptions.ReturnOutArgs; } if ((funcEvalOptions & FuncEvalOptions.Virtual) != 0) { options |= InvokeOptions.Virtual; } return(options); }
public abstract InvokeResult CallMethod(MethodMirror method, Value?obj, IList <Value> arguments, FuncEvalOptions options);
public abstract InvokeResult CreateInstance(MethodMirror method, IList <Value> arguments, FuncEvalOptions options);
InvokeResult CallCore(MethodMirror method, Value?obj, IList <Value> arguments, FuncEvalOptions options, bool isNewobj) { if (evalTimedOut) { throw new TimeoutException(); } IInvokeAsyncResult?asyncRes = null; bool done = false; try { funcEvalState.isEvaluatingCounter++; var currTime = DateTime.UtcNow; var timeLeft = endTime - currTime; if (timeLeft >= TimeSpan.Zero) { funcEvalState.methodInvokeCounter++; Debug2.Assert(!isNewobj || obj is null); bool isInvokeInstanceMethod = obj is not null && !isNewobj; AsyncCallback asyncCallback = asyncRes2 => { if (done) { return; } InvokeResult resTmp; try { if (isInvokeInstanceMethod) { resTmp = obj !.EndInvokeMethodWithResult(asyncRes2); } else { resTmp = method.DeclaringType.EndInvokeMethodWithResult(asyncRes2); } debugMessageDispatcher.CancelDispatchQueue(resTmp); } catch (Exception ex) { debugMessageDispatcher.CancelDispatchQueue(ExceptionDispatchInfo.Capture(ex)); } }; if (isInvokeInstanceMethod) { asyncRes = obj !.BeginInvokeMethod(thread, method, arguments, GetInvokeOptions(options), asyncCallback, null); } else { asyncRes = method.DeclaringType.BeginInvokeMethod(thread, method, arguments, GetInvokeOptions(options), asyncCallback, null); } var res = debugMessageDispatcher.DispatchQueue(timeLeft, out bool timedOut); if (timedOut) { evalTimedOut = true; try { asyncRes.Abort(); } catch (CommandException ce) when(ce.ErrorCode == ErrorCode.ERR_NO_INVOCATION) { } throw new TimeoutException(); } if (res is ExceptionDispatchInfo exInfo) { exInfo.Throw(); } Debug.Assert(res is InvokeResult); return(res as InvokeResult ?? throw new InvalidOperationException()); } else { evalTimedOut = true; throw new TimeoutException(); } } finally { done = true; funcEvalState.isEvaluatingCounter--; asyncRes?.Dispose(); } }
public override InvokeResult CallMethod(MethodMirror method, Value?obj, IList <Value> arguments, FuncEvalOptions options) => CallCore(method, obj, arguments, options, isNewobj: false);
public override InvokeResult CreateInstance(MethodMirror method, IList <Value> arguments, FuncEvalOptions options) => CallCore(method, null, arguments, options, isNewobj: true);