/// <summary> /// Audits the class table for multiple symbol definition. /// </summary> /// <param name="status">BuildStatus to log the warnings if /// multiple symbol found.</param> /// /// <param name="guid">Guid of node to which warning corresponds</param> public void AuditMultipleDefinition(BuildStatus status, AssociativeGraph.GraphNode graphNode) { var names = symbolTable.GetAllSymbolNames(); if (names.Count == symbolTable.GetSymbolCount()) { return; } foreach (var name in names) { var symbols = symbolTable.GetAllSymbols(name); if (symbols.Count > 1) { var baseClass = GetCommonBaseClass(symbols); if (baseClass != null) { continue; } string message = string.Format(Resources.kMultipleSymbolFound, name, ""); foreach (var symbol in symbols) { message += ", " + symbol.FullName; } status.LogWarning(BuildData.WarningID.MultipleSymbolFound, message, graphNode: graphNode); } } }
/// <summary> /// This function sets the modified temp graphnodes to the last graphnode in a statement /// </summary> /// <param name="graphnode"></param> public static void SetFinalGraphNodeRuntimeDependents(AssociativeGraph.GraphNode graphnode) { if (null != graphnode && graphnode.IsSSANode()) { if (null != graphnode.lastGraphNode) { graphnode.lastGraphNode.symbolListWithinExpression.Add(graphnode.updateNodeRefList[0].nodeList[0].symbol); } } }
// // 1. Get the graphnode given the varname // 2. Get the sv of the symbol // 3. set the sv to the new value // 4. Get all graphnpodes dependent on the symbol and mark them dirty // 5. Re-execute the script // proc AssociativeEngine.SetValue(string varname, int block, StackValue, sv) // symbol = dsEXE.GetSymbol(varname, block) // globalStackIndex = symbol.stackindex // runtime.stack[globalStackIndex] = sv // AssociativeEngine.Propagate(symbol) // runtime.Execute() // end // private bool SetValue(string varName, int?value, out int nodesMarkedDirty) { int blockId = 0; // 1. Get the graphnode given the varname AssociativeGraph.GraphNode graphNode = MirrorTarget.GetFirstGraphNode(varName, out blockId); if (graphNode == null) { nodesMarkedDirty = 0; return(false); } SymbolNode symbol = graphNode.updateNodeRefList[0].nodeList[0].symbol; // 2. Get the sv of the symbol int globalStackIndex = symbol.index; // 3. set the sv to the new value StackValue sv; if (null == value) { sv = StackValue.Null; } else { sv = StackValue.BuildInt((long)value); } MirrorTarget.rmem.Stack[globalStackIndex] = sv; // 4. Get all graphnpodes dependent on the symbol and mark them dirty const int outerBlock = 0; ProtoCore.DSASM.Executable exe = MirrorTarget.exe; List <AssociativeGraph.GraphNode> reachableGraphNodes = AssociativeEngine.Utils.UpdateDependencyGraph( graphNode, MirrorTarget, graphNode.exprUID, false, runtimeCore.Options.ExecuteSSA, outerBlock, false); // Mark reachable nodes as dirty Validity.Assert(reachableGraphNodes != null); nodesMarkedDirty = reachableGraphNodes.Count; foreach (AssociativeGraph.GraphNode gnode in reachableGraphNodes) { gnode.isDirty = true; } // 5. Re-execute the script - re-execution occurs after this call return(true); }
/// <summary> /// Audits the class table for multiple symbol definition. /// </summary> /// <param name="status">BuildStatus to log the warnings if /// multiple symbol found.</param> /// /// <param name="guid">Guid of node to which warning corresponds</param> public void AuditMultipleDefinition(BuildStatus status, AssociativeGraph.GraphNode graphNode) { var names = symbolTable.GetAllSymbolNames(); if (names.Count == symbolTable.GetSymbolCount()) { return; } foreach (var name in names) { var symbols = symbolTable.GetAllSymbols(name); if (symbols.Count > 1) { string message = string.Format(StringConstants.kMultipleSymbolFound, name, ""); foreach (var symbol in symbols) { message += ", " + symbol.FullName; } status.LogWarning(BuildData.WarningID.kMultipleSymbolFound, message, graphNode: graphNode); } } }
public override StackValue Execute(ProtoCore.Runtime.Context c, List <StackValue> formalParameters, ProtoCore.DSASM.StackFrame stackFrame, Core core) { ProtoCore.DSASM.Interpreter interpreter = new ProtoCore.DSASM.Interpreter(core, true); ProtoCore.DSASM.Executive oldDSASMExec = null; if (core.CurrentExecutive != null) { oldDSASMExec = core.CurrentExecutive.CurrentDSASMExec; core.CurrentExecutive.CurrentDSASMExec = interpreter.runtime; } // Assert for the block type activation.globs = core.DSExecutable.runtimeSymbols[core.RunningBlock].GetGlobalSize(); // // Comment Jun: // Storing execution states is relevant only if the current scope is a function, // as this mechanism is used to keep track of maintining execution states of recursive calls // This mechanism should also be ignored if the function call is non-recursive as it does not need to maintains state in that case int execStateSize = procedureNode.GraphNodeList.Count; stackFrame.ExecutionStateSize = execStateSize; for (int n = execStateSize - 1; n >= 0; --n) { AssociativeGraph.GraphNode gnode = procedureNode.GraphNodeList[n]; interpreter.Push(StackValue.BuildBoolean(gnode.isDirty)); } // Push Params formalParameters.Reverse(); for (int i = 0; i < formalParameters.Count; i++) { interpreter.Push(formalParameters[i]); } StackValue svThisPtr = stackFrame.ThisPtr; StackValue svBlockDecl = StackValue.BuildBlockIndex(stackFrame.FunctionBlock); // Jun: Make sure we have no empty or unaligned frame data Validity.Assert(DSASM.StackFrame.kStackFrameSize == stackFrame.Frame.Length); // Setup the stack frame data //int thisPtr = (int)stackFrame.GetAt(DSASM.StackFrame.AbsoluteIndex.kThisPtr).opdata; int ci = activation.classIndex; int fi = activation.funcIndex; int returnAddr = stackFrame.ReturnPC; int blockDecl = stackFrame.FunctionBlock; int blockCaller = stackFrame.FunctionCallerBlock; int framePointer = core.Rmem.FramePointer; int locals = activation.locals; // Update the running block to tell the execution engine which set of instruction to execute // TODO(Jun/Jiong): Considering store the orig block id to stack frame int origRunningBlock = core.RunningBlock; core.RunningBlock = (int)svBlockDecl.opdata; // Set SX register interpreter.runtime.SX = svBlockDecl; StackFrameType callerType = stackFrame.CallerStackFrameType; List <StackValue> registers = new List <DSASM.StackValue>(); StackValue svCallConvention; bool isDispose = CoreUtils.IsDisposeMethod(procedureNode.name); bool explicitCall = !c.IsReplicating && !c.IsImplicitCall && !isDispose; if (explicitCall) { svCallConvention = StackValue.BuildCallingConversion((int)ProtoCore.DSASM.CallingConvention.CallType.kExplicit); } else { svCallConvention = StackValue.BuildCallingConversion((int)ProtoCore.DSASM.CallingConvention.CallType.kImplicit); } stackFrame.TX = svCallConvention; interpreter.runtime.TX = svCallConvention; // Set SX register stackFrame.SX = svBlockDecl; interpreter.runtime.SX = svBlockDecl; // TODO Jun: // The stackframe carries the current set of registers // Determine if this can be done even for the non explicit call implementation registers.AddRange(stackFrame.GetRegisters()); // Comment Jun: the depth is always 0 for a function call as we are reseting this for each function call // This is only incremented for every language block bounce int depth = stackFrame.Depth; DSASM.StackFrameType type = stackFrame.StackFrameType; Validity.Assert(depth == 0); Validity.Assert(type == DSASM.StackFrameType.kTypeFunction); core.Rmem.PushStackFrame(svThisPtr, ci, fi, returnAddr, blockDecl, blockCaller, callerType, type, depth, framePointer, registers, locals, execStateSize); StackValue svRet; if (explicitCall) { svRet = ProtoCore.DSASM.StackValue.BuildExplicitCall(activation.pc); } else { svRet = interpreter.Run(core.RunningBlock, activation.pc, Language.kInvalid, core.Breakpoints); core.RunningBlock = origRunningBlock; } if (core.CurrentExecutive != null) { core.CurrentExecutive.CurrentDSASMExec = oldDSASMExec; } return(svRet); //DSASM.Mirror.ExecutionMirror.Unpack(svRet, core.heap, core); }