Пример #1
0
        private void RETURN_Handler()
        {
            runtimeVerify(rmem.ValidateStackFrame());

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

            int blockId = (int)SX.opdata;

            StackValue svBlockDecl = rmem.GetAtRelative(StackFrame.kFrameIndexRegisterSX);
            Validity.Assert(svBlockDecl.IsBlockIndex);
            blockId = (int)svBlockDecl.opdata;

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

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

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

            if (runtimeCore.Options.RunMode != InterpreterMode.kExpressionInterpreter)
            {
                ReturnSiteGC(blockId, ci, fi);
            }

            RestoreFromCall();
            runtimeCore.RunningBlock = executingBlock;


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


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

                execStateRestore = RetrieveExecutionStatesFromStack(localCount, paramCount);

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

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

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

                    bounceType = (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, runtimeCore, RX);
                    StackValue svRet = RX;
                    GCDotMethods(procNode.Name, ref svRet, Properties.functionCallDotCallDimensions, Properties.functionCallArguments);
                    RX = svRet;
                }
            }

            SetupGraphNodesInScope();          
            RestoreGraphNodeExecutionStates(procNode, execStateRestore);
        }
Пример #2
0
        public Executive(RuntimeCore runtimeCore, bool isFep = false)
        {
            IsExplicitCall = false;
            Validity.Assert(runtimeCore != null);

            this.runtimeCore = runtimeCore;
            enableLogging = runtimeCore.Options.Verbose;

            exe = runtimeCore.DSExecutable;
            istream = null;

            fepRun = isFep;
            Properties = new InterpreterProperties();

            rmem = runtimeCore.RuntimeMemory;

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

            bounceType = CallingConvention.BounceType.kImplicit;

            deferedGraphNodes = new List<AssociativeGraph.GraphNode>();
        }
Пример #3
0
        private void RETC_Handler()
        {
            runtimeVerify(rmem.ValidateStackFrame());

            RX = rmem.GetAtRelative(StackFrame.kFrameIndexThisPtr);

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

            pc = (int)rmem.GetAtRelative(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 (runtimeCore.Options.RunMode != InterpreterMode.kExpressionInterpreter)
            {
                ReturnSiteGC(blockId, ci, fi);
            }


            RestoreFromCall();
            runtimeCore.RunningBlock = executingBlock;

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

            List<bool> execStateRestore = new List<bool>();
            if (!runtimeCore.Options.IDEDebugMode || runtimeCore.Options.RunMode == InterpreterMode.kExpressionInterpreter)
            {
                int localCount;
                int paramCount;
                GetLocalAndParamCount(blockId, ci, fi, out localCount, out paramCount);

                execStateRestore = RetrieveExecutionStatesFromStack(localCount, paramCount);

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

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

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


            terminate = !explicitCall;

            Properties = PopInterpreterProps();

            ProcedureNode procNode = GetProcedureNode(blockId, ci, fi);
            if (explicitCall)
            {
                DebugReturn(procNode, pc);
            }

            SetupGraphNodesInScope();   
            RestoreGraphNodeExecutionStates(procNode, execStateRestore);
        }
Пример #4
0
        private void RETB_Handler()
        {
            if (runtimeCore.Options.RunMode != InterpreterMode.kExpressionInterpreter)
            {
                runtimeCore.RuntimeMemory.PopConstructBlockId();
            }

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

            if (CallingConvention.BounceType.kExplicit == bounceType)
            {
                RestoreFromBounce();
                runtimeCore.RunningBlock = executingBlock;
            }

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


            StackFrameType type;

            // 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(StackFrame.kFrameIndexCallerStackFrameType);
                type = (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 (runtimeCore.RunningBlock != 0)
            if (!runtimeCore.Options.IDEDebugMode || runtimeCore.Options.RunMode == InterpreterMode.kExpressionInterpreter)
            {
                rmem.FramePointer = (int)rmem.GetAtRelative(StackFrame.kFrameIndexFramePointer).opdata;
                rmem.PopFrame(StackFrame.kStackFrameSize);

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

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

            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(StackFrame.kFrameIndexRegisterTX);
                    Validity.Assert(sv.IsCallingConvention);
                    CallingConvention.CallType callType = (CallingConvention.CallType)sv.opdata;
                    if (CallingConvention.CallType.kExplicit == callType)
                    {
                        int callerblock = (int)rmem.GetAtRelative(StackFrame.kFrameIndexFunctionBlock).opdata;
                        istream = exe.instrStreamList[callerblock];
                    }
                }
            }
            Properties = PopInterpreterProps();
            SetupGraphNodesInScope();   
        }
Пример #5
0
        // 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
        private void ExecuteDebug(int exeblock, int entry, List<Instruction> breakpoints, Language language = Language.NotSpecified)
        {
            // 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 = (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));
            }

            runtimeCore.DebugProps.isResume = false;

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

                    // if no longer inside a replicated/external function call, restore breakpoints
                    if (!runtimeCore.DebugProps.DebugStackFrameContains(DebugProperties.StackFrameFlagOptions.IsReplicating) &&
                        !runtimeCore.DebugProps.DebugStackFrameContains(DebugProperties.StackFrameFlagOptions.IsExternalFunction))
                    {
                        if (runtimeCore.DebugProps.InlineConditionOptions.ActiveBreakPoints.Count > 0)
                        {
                            runtimeCore.Breakpoints.Clear();
                            runtimeCore.Breakpoints.AddRange(runtimeCore.DebugProps.InlineConditionOptions.ActiveBreakPoints);
                            runtimeCore.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;
                    runtimeCore.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[runtimeCore.DebugProps.DebugEntryPC].opCode == OpCode.RETURN || instructions[runtimeCore.DebugProps.DebugEntryPC].opCode == OpCode.RETC))
                {
                    int ci, fi;
                    bool isReplicating;
                    DebugFrame debugFrame;
                    DebugReturnFromFunctionCall(pc, ref exeblock, out ci, out fi, out isReplicating, out debugFrame);

                    instructions = istream.instrList;
                    executingBlock = exeblock;
                    runtimeCore.DebugProps.CurrentBlockId = exeblock;

                    SetupGraphNodesInScope();
                }
                else if (executeInstruction.opCode == OpCode.RETB)
                {
                    tempFrame = runtimeCore.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
                        runtimeCore.DebugProps.DebugEntryPC = runtimeCore.DebugProps.ReturnPCFromDispose;
                        break;
                    }
                    else
                    {
                        runtimeCore.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;
                    runtimeCore.RunningBlock = exeblock;
                }
                else
                {
                    runtimeCore.DebugProps.DebugEntryPC = pc;
                }

                DebugFrame frame = runtimeCore.DebugProps.DebugStackFrame.Peek();
                if (frame.IsInlineConditional)
                {
                    RestoreDebugPropsOnReturnFromBuiltIns();
                    runtimeCore.DebugProps.DebugEntryPC = pc;
                }

                //runtimeCore.RuntimeMemory = rmem;
                runtimeCore.RuntimeMemory = rmem;

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

            if (!fepRun || fepRun && debugRun)
            {
                logVMMessage("End JIL Execution - " + CoreUtils.GetLanguageString(language));
            }
        }
Пример #6
0
        private void BOUNCE_Handler(Instruction instruction)
        {
            // We disallow language blocks inside watch window currently - pratapa
            Validity.Assert(InterpreterMode.kExpressionInterpreter != runtimeCore.Options.RunMode);

            runtimeVerify(instruction.op1.IsBlockIndex);
            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
            runtimeCore.DebugProps.CurrentBlockId = blockId;

            runtimeVerify(instruction.op2.IsInteger);

            // TODO(Jun/Jiong): Considering store the orig block id to stack frame
            runtimeCore.RunningBlock = blockId;

            runtimeCore.RuntimeMemory = rmem;
            if (runtimeCore.Options.RunMode != InterpreterMode.kExpressionInterpreter)
            {
                runtimeCore.RuntimeMemory.PushConstructBlockId(blockId);
            }

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

            StackValue svThisPtr;
            if (rmem.CurrentStackFrame == null)
            {
                svThisPtr = StackValue.BuildPointer(Constants.kInvalidPointer);
            }
            else
            {
                svThisPtr = rmem.CurrentStackFrame.ThisPtr;
            }
            int returnAddr = pc + 1;

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

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

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

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

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


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

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

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

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

                Language bounceLangauge = exe.instrStreamList[blockId].language;
                BounceExplicit(blockId, 0, bounceLangauge, stackFrame);
            }
        }
Пример #7
0
        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(runtimeCore.DebugProps.DebugStackFrame.Count > 0);

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

            isReplicating = debugFrame.IsReplicating;

            if (!isReplicating)
            {
                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 = runtimeCore.DebugProps.DebugStackFrame.Pop();
                    waspopped = true;

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

                    DebugPerformCoercionAndGC(debugFrame);

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

                    terminate = false;
                }

                Properties.executingGraphNode = debugFrame.ExecutingGraphNode;

                if (runtimeCore.DebugProps.RunMode.Equals(Runmode.StepOut) && pc == runtimeCore.DebugProps.StepOutReturnPC)
                {
                    runtimeCore.Breakpoints.Clear();
                    runtimeCore.Breakpoints.AddRange(runtimeCore.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(StackFrame.kFrameIndexClass).opdata;
            fi = (int)rmem.GetAtRelative(StackFrame.kFrameIndexFunction).opdata;

            int localCount;
            int paramCount;
            int blockId = (int)rmem.GetAtRelative(StackFrame.kFrameIndexFunctionBlock).opdata;
            GetLocalAndParamCount(blockId, ci, fi, out localCount, out paramCount);

            // Get execution states
            List<bool> execStateRestore = new List<bool>();
            execStateRestore = RetrieveExecutionStatesFromStack(localCount, paramCount);

            // Pop function stackframe as this is not allowed in Ret/Retc in debug mode
            rmem.FramePointer = (int)rmem.GetAtRelative(StackFrame.kFrameIndexFramePointer).opdata;

            rmem.PopFrame(StackFrame.kStackFrameSize + localCount + paramCount + execStateRestore.Count); 

            ResumeRegistersFromStackExceptRX();

            //StackValue svFrameType = rmem.GetAtRelative(StackFrame.kFrameIndexCallerStackFrameType);
            StackValue svFrameType = rmem.GetAtRelative(StackFrame.kFrameIndexStackFrameType);
            StackFrameType frametype = (StackFrameType)svFrameType.opdata;
            if (frametype == StackFrameType.kTypeLanguage)
            {
                bounceType = (CallingConvention.BounceType)TX.opdata;
            }
            return waspopped;
        }
Пример #8
0
        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(runtimeCore.DebugProps.DebugStackFrame.Count > 0);
            {
                // Restore fepRun
                DebugFrame debugFrame = runtimeCore.DebugProps.DebugStackFrame.Pop();

                bool isResume = debugFrame.IsResume;

                if (isResume)
                {
                    if (runtimeCore.DebugProps.DebugStackFrame.Count > 1)
                    {
                        DebugFrame frame = runtimeCore.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(StackFrame.kFrameIndexFramePointer).opdata;
                rmem.PopFrame(StackFrame.kStackFrameSize);

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

            if (pc < 0)
            {
                throw new EndOfScript();
            }
        }
Пример #9
0
        private void RestoreFromCall()
        {
            int ci = rmem.GetAtRelative(StackFrame.FrameIndexClassIndex).ClassIndex;
            int fi = rmem.GetAtRelative(StackFrame.FrameIndexFunctionIndex).FunctionIndex;
            int blockId = rmem.GetAtRelative(StackFrame.FrameIndexBlockIndex).BlockIndex;
            if (runtimeCore.Options.RunMode != InterpreterMode.Expression)
            {
                ReturnSiteGC(blockId, ci, fi);
            }

            ProcedureNode procNode = GetProcedureNode(blockId, ci, fi);
            if (procNode.IsConstructor)
            {
                RX = rmem.GetAtRelative(StackFrame.FrameIndexThisPtr);
            }
            else
            {
                RX = rmem.Pop();
            }

            pc = (int)rmem.GetAtRelative(StackFrame.FrameIndexReturnAddress).IntegerValue;
            executingBlock = rmem.GetAtRelative(StackFrame.FrameIndexCallerBlockIndex).BlockIndex;
            istream = exe.instrStreamList[executingBlock];
            runtimeCore.RunningBlock = executingBlock;

            StackFrameType callerType = rmem.GetAtRelative(StackFrame.FrameIndexCallerStackFrameType).FrameType;
            fepRun = callerType == StackFrameType.Function;

            // If we're returning from a block to a function, the instruction stream needs to be restored.
            StackValue sv = rmem.GetAtRelative(StackFrame.FrameIndexTX);
            CallingConvention.CallType callType = sv.CallType;
            IsExplicitCall = CallingConvention.CallType.Explicit == callType || CallingConvention.CallType.ExplicitBase == callType;

            List<bool> execStateRestore = new List<bool>();
            if (!runtimeCore.Options.IDEDebugMode || runtimeCore.Options.RunMode == InterpreterMode.Expression)
            {
                int localCount = procNode.LocalCount;
                int paramCount = procNode.ArgumentTypes.Count;

                execStateRestore = RetrieveExecutionStatesFromStack(localCount, paramCount);

                rmem.FramePointer = (int)rmem.GetAtRelative(StackFrame.FrameIndexFramePointer).IntegerValue;
                rmem.PopFrame(StackFrame.StackFrameSize + localCount + paramCount + execStateRestore.Count);

                if (runtimeCore.Options.RunMode != InterpreterMode.Expression)
                {
                    // Restoring the registers require the current frame pointer of the stack frame 
                    ResumeRegistersFromStackExceptRX();
                    bounceType = (CallingConvention.BounceType)TX.CallType;
                }

                if (execStateRestore.Any())
                {
                    Validity.Assert(execStateRestore.Count == procNode.GraphNodeList.Count);
                    for (int n = 0; n < execStateRestore.Count; ++n)
                    {
                        procNode.GraphNodeList[n].isDirty = execStateRestore[n];
                    }
                }
            }

            terminate = !IsExplicitCall;
            bool isDispose = CoreUtils.IsDisposeMethod(procNode.Name);
            if (isDispose)
            {
                terminate = true;
            }

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

            if (IsExplicitCall)
            {
                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 (!procNode.IsConstructor && !wasDebugPropsPopped)
                {
                    RX = CallSite.PerformReturnTypeCoerce(procNode, runtimeCore, RX);
                    if (CoreUtils.IsDotMethod(procNode.Name))
                    {
                        RX = IndexIntoArray(RX, Properties.functionCallDotCallDimensions);
                        rmem.PopFrame(Constants.kDotCallArgCount);
                    }

                    if (Properties.DominantStructure != null)
                    {
                        RX = AtLevelHandler.RestoreDominantStructure(RX, Properties.DominantStructure, null, runtimeCore); 
                    }
                }
            }

            SetupGraphNodesInScope();          
        }
Пример #10
0
        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();

            rmem = core.Rmem;

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

            bounceType = CallingConvention.BounceType.kImplicit;

            deferedGraphNodes = new List<AssociativeGraph.GraphNode>();

            // Execute DS Debug watch
            //debugFlags = (int)DebugFlags.ENABLE_LOG | (int)DebugFlags.SPAWN_DEBUGGER;
        }
Пример #11
0
        private void THROW_Handler()
        {
#if ENABLE_EXCEPTION_HANDLING
            runtimeVerify(instruction.op1.IsBlockIndex);
            int blockId = (int)instruction.op1.opdata;

            runtimeVerify(instruction.op2.IsClassIndex);
            int classScope = (int)instruction.op2.opdata;

            runtimeVerify(instruction.op3.IsFunctionIndex);
            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 = 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(StackFrame.kFrameIndexFramePointer).opdata;
                        rmem.PopFrame(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 = 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(StackFrame.kFrameIndexClass).opdata;
                        int fi = (int)rmem.GetAtRelative(StackFrame.kFrameIndexFunction).opdata;

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

                        rmem.FramePointer = (int)rmem.GetAtRelative(StackFrame.kFrameIndexFramePointer).opdata;
                        rmem.PopFrame(StackFrame.kStackFrameSize + localCount + paramCount);
                    }
                }
            }
            return;
#else
            throw new NotImplementedException();
#endif
        }
Пример #12
0
        private void RETB_Handler()
        {
            if (core.ExecMode != InterpreterMode.kExpressionInterpreter)
            {
                core.Rmem.PopConstructBlockId();
            }

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

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

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


            StackFrameType type;

            // 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(StackFrame.kFrameIndexCallerStackFrameType);
                type = (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(StackFrame.kFrameIndexFramePointer).opdata;
                rmem.PopFrame(StackFrame.kStackFrameSize);

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

                    bounceType = (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 = 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(StackFrame.kFrameIndexRegisterTX);
                    Validity.Assert(sv.IsCallingConvention);
                    CallingConvention.CallType callType = (CallingConvention.CallType)sv.opdata;
                    if (CallingConvention.CallType.kExplicit == callType)
                    {
                        int callerblock = (int)rmem.GetAtRelative(StackFrame.kFrameIndexFunctionBlock).opdata;
                        istream = exe.instrStreamList[callerblock];
                    }
                }
            }
            Properties = PopInterpreterProps();
        }
Пример #13
0
        private void RETC_Handler()
        {
            runtimeVerify(rmem.ValidateStackFrame());

            RX = rmem.GetAtRelative(StackFrame.kFrameIndexThisPtr);

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

            pc = (int)rmem.GetAtRelative(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 != 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(StackFrame.kFrameIndexRegisterTX);
            Validity.Assert(sv.IsCallingConvention);
            CallingConvention.CallType callType = (CallingConvention.CallType)sv.opdata;
            bool explicitCall = CallingConvention.CallType.kExplicit == callType || CallingConvention.CallType.kExplicitBase == callType;
            IsExplicitCall = explicitCall;

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

                execStateRestore = RetrieveExecutionStatesFromStack(localCount, paramCount);

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

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

                    bounceType = (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);
                    }
                }
            }

            // This resotring execution states is only permitted if the current scope is still in a function
            //if (currentScopeFunction != Constants.kGlobalScope)
            {
                RestoreGraphNodeExecutionStates(procNode, execStateRestore);
            }
        }