Exemplo n.º 1
0
 /// <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);
         }
     }
 }
Exemplo n.º 2
0
        public void LogSemanticError(string msg, string fileName = null, int line = -1, int col = -1, AssociativeGraph.GraphNode graphNode = null)
        {
            /*if (fileName == null)
            {
                fileName = "N.A.";
            }*/

            if (logErrors)
            {
                System.Console.WriteLine("{0}({1},{2}) Error:{3}", fileName, line, col, msg);
            }

            if (compileState.Options.IsDeltaExecution)
            {
                compileState.LogErrorInGlobalMap(ProtoLanguage.CompileStateTracker.ErrorType.Error, msg, fileName, line, col);
            }

            BuildData.ErrorEntry errorEntry = new BuildData.ErrorEntry
            {
                FileName = fileName,
                Message = msg,
                Line = line,
                Col = col
            };
            errors.Add(errorEntry);

            // Comment: This is true for example in Graph Execution mode
            /*if (errorAsWarning)
            {
                if (graphNode != null)
                {
                    graphNode.isDirty = false;
                    return;
                }
            }*/

            OutputMessage outputmessage = new OutputMessage(OutputMessage.MessageType.Error, msg.Trim(), fileName, line, col);
            if (MessageHandler != null)
            {
                MessageHandler.Write(outputmessage);
                if (WebMsgHandler != null)
                {
                    OutputMessage webOutputMsg = new OutputMessage(OutputMessage.MessageType.Error, msg.Trim(), "", line, col);
                    WebMsgHandler.Write(webOutputMsg);
                }
                if (!outputmessage.Continue)
                    throw new BuildHaltException(msg);
            }
            throw new BuildHaltException(msg);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Check if an update is triggered;
        /// Find all graph nodes whos dependents contain this symbol;
        /// Mark those nodes as dirty
        /// </summary>
        public int UpdateDependencyGraph(
            int exprUID,
            int modBlkId,
            bool isSSAAssign,
            AssociativeGraph.GraphNode executingGraphNode,
            bool propertyChanged = false)
        {
            int nodesMarkedDirty = 0;
            if (executingGraphNode == null)
            {
                return nodesMarkedDirty;
            }

            int classIndex = executingGraphNode.classIndex;
            int procIndex = executingGraphNode.procIndex;

            var graph = istream.dependencyGraph;
            var graphNodes = graph.GetGraphNodesAtScope(classIndex, procIndex);
            if (graphNodes == null)
            {
                return nodesMarkedDirty;
            }

            //foreach (var graphNode in graphNodes)
            for (int i = 0; i < graphNodes.Count; ++i)
            {
                var graphNode = graphNodes[i];

                // If the graphnode is inactive then it is no longer executed
                if (!graphNode.isActive)
                {
                    continue;
                }
                //
                // Comment Jun: 
                //      This is clarifying the intention that if the graphnode is within the same SSA expression, we still allow update
                //
                bool allowUpdateWithinSSA = false;
                if (core.Options.ExecuteSSA)
                {
                    allowUpdateWithinSSA = true;
                    isSSAAssign = false; // Remove references to this when ssa flag is removed

                    // Do not update if its a property change and the current graphnode is the same expression
                    if (propertyChanged && graphNode.exprUID == Properties.executingGraphNode.exprUID)
                    {
                        continue;
                    }
                }
                else
                {
                    // TODO Jun: Remove this code immediatley after enabling SSA
                    bool withinSSAStatement = graphNode.UID == executingGraphNode.UID;
                    allowUpdateWithinSSA = !withinSSAStatement;
                }

                if (!allowUpdateWithinSSA || (propertyChanged && graphNode == Properties.executingGraphNode))
                {
                    continue;
                }

                foreach (var noderef in executingGraphNode.updateNodeRefList)
                {
                    ProtoCore.AssociativeGraph.GraphNode matchingNode = null;
                    if (!graphNode.DependsOn(noderef, ref matchingNode))
                    {
                        continue;
                    }

                    // Jun: only allow update to other expr id's (other statements) if this is the final SSA assignment
                    if (core.Options.ExecuteSSA && !propertyChanged)
                    {
                        if (null != Properties.executingGraphNode && Properties.executingGraphNode.IsSSANode())
                        {
                            // This is still an SSA statement, if a node of another statement depends on it, ignore it
                            if (graphNode.exprUID != Properties.executingGraphNode.exprUID)
                            {
                                // Defer this update until the final non-ssa node
                                deferedGraphNodes.Add(graphNode);
                                continue;
                            }
                        }
                    }

                    // @keyu: if we are modifying an object's property, e.g.,
                    // 
                    //    foo.id = 42;
                    //
                    // both dependent list and update list of the corresponding 
                    // graph node contains "foo" and "id", so if property "id"
                    // is changed, this graph node will be re-executed and the
                    // value of "id" is incorrectly set back to old value.
                    if (propertyChanged)
                    {
                        var depUpdateNodeRef = graphNode.dependentList[0].updateNodeRefList[0];
                        if (graphNode.updateNodeRefList.Count == 1)
                        {
                            var updateNodeRef = graphNode.updateNodeRefList[0];
                            if (depUpdateNodeRef.IsEqual(updateNodeRef))
                            {
                                continue;
                            }
                        }
                    }

                    //
                    // Comment Jun: We dont want to cycle between such statements:
                    //
                    // a1.a = 1;
                    // a1.a = 10;
                    //

                    Validity.Assert(null != matchingNode);
                    bool isLHSModification = matchingNode.isLHSNode;
                    bool isUpdateable = matchingNode.IsUpdateableBy(noderef);

                    // isSSAAssign means this is the graphnode of the final SSA assignment
                    // Overrride this if allowing within SSA update
                    // TODO Jun: Remove this code when SSA is completely enabled
                    bool allowSSADownstream = false;
                    if (core.Options.ExecuteSSA)
                    {
                        // Check if we allow downstream update
                        if (exprUID == graphNode.exprUID)
                        {
                            allowSSADownstream = graphNode.AstID > executingGraphNode.AstID;
                        }
                    }


                    // Comment Jun: 
                    //      If the triggered dependent graphnode is LHS 
                    //          and... 
                    //      the triggering node (executing graphnode)
                    if (isLHSModification && !isUpdateable)
                    {
                        break;
                    }

                    // TODO Jun: Optimization - Reimplement update delta evaluation using registers
                    //if (IsNodeModified(EX, FX))
                    bool isLastSSAAssignment = (exprUID == graphNode.exprUID) && graphNode.IsLastNodeInSSA && !graphNode.isReturn;
                    if (exprUID != graphNode.exprUID && modBlkId != graphNode.modBlkUID)
                    {
                        UpdateModifierBlockDependencyGraph(graphNode);
                    }
                    else if (allowSSADownstream
                              || isSSAAssign
                                || isLastSSAAssignment
                              || (exprUID != graphNode.exprUID
                                 && modBlkId == Constants.kInvalidIndex
                                 && graphNode.modBlkUID == Constants.kInvalidIndex)
                        )
                    {
                        if (graphNode.isCyclic)
                        {
                            // If the graphnode is cyclic, mark it as not dirst so it wont get executed 
                            // Sets its cyclePoint graphnode to be not dirty so it also doesnt execute.
                            // The cyclepoint is the other graphNode that the current node cycles with
                            graphNode.isDirty = false;
                            if (null != graphNode.cyclePoint)
                            {
                                graphNode.cyclePoint.isDirty = false;
                                graphNode.cyclePoint.isCyclic = true;
                            }
                        }
                        else if (!graphNode.isDirty)
                        {
                            // If the graphnode is not cyclic, then it can be safely marked as dirty, in preparation of its execution
                            if (core.Options.EnableVariableAccumulator
                                && !isSSAAssign
                                && graphNode.IsSSANode())
                            {
                                //
                                // Comment Jun: Backtrack and firt the first graphnode of this SSA transform and mark it dirty. 
                                //              We want to execute the entire statement, not just the partial SSA nodes
                                //

                                // TODO Jun: Optimization - Statically determine the index of the starting graphnode of this SSA expression

                                // Looks we should partially execuate graph
                                // nodes otherwise we will get accumulative
                                // update. - Yu Ke 

                                /*
                                int graphNodeIndex = 0;
                                for (; graphNodeIndex < graph.GraphList.Count; graphNodeIndex++)
                                {
                                    if (graph.GraphList[graphNodeIndex].UID == graphNode.UID)
                                        break;
                                }
                                var firstGraphNode = GetFirstSSAGraphnode(graphNodeIndex - 1, graphNode.exprUID);
                                firstGraphNode.isDirty = true;
                                */
                            }

                            if (core.Options.ElementBasedArrayUpdate)
                            {
                                UpdateDimensionsForGraphNode(graphNode, matchingNode, executingGraphNode);
                            }
                            graphNode.isDirty = true;
                            graphNode.forPropertyChanged = propertyChanged;
                            nodesMarkedDirty++;
                            
                            // On debug mode:
                            //      we want to mark all ssa statements dirty for an if the lhs pointer is a new instance.
                            //      In this case, the entire line must be re-executed
                            //      
                            //  Given:
                            //      x = 1
                            //      p = p.f(x) 
                            //      x = 2
                            //
                            //  To SSA:
                            //
                            //      x = 1
                            //      t0 = p -> we want to execute from here of member function 'f' returned a new instance of 'p'
                            //      t1 = x
                            //      t2 = t0.f(t1)
                            //      p = t2
                            //      x = 2
                            if (null != executingGraphNode.lastGraphNode && executingGraphNode.lastGraphNode.reExecuteExpression)
                            {
                                executingGraphNode.lastGraphNode.reExecuteExpression = false;
                                //if (core.Options.GCTempVarsOnDebug && core.Options.IDEDebugMode)
                                {
                                    var firstGraphNode = GetFirstSSAGraphnode(i - 1, graphNode.exprUID);
                                    firstGraphNode.isDirty = true;
                                }
                            }
                        }
                    }
                }
            }
            return nodesMarkedDirty;
        }
Exemplo n.º 4
0
 private void SetGraphNodeStackValueNull(AssociativeGraph.GraphNode graphNode)
 {
     StackValue svNull = StackValue.Null;
     SetGraphNodeStackValue(graphNode, svNull);
 }
Exemplo n.º 5
0
 private bool HasCyclicDependency(AssociativeGraph.GraphNode node)
 {
     return node.counter > runtimeCore.Options.kDynamicCycleThreshold;
 }
Exemplo n.º 6
0
        protected void BuildRealDependencyForIdentList(AssociativeGraph.GraphNode graphNode)
        {
            if (ssaPointerStack.Count == 0)
            {
                return;
            }

            // Push all dependent pointers
            ProtoCore.AST.AssociativeAST.IdentifierListNode identList = BuildIdentifierList(ssaPointerStack.Peek());

            // Comment Jun: perhaps this can be an assert?
            if (null != identList)
            {
                ProtoCore.Type type = new ProtoCore.Type();
                type.UID = globalClassIndex;
                ProtoCore.AssociativeGraph.UpdateNodeRef nodeRef = new AssociativeGraph.UpdateNodeRef();
                int functionIndex = globalProcIndex;
                DFSGetSymbolList_Simple(identList, ref type, ref functionIndex, nodeRef);

                if (null != graphNode && nodeRef.nodeList.Count > 0)
                {
                    ProtoCore.AssociativeGraph.GraphNode dependentNode = new ProtoCore.AssociativeGraph.GraphNode();
                    dependentNode.updateNodeRefList.Add(nodeRef);
                    graphNode.PushDependent(dependentNode);

                    // If the pointerList is a setter, then it should also be in the lhs of a graphNode
                    //  Given:
                    //      a.x = 1 
                    //  Which was converted to: 
                    //      tvar = a.set_x(1)
                    //  Set a.x as lhs of the graphnode. 
                    //  This means that statement that depends on a.x can re-execute, such as:
                    //      p = a.x;
                    //
                    List<ProtoCore.AST.AssociativeAST.AssociativeNode> topList = ssaPointerStack.Peek();
                    string propertyName = topList[topList.Count - 1].Name;
                    bool isSetter = propertyName.StartsWith(Constants.kSetterPrefix);
                    if (isSetter)
                    {
                        graphNode.updateNodeRefList.Add(nodeRef);
                        graphNode.IsLHSIdentList = true;

                        AutoGenerateUpdateArgumentReference(nodeRef, graphNode);
                    }
                }
            }
        }
Exemplo n.º 7
0
        protected void EmitStringNode(
            Node node, 
            ref Type inferedType, 
            AssociativeGraph.GraphNode graphNode = null,
            ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass = ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone)
        {
            if (subPass == ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier)
            {
                return;
            }

            dynamic sNode = node;
            if (!enforceTypeCheck || core.TypeSystem.IsHigherRank((int)PrimitiveType.kTypeString, inferedType.UID))
            {
                inferedType.UID = (int)PrimitiveType.kTypeString;
            }

            if (core.Options.TempReplicationGuideEmptyFlag && emitReplicationGuide)
            {
                EmitInstrConsole(ProtoCore.DSASM.kw.push, 0 + "[guide]");
                StackValue opNumGuides = StackValue.BuildReplicationGuide(0);
                EmitPush(opNumGuides);
            }

            string value = (string)sNode.Value;
            StackValue svString = core.Heap.AllocateFixedString(value);
            if (core.Options.TempReplicationGuideEmptyFlag && emitReplicationGuide)
            {
                EmitInstrConsole(kw.pushg, "\"" + value + "\"");
                EmitPushG(svString, node.line, node.col);
            }
            else
            {
                EmitInstrConsole(kw.push, "\"" + value + "\"");
                EmitPush(svString, node.line, node.col);
            }

            if (IsAssociativeArrayIndexing && graphNode != null && graphNode.isIndexingLHS)
            {
                SymbolNode literalSymbol = new SymbolNode();
                literalSymbol.name = value;

                var dimNode = new AssociativeGraph.UpdateNode();
                dimNode.symbol = literalSymbol;
                dimNode.nodeType = AssociativeGraph.UpdateNodeType.kLiteral;

                graphNode.dimensionNodeList.Add(dimNode);
            }
        }
Exemplo n.º 8
0
 /// <summary>
 /// Append the graphnode to the instruction stream and procedure nodes
 /// </summary>
 /// <param name="graphnode"></param>
 protected void PushGraphNode(AssociativeGraph.GraphNode graphnode)
 {
     codeBlock.instrStream.dependencyGraph.Push(graphnode);
     if (globalProcIndex != Constants.kGlobalScope)
     {
         localProcedure.GraphNodeList.Add(graphnode);
     }
 }
Exemplo n.º 9
0
        //
        // Comment Jun: Revised 
        //
        //  proc UpdateGraphNodeDependency(execnode)
        //      foreach node in graphnodelist 
        //          if execnode.lhs is equal to node.lhs
        //              if execnode.HasDependents() 
        //                  if execnode.Dependents() is not equal to node.Dependents()
        //                      node.RemoveDependents()
        //                  end
        //              end
        //          end
        //      end
        //  end
        //
        private void UpdateGraphNodeDependency(AssociativeGraph.GraphNode gnode, AssociativeGraph.GraphNode executingNode)
        {
            if (gnode.UID >= executingNode.UID // for previous graphnodes
                || gnode.updateNodeRefList.Count == 0
                || gnode.updateNodeRefList.Count != executingNode.updateNodeRefList.Count
                || gnode.isAutoGenerated)
            {
                return;
            }

            for (int n = 0; n < executingNode.updateNodeRefList.Count; ++n)
            {
                if (!gnode.updateNodeRefList[n].IsEqual(executingNode.updateNodeRefList[n]))
                {
                    return;
                }
            }

            //if (executingNode.dependentList.Count > 0)
            {
                // if execnode.Dependents() is not equal to node.Dependents()
                // TODO Jun: Extend this check
                bool areDependentsEqual = false;
                if (!areDependentsEqual)
                {
                    gnode.dependentList.Clear();
                }
            }
        }
Exemplo n.º 10
0
 private void SetGraphNodeStackValueNull(AssociativeGraph.GraphNode graphNode)
 {
     StackValue svNull = StackUtils.BuildNull();
     SetGraphNodeStackValue(graphNode, svNull);
 }
Exemplo n.º 11
0
        public void SetUpStepOverFunctionCalls(ProtoCore.Core core, ProcedureNode fNode, AssociativeGraph.GraphNode graphNode, bool hasDebugInfo)
        {
            int tempPC = DebugEntryPC;
            int limit = 0;  // end pc of current expression
            InstructionStream istream;

            int pc = tempPC;
            if (core.DebugProps.InlineConditionOptions.isInlineConditional == true)
            {
                tempPC = InlineConditionOptions.startPc;
                limit = InlineConditionOptions.endPc;
                istream = core.DSExecutable.instrStreamList[InlineConditionOptions.instructionStream];
            }
            else
            {
                pc = tempPC;
                istream = core.DSExecutable.instrStreamList[core.RunningBlock];
                if (istream.language == Language.kAssociative)
                {
                    limit = FindEndPCForAssocGraphNode(pc, istream, fNode, graphNode, core.Options.ExecuteSSA);
                    //Validity.Assert(limit != ProtoCore.DSASM.Constants.kInvalidIndex);
                }
                else if (istream.language == Language.kImperative)
                {
                    // Check for 'SETEXPUID' instruction to check for end of expression
                    while (++pc < istream.instrList.Count)
                    {
                        Instruction instr = istream.instrList[pc];
                        if (instr.opCode == OpCode.SETEXPUID)
                        {
                            limit = pc;
                            break;
                        }
                    }
                }
            }

            // Determine if this is outermost CALLR in the expression
            // until then do not restore any breakpoints
            // If outermost CALLR, restore breakpoints after end of expression
            pc = tempPC;
            int numNestedFunctionCalls = 0;
            while (++pc <= limit)
            {
                Instruction instr = istream.instrList[pc];
                if (instr.opCode == OpCode.CALLR && instr.debug != null)
                {
                    numNestedFunctionCalls++;
                }
            }
            if (numNestedFunctionCalls == 0)
            {
                // If this is the outermost function call 
                core.Breakpoints.Clear();
                core.Breakpoints.AddRange(AllbreakPoints);

                pc = tempPC;
                while (++pc <= limit)
                {
                    Instruction instr = istream.instrList[pc];
                    // We still want to break at the closing brace of a function or ctor call or language block
                    if (instr.debug != null && instr.opCode != OpCode.RETC && instr.opCode != OpCode.RETURN && 
                        (instr.opCode != OpCode.RETB)) 
                    {
                        if (core.Breakpoints.Contains(instr))
                            core.Breakpoints.Remove(instr);
                    }
                }
            }
        }
Exemplo n.º 12
0
        private int FindEndPCForAssocGraphNode(int tempPC, InstructionStream istream, ProcedureNode fNode, AssociativeGraph.GraphNode graphNode, bool handleSSATemps)
        {
            int limit = Constants.kInvalidIndex;
            //AssociativeGraph.GraphNode currentGraphNode = executingGraphNode;
            AssociativeGraph.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;
                AssociativeGraph.GraphNode nextGraphNode = currentGraphNode;
                while (currentGraphNode.exprUID != ProtoCore.DSASM.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;
        }
Exemplo n.º 13
0
        /// <summary>
        /// Check if an update is triggered;
        /// Find all graph nodes whos dependents contain this symbol;
        /// Mark those nodes as dirty
        /// </summary>
        public int UpdateDependencyGraph(
            int exprUID,
            int modBlkId,
            bool isSSAAssign,
            AssociativeGraph.GraphNode executingGraphNode,
            bool propertyChanged = false)
        {
            int nodesMarkedDirty = 0;
            if (executingGraphNode == null)
            {
                return nodesMarkedDirty;
            }

            int classIndex = executingGraphNode.classIndex;
            int procIndex = executingGraphNode.procIndex;

            var graph = istream.dependencyGraph;
            var graphNodes = graph.GetGraphNodesAtScope(classIndex, procIndex);
            if (graphNodes == null)
            {
                return nodesMarkedDirty;
            }

            foreach (var graphNode in graphNodes)
            {
                //
                // Comment Jun: 
                //      This is clarifying the intention that if the graphnode is within the same SSA expression, we still allow update
                //
                bool allowUpdateWithinSSA = true;
                if (!allowUpdateWithinSSA || (propertyChanged && graphNode == Properties.executingGraphNode))
                {
                    continue;
                }

                foreach (var noderef in executingGraphNode.updateNodeRefList)
                {
                    ProtoCore.AssociativeGraph.GraphNode matchingNode = null;
                    if (!graphNode.DependsOn(noderef, ref matchingNode))
                    {
                        continue;
                    }

                    // @keyu: if we are modifying an object's property, e.g.,
                    // 
                    //    foo.id = 42;
                    //
                    // both dependent list and update list of the corresponding 
                    // graph node contains "foo" and "id", so if property "id"
                    // is changed, this graph node will be re-executed and the
                    // value of "id" is incorrectly set back to old value.
                    if (propertyChanged)
                    {
                        var depUpdateNodeRef = graphNode.dependentList[0].updateNodeRefList[0];
                        if (graphNode.updateNodeRefList.Count == 1)
                        {
                            var updateNodeRef = graphNode.updateNodeRefList[0];
                            if (depUpdateNodeRef.IsEqual(updateNodeRef))
                            {
                                continue;
                            }
                        }
                    }

                    //
                    // Comment Jun: We dont want to cycle between such statements:
                    //
                    // a1.a = 1;
                    // a1.a = 10;
                    //

                    Validity.Assert(null != matchingNode);
                    bool isLHSModification = matchingNode.isLHSNode;
                    bool isUpdateable = matchingNode.IsUpdateableBy(noderef);

                    // isSSAAssign means this is the graphnode of the final SSA assignment
                    // Overrride this if allowing within SSA update
                    // TODO Jun: Remove this code when SSA is completely enabled
                    bool allowSSADownstream = graphNode.UID > executingGraphNode.UID;
                    

                    // Comment Jun: 
                    //      If the triggered dependent graphnode is LHS 
                    //          and... 
                    //      the triggering node (executing graphnode)
                    if (isLHSModification && !isUpdateable)
                    {
                        break;
                    }

                    // TODO Jun: Optimization - Reimplement update delta evaluation using registers
                    //if (IsNodeModified(EX, FX))
                    if (exprUID != graphNode.exprUID && modBlkId != graphNode.modBlkUID)
                    {
                        UpdateModifierBlockDependencyGraph(graphNode);
                    }
                    else if (allowSSADownstream
                              || isSSAAssign
                              || (exprUID != graphNode.exprUID
                                 && modBlkId == Constants.kInvalidIndex
                                 && graphNode.modBlkUID == Constants.kInvalidIndex)
                        )
                    {
                        if (graphNode.isCyclic)
                        {
                            // If the graphnode is cyclic, mark it as not dirst so it wont get executed 
                            // Sets its cyclePoint graphnode to be not dirty so it also doesnt execute.
                            // The cyclepoint is the other graphNode that the current node cycles with
                            graphNode.isDirty = false;
                            if (null != graphNode.cyclePoint)
                            {
                                graphNode.cyclePoint.isDirty = false;
                                graphNode.cyclePoint.isCyclic = true;
                            }
                        }
                        else if (!graphNode.isDirty)
                        {

                            if (core.Options.ElementBasedArrayUpdate)
                            {
                                UpdateDimensionsForGraphNode(graphNode, matchingNode, executingGraphNode);
                            }
                            graphNode.isDirty = true;
                            graphNode.forPropertyChanged = propertyChanged;
                            nodesMarkedDirty++;
                        }
                    }
                }
            }
            return nodesMarkedDirty;
        }
Exemplo n.º 14
0
        protected int DfsEmitArrayIndexHeap(Node node, AssociativeGraph.GraphNode graphNode = null, ProtoCore.AST.Node parentNode = null, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone)
        {
            int indexCnt = 0;
            Debug.Assert(node is ProtoCore.AST.AssociativeAST.ArrayNode || node is ProtoCore.AST.ImperativeAST.ArrayNode);

            IsAssociativeArrayIndexing = true;

            dynamic arrayNode = node;
            while (arrayNode is ProtoCore.AST.AssociativeAST.ArrayNode || arrayNode is ProtoCore.AST.ImperativeAST.ArrayNode)
            {
                ++indexCnt;
                dynamic array = arrayNode;
                ProtoCore.Type lastType = new ProtoCore.Type();
                lastType.UID = (int)PrimitiveType.kTypeVoid;
                lastType.IsIndexable = false;
                DfsTraverse(array.Expr, ref lastType, false, graphNode, subPass, parentNode);
                arrayNode = array.Type;
            }

            IsAssociativeArrayIndexing = false;

            return indexCnt;
        }
Exemplo n.º 15
0
        protected void EmitStringNode(
            Node node, 
            ref Type inferedType, 
            AssociativeGraph.GraphNode graphNode = null,
            AssociativeSubCompilePass subPass = AssociativeSubCompilePass.kNone)
        {
            if (subPass == AssociativeSubCompilePass.kUnboundIdentifier)
            {
                return;
            }

            dynamic sNode = node;
            if (!enforceTypeCheck || core.TypeSystem.IsHigherRank((int)PrimitiveType.kTypeString, inferedType.UID))
            {
                inferedType.UID = (int)PrimitiveType.kTypeString;
            }

            Byte[] utf8bytes = EncodingUtils.UTF8StringToUTF8Bytes((String)sNode.value);
            String value = Encoding.UTF8.GetString(utf8bytes);

            foreach (char ch in value)
            {
                String strValue = "'" + ch + "'";
                EmitInstrConsole(kw.push, strValue);

                StackValue op = StackValue.BuildChar(ch);
                EmitPush(op, node.line, node.col);
            }

            if (IsAssociativeArrayIndexing && graphNode != null && graphNode.isIndexingLHS)
            {
                SymbolNode literalSymbol = new SymbolNode();
                literalSymbol.name = value;

                var dimNode = new AssociativeGraph.UpdateNode();
                dimNode.symbol = literalSymbol;
                dimNode.nodeType = AssociativeGraph.UpdateNodeType.kLiteral;

                graphNode.dimensionNodeList.Add(dimNode);
            }

            EmitInstrConsole(kw.alloca, value.Length.ToString());
            EmitPopString(value.Length);
        }
Exemplo n.º 16
0
 private void SetGraphNodeStackValue(AssociativeGraph.GraphNode graphNode, StackValue sv)
 {
     Validity.Assert(!graphNode.isReturn);
     // TODO Jun: Expand me to handle complex ident lists
     SymbolNode symbol = graphNode.updateNodeRefList[0].nodeList[0].symbol;
     Validity.Assert(null != symbol);
     rmem.SetSymbolValue(symbol, sv);
 }
Exemplo n.º 17
0
        protected int DfsEmitArrayIndexHeap(Node node, AssociativeGraph.GraphNode graphNode = null, ProtoCore.AST.Node parentNode = null, ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass = ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone)
        {
            int indexCnt = 0;
            Validity.Assert(node is ProtoCore.AST.AssociativeAST.ArrayNode || node is ProtoCore.AST.ImperativeAST.ArrayNode);

            IsAssociativeArrayIndexing = true;

            dynamic arrayNode = node;
            while (arrayNode is ProtoCore.AST.AssociativeAST.ArrayNode || arrayNode is ProtoCore.AST.ImperativeAST.ArrayNode)
            {
                ++indexCnt;
                dynamic array = arrayNode;
                ProtoCore.Type lastType = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeVar, 0);
                DfsTraverse(array.Expr, ref lastType, false, graphNode, subPass, parentNode);
                arrayNode = array.Type;
            }

            IsAssociativeArrayIndexing = false;

            return indexCnt;
        }
Exemplo n.º 18
0
 /// <summary>
 /// Logs the unbound variable warning and sets the unbound symbol
 /// </summary>
 /// <param name="unboundSymbol"></param>
 /// <param name="message"></param>
 /// <param name="fileName"></param>
 /// <param name="line"></param>
 /// <param name="col"></param>
 /// <param name="graphNode"></param>
 public void LogUnboundVariableWarning(
                         SymbolNode unboundSymbol,  
                         string message, 
                         string fileName = null, 
                         int line = -1, 
                         int col = -1, 
                         AssociativeGraph.GraphNode graphNode = null)
 {
     LogWarning(BuildData.WarningID.IdUnboundIdentifier, message, core.CurrentDSFileName, line, col, graphNode, unboundSymbol);
 }
Exemplo n.º 19
0
        /// <summary>
        /// Generates unique identifier for the callsite associated with the graphnode
        /// </summary>
        /// <param name="graphNode"></param>
        /// <param name="procNode"></param>
        protected void GenerateCallsiteIdentifierForGraphNode(AssociativeGraph.GraphNode graphNode, string procName)
        {
            // This instance count in which the function appears lexically in the current guid
            // This must be stored and incremented
            int functionCallInstance = 0;


            // Cache this function call instance count 
            // This is the count of the number of times in which this callsite appears in the program
            int callInstance = 0;
            if (!core.CallsiteGuidMap.TryGetValue(graphNode.guid, out callInstance))
            {
                // The guid doesnt exist yet
                core.CallsiteGuidMap.Add(graphNode.guid, 0);
            }
            else
            {
                // Increment the current count
                core.CallsiteGuidMap[graphNode.guid]++;
                functionCallInstance = core.CallsiteGuidMap[graphNode.guid];
            }

            // Build the unique ID for a callsite 
            string callsiteIdentifier =
                procName + 
                "_InClassDecl" + globalClassIndex + 
                "_InFunctionScope" + globalProcIndex + 
                "_Instance" + functionCallInstance.ToString() + 
                "_" + graphNode.guid.ToString();

            // TODO Jun: Address this in MAGN-3774
            // The current limitation is retrieving the cached trace data for multiple callsites in a single CBN
            // after modifying the lines of code.
            graphNode.CallsiteIdentifier = callsiteIdentifier;
        }
Exemplo n.º 20
0
        protected void BuildRealDependencyForIdentList(AssociativeGraph.GraphNode graphNode)
        {
            // Push all dependent pointers
            ProtoCore.AST.AssociativeAST.IdentifierListNode identList = BuildIdentifierList(ssaPointerList);

            // Comment Jun: perhaps this can be an assert?
            if (null != identList)
            {
                ProtoCore.Type type = new ProtoCore.Type();
                type.UID = globalClassIndex;
                ProtoCore.AssociativeGraph.UpdateNodeRef nodeRef = new AssociativeGraph.UpdateNodeRef();
                int functionIndex = globalProcIndex;
                DFSGetSymbolList_Simple(identList, ref type, ref functionIndex, nodeRef);

                if (null != graphNode && nodeRef.nodeList.Count > 0)
                {
                    ProtoCore.AssociativeGraph.GraphNode dependentNode = new ProtoCore.AssociativeGraph.GraphNode();
                    dependentNode.updateNodeRefList.Add(nodeRef);
                    graphNode.PushDependent(dependentNode);
                }
            }
        }
Exemplo n.º 21
0
        private void BuildSSADependency(Node node, AssociativeGraph.GraphNode graphNode)
        {
            // Jun Comment: set the graphNode dependent as this identifier list
            ProtoCore.Type type = new ProtoCore.Type();
            type.UID = globalClassIndex;
            ProtoCore.AssociativeGraph.UpdateNodeRef nodeRef = new AssociativeGraph.UpdateNodeRef();
            DFSGetSymbolList(node, ref type, nodeRef);

            if (null != graphNode && nodeRef.nodeList.Count > 0)
            {
                ProtoCore.AssociativeGraph.GraphNode dependentNode = new ProtoCore.AssociativeGraph.GraphNode();
                dependentNode.updateNodeRefList.Add(nodeRef);
                graphNode.PushDependent(dependentNode);
            }
        }
Exemplo n.º 22
0
        public void LogSemanticError(string msg, string fileName = null, int line = -1, int col = -1, AssociativeGraph.GraphNode graphNode = null)
        {
            if (logErrors)
            {
                System.Console.WriteLine("{0}({1},{2}) Error:{3}", fileName, line, col, msg);
            }

            if (core.Options.IsDeltaExecution)
            {
            }

            BuildData.ErrorEntry errorEntry = new BuildData.ErrorEntry
            {
                FileName = fileName,
                Message = msg,
                Line = line,
                Column = col
            };
            errors.Add(errorEntry);

            OutputMessage outputmessage = new OutputMessage(OutputMessage.MessageType.Error, msg.Trim(), fileName, line, col);
            if (MessageHandler != null)
            {
                MessageHandler.Write(outputmessage);
                if (WebMsgHandler != null)
                {
                    OutputMessage webOutputMsg = new OutputMessage(OutputMessage.MessageType.Error, msg.Trim(), "", line, col);
                    WebMsgHandler.Write(webOutputMsg);
                }
                if (!outputmessage.Continue)
                    throw new BuildHaltException(msg);
            }
            throw new BuildHaltException(msg);
        }
Exemplo n.º 23
0
        /// <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(Resources.kMultipleSymbolFound, name, "");
                    foreach (var symbol in symbols)
                    {
                        message += ", " + symbol.FullName;
                    }

                    status.LogWarning(BuildData.WarningID.MultipleSymbolFound, message, graphNode: graphNode);
                }
            }
        }
Exemplo n.º 24
0
        public void LogWarning(BuildData.WarningID warningID, 
                               string message, 
                               string fileName = null, 
                               int line = -1, 
                               int col = -1, 
                               AssociativeGraph.GraphNode graphNode = null)
        { 
            var entry = new BuildData.WarningEntry 
            { 
                ID = warningID, 
                Message = message, 
                Line = line, 
                Column = col, 
                GraphNodeGuid = graphNode == null ? default(Guid) : graphNode.guid,
                AstID = graphNode == null? DSASM.Constants.kInvalidIndex : graphNode.OriginalAstID,
                FileName = fileName 
            };
            warnings.Add(entry);

            if (core.Options.IsDeltaExecution)
            {
            }

            if (LogWarnings)
            {
                System.Console.WriteLine("{0}({1},{2}) Warning:{3}", fileName, line, col, message);

                OutputMessage outputmessage = new OutputMessage(OutputMessage.MessageType.Warning, message.Trim(), fileName, line, col);
                if (MessageHandler != null)
                {
                    MessageHandler.Write(outputmessage);
                    if (WebMsgHandler != null)
                    {
                        OutputMessage webOutputMsg = new OutputMessage(OutputMessage.MessageType.Warning, message.Trim(), "", line, col);
                        WebMsgHandler.Write(webOutputMsg);
                    }
                    if (!outputmessage.Continue)
                        throw new BuildHaltException(message);
                }
            }
        }
Exemplo n.º 25
0
 private void SetGraphNodeStackValue(AssociativeGraph.GraphNode graphNode, StackValue sv)
 {
     Validity.Assert(!graphNode.isReturn);
     // TODO Jun: Expand me to handle complex ident lists
     ProtoCore.DSASM.SymbolNode symbol = graphNode.updateNodeRefList[0].nodeList[0].symbol;
     Validity.Assert(null != symbol);
     rmem.SetStackData(symbol.runtimeTableIndex, symbol.symbolTableIndex, symbol.classScope, sv);
 }
Exemplo n.º 26
0
 private bool HasCyclicDependency(AssociativeGraph.GraphNode node)
 {
     return IsExecutedTooManyTimes(node, runtimeCore.Options.kDynamicCycleThreshold);
 }
Exemplo n.º 27
0
        /// <summary>
        /// To implement element based update: when an element in an array is
        /// updated, only updates the corresponding element in its updatee.
        /// 
        /// For example:
        /// 
        ///     a = b;    // b = {1, 2, 3};
        ///     b[0] = 0; // should only update a[0].
        ///     
        /// The basic idea is checking the dimension node in the executing 
        /// graph node (i.e., [0] in the executing graph node b[0] = 0), and
        /// apply thsi dimension to the dirty graph node (i.e., a = b), so when
        /// executing that dirty graph node, [0] will be applied to all POP and
        /// PUSH instructions. So for statement a = b; essentially the VM 
        /// will do
        /// 
        ///      push b[0];
        ///      pop to a[0];
        ///  
        /// Now this function only considers about the simpliest case, i.e., 
        /// only variable is on the RHS of expression because a function may
        /// involve array promotion, type conversion, replication guide and so
        /// on.   -- Yu Ke
        /// </summary>
        /// <param name="graphNode">The graph node that is to be update</param>
        /// <param name="matchingNode">Matching node</param>
        /// <param name="executingGraphNode">The executing graph node</param>
        private void UpdateDimensionsForGraphNode(
            AssociativeGraph.GraphNode graphNode,
            AssociativeGraph.GraphNode matchingNode,
            AssociativeGraph.GraphNode executingGraphNode)
        {
            Validity.Assert(graphNode != null && executingGraphNode != null);
            graphNode.updateDimensions.Clear();

            var updateDimNodes = executingGraphNode.dimensionNodeList;
            if (updateDimNodes == null)
            {
                return;
            }

            // We may take replication control into account in the future. 
            // But right now let's just skip it.
            var rcInstructions = executingGraphNode.replicationControl.Instructions;

            // Update node list can be a, b, c for the case like:
            //     a.b.c[0] = ...
            // 
            // Let's only support the simplest case now:
            //
            //    a[0] = ...
            Validity.Assert(matchingNode.updateNodeRefList != null
                && matchingNode.updateNodeRefList.Count > 0);
            var depNodes = matchingNode.updateNodeRefList[0].nodeList;
            if (depNodes == null || depNodes.Count != 1)
            {
                return;
            }


            if (graphNode.firstProc != null && graphNode.firstProc.argTypeList.Count != 0)
            {
                // Skip the case that function on RHS takes over 1 parameters --
                // there is potential replication guide which hasn't been supported
                // yet right now. 
                // 
                //     x = foo(a, b);
                //     a[0] = ...
                //
                if (graphNode.firstProc.argTypeList.Count > 1)
                {
                    return;
                }

                // Not support function parameter whose rank >= 1
                // 
                // def foo(a:int[])
                // {
                //    ...
                // }
                // a = {1, 2, 3};
                // b = a;
                // a[0] = 0;   // b[0] = foo(a[0]) doesn't work!
                //  
                if (graphNode.firstProc.argTypeList[0].rank >= 1)
                {
                    return;
                }
            }

            var depDimNodes = depNodes.Last().dimensionNodeList;
            int dimIndex = 0;

            if (depDimNodes != null)
            {
                // Try to match all dependent dimensions. For example:
                //  
                //     ... = a[0][i];
                //     a[0][j] = ...;  
                //
                // Here [i], [j] doesn't match, even they may have same value.
                // Or, 
                //  
                //     ... = a[0][1][2];
                //     a[0][1] = ...;  
                //
                // where [2] hasn't been matched yet. 
                //
                // For these cases, right now just do full update. 
                if (depDimNodes.Count > updateDimNodes.Count)
                {
                    return;
                }

                // For the case:
                //
                //     x = a[0];
                //     a[0] = 1;   
                //
                // We don't want to apply array indexing [0] to a[0] again. But we 
                // do want to apply array indexing [1] for the following case:
                //
                //    x = a[0];
                //    a[0][1] = 1;  --> x[1] = a[0][1]
                //
                // So basically we should eliminate the common part.
                for (; dimIndex < depDimNodes.Count; ++dimIndex)
                {
                    var dimSymbol1 = depDimNodes[dimIndex].symbol;
                    var dimSymbol2 = updateDimNodes[dimIndex].symbol;
                    if (!dimSymbol1.IsEqualAtScope(dimSymbol2))
                    {
                        return;
                    }
                }
            }

            for (; dimIndex < updateDimNodes.Count; ++dimIndex)
            {
                var dimNode = updateDimNodes[dimIndex];
                var dimSymbol = dimNode.symbol;

                switch (dimNode.nodeType)
                {
                    case AssociativeGraph.UpdateNodeType.kSymbol:
                        {
                            var opSymbol = StackValue.Null;
                            if (dimSymbol.classScope != Constants.kInvalidIndex &&
                                dimSymbol.functionIndex == Constants.kInvalidIndex)
                            {
                                opSymbol = StackValue.BuildMemVarIndex(dimSymbol.symbolTableIndex);
                            }
                            else
                            {
                                opSymbol = StackValue.BuildVarIndex(dimSymbol.symbolTableIndex);
                            }

                            var dimValue = GetOperandData(dimSymbol.codeBlockId,
                                                          opSymbol,
                                                          StackValue.BuildInt(dimSymbol.classScope));
                            graphNode.updateDimensions.Add(dimValue);
                            break;
                        }

                    case AssociativeGraph.UpdateNodeType.kLiteral:
                        {
                            int dimValue = Constants.kInvalidIndex;
                            if (Int32.TryParse(dimSymbol.name, out dimValue))
                            {
                                graphNode.updateDimensions.Add(StackValue.BuildInt(dimValue));
                            }
                            else
                            {
                                // No idea for this dimension, just terminate. 
                                return;
                            }
                            break;
                        }
                    default:
                        // No idea to how to handle method and other node types,
                        // just stop here at least we can get partial element
                        // based array update. 
                        return;
                }
            }
        }
Exemplo n.º 28
0
 private bool IsExecutedTooManyTimes(AssociativeGraph.GraphNode node, int limit)
 {
     Validity.Assert(null != node);
     return (node.counter > limit);
 }
Exemplo n.º 29
0
        //
        // Comment Jun: Revised 
        //
        //  proc UpdateGraphNodeDependency(execnode)
        //      foreach node in graphnodelist 
        //          if execnode.lhs is equal to node.lhs
        //              if execnode.HasDependents() 
        //                  if execnode.Dependents() is not equal to node.Dependents()
        //                      node.RemoveDependents()
        //                  end
        //              end
        //          end
        //      end
        //  end
        //
        private void UpdateGraphNodeDependency(AssociativeGraph.GraphNode gnode, AssociativeGraph.GraphNode executingNode)
        {
            if (gnode.UID >= executingNode.UID // for previous graphnodes
                || gnode.updateNodeRefList.Count == 0
                || gnode.updateNodeRefList.Count != executingNode.updateNodeRefList.Count
                || gnode.isAutoGenerated)
            {
                return;
            }

            for (int n = 0; n < executingNode.updateNodeRefList.Count; ++n)
            {
                if (!gnode.updateNodeRefList[n].IsEqual(executingNode.updateNodeRefList[n]))
                {
                    return;
                }

                if (gnode.guid == executingNode.guid && gnode.ssaExprID == executingNode.ssaExprID)
                //if (gnode.exprUID == executingNode.exprUID)
                {
                    // These nodes are within the same expression, no redifinition can occur
                    return;
                }
            }

            //if (executingNode.dependentList.Count > 0)
            {
                // if execnode.Dependents() is not equal to node.Dependents()
                // TODO Jun: Extend this check
                bool areDependentsEqual = false;
                if (!areDependentsEqual)
                {
                    gnode.dependentList.Clear();

                    // GC all the temporaries associated with the redefined variable
                    // Given:
                    //      a = A.A()
                    //      a = 10
                    //
                    // Transforms to:
                    //        
                    //      t0 = A.A()
                    //      a = t0
                    //      a = 10      // Redefinition of 'a' will GC 't0'
                    //
                    // Another example
                    // Given:
                    //      a = {A.A()}
                    //      a = 10
                    //
                    // Transforms to:
                    //        
                    //      t0 = A.A()
                    //      t1 = {t0}
                    //      a = t1
                    //      a = 10      // Redefinition of 'a' will GC t0 and t1
                    //
                    GCAnonymousSymbols(gnode.symbolListWithinExpression);
                    gnode.symbolListWithinExpression.Clear();
                }
            }
        }
Exemplo n.º 30
0
        protected void EmitStringNode(
            Node node, 
            ref Type inferedType, 
            AssociativeGraph.GraphNode graphNode = null,
            ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass = ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone)
        {
            if (subPass == ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier)
            {
                return;
            }

            dynamic sNode = node;
            if (!enforceTypeCheck || core.TypeSystem.IsHigherRank((int)PrimitiveType.kTypeString, inferedType.UID))
            {
                inferedType.UID = (int)PrimitiveType.kTypeString;
            }

            string value = (string)sNode.Value;
            StackValue svString = core.Heap.AllocateFixedString(value);
            EmitOpWithEmptyReplicationGuide(emitReplicationGuide, svString, "\"" + value + "\"", node);

            if (IsAssociativeArrayIndexing && graphNode != null && graphNode.isIndexingLHS)
            {
                SymbolNode literalSymbol = new SymbolNode();
                literalSymbol.name = value;

                var dimNode = new AssociativeGraph.UpdateNode();
                dimNode.symbol = literalSymbol;
                dimNode.nodeType = AssociativeGraph.UpdateNodeType.kLiteral;

                graphNode.dimensionNodeList.Add(dimNode);
            }
        }