public CodeBlock(Guid guid, CodeBlockType type, ProtoCore.Language langId, int cbID, SymbolTable symbols, ProcedureTable procTable, bool isBreakableBlock = false, ProtoCore.Core core = null) { this.guid = guid; blockType = type; parent = null; children = new List <CodeBlock>(); language = langId; instrStream = new InstructionStream(langId, core); symbolTable = symbols; procedureTable = procTable; isBreakable = isBreakableBlock; core.CompleteCodeBlockList.Add(this); this.codeBlockId = core.CompleteCodeBlockList.Count - 1; symbols.RuntimeIndex = this.codeBlockId; if (core.ProcNode != null) { core.ProcNode.ChildCodeBlocks.Add(codeBlockId); } }
public void Reset() { isSingleAssocBlock = true; runtimeSymbols = null; procedureTable = null; classTable = null; instrStreamList = null; iStreamCanvas = null; }
public CodeBlock(CodeBlockType type, ProtoCore.Language langId, int codeBlockId, SymbolTable symbols, ProcedureTable procTable, bool isBreakableBlock = false, ProtoCore.Core core = null) { blockType = type; parent = null; children = new List<CodeBlock>(); language = langId; this.codeBlockId = codeBlockId; instrStream = new InstructionStream(langId, core); symbolTable = symbols; procedureTable = procTable; isBreakable = isBreakableBlock; }
public CodeBlock(CodeBlockType type, ProtoCore.Language langId, int codeBlockId, SymbolTable symbols, ProcedureTable procTable, bool isBreakableBlock = false, ProtoLanguage.CompileStateTracker compileState = null) { blockType = type; parent = null; children = new List <CodeBlock>(); language = langId; this.codeBlockId = codeBlockId; instrStream = new InstructionStream(langId, compileState); symbolTable = symbols; procedureTable = procTable; isBreakable = isBreakableBlock; }
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.Implicit; deferedGraphNodes = new List<AssociativeGraph.GraphNode>(); }
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(); } }
private void RestoreExecutive(int exeblock) { // Jun Comment: the stackframe mpof the current language must still be present for this this method to restore the executuve // It must be popped off after this call executingLanguage = exe.instrStreamList[exeblock].language; // TODO Jun: Remove this check once the global bounce stackframe is pushed if (rmem.FramePointer >= ProtoCore.DSASM.StackFrame.kStackFrameSize) { fepRun = false; isGlobScope = true; StackFrameType callerType = (StackFrameType)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexCallerStackFrameType).opdata; if (callerType == StackFrameType.kTypeFunction) { fepRun = true; isGlobScope = false; } } istream = exe.instrStreamList[exeblock]; Validity.Assert(null != istream); Validity.Assert(null != istream.instrList); pc = (int)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexReturnAddress).opdata; }
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; }
private void RestoreFromCall() { StackValue svExecutingBlock = rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexFunctionCallerBlock); Validity.Assert(AddressType.BlockIndex == svExecutingBlock.optype); executingBlock = (int)svExecutingBlock.opdata; istream = exe.instrStreamList[executingBlock]; fepRun = false; isGlobScope = true; StackFrameType callerType = (StackFrameType)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexCallerStackFrameType).opdata; if (callerType == StackFrameType.kTypeFunction) { fepRun = true; isGlobScope = false; } }
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(); }
private void SetupExecutive(int exeblock, int entry) { PushInterpreterProps(Properties); Properties.Reset(); if (runtimeCore.Options.RunMode == InterpreterMode.kNormal) { exe = runtimeCore.DSExecutable; } else if (runtimeCore.Options.RunMode == InterpreterMode.kExpressionInterpreter) { exe = runtimeCore.ExprInterpreterExe; } else { Validity.Assert(false, "Invalid execution mode"); } executingBlock = exeblock; istream = exe.instrStreamList[exeblock]; Validity.Assert(null != istream); Validity.Assert(null != istream.instrList); SetupGraphNodesInScope(); if (!fepRun) { // TODO Jun: Perhaps the entrypoint now can be set from the argument 'entry' only...instead of the stream pc = istream.entrypoint; // JILFep handles function call stack frames rmem.FramePointer = rmem.Stack.Count; } else { pc = entry; } executingLanguage = exe.instrStreamList[exeblock].language; if (Language.Associative == executingLanguage) { SetupEntryPoint(); } if (runtimeCore.Options.RunMode == InterpreterMode.kExpressionInterpreter) { pc = entry; } Validity.Assert(null != rmem); }
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.FrameIndexReturnAddress).IntegerValue; exeblock = rmem.GetAtRelative(StackFrame.FrameIndexCallerBlockIndex).BlockIndex; istream = exe.instrStreamList[exeblock]; instructions = istream.instrList; executingLanguage = istream.language; ci = rmem.GetAtRelative(StackFrame.FrameIndexClassIndex).ClassIndex; fi = rmem.GetAtRelative(StackFrame.FrameIndexFunctionIndex).FunctionIndex; int localCount; int paramCount; int blockId = rmem.GetAtRelative(StackFrame.FrameIndexFunctionBlockIndex).BlockIndex; 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.FrameIndexFramePointer).IntegerValue; rmem.PopFrame(StackFrame.StackFrameSize + localCount + paramCount + execStateRestore.Count); ResumeRegistersFromStackExceptRX(); //StackValue svFrameType = rmem.GetAtRelative(StackFrame.kFrameIndexCallerStackFrameType); StackValue svFrameType = rmem.GetAtRelative(StackFrame.FrameIndexStackFrameType); StackFrameType frametype = svFrameType.FrameType; if (frametype == StackFrameType.LanguageBlock) { bounceType = TX.BounceType; } return waspopped; }
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; }
private void SetupExecutiveForCall(int exeblock, int entry) { PushInterpreterProps(Properties); Properties.Reset(); if (core.ExecMode == InterpreterMode.kNormal) { exe = core.DSExecutable; } else if (core.ExecMode == InterpreterMode.kExpressionInterpreter) { exe = core.ExprInterpreterExe; } else { Validity.Assert(false, "Invalid execution mode"); } fepRun = true; isGlobScope = false; executingBlock = exeblock; istream = exe.instrStreamList[exeblock]; Validity.Assert(null != istream); Validity.Assert(null != istream.instrList); pc = entry; executingLanguage = exe.instrStreamList[exeblock].language; if (Language.kAssociative == executingLanguage) { int ci = (int)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexClass).opdata; int fi = (int)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexFunction).opdata; UpdateMethodDependencyGraph(pc, fi, ci); } }
private void BfsBuildInstructionStreams(CodeBlock codeBlock, InstructionStream[] istreamList) { if (null != codeBlock) { if (DSASM.CodeBlockType.kLanguage == codeBlock.blockType || DSASM.CodeBlockType.kFunction == codeBlock.blockType) { Debug.Assert(codeBlock.codeBlockId < CodeBlockIndex); istreamList[codeBlock.codeBlockId] = codeBlock.instrStream; } foreach (DSASM.CodeBlock child in codeBlock.children) { BfsBuildInstructionStreams(child, istreamList); } } }
private void SetupExecutiveForCall(int exeblock, int entry) { PushInterpreterProps(Properties); Properties.Reset(); if (runtimeCore.Options.RunMode == InterpreterMode.Normal) { exe = runtimeCore.DSExecutable; } else if (runtimeCore.Options.RunMode == InterpreterMode.Expression) { exe = runtimeCore.ExprInterpreterExe; } else { Validity.Assert(false, "Invalid execution mode"); } fepRun = true; executingBlock = exeblock; istream = exe.instrStreamList[exeblock]; Validity.Assert(null != istream); Validity.Assert(null != istream.instrList); SetupGraphNodesInScope(); pc = entry; executingLanguage = exe.instrStreamList[exeblock].language; if (Language.Associative == executingLanguage) { int ci = rmem.GetAtRelative(StackFrame.FrameIndexClassIndex).ClassIndex; int fi = rmem.GetAtRelative(StackFrame.FrameIndexFunctionIndex).FunctionIndex; UpdateMethodDependencyGraph(pc, fi, ci); } }
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(); }
private void SetupExecutive(int exeblock, int entry, Language language, List<Instruction> breakpoints) { core.ExecMode = InterpreterMode.kNormal; // exe need to be assigned at the constructor, // for function call with replication, gc is triggered to handle the parameter and return value at FunctionEndPoint // gc requirs exe to be not null but at that point, Execute has not been called //Validity.Assert(exe == null); exe = core.DSExecutable; executingBlock = exeblock; core.DebugProps.CurrentBlockId = exeblock; istream = exe.instrStreamList[exeblock]; Validity.Assert(null != istream); core.DebugProps.DebugEntryPC = entry; List<Instruction> instructions = istream.instrList; Validity.Assert(null != instructions); // Restore the previous state rmem = core.Rmem; bool _isNewFunction = rmem.FramePointer == 0; if (core.DebugProps.isResume) // resume from a breakpoint, { Validity.Assert(core.DebugProps.DebugStackFrame.Count > 0); DebugFrame debugFrame = core.DebugProps.DebugStackFrame.Peek(); // TODO: The FepRun info need not be cached in DebugProps any longer // as it can be replaced by StackFrameType in rmem.Stack - pratapa fepRun = debugFrame.FepRun == 1; //StackFrameType stackFrameType = (StackFrameType)rmem.GetAtRelative(StackFrame.kFrameIndexStackFrameType).opdata; //fepRun = (stackFrameType == StackFrameType.kTypeFunction) ? true : false; //ResumeRegistersFromStack(); fepRunStack = core.DebugProps.FRStack; Properties = PopInterpreterProps(); Properties.executingGraphNode = core.DebugProps.executingGraphNode; deferedGraphNodes = core.DebugProps.deferedGraphnodes; } else { PushInterpreterProps(Properties); Properties.Reset(); } if (false == fepRun) { if (core.DebugProps.isResume) // resume from a breakpoint, { pc = entry; } else { pc = istream.entrypoint; rmem.FramePointer = rmem.Stack.Count; } } else { pc = entry; isGlobScope = false; } executingLanguage = exe.instrStreamList[exeblock].language; if (Language.kAssociative == executingLanguage && !core.DebugProps.isResume) { if (fepRun) { int ci = (int)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexClass).opdata; int fi = (int)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexFunction).opdata; UpdateMethodDependencyGraph(pc, fi, ci); } else { if (!core.Options.IsDeltaExecution) { UpdateLanguageBlockDependencyGraph(pc); } SetupGraphEntryPoint(pc); } } Validity.Assert(null != rmem); rmem.Executable = exe; rmem.ClassTable = exe.classTable; }
/// <summary> /// A CodeBlock represents a body of DS code /// </summary> /// <param name="guid"></param> /// <param name="type"></param> /// <param name="langId"></param> /// <param name="cbID"></param> /// <param name="symbols"></param> /// <param name="procTable"></param> /// <param name="isBreakableBlock"></param> /// <param name="core"></param> public CodeBlock(Guid guid, CodeBlockType type, ProtoCore.Language langId, int cbID, SymbolTable symbols, ProcedureTable procTable, bool isBreakableBlock = false, ProtoCore.Core core = null) { this.guid = guid; blockType = type; parent = null; children = new List<CodeBlock>(); language = langId; instrStream = new InstructionStream(langId, core); symbolTable = symbols; procedureTable = procTable; isBreakable = isBreakableBlock; core.CompleteCodeBlockList.Add(this); this.codeBlockId = core.CompleteCodeBlockList.Count - 1; symbols.RuntimeIndex = this.codeBlockId; if (core.ProcNode != null) { core.ProcNode.ChildCodeBlocks.Add(codeBlockId); } }
private void SetupExecutive(int exeblock, int entry, Language language) { PushInterpreterProps(Properties); Properties.Reset(); if (core.ExecMode == InterpreterMode.kNormal) { exe = core.DSExecutable; } else if (core.ExecMode == InterpreterMode.kExpressionInterpreter) { exe = core.ExprInterpreterExe; } else { Validity.Assert(false, "Invalid execution mode"); } executingBlock = exeblock; istream = exe.instrStreamList[exeblock]; Validity.Assert(null != istream); Validity.Assert(null != istream.instrList); if (!fepRun) { // TODO Jun: Perhaps the entrypoint now can be set from the argument 'entry' only...instead of the stream pc = istream.entrypoint; // JILFep handles function call stack frames rmem.FramePointer = rmem.Stack.Count; } else { pc = entry; isGlobScope = false; } executingLanguage = exe.instrStreamList[exeblock].language; string engine = ProtoCore.Utils.CoreUtils.GetLanguageString(language); if (Language.kAssociative == executingLanguage) { if (fepRun) { int ci = (int)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexClass).opdata; int fi = (int)rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexFunction).opdata; UpdateMethodDependencyGraph(pc, fi, ci); } else { if (!core.Options.IsDeltaExecution) { UpdateLanguageBlockDependencyGraph(pc); SetupGraphEntryPoint(pc); } else { // See if we need to repond to property changed event. if (UpdatePropertyChangedGraphNode()) { SetupNextExecutableGraph(-1, -1); } else { SetupGraphEntryPoint(pc); } if (core.Options.ExecuteSSA) { ProtoCore.AssociativeEngine.Utils.SetFinalGraphNodeRuntimeDependents(Properties.executingGraphNode); } } } } if (core.ExecMode == InterpreterMode.kExpressionInterpreter) { pc = entry; } Validity.Assert(null != rmem); rmem.Executable = exe; rmem.ClassTable = exe.classTable; }
private int FindEndPCForAssocGraphNode(int tempPC, InstructionStream istream, ProcedureNode fNode, GraphNode graphNode, bool handleSSATemps) { int limit = Constants.kInvalidIndex; //AssociativeGraph.GraphNode currentGraphNode = executingGraphNode; GraphNode currentGraphNode = graphNode; //Validity.Assert(currentGraphNode != null); if (currentGraphNode != null) { if (tempPC < currentGraphNode.updateBlock.startpc || tempPC > currentGraphNode.updateBlock.endpc) { // return false; return Constants.kInvalidIndex; } int i = currentGraphNode.dependencyGraphListID; GraphNode nextGraphNode = currentGraphNode; while (currentGraphNode.exprUID != Constants.kInvalidIndex && currentGraphNode.exprUID == nextGraphNode.exprUID) { limit = nextGraphNode.updateBlock.endpc; if (++i < istream.dependencyGraph.GraphList.Count) { nextGraphNode = istream.dependencyGraph.GraphList[i]; } else { break; } // Is it the next statement // This check will be deprecated on full SSA if (handleSSATemps) { if (!nextGraphNode.IsSSANode()) { // The next graphnode is nolonger part of the current statement // This is the end pc needed to run until nextGraphNode = istream.dependencyGraph.GraphList[i]; limit = nextGraphNode.updateBlock.endpc; break; } } } } // If graph node is null in associative lang block, it either is the very first property declaration or // it is the very first or only function call statement ("return = f();") inside the calling function // Here there's most likely a DEP or RETURN respectively after the function call // in which case, search for the instruction and set that as the new pc limit else if (!fNode.name.Contains(Constants.kSetterPrefix)) { while (++tempPC < istream.instrList.Count) { Instruction instr = istream.instrList[tempPC]; if (instr.opCode == OpCode.DEP || instr.opCode == OpCode.RETURN) { limit = tempPC; break; } } } return limit; }
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; }
private void SetupExecutive(int exeblock, int entry, Language language, List<Instruction> breakpoints) { // exe need to be assigned at the constructor, // for function call with replication, gc is triggered to handle the parameter and return value at FunctionEndPoint // gc requirs exe to be not null but at that point, Execute has not been called //Validity.Assert(exe == null); exe = runtimeCore.DSExecutable; executingBlock = exeblock; runtimeCore.DebugProps.CurrentBlockId = exeblock; istream = exe.instrStreamList[exeblock]; Validity.Assert(null != istream); runtimeCore.DebugProps.DebugEntryPC = entry; List<Instruction> instructions = istream.instrList; Validity.Assert(null != instructions); SetupGraphNodesInScope(); // Restore the previous state //rmem = runtimeCore.RuntimeMemory; rmem = runtimeCore.RuntimeMemory; if (runtimeCore.DebugProps.isResume) // resume from a breakpoint, { Validity.Assert(runtimeCore.DebugProps.DebugStackFrame.Count > 0); DebugFrame debugFrame = runtimeCore.DebugProps.DebugStackFrame.Peek(); // TODO: The FepRun info need not be cached in DebugProps any longer // as it can be replaced by StackFrameType in rmem.Stack - pratapa fepRun = debugFrame.FepRun == 1; //StackFrameType stackFrameType = (StackFrameType)rmem.GetAtRelative(StackFrame.kFrameIndexStackFrameType).opdata; //fepRun = (stackFrameType == StackFrameType.kTypeFunction) ? true : false; //ResumeRegistersFromStack(); fepRunStack = runtimeCore.DebugProps.FRStack; Properties = PopInterpreterProps(); Properties.executingGraphNode = runtimeCore.DebugProps.executingGraphNode; deferedGraphNodes = runtimeCore.DebugProps.deferedGraphnodes; } else { PushInterpreterProps(Properties); Properties.Reset(); } if (false == fepRun) { if (runtimeCore.DebugProps.isResume) // resume from a breakpoint, { pc = entry; } else { pc = istream.entrypoint; rmem.FramePointer = rmem.Stack.Count; } } else { pc = entry; } executingLanguage = exe.instrStreamList[exeblock].language; if (Language.Associative == executingLanguage && !runtimeCore.DebugProps.isResume) { SetupEntryPoint(); } Validity.Assert(null != rmem); }
private void BfsBuildInstructionStreams(CodeBlock codeBlock, InstructionStream[] istreamList) { if (null != codeBlock) { if (CodeBlockType.Language == codeBlock.blockType || CodeBlockType.Function == codeBlock.blockType) { Validity.Assert(codeBlock.codeBlockId < RuntimeTableIndex); istreamList[codeBlock.codeBlockId] = codeBlock.instrStream; } foreach (CodeBlock child in codeBlock.children) { BfsBuildInstructionStreams(child, istreamList); } } }
private void RestoreFromCall() { StackValue svExecutingBlock = rmem.GetAtRelative(StackFrame.kFrameIndexFunctionCallerBlock); Validity.Assert(svExecutingBlock.IsBlockIndex); executingBlock = (int)svExecutingBlock.opdata; istream = exe.instrStreamList[executingBlock]; fepRun = false; StackFrameType callerType = (StackFrameType)rmem.GetAtRelative(StackFrame.kFrameIndexCallerStackFrameType).opdata; if (callerType == StackFrameType.kTypeFunction) { fepRun = true; } }