コード例 #1
0
ファイル: Executive.cs プロジェクト: TheChosen0ne/Dynamo
        public Executive(Core core, bool isFep = false)
        {
            isExplicitCall = false;
            Validity.Assert(core != null);
            this.core = core;
            enableLogging = core.Options.Verbose;

            exe = core.DSExecutable;
            istream = null;

            fepRun = isFep;
            //executingGraphNode = null;
            //nodeExecutedSameTimes = new List<AssociativeGraph.GraphNode>();
            Properties = new InterpreterProperties();
            allSSA = new List<AssociativeGraph.GraphNode>();


            rmem = core.Rmem;

            // Execute DS View VM Log
            //
            debugFlags = (int)DebugFlags.ENABLE_LOG;

            bounceType = CallingConvention.BounceType.kImplicit;

            // Execute DS Debug watch
            //debugFlags = (int)DebugFlags.ENABLE_LOG | (int)DebugFlags.SPAWN_DEBUGGER;
        }
コード例 #2
0
ファイル: Executive.cs プロジェクト: TheChosen0ne/Dynamo
        private void RETURN_Handler(Instruction instruction)
        {
            isGlobScope = true;

            runtimeVerify(rmem.ValidateStackFrame());

            int ptr = (int)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexThisPtr).opdata;
            int ci = (int)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexClass).opdata;
            int fi = (int)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexFunction).opdata;

            int blockId = (int)SX.opdata;

            StackValue svBlockDecl = rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexRegisterSX);
            Validity.Assert(AddressType.BlockIndex == svBlockDecl.optype);
            blockId = (int)svBlockDecl.opdata;

            ProcedureNode procNode = GetProcedureNode(blockId, ci, fi);

            if (core.Options.ExecuteSSA)
            {
                if (core.Options.GCTempVarsOnDebug && core.Options.IDEDebugMode)
                {
                    // GC anonymous variables in the return stmt
                    if (null != Properties.executingGraphNode && !Properties.executingGraphNode.IsSSANode())
                    {
                        GCAnonymousSymbols(Properties.executingGraphNode.symbolListWithinExpression);
                        Properties.executingGraphNode.symbolListWithinExpression.Clear();
                    }
                }
            }

            pc = (int)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexReturnAddress).opdata;
            executingBlock = (int)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexFunctionCallerBlock).opdata;

            if (core.ExecMode != ProtoCore.DSASM.InterpreterMode.kExpressionInterpreter)
            {
                ReturnSiteGC(blockId, ci, fi);
            }

            RestoreFromCall();
            core.RunningBlock = executingBlock;


            // If we're returning from a block to a function, the instruction stream needs to be restored.
            StackValue sv = rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexRegisterTX);
            Validity.Assert(AddressType.CallingConvention == sv.optype);
            CallingConvention.CallType callType = (CallingConvention.CallType)sv.opdata;
            bool explicitCall = CallingConvention.CallType.kExplicit == callType;
            isExplicitCall = explicitCall;


            List<bool> execStateRestore = new List<bool>();
            if (!core.Options.IDEDebugMode || core.ExecMode == InterpreterMode.kExpressionInterpreter)
            {
                // Get stack frame size
                int localCount = 0;
                int paramCount = 0;
                GetLocalAndParamCount(blockId, ci, fi, out localCount, out paramCount);

                // Retrieve the execution execution states 
                int execstates = (int)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexExecutionStates).opdata;
                if (execstates > 0)
                {
                    int offset = ProtoCore.DSASM.StackFrame.kStackFrameSize + localCount + paramCount;
                    for (int n = 0; n < execstates; ++n)
                    {
                        int relativeIndex = -offset - n - 1; 
                        StackValue svState = rmem.GetAtRelative(relativeIndex);
                        Validity.Assert(svState.optype == AddressType.Boolean);
                        execStateRestore.Add(svState.opdata == 0 ? false : true);
                    }
                }

                // Pop the stackframe
                rmem.FramePointer = (int)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexFramePointer).opdata;

                // Get the size of the stackframe and all variable size contents (local, args and exec states)
                int stackFrameSize = ProtoCore.DSASM.StackFrame.kStackFrameSize + localCount + paramCount + execstates;
                rmem.PopFrame(stackFrameSize);

                if (core.ExecMode != InterpreterMode.kExpressionInterpreter)
                {
                    // Restoring the registers require the current frame pointer of the stack frame 
                    RestoreRegistersFromStackFrame();

                    bounceType = (ProtoCore.DSASM.CallingConvention.BounceType)TX.opdata;
                }
            }


            terminate = !explicitCall;

            // Comment Jun: Dispose calls are always implicit and need to terminate
            // TODO Jun: This instruction should not know about dispose
            bool isDispose = CoreUtils.IsDisposeMethod(procNode.name);
            if (isDispose)
            {
                terminate = true;
            }

            // Let the return graphNode always be active 
            if (null != Properties.executingGraphNode)
            {
                Properties.executingGraphNode.isDirty = true;
            }

            Properties = PopInterpreterProps();

            if (explicitCall)
            {
                bool wasDebugPropsPopped = false;
                if (!isDispose)
                {
                    wasDebugPropsPopped = DebugReturn(procNode, pc);

                }

                // This condition should only be reached in the following cases:
                // 1. Debug StepOver or External Function call in non-replicating mode
                // 2. Normal execution in Serial (explicit call), non-replicating mode
                if (!wasDebugPropsPopped)
                {
                    RX = CallSite.PerformReturnTypeCoerce(procNode, core, RX);

                    // Comment Jun: For explicit calls, we need to manually GC decrement the arguments passed into the function 
                    // These arguments were GC incremented on callr
                    for (int i = 0; i < Properties.functionCallArguments.Count; ++i)
                    {
                        GCUtils.GCRelease(Properties.functionCallArguments[i], core);
                    }

                    StackValue svRet = RX;
                    GCDotMethods(procNode.name, ref svRet, Properties.functionCallDotCallDimensions, Properties.functionCallArguments);
                    DecRefCounter(svRet);

                    RX = svRet;

                }
            }
            
            // Restore the execution states
            if (execStateRestore.Count > 0)
            {
                // Now that the stack frame is popped off, we can retrieve the returned scope
                // Get graphnodes at the current scope after the return
                int currentScopeClass = (int)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexClass).opdata;
                int currentScopeFunction = (int)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexFunction).opdata;

                bool isReturningFromRecursiveCall = procNode.procId == currentScopeFunction;
                if (isReturningFromRecursiveCall)
                {
                    // Since there are execution states retrieved from the stack frame,
                    // this means that we must be returning to a function and not the global scope
                    Validity.Assert(currentScopeFunction != ProtoCore.DSASM.Constants.kGlobalScope);

                    // Get the instruction stream where the current function resides in
                    StackValue svCurrentFunctionBlockDecl = rmem.GetAtRelative(rmem.GetStackIndex(ProtoCore.DSASM.StackFrame.kFrameIndexFunctionBlock));
                    Validity.Assert(svCurrentFunctionBlockDecl.optype == AddressType.BlockIndex);
                    AssociativeGraph.DependencyGraph depgraph = exe.instrStreamList[(int)svCurrentFunctionBlockDecl.opdata].dependencyGraph;

                    List<AssociativeGraph.GraphNode> graphNodesInScope = depgraph.GetGraphNodesAtScope(currentScopeClass, currentScopeFunction);
                    Validity.Assert(execStateRestore.Count == graphNodesInScope.Count);
                    for (int n = 0; n < execStateRestore.Count; ++n)
                    {
                        graphNodesInScope[n].isDirty = execStateRestore[n];
                    }
                }
            }

            return;
        }
コード例 #3
0
ファイル: Executive.cs プロジェクト: TheChosen0ne/Dynamo
        private void THROW_Handler(Instruction instruction)
        {
#if ENABLE_EXCEPTION_HANDLING
            runtimeVerify(ProtoCore.DSASM.AddressType.BlockIndex == instruction.op1.optype);
            int blockId = (int)instruction.op1.opdata;

            runtimeVerify(ProtoCore.DSASM.AddressType.ClassIndex == instruction.op2.optype);
            int classScope = (int)instruction.op2.opdata;

            runtimeVerify(ProtoCore.DSASM.AddressType.FunctionIndex == instruction.op3.optype);
            int functionScope = (int)instruction.op3.opdata;

            StackValue exceptionValue = LX;
            ProtoCore.Exceptions.ExceptionContext context = new Exceptions.ExceptionContext();
            context.pc = pc;
            context.codeBlockId = blockId;
            context.functionScope = functionScope;
            context.classScope = classScope;
            switch (exceptionValue.optype)
            {
                case AddressType.Int:
                    context.typeUID = (int)ProtoCore.PrimitiveType.kTypeInt;
                    break;
                case AddressType.Double:
                    context.typeUID = (int)ProtoCore.PrimitiveType.kTypeDouble;
                    break;
                case AddressType.Boolean:
                    context.typeUID = (int)ProtoCore.PrimitiveType.kTypeBool;
                    break;
                case AddressType.Pointer:
                    context.typeUID = (int)exceptionValue.metaData.type;
                    break;
                default:
                    context.typeUID = (int)ProtoCore.PrimitiveType.kTypeVar;
                    break;
            }
            // Walk through exception chain, a.k.a. 1st hand exception
            // handling
            core.ExceptionHandlingManager.HandleFirstHandException(context);

            // The exception can be handled in current scope, so simply jmp to 
            // the corresponding catch block
            int newpc = ProtoCore.DSASM.Constants.kInvalidIndex;
            if (core.ExceptionHandlingManager.CanHandleIt(ref newpc))
            {
                pc = newpc;
                core.ExceptionHandlingManager.SetHandled();
            }
            else
            {
                RX = LX;
            }

            if (core.ExceptionHandlingManager.IsStackUnwinding)
            {
                while (core.stackActiveExceptionRegistration.Count > 1)
                {
                    StackValue svType = rmem.GetAtRelative(StackFrame.kFrameIndexStackFrameType);
                    StackFrameType type = (StackFrameType)svType.opdata;
                    if (StackFrameType.kTypeLanguage == type)
                    {
                        RestoreFromBounce();
                        rmem.FramePointer = (int)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexFramePointer).opdata;
                        rmem.PopFrame(ProtoCore.DSASM.StackFrame.kStackFrameSize);


                        // Restoring the registers require the current frame pointer of the stack frame 
                        RestoreRegistersFromStackFrame();

                        bounceType = (ProtoCore.DSASM.CallingConvention.BounceType)TX.opdata;

                        core.ExceptionHandlingManager.CurrentActiveRegistration = core.stackActiveExceptionRegistration.Pop();

            #region __MERGE_WITH_STACKUNWIND

                        // The excecution of last langage block is interrupted
                        // abnormally because of stack unwinding, so we need to 
                        // run GC to reclaim those allocated memory.
                        GCCodeBlock(core.RunningBlock);

                        newpc = ProtoCore.DSASM.Constants.kInvalidIndex;
                        if (core.ExceptionHandlingManager.CanHandleIt(ref newpc))
                        {
                            LX = RX;
                            pc = newpc;
                            core.ExceptionHandlingManager.SetHandled();
                            break;
                        }
                        // else cannot handle in this scope, so in the next
                        // loop of Execute(), current executive will be ;
                        // ended and returns to the last scope, continues
                        // stack unwinding

                        int origRunningBlock = executingBlock;
                        core.RunningBlock = origRunningBlock;
#endregion
                    }
                    else
                    {
                        RestoreFromCall();

                        int ci = (int)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexClass).opdata;
                        int fi = (int)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexFunction).opdata;

                        int localCount = 0;
                        int paramCount = 0;
                        GetLocalAndParamCount(executingBlock, ci, fi, out localCount, out paramCount);

                        rmem.FramePointer = (int)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexFramePointer).opdata;
                        rmem.PopFrame(ProtoCore.DSASM.StackFrame.kStackFrameSize + localCount + paramCount);
                    }
                }
            }
            return;
#else
            throw new NotImplementedException();
#endif
        }
コード例 #4
0
ファイル: Executive.cs プロジェクト: TheChosen0ne/Dynamo
        private void RETC_Handler(Instruction instruction)
        {
            runtimeVerify(rmem.ValidateStackFrame());

            RX = rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexThisPtr);

            int ci = (int)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexClass).opdata;
            int fi = (int)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexFunction).opdata;

            pc = (int)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexReturnAddress).opdata;

            // block id is used in ReturnSiteGC to get the procedure node if it is not a member function 
            // not meaningful here, because we are inside a constructor
            int blockId = (int)SX.opdata;

            if (core.ExecMode != ProtoCore.DSASM.InterpreterMode.kExpressionInterpreter)
            {
                ReturnSiteGC(blockId, ci, fi);
            }


            RestoreFromCall();
            core.RunningBlock = executingBlock;

            // If we're returning from a block to a function, the instruction stream needs to be restored.
            StackValue sv = rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexRegisterTX);
            Validity.Assert(AddressType.CallingConvention == sv.optype);
            CallingConvention.CallType callType = (CallingConvention.CallType)sv.opdata;
            bool explicitCall = CallingConvention.CallType.kExplicit == callType || CallingConvention.CallType.kExplicitBase == callType;
            isExplicitCall = explicitCall;

            if (!core.Options.IDEDebugMode || core.ExecMode == InterpreterMode.kExpressionInterpreter)
            {
                int localCount = 0;
                int paramCount = 0;
                GetLocalAndParamCount(blockId, ci, fi, out localCount, out paramCount);

                rmem.FramePointer = (int)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexFramePointer).opdata;
                rmem.PopFrame(ProtoCore.DSASM.StackFrame.kStackFrameSize + localCount + paramCount);

                if (core.ExecMode != InterpreterMode.kExpressionInterpreter)
                {
                    // Restoring the registers require the current frame pointer of the stack frame 
                    RestoreRegistersFromStackFrame();

                    bounceType = (ProtoCore.DSASM.CallingConvention.BounceType)TX.opdata;
                }
            }


            terminate = !explicitCall;

            Properties = PopInterpreterProps();


            ProcedureNode procNode = GetProcedureNode(blockId, ci, fi);
            if (explicitCall)
            {
                //RX = CallSite.PerformReturnTypeCoerce(procNode, core, RX);

                bool wasDebugPropsPopped = DebugReturn(procNode, pc);



                // Comment Jun: For explicit calls, we need to manually GC decrement the arguments.
                //  These arguments were GC incremented on callr
                if (!wasDebugPropsPopped)
                //if (!core.Options.IDEDebugMode || core.ExecMode == ExecutionMode.kExpressionInterpreter)
                {
                    for (int i = 0; i < Properties.functionCallArguments.Count; ++i)
                    {
                        GCUtils.GCRelease(Properties.functionCallArguments[i], core);
                    }
                }

                if (CallingConvention.CallType.kExplicitBase != callType)
                {
                    //if (!core.Options.IDEDebugMode || core.ExecMode == ExecutionMode.kExpressionInterpreter)
                    if (!wasDebugPropsPopped)
                    {
                        DecRefCounter(RX);
                    }
                }
            }
            return;
        }
コード例 #5
0
ファイル: Executive.cs プロジェクト: TheChosen0ne/Dynamo
        private void RETB_Handler(Instruction instruction)
        {
            if (core.ExecMode != InterpreterMode.kExpressionInterpreter)
            {
                core.Rmem.PopConstructBlockId();
            }

            if (!core.Options.IsDeltaExecution || (core.Options.IsDeltaExecution && 0 != core.RunningBlock))
            {
                GCCodeBlock(core.RunningBlock);
            }

            if (ProtoCore.DSASM.CallingConvention.BounceType.kExplicit == bounceType)
            {
                RestoreFromBounce();
                core.RunningBlock = executingBlock;
            }

            if (ProtoCore.DSASM.CallingConvention.BounceType.kImplicit == bounceType)
            {
                pc = (int)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexReturnAddress).opdata;
                terminate = true;
            }


            ProtoCore.DSASM.StackFrameType type = StackFrameType.kTypeLanguage;

            // Comment Jun: Just want to see if this is the global rerb, in which case we dont retrieve anything
            //if (executingBlock > 0)
            {
                StackValue svCallerType = rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexCallerStackFrameType);
                type = (ProtoCore.DSASM.StackFrameType)svCallerType.opdata;
            }

            // Pop the frame as we are adding stackframes for language blocks as well - pratapa
            // Do not do this for the final Retb 
            //if (core.RunningBlock != 0)
            if (!core.Options.IDEDebugMode || core.ExecMode == InterpreterMode.kExpressionInterpreter)
            {
                rmem.FramePointer = (int)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexFramePointer).opdata;
                rmem.PopFrame(ProtoCore.DSASM.StackFrame.kStackFrameSize);

                if (bounceType == CallingConvention.BounceType.kExplicit)
                {
                    // Restoring the registers require the current frame pointer of the stack frame 
                    RestoreRegistersFromStackFrame();

                    bounceType = (ProtoCore.DSASM.CallingConvention.BounceType)TX.opdata;

#if ENABLE_EXCEPTION_HANDLING
                    core.ExceptionHandlingManager.CurrentActiveRegistration = core.stackActiveExceptionRegistration.Pop();
                    if (core.ExceptionHandlingManager.IsStackUnwinding)
                    {
                    #region __MERGE_WITH_STACKUNWIND
                        // The excecution of last langage block is interrupted
                        // abnormally because of stack unwinding, so we need to 
                        // run GC to reclaim those allocated memory.
                        GCCodeBlock(core.RunningBlock);

                        int newpc = ProtoCore.DSASM.Constants.kInvalidIndex;
                        if (core.ExceptionHandlingManager.CanHandleIt(ref newpc))
                        {
                            LX = RX;
                            pc = newpc;
                            core.ExceptionHandlingManager.SetHandled();
                        }
                        // else cannot handle in this scope, so in the next
                        // loop of Execute(), current executive will be ;
                        // ended and returns to the last scope, continues
                        // stack unwinding

                        int origRunningBlock = executingBlock;
                        core.RunningBlock = origRunningBlock;
#endregion
                    }
                    else
                    {
                        DecRefCounter(RX);
                    }
#else
                    DecRefCounter(RX);
#endif
                }
            }
            else
            {
                DecRefCounter(RX);
            }

            if (type == StackFrameType.kTypeFunction)
            {
                // Comment Jun: 
                // Consider moving this to a restore to function method

                // If this language block was called explicitly, only then do we need to restore the instruction stream
                if (bounceType == CallingConvention.BounceType.kExplicit)
                {
                    // If we're returning from a block to a function, the instruction stream needs to be restored.
                    StackValue sv = rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexRegisterTX);
                    Validity.Assert(AddressType.CallingConvention == sv.optype);
                    CallingConvention.CallType callType = (CallingConvention.CallType)sv.opdata;
                    if (CallingConvention.CallType.kExplicit == callType)
                    {
                        int callerblock = (int)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexFunctionBlock).opdata;
                        istream = exe.instrStreamList[callerblock];
                    }
                }
            }
            Properties = PopInterpreterProps();
            return;
        }
コード例 #6
0
ファイル: Executive.cs プロジェクト: TheChosen0ne/Dynamo
        private void BOUNCE_Handler(Instruction instruction)
        {
            // We disallow language blocks inside watch window currently - pratapa
            Validity.Assert(DSASM.InterpreterMode.kExpressionInterpreter != Core.ExecMode);

            runtimeVerify(ProtoCore.DSASM.AddressType.BlockIndex == instruction.op1.optype);
            int blockId = (int)instruction.op1.opdata;

            // Comment Jun: On a bounce, update the debug property to reflect this.
            // Before the explicit bounce, this was done in Execute() which is now no longer the case
            // as Execute is only called once during first bounce and succeeding bounce reuse the same interpreter
            core.DebugProps.CurrentBlockId = blockId;

            runtimeVerify(ProtoCore.DSASM.AddressType.Int == instruction.op2.optype);
            int entrypoint = (int)instruction.op2.opdata;

            ProtoCore.Runtime.Context context = new ProtoCore.Runtime.Context();
            // TODO(Jun/Jiong): Considering store the orig block id to stack frame
            int origRunningBlock = core.RunningBlock;
            core.RunningBlock = blockId;

            core.Rmem = rmem;
            if (core.ExecMode != InterpreterMode.kExpressionInterpreter)
            {
                core.Rmem.PushConstructBlockId(blockId);
            }

#if ENABLE_EXCEPTION_HANDLING
                core.stackActiveExceptionRegistration.Push(core.ExceptionHandlingManager.CurrentActiveRegistration);
#endif

            int ci = ProtoCore.DSASM.Constants.kInvalidIndex;
            int fi = ProtoCore.DSASM.Constants.kInvalidIndex;
            if (rmem.Stack.Count >= ProtoCore.DSASM.StackFrame.kStackFrameSize)
            {
                StackValue sci = rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexClass);
                StackValue sfi = rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexFunction);
                if (sci.optype == AddressType.Int && sfi.optype == AddressType.Int)
                {
                    ci = (int)sci.opdata;
                    fi = (int)sfi.opdata;
                }
            }

#if ENABLE_EXCEPTION_HANDLING
            core.ExceptionHandlingManager.SwitchContextTo(blockId, fi, ci, pc);
#endif

            StackValue svThisPtr = ProtoCore.DSASM.StackValue.BuildPointer(ProtoCore.DSASM.Constants.kInvalidPointer);
            int returnAddr = pc + 1;

            Validity.Assert(ProtoCore.DSASM.Constants.kInvalidIndex != executingBlock);
            //int blockDecl = executingBlock;
            int blockDecl = (int)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexFunctionBlock).opdata;
            int blockCaller = executingBlock;

            StackFrameType type = StackFrameType.kTypeLanguage;
            int depth = (int)rmem.GetAtRelative(StackFrame.kFrameIndexStackFrameDepth).opdata;
            int framePointer = core.Rmem.FramePointer;

            // Comment Jun: Use the register TX to store explicit/implicit bounce state
            bounceType = ProtoCore.DSASM.CallingConvention.BounceType.kExplicit;
            TX = StackValue.BuildCallingConversion((int)ProtoCore.DSASM.CallingConvention.BounceType.kExplicit);

            List<StackValue> registers = new List<StackValue>();
            SaveRegisters(registers);

            StackFrameType callerType = (fepRun) ? StackFrameType.kTypeFunction : StackFrameType.kTypeLanguage;


            if (core.Options.IDEDebugMode && core.ExecMode != InterpreterMode.kExpressionInterpreter)
            {
                // Comment Jun: Temporarily disable debug mode on bounce
                //Validity.Assert(false); 

                //Validity.Assert(core.Breakpoints != null);
                //blockDecl = blockCaller = core.DebugProps.CurrentBlockId;

                core.DebugProps.SetUpBounce(this, blockCaller, returnAddr);

                StackFrame stackFrame = new StackFrame(svThisPtr, ci, fi, returnAddr, blockDecl, blockCaller, callerType, type, depth + 1, framePointer, registers, null);
                ProtoCore.Language bounceLangauge = exe.instrStreamList[blockId].language;
                BounceExplicit(blockId, 0, bounceLangauge, stackFrame, core.Breakpoints);
            }
            else //if (core.Breakpoints == null)
            {
                StackFrame stackFrame = new StackFrame(svThisPtr, ci, fi, returnAddr, blockDecl, blockCaller, callerType, type, depth + 1, framePointer, registers, null);

                ProtoCore.Language bounceLangauge = exe.instrStreamList[blockId].language;
                BounceExplicit(blockId, 0, bounceLangauge, stackFrame);
            }

            return;
        }
コード例 #7
0
ファイル: Executive.cs プロジェクト: TheChosen0ne/Dynamo
        // This will be called only at the time of creation of the main interpreter in the explicit case OR
        // for every implicit function call (like in replication) OR 
        // for every implicit bounce (like in dynamic lang block in inline condition) OR
        // for a Debug Resume from a breakpoint
        public void Execute(int exeblock, int entry, List<Instruction> breakpoints, Language language = Language.kInvalid)
        {
            // TODO Jun: Call RestoreFromBounce here?
            StackValue svType = rmem.GetAtRelative(StackFrame.kFrameIndexStackFrameType);
            StackFrameType type = (StackFrameType)svType.opdata;
            if (StackFrameType.kTypeLanguage == type || StackFrameType.kTypeFunction == type)
            {
                ResumeRegistersFromStack();
                bounceType = (ProtoCore.DSASM.CallingConvention.BounceType)TX.opdata;
            }

            SetupExecutive(exeblock, entry, language, breakpoints);


            bool debugRun = (0 != (debugFlags & (int)DebugFlags.SPAWN_DEBUGGER));
            if (!fepRun || fepRun && debugRun)
            {
                logVMMessage("Start JIL Execution - " + CoreUtils.GetLanguageString(language));
            }

            core.DebugProps.isResume = false;

            while (!terminate)
            {
                // This will be true only for inline conditions in Associative blocks 
                if (core.DebugProps.InlineConditionOptions.isInlineConditional == true &&
                    core.DebugProps.InlineConditionOptions.instructionStream == exeblock && core.DebugProps.InlineConditionOptions.endPc == pc)
                {
                    // turn off inline conditional flag
                    {
                        core.DebugProps.InlineConditionOptions.isInlineConditional = false;
                        core.DebugProps.InlineConditionOptions.startPc = Constants.kInvalidIndex;
                        core.DebugProps.InlineConditionOptions.endPc = Constants.kInvalidIndex;
                        core.DebugProps.InlineConditionOptions.instructionStream = 0;
                    }

                    // if no longer inside a replicated/external function call, restore breakpoints
                    if (!core.DebugProps.DebugStackFrameContains(DebugProperties.StackFrameFlagOptions.IsReplicating) &&
                        !core.DebugProps.DebugStackFrameContains(DebugProperties.StackFrameFlagOptions.IsExternalFunction))
                    {
                        if (core.DebugProps.InlineConditionOptions.ActiveBreakPoints.Count > 0)
                        {
                            core.Breakpoints.Clear();
                            core.Breakpoints.AddRange(core.DebugProps.InlineConditionOptions.ActiveBreakPoints);
                            core.DebugProps.InlineConditionOptions.ActiveBreakPoints.Clear();
                        }
                    }
                }

                List<Instruction> instructions = istream.instrList;

                // Execute the instruction!
                Instruction executeInstruction = instructions[pc];
                Exec(instructions[pc]);

                bool restoreInstructionStream =
                    executeInstruction.opCode == OpCode.CALLR ||
                    executeInstruction.opCode == OpCode.RETURN
                    || executeInstruction.opCode == OpCode.RETC;
                if (restoreInstructionStream && isExplicitCall)
                {
                    // The instruction stream list is updated on callr
                    instructions = istream.instrList;
                    exeblock = executingBlock;
                    core.DebugProps.CurrentBlockId = exeblock;
                }

                // Disabling support for stepping into replicating function calls temporarily - pratapa
                // Check if the current instruction is a return from a function call or constructor

                DebugFrame tempFrame = null;
                if (!isExplicitCall && (instructions[core.DebugProps.DebugEntryPC].opCode == OpCode.RETURN || instructions[core.DebugProps.DebugEntryPC].opCode == OpCode.RETC))
                {
                    int ci, fi;
                    bool isReplicating;
                    DebugFrame debugFrame = null;
                    DebugReturnFromFunctionCall(pc, ref exeblock, out ci, out fi, out isReplicating, out debugFrame);

                    instructions = istream.instrList;
                    executingBlock = exeblock;
                    core.DebugProps.CurrentBlockId = exeblock;
                }
                else if (executeInstruction.opCode == OpCode.RETB)
                {
                    tempFrame = core.DebugProps.DebugStackFrame.Peek();

                    RestoreDebugPropsOnReturnFromLangBlock(ref exeblock, ref instructions);

                    // TODO: If return from previous lang block calls "_Dispose", and we have stepped into it,
                    // we need to restore the calling stackframe - pratapa
                    if (tempFrame.IsDisposeCall)
                    {
                        // TODO: If we have stepped inside _Dispose and are resuming from it - pratapa
                        if (!terminate)
                        {
                            // 1. Call everything after GC in OpCode.RETB
                            // 2. Call RestoreDebugPropsOnReturnFromLangBlock() for caller lang block
                            // 3. Return address from _Dispose is one more than the correct value and therefore needs to be fixed
                        }
                        // TODO: This works assuming debugging inside _Dispose functions is disabled
                        // ie stepping over _Dispose - pratapa
                        core.DebugProps.DebugEntryPC = core.DebugProps.ReturnPCFromDispose;
                        break;
                    }
                    else
                    {
                        core.DebugProps.DebugEntryPC = pc;
                    }
                    // Comment Jun: On explictit bounce, only on retb we update the executing block
                    // as the block scope has already change by returning to the caller block
                    executingBlock = exeblock;
                    core.RunningBlock = exeblock;
                }
                else
                {
                    core.DebugProps.DebugEntryPC = pc;
                }

                DebugFrame frame = core.DebugProps.DebugStackFrame.Peek();
                if (frame.IsInlineConditional)
                {
                    // The reference count of RX has been decreased in RETB
                    // instruction for inline conditional statement. 
                    GCRetain(RX);
                    RestoreDebugPropsOnReturnFromBuiltIns(ref exeblock, ref instructions);
                    core.DebugProps.DebugEntryPC = pc;
                }

                core.Rmem = rmem;

                bool terminateExec = HandleBreakpoint(breakpoints, instructions, pc, exeblock);
                if (terminateExec)
                {
                    break;
                }
            }

            if (!fepRun || fepRun && debugRun)
            {
                logVMMessage("End JIL Execution - " + CoreUtils.GetLanguageString(language));
            }
        }
コード例 #8
0
ファイル: Executive.cs プロジェクト: TheChosen0ne/Dynamo
        void RestoreDebugPropsOnReturnFromLangBlock(ref int exeblock, ref List<Instruction> instructions)
        {
            // On the new stack frame, this dependency has already been executed at retb in RestoreFromBounce
            //XLangUpdateDependencyGraph(exeblock);

            Validity.Assert(core.DebugProps.DebugStackFrame.Count > 0);
            {
                // Restore fepRun
                DebugFrame debugFrame = core.DebugProps.DebugStackFrame.Pop();

                bool isResume = debugFrame.IsResume;

                if (isResume)
                {
                    if (core.DebugProps.DebugStackFrame.Count > 1)
                    {
                        DebugFrame frame = core.DebugProps.DebugStackFrame.Peek();
                        frame.IsResume = true;
                    }

                    terminate = false;

                    // Restore registers except RX on popping of language stackframe
                    ResumeRegistersFromStackExceptRX();
                }

                // Restore return address and lang block    
                pc = (int)rmem.GetAtRelative(StackFrame.kFrameIndexReturnAddress).opdata;
                exeblock = (int)rmem.GetAtRelative(StackFrame.kFrameIndexFunctionCallerBlock).opdata;

                istream = exe.instrStreamList[exeblock];
                instructions = istream.instrList;
                executingLanguage = istream.language;

                Properties.executingGraphNode = debugFrame.ExecutingGraphNode;

                // Pop language stackframe as this is not allowed in Retb in debug mode
                rmem.FramePointer = (int)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexFramePointer).opdata;
                rmem.PopFrame(ProtoCore.DSASM.StackFrame.kStackFrameSize);

                ResumeRegistersFromStackExceptRX();
                bounceType = (ProtoCore.DSASM.CallingConvention.BounceType)TX.opdata;
            }

            if (pc < 0)
            {
                throw new ProtoCore.Exceptions.EndOfScript();
            }
        }
コード例 #9
0
ファイル: Executive.cs プロジェクト: TheChosen0ne/Dynamo
        bool RestoreDebugPropsOnReturnFromFunctionCall(ref int exeblock, ref List<Instruction> instructions, out int ci, out int fi, out bool isReplicating,
            out DebugFrame debugFrame)
        {
            //
            // TODO: Aparajit, Jun - Determine an alternative to the waspopped flag
            //
            bool waspopped = false;
            Validity.Assert(core.DebugProps.DebugStackFrame.Count > 0);

            debugFrame = core.DebugProps.DebugStackFrame.Peek();

            isReplicating = debugFrame.IsReplicating;

#if !__DEBUG_REPLICATE
            if (!isReplicating)
#endif
            {
                bool isResume = debugFrame.IsResume;

                // Comment Jun: Since we dont step into _Dispose() calls, then its debugframe should not be popped off here.
                bool isDispose = debugFrame.IsDisposeCall;

                // RestoreCallrForNoBreak and PerformReturnTypeCoerce are NOT called if this is true
                // or for base class ctor calls and therefore need to be taken care of here
                if ((isResume || debugFrame.IsBaseCall) && !isDispose)
                {
                    debugFrame = core.DebugProps.DebugStackFrame.Pop();
                    waspopped = true;

                    if (isResume)
                    {
                        if (core.DebugProps.DebugStackFrame.Count > 1)
                        {
                            DebugFrame frame = core.DebugProps.DebugStackFrame.Peek();
                            frame.IsResume = true;
                        }
                    }

#if __DEBUG_REPLICATE
                    // Return type coercion and function call GC for replicating case takes place separately 
                    // in SerialReplication() when ContinuationStruct.Done == true - pratapa
                    if (!isReplicating)
#endif
                    {
                        DebugPerformCoercionAndGC(debugFrame);
                    }

                    // Restore registers except RX on popping of function stackframe
                    ResumeRegistersFromStackExceptRX();

                    terminate = false;
                }

                Properties.executingGraphNode = debugFrame.ExecutingGraphNode;

                if (core.DebugProps.RunMode.Equals(Runmode.StepOut) && pc == core.DebugProps.StepOutReturnPC)
                {
                    core.Breakpoints.Clear();
                    core.Breakpoints.AddRange(core.DebugProps.AllbreakPoints);
                }
            }

            // Restore return address and lang block
            pc = (int)rmem.GetAtRelative(StackFrame.kFrameIndexReturnAddress).opdata;
            exeblock = (int)rmem.GetAtRelative(StackFrame.kFrameIndexFunctionCallerBlock).opdata;

            istream = exe.instrStreamList[exeblock];
            instructions = istream.instrList;
            executingLanguage = istream.language;

            ci = (int)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexClass).opdata;
            fi = (int)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexFunction).opdata;

            int localCount = 0;
            int paramCount = 0;

            int blockId = (int)rmem.GetAtRelative(StackFrame.kFrameIndexFunctionBlock).opdata;

            GetLocalAndParamCount(blockId, ci, fi, out localCount, out paramCount);

            // Pop function stackframe as this is not allowed in Ret/Retc in debug mode
            rmem.FramePointer = (int)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexFramePointer).opdata;
            rmem.PopFrame(ProtoCore.DSASM.StackFrame.kStackFrameSize + localCount + paramCount);


            ResumeRegistersFromStackExceptRX();

            //StackValue svFrameType = rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexCallerStackFrameType);
            StackValue svFrameType = rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexStackFrameType);
            StackFrameType frametype = (StackFrameType)svFrameType.opdata;
            if (frametype == StackFrameType.kTypeLanguage)
            {
                bounceType = (ProtoCore.DSASM.CallingConvention.BounceType)TX.opdata;
            }
            return waspopped;
        }
コード例 #10
0
ファイル: Executive.cs プロジェクト: santom/designscript
        private void RETURN_Handler(Instruction instruction)
        {
            isGlobScope = true;

            runtimeVerify(rmem.ValidateStackFrame());

            int ptr = (int)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexThisPtr).opdata;
            int ci = (int)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexClass).opdata;
            int fi = (int)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexFunction).opdata;

            int blockId = (int)SX.opdata;

            StackValue svBlockDecl = rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexRegisterSX);
            Validity.Assert(AddressType.BlockIndex == svBlockDecl.optype);
            blockId = (int)svBlockDecl.opdata;

            ProcedureNode procNode = GetProcedureNode(blockId, ci, fi);

            pc = (int)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexReturnAddress).opdata;
            executingBlock = (int)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexFunctionCallerBlock).opdata;

            if (core.ExecMode != ProtoCore.DSASM.InterpreterMode.kExpressionInterpreter)
            {
                ReturnSiteGC(blockId, ci, fi);
            }

            RestoreFromCall();
            core.RunningBlock = executingBlock;

            // If we're returning from a block to a function, the instruction stream needs to be restored.
            StackValue sv = rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexRegisterTX);
            Validity.Assert(AddressType.CallingConvention == sv.optype);
            CallingConvention.CallType callType = (CallingConvention.CallType)sv.opdata;
            bool explicitCall = CallingConvention.CallType.kExplicit == callType;
            isExplicitCall = explicitCall;


            if (!core.Options.IDEDebugMode || core.ExecMode == InterpreterMode.kExpressionInterpreter)
            {
                int localCount = 0;
                int paramCount = 0;
                GetLocalAndParamCount(blockId, ci, fi, out localCount, out paramCount);

                rmem.FramePointer = (int)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexFramePointer).opdata;
                rmem.PopFrame(ProtoCore.DSASM.StackFrame.kStackFrameSize + localCount + paramCount);

                if (core.ExecMode != InterpreterMode.kExpressionInterpreter)
                {
                    // Restoring the registers require the current frame pointer of the stack frame 
                    RestoreRegistersFromStackFrame();

                    bounceType = (ProtoCore.DSASM.CallingConvention.BounceType)TX.opdata;
                }
            }


            terminate = !explicitCall;

            // Comment Jun: Dispose calls are always implicit and need to terminate
            // TODO Jun: This instruction should not know about dispose
            bool isDispose = procNode.name.Equals(ProtoCore.DSDefinitions.Kw.kw_Dispose);
            if (isDispose)
            {
                terminate = true;
            }

            // Let the return graphNode always be active 
            if (null != Properties.executingGraphNode)
            {
                Properties.executingGraphNode.isDirty = true;
            }

            Properties = PopInterpreterProps();

            if (explicitCall)
            {
                bool wasDebugPropsPopped = false;
                if (!isDispose)
                {
                    wasDebugPropsPopped = DebugReturn(procNode, pc);

                }

                // This condition should only be reached in the following cases:
                // 1. Debug StepOver or External Function call in non-replicating mode
                // 2. Normal execution in Serial (explicit call), non-replicating mode
                if (!wasDebugPropsPopped)
                {
                    RX = CallSite.PerformReturnTypeCoerce(procNode, core, RX);

                    // Comment Jun: For explicit calls, we need to manually GC decrement the arguments passed into the function 
                    // These arguments were GC incremented on callr
                    for (int i = 0; i < Properties.functionCallArguments.Count; ++i)
                    {
                        GCUtils.GCRelease(Properties.functionCallArguments[i], core);
                    }

                    StackValue svRet = RX;
                    GCDotMethods(procNode.name, ref svRet, Properties.functionCallDotCallDimensions, Properties.functionCallArguments);
                    DecRefCounter(svRet);

                    RX = svRet;

                }
            }

            return;
        }