/// <summary>
 /// Initialize, after the constructor, the other properties
 /// </summary>
 internal override void Initialize()
 {
     Variables = new Collection <Variable>();
     ParentProgramInterpreter = (ProgramInterpreter)GetFirstNextParentInterpreter(InterpreterType.ProgramInterpreter);
     ParentClassInterpreter   = (ClassInterpreter)GetFirstNextParentInterpreter(InterpreterType.ClassInterpreter);
     _callStackService        = ParentProgramInterpreter.DebugInfo.CallStackService;
 }
示例#2
0
 /// <summary>
 /// Initialize a new instance of <see cref="DebugInfo"/>
 /// </summary>
 internal DebugInfo()
 {
     CallStackService = new CallStackService();
 }
示例#3
0
 /// <summary>
 /// Invoke a method in a new thread to avoid a stack overflow exception
 /// </summary>
 /// <param name="referenceClass">The class reference</param>
 /// <param name="argumentValues">The arguments values</param>
 /// <param name="callerMethod">The method from which we do the call</param>
 /// <param name="callStackService">The user call stack service</param>
 /// <returns></returns>
 private async Task CallMethodNewThread(ClassInterpreter referenceClass, Collection <object> argumentValues, MethodInterpreter callerMethod, CallStackService callStackService)
 {
     await ThreadPool.RunAsync(delegate { _result = referenceClass.InvokeMethod(ParentInterpreter, Expression, argumentValues, callerMethod, callStackService); });
 }
        /// <summary>
        /// Invoke the specified method
        /// </summary>
        /// <param name="callerInterpreter">The caller interpreter (usually a block)</param>
        /// <param name="invokeExpression">The invoke expression</param>
        /// <param name="argumentValues">The list of argument values</param>
        /// <param name="parentMethodInterpreter">The parent method interpret from where the invocation happened</param>
        /// <param name="callStackService">The user call stack service</param>
        /// <returns>Returns the result of the method</returns>
        internal object InvokeMethod(Interpret callerInterpreter, AlgorithmExpression invokeExpression, Collection <object> argumentValues, MethodInterpreter parentMethodInterpreter, CallStackService callStackService)
        {
            var methodName = invokeExpression._methodName.ToString();
            var method     = Methods.FirstOrDefault(m => m.MethodDeclaration._name.ToString() == methodName);

            if (method == null)
            {
                callerInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new MethodNotFoundException(methodName, $"The method '{methodName}' does not exists in the current class or is not accessible."), ClassDeclaration), callerInterpreter.GetDebugInfo()));
                return(null);
            }

            if (!method.MethodDeclaration._isAsync && invokeExpression._await)
            {
                callerInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new MethodNotAwaitableException(methodName), method.MethodDeclaration), callerInterpreter.GetDebugInfo()));
                return(null);
            }

            Guid stackTraceId;
            var  isAsync = method.MethodDeclaration._isAsync;

            if (parentMethodInterpreter == null)
            {
                stackTraceId = Guid.Empty;
            }
            else
            {
                stackTraceId = parentMethodInterpreter.StacktraceId;
                if (DebugMode)
                {
                    var callStack = callStackService.CallStacks.Single(cs => cs.TaceId == stackTraceId);
                    var call      = callStack.Stack.Pop();
                    if (call != null)
                    {
                        call.Variables = callerInterpreter.GetAllAccessibleVariable().DeepClone();
                        callStack.Stack.Push(call);
                    }
                }
            }

            method = new MethodInterpreter(method.MethodDeclaration, DebugMode);
            method.StateChanged           += ChangeState;
            method.OnGetParentInterpreter += new Func <ClassInterpreter>(() => this);
            method.OnDone += new Action <MethodInterpreter>((met) =>
            {
                met.Dispose();
                met.StateChanged -= ChangeState;
            });
            method.Initialize();
            method.Run(invokeExpression._await, argumentValues, stackTraceId);

            if (isAsync && !invokeExpression._await)
            {
                return(null);
            }
            return(method.ReturnedValue);
        }