Esempio n. 1
0
        public bool IsEqual(UpdateNodeRef rhs)
        {
            if (nodeList.Count != rhs.nodeList.Count)
            {
                return(false);
            }

            for (int n = 0; n < nodeList.Count; ++n)
            {
                if (nodeList[n].dimensionNodeList.Count != rhs.nodeList[n].dimensionNodeList.Count)
                {
                    return(false);
                }
                else if (nodeList[n].dimensionNodeList.Count != 0)
                {
                    for (int m = 0; m < nodeList[n].dimensionNodeList.Count; m++)
                    {
                        if (nodeList[n].dimensionNodeList[m].symbol.name != rhs.nodeList[n].dimensionNodeList[m].symbol.name)
                        {
                            return(false);
                        }
                    }
                }
                if (!nodeList[n].IsEqual(rhs.nodeList[n]))
                {
                    return(false);
                }
            }
            return(true);
        }
Esempio n. 2
0
 public void PushUpdateNodeRef(UpdateNodeRef nodeRef)
 {
     Validity.Assert(null != nodeList);
     foreach (UpdateNode node in nodeRef.nodeList)
     {
         nodeList.Add(node);
     }
 }
Esempio n. 3
0
 public UpdateNodeRef(UpdateNodeRef rhs)
 {
     if (null != rhs && null != rhs.nodeList)
     {
         nodeList = new List <UpdateNode>(rhs.nodeList);
     }
     else
     {
         nodeList = new List <UpdateNode>();
     }
 }
Esempio n. 4
0
 public UpdateNodeRef(UpdateNodeRef rhs)
 {
     nodeList = new List <UpdateNode>();
     if (null != rhs && null != rhs.nodeList)
     {
         foreach (UpdateNode node in rhs.nodeList)
         {
             PushUpdateNode(node);
         }
     }
 }
Esempio n. 5
0
        public UpdateNodeRef GetUntilFirstProc()
        {
            UpdateNodeRef newRef = new UpdateNodeRef();

            foreach (UpdateNode node in nodeList)
            {
                if (node.nodeType != UpdateNodeType.kMethod)
                {
                    newRef.nodeList.Add(node);
                }
            }
            return(newRef);
        }
Esempio n. 6
0
        public void PushSymbolReference(SymbolNode symbol, UpdateNodeType type = UpdateNodeType.kSymbol)
        {
            Validity.Assert(null != symbol);
            UpdateNode updateNode = new UpdateNode();

            updateNode.symbol   = symbol;
            updateNode.nodeType = type;

            UpdateNodeRef nodeRef = new UpdateNodeRef();

            nodeRef.PushUpdateNode(updateNode);

            updateNodeRefList.Add(nodeRef);
        }
Esempio n. 7
0
        public void PushProcReference(ProtoCore.DSASM.ProcedureNode proc)
        {
            Debug.Assert(null != proc);
            Debug.Assert(null != updateNodeRefList);
            UpdateNode updateNode = new UpdateNode();

            updateNode.procNode = proc;
            updateNode.nodeType = UpdateNodeType.kMethod;

            UpdateNodeRef nodeRef = new UpdateNodeRef();

            nodeRef.PushUpdateNode(updateNode);

            updateNodeRefList.Add(nodeRef);
        }
Esempio n. 8
0
        public void PushSymbolReference(ProtoCore.DSASM.SymbolNode symbol, ProtoCore.AssociativeGraph.UpdateNodeType type = UpdateNodeType.kSymbol)
        {
            Debug.Assert(null != symbol);
            Debug.Assert(null != updateNodeRefList);
            UpdateNode updateNode = new UpdateNode();

            updateNode.symbol   = symbol;
            updateNode.nodeType = type;

            UpdateNodeRef nodeRef = new UpdateNodeRef();

            nodeRef.PushUpdateNode(updateNode);

            updateNodeRefList.Add(nodeRef);
        }
Esempio n. 9
0
        public void PushSymbolReference(SymbolNode symbol)
        {
            Validity.Assert(null != symbol);
            UpdateNode updateNode = new UpdateNode();

            updateNode.symbol   = symbol;
            updateNode.nodeType = UpdateNodeType.kSymbol;

            UpdateNodeRef nodeRef = new UpdateNodeRef();

            nodeRef.block = symbol.runtimeTableIndex;
            nodeRef.PushUpdateNode(updateNode);

            updateNodeRefList.Add(nodeRef);
        }
Esempio n. 10
0
        public void PushSymbolReference(ProtoCore.DSASM.SymbolNode symbol)
        {
            Debug.Assert(null != symbol);
            Debug.Assert(null != updateNodeRefList);
            UpdateNode updateNode = new UpdateNode();

            updateNode.symbol   = symbol;
            updateNode.nodeType = UpdateNodeType.kSymbol;

            UpdateNodeRef nodeRef = new UpdateNodeRef();

            nodeRef.block = symbol.runtimeTableIndex;
            nodeRef.PushUpdateNode(updateNode);

            updateNodeRefList.Add(nodeRef);
        }
Esempio n. 11
0
        public bool IsUpdateableBy(UpdateNodeRef modifiedRef)
        {
            // Function to check if the current graphnode can be modified by the modified reference
            bool isUpdateable = false;

            if (modifiedRef.nodeList.Count < updateNodeRefList[0].nodeList.Count)
            {
                isUpdateable = true;
                for (int n = 0; n < modifiedRef.nodeList.Count; ++n)
                {
                    UpdateNode updateNode = modifiedRef.nodeList[n];
                    if (!updateNode.Equals(updateNodeRefList[0].nodeList[n]))
                    {
                        isUpdateable = false;
                        break;
                    }
                }
            }
            return(isUpdateable);
        }
Esempio n. 12
0
        public void PushSymbolReference(ProtoCore.DSASM.SymbolNode symbol)
        {
            Validity.Assert(null != symbol);
            Validity.Assert(null != updateNodeRefList);
            UpdateNode updateNode = new UpdateNode();
            updateNode.symbol = symbol;
            updateNode.nodeType = UpdateNodeType.kSymbol;

            UpdateNodeRef nodeRef = new UpdateNodeRef();
            nodeRef.block = symbol.runtimeTableIndex;
            nodeRef.PushUpdateNode(updateNode);

            updateNodeRefList.Add(nodeRef);
        }
Esempio n. 13
0
 public UpdateNodeRef(UpdateNodeRef rhs)
 {
     if (null != rhs && null != rhs.nodeList)
     {
         nodeList = new List<UpdateNode>(rhs.nodeList);
     }
     else
     {
         nodeList = new List<UpdateNode>();
     }
 }
Esempio n. 14
0
        public bool DependsOn(UpdateNodeRef modifiedRef, ref GraphNode dependentNode)
        {
            bool match = false;

            foreach (GraphNode depNode in dependentList)
            {

                Validity.Assert(1 == depNode.updateNodeRefList.Count);
                //foreach (UpdateNodeRef depNodeRef in depNode.updateNodeRefList)
                //{
                UpdateNodeRef depNodeRef = depNode.updateNodeRefList[0];
                bool bothSymbolsMatch = false;
                bool bothSymbolsStatic = false;
                bool inImperativeMatch = false;
                bool inImperative = false;
                if (depNodeRef != null)
                    if (depNodeRef.nodeList != null && modifiedRef.nodeList != null && depNodeRef.nodeList.Count > 0 && modifiedRef.nodeList.Count > 0)
                    {
                        if (depNodeRef.nodeList.Count > modifiedRef.nodeList.Count)
                        {
                            for (int m = 0; m < depNodeRef.nodeList.Count; m++)
                            {

                                if (depNodeRef.nodeList[m] != null && modifiedRef.nodeList[0] != null && depNodeRef.nodeList[m].symbol != null && modifiedRef.nodeList[0].symbol != null)
                                {
                                    if (modifiedRef.nodeList[0].symbol.forArrayName != null && !modifiedRef.nodeList[0].symbol.forArrayName.Equals(""))
                                    {
                                        inImperative = true;
                                        if (modifiedRef.nodeList[0].symbol.functionIndex == Constants.kInvalidIndex)
                                        {
                                            inImperative = inImperative
                                                && (depNodeRef.nodeList[m].symbol.functionIndex == Constants.kInvalidIndex)
                                                && (modifiedRef.nodeList[0].symbol.codeBlockId == depNodeRef.nodeList[m].symbol.codeBlockId);
                                        }

                                        if (inImperative && modifiedRef.nodeList[0].symbol.functionIndex == depNodeRef.nodeList[m].symbol.functionIndex && (modifiedRef.nodeList[0].symbol.name == depNodeRef.nodeList[m].symbol.name || modifiedRef.nodeList[0].symbol.forArrayName == depNodeRef.nodeList[m].symbol.name))
                                        {
                                            inImperativeMatch = true;
                                        }

                                    }
                                }
                            }
                        }
                        else if (depNodeRef.nodeList.Count == modifiedRef.nodeList.Count)
                        {
                            for (int m = 0; m < depNodeRef.nodeList.Count && m < modifiedRef.nodeList.Count; m++)
                            {

                                if (depNodeRef.nodeList[m] != null && modifiedRef.nodeList[m] != null && depNodeRef.nodeList[m].symbol != null && modifiedRef.nodeList[m].symbol != null)
                                {
                                    if (modifiedRef.nodeList[0].symbol.forArrayName != null && !modifiedRef.nodeList[0].symbol.forArrayName.Equals(""))
                                    {
                                        inImperative = true;
                                        if (modifiedRef.nodeList[m].symbol.functionIndex == Constants.kInvalidIndex)
                                        {
                                            inImperative = inImperative
                                                && (depNodeRef.nodeList[m].symbol.functionIndex == Constants.kInvalidIndex)
                                                && (modifiedRef.nodeList[m].symbol.codeBlockId == depNodeRef.nodeList[m].symbol.codeBlockId);
                                        }
                                        if (inImperative && modifiedRef.nodeList[m].symbol.functionIndex == depNodeRef.nodeList[m].symbol.functionIndex && modifiedRef.nodeList[m].symbol.name == depNodeRef.nodeList[m].symbol.name )
                                        {
                                            inImperativeMatch = true;
                                        }

                                    }
                                }
                            }
                        }
                    }


                if (!inImperativeMatch)
                {
                    // Does first symbol match


                    if (null != modifiedRef.nodeList[0].symbol && null != depNodeRef.nodeList[0].symbol)
                    {
                        bothSymbolsMatch = modifiedRef.nodeList[0].symbol.Equals(depNodeRef.nodeList[0].symbol);


                        bothSymbolsStatic =
                            modifiedRef.nodeList[0].symbol.memregion == MemoryRegion.kMemStatic
                            && depNodeRef.nodeList[0].symbol.memregion == MemoryRegion.kMemStatic
                            && modifiedRef.nodeList[0].symbol.name == depNodeRef.nodeList[0].symbol.name;

                        // Check further if their array index match in literal values
                        if (bothSymbolsMatch)
                        {
                            // Are the indices the same number
                            bool areIndicesMatching = modifiedRef.nodeList[0].dimensionNodeList.Count >= depNodeRef.nodeList[0].dimensionNodeList.Count;
                            if (areIndicesMatching && depNodeRef.nodeList[0].dimensionNodeList.Count > 0)
                            {
                                for (int n = 0; n < depNodeRef.nodeList[0].dimensionNodeList.Count; ++n)
                                {
                                    // Is either a non-literal
                                    UpdateNode modDimNode =modifiedRef.nodeList[0].dimensionNodeList[n];
                                    UpdateNode depDimNode = depNodeRef.nodeList[0].dimensionNodeList[n];

                                    if (modDimNode.nodeType != depDimNode.nodeType)
                                    {
                                        bothSymbolsMatch = false;
                                    }
                                    else if (modDimNode.nodeType == UpdateNodeType.kLiteral)
                                    {
                                        bothSymbolsMatch = modDimNode.symbol.name.CompareTo(depDimNode.symbol.name) == 0;
                                    }
                                    else if (modDimNode.nodeType == UpdateNodeType.kSymbol)
                                    {
                                        bothSymbolsMatch = modDimNode.symbol.Equals(depDimNode.symbol);
                                    }
                                    else
                                    {
                                        bothSymbolsMatch = false;
                                    }

                                    if (!bothSymbolsMatch)
                                    { 
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    if (bothSymbolsMatch || bothSymbolsStatic)
                    {
                        match = true;

                        // If it is static, then all symbols must match
                        if (bothSymbolsStatic)
                        {
                            // The number of symbols in the modifed reference... 
                            //  ...must match
                            // The number of symbols in the current dependency noderef
                            if (modifiedRef.nodeList.Count == depNodeRef.nodeList.Count)
                            {
                                for (int n = 1; n < modifiedRef.nodeList.Count; ++n)
                                {
                                    //Validity.Assert(!modifiedRef.nodeList[n].isMethod);
                                    //Validity.Assert(!depNodeRef.nodeList[n].isMethod);

                                    if (UpdateNodeType.kMethod == modifiedRef.nodeList[n].nodeType || UpdateNodeType.kMethod == depNodeRef.nodeList[n].nodeType)
                                    {
                                        match = false;
                                        break;
                                    }

                                    if (modifiedRef.nodeList[n].symbol.index != depNodeRef.nodeList[n].symbol.index)
                                    {
                                        match = false;
                                        break;
                                    }
                                }
                            }
                            else
                            {
                                match = false;
                            }
                        }
                        else
                        {
                            if (modifiedRef.nodeList.Count >= depNodeRef.nodeList.Count)
                            {
                                //
                                // The modifed reference is either the same nodelist length or more than the current dependent
                                // a.x.y is being compared to a.x
                                //
                                for (int n = 1; n < modifiedRef.nodeList.Count; ++n)
                                {
                                    if (modifiedRef.nodeList.Count != depNodeRef.nodeList.Count)
                                    {
                                        if (n >= depNodeRef.nodeList.Count)
                                        {
                                            match = false;
                                            break;
                                        }
                                    }

                                    if (UpdateNodeType.kMethod == modifiedRef.nodeList[n].nodeType || UpdateNodeType.kMethod == depNodeRef.nodeList[n].nodeType)
                                    {
                                        match = false;
                                        break;
                                    }

                                    if (modifiedRef.nodeList[n].symbol.name != depNodeRef.nodeList[n].symbol.name)
                                    {
                                        match = false;
                                        break;
                                    }
                                }
                            }
                            else
                            {
                                //
                                // The modifed reference nodelist is less than than the current dependent nodelist
                                // a.x is being compared to a.x.y 
                                //
                                for (int n = 1; n < depNodeRef.nodeList.Count; ++n)
                                {

                                    if (n >= modifiedRef.nodeList.Count)
                                    {
                                        break;
                                    }

                                    if (UpdateNodeType.kMethod == modifiedRef.nodeList[n].nodeType || UpdateNodeType.kMethod == depNodeRef.nodeList[n].nodeType)
                                    {
                                        match = false;
                                        break;
                                    }

                                    if (modifiedRef.nodeList[n].symbol.name != depNodeRef.nodeList[n].symbol.name)
                                    {
                                        match = false;
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    dependentNode = depNode;
                    if (match)
                    {
                        break;
                    }

                }
                else
                {
                    for (int m = 0; m < depNodeRef.nodeList.Count && m < modifiedRef.nodeList.Count; m++)
                    {
                        // Does first symbol match

                        if (null != modifiedRef.nodeList[m].symbol && null != depNodeRef.nodeList[m].symbol)
                        {
                            bothSymbolsMatch = modifiedRef.nodeList[m].symbol.Equals(depNodeRef.nodeList[m].symbol);
                            bothSymbolsStatic =
                                modifiedRef.nodeList[m].symbol.memregion == MemoryRegion.kMemStatic
                                && depNodeRef.nodeList[m].symbol.memregion == MemoryRegion.kMemStatic
                                && modifiedRef.nodeList[m].symbol.name == depNodeRef.nodeList[m].symbol.name;

                            // Check further if their array index match in literal values
                            if (bothSymbolsMatch)
                            {
                                // Are the indices the same number
                                bool areIndicesMatching = modifiedRef.nodeList[m].dimensionNodeList.Count == depNodeRef.nodeList[m].dimensionNodeList.Count;
                                if (areIndicesMatching && modifiedRef.nodeList[m].dimensionNodeList.Count > 0)
                                {
                                    for (int n = 0; n < modifiedRef.nodeList[m].dimensionNodeList.Count; ++n)
                                    {
                                        // Is either a non-literal
                                        bool isEitherNonLiteral = modifiedRef.nodeList[m].dimensionNodeList[n].nodeType != UpdateNodeType.kLiteral
                                            || depNodeRef.nodeList[m].dimensionNodeList[n].nodeType != UpdateNodeType.kLiteral;
                                        if (isEitherNonLiteral)
                                        {
                                            bothSymbolsMatch = false;
                                            break;
                                        }

                                        // They are both literal, now check for their literal values
                                        if (0 != modifiedRef.nodeList[m].dimensionNodeList[n].symbol.name.CompareTo(depNodeRef.nodeList[m].dimensionNodeList[n].symbol.name))
                                        {
                                            // They are not the same
                                            bothSymbolsMatch = false;
                                            break;
                                        }
                                    }
                                }
                            }
                        }

                        if (bothSymbolsMatch || bothSymbolsStatic || inImperativeMatch)
                        {
                            match = true;

                            // If it is static, then all symbols must match
                            if (bothSymbolsStatic)
                            {
                                // The number of symbols in the modifed reference... 
                                //  ...must match
                                // The number of symbols in the current dependency noderef
                                if (modifiedRef.nodeList.Count == depNodeRef.nodeList.Count)
                                {
                                    for (int n = 1; n < modifiedRef.nodeList.Count; ++n)
                                    {
                                        //Validity.Assert(!modifiedRef.nodeList[n].isMethod);
                                        //Validity.Assert(!depNodeRef.nodeList[n].isMethod);

                                        if (UpdateNodeType.kMethod == modifiedRef.nodeList[n].nodeType || UpdateNodeType.kMethod == depNodeRef.nodeList[n].nodeType)
                                        {
                                            match = false;
                                            break;
                                        }

                                        if (modifiedRef.nodeList[n].symbol.index != depNodeRef.nodeList[n].symbol.index)
                                        {
                                            match = false;
                                            break;
                                        }
                                    }
                                }
                                else
                                {
                                    match = false;
                                }
                            }
                            else
                            {
                                if (modifiedRef.nodeList.Count >= depNodeRef.nodeList.Count)
                                {
                                    //
                                    // The modifed reference is either the same nodelist length or more than the current dependent
                                    // a.x.y is being compared to a.x
                                    //
                                    for (int n = 1; n < modifiedRef.nodeList.Count; ++n)
                                    {
                                        if (modifiedRef.nodeList.Count != depNodeRef.nodeList.Count)
                                        {
                                            if (n >= depNodeRef.nodeList.Count)
                                            {
                                                match = false;
                                                break;
                                            }
                                        }

                                        if (UpdateNodeType.kMethod == modifiedRef.nodeList[n].nodeType || UpdateNodeType.kMethod == depNodeRef.nodeList[n].nodeType)
                                        {
                                            match = false;
                                            break;
                                        }

                                        if (modifiedRef.nodeList[n].symbol.name != depNodeRef.nodeList[n].symbol.name)
                                        {
                                            match = false;
                                            break;
                                        }
                                    }
                                }
                                else
                                {
                                    //
                                    // The modifed reference nodelist is less than than the current dependent nodelist
                                    // a.x is being compared to a.x.y 
                                    //
                                    for (int n = 1; n < depNodeRef.nodeList.Count; ++n)
                                    {

                                        if (n >= modifiedRef.nodeList.Count)
                                        {
                                            break;
                                        }

                                        if (UpdateNodeType.kMethod == modifiedRef.nodeList[n].nodeType || UpdateNodeType.kMethod == depNodeRef.nodeList[n].nodeType)
                                        {
                                            match = false;
                                            break;
                                        }

                                        if (modifiedRef.nodeList[n].symbol.name != depNodeRef.nodeList[n].symbol.name)
                                        {
                                            match = false;
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    dependentNode = depNode;
                    if (match)
                    {
                        break;
                    }
                }
                //}
            }
            return match;
        }
Esempio n. 15
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);
                    }
                }
            }
        }
Esempio n. 16
0
        private ProtoCore.AssociativeGraph.UpdateNodeRef AutoGenerateUpdateReference(AssociativeNode node, ProtoCore.AssociativeGraph.GraphNode graphNode)
        {
            // Get the lhs symbol list
            ProtoCore.Type type = new ProtoCore.Type();
            type.UID = globalClassIndex;
            ProtoCore.AssociativeGraph.UpdateNodeRef leftNodeRef = new ProtoCore.AssociativeGraph.UpdateNodeRef();
            DFSGetSymbolList(node, ref type, leftNodeRef);

            // Auto-generate the updateNodeRefs for this graphnode given the list 
            // stored in the first procedure found in the assignment expression
            if (functionCallStack.Count > 0)
            {
                ProtoCore.DSASM.ProcedureNode firstProc = functionCallStack[0];
                if (!firstProc.IsAutoGenerated)
                {
                    graphNode.firstProc = firstProc;
                }
            }

            return leftNodeRef;
        }
Esempio n. 17
0
        private ProtoCore.AssociativeGraph.UpdateNodeRef GetUpdatedNodeRef(AssociativeNode node)
        {
            if (null == localProcedure)
            {
                return null;
            }

            // Get the lhs symbol list
            ProtoCore.Type type = new ProtoCore.Type();
            type.UID = globalClassIndex;
            ProtoCore.AssociativeGraph.UpdateNodeRef leftNodeRef = new ProtoCore.AssociativeGraph.UpdateNodeRef();
            DFSGetSymbolList(node, ref type, leftNodeRef);

     
            return leftNodeRef;
        }
Esempio n. 18
0
        public void PushSymbolReference(SymbolNode symbol, UpdateNodeType type = UpdateNodeType.kSymbol)
        {
            Validity.Assert(null != symbol);
            UpdateNode updateNode = new UpdateNode();
            updateNode.symbol = symbol;
            updateNode.nodeType = type;

            UpdateNodeRef nodeRef = new UpdateNodeRef();
            nodeRef.PushUpdateNode(updateNode);

            updateNodeRefList.Add(nodeRef);
        }
Esempio n. 19
0
        public ProcedureNode TraverseDotFunctionCall(
                                ProtoCore.AST.Node node, 
                                ProtoCore.AST.Node parentNode, 
                                int lefttype, 
                                int depth, 
                                GraphNode graphNode, 
                                ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass,
                                BinaryExpressionNode bnode,
                                ref ProtoCore.Type inferedType)
        {
            ProcedureNode procCallNode = null;

            var dotCallType = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeVar, 0); ;

            bool isConstructor = false;
            bool isStaticCall = false;
            bool isUnresolvedDot = false;

            int classIndex = Constants.kInvalidIndex;
            string className = string.Empty;

            var dotCall = new FunctionDotCallNode(node as FunctionDotCallNode);
            var funcCall = dotCall.DotCall;
            var procName = dotCall.FunctionCall.Function.Name;

            var firstArgument = dotCall.DotCall.FormalArguments[0];
            if (firstArgument is FunctionDotCallNode)
            {
                isUnresolvedDot = true;
            }
            else if (firstArgument is IdentifierNode)
            {
                // Check if the lhs identifer is a class name
                className = (firstArgument as IdentifierNode).Name;
                classIndex = core.ClassTable.IndexOf(className);

                // Check if the lhs is an variable
                SymbolNode symbolnode;
                bool isAccessible;
                bool hasAllocated = VerifyAllocation(className,
                                                     globalClassIndex,
                                                     globalProcIndex,
                                                     out symbolnode,
                                                     out isAccessible);

                bool toResolveMethodOnClass = classIndex != Constants.kInvalidIndex;

                // If the lhs is an variable which happens to have a same name
                // as some class, then check the right hand side is a valid 
                // constructor or static function call. 
                if (toResolveMethodOnClass && hasAllocated && isAccessible)
                {
                    var classes = core.ClassTable.ClassNodes;
                    var classNode = classes[classIndex];
                    int argCount = dotCall.FunctionCall.FormalArguments.Count;
                    var procNode = classNode.GetFirstConstructorBy(procName, argCount);
                    if (procNode == null)
                    {
                        procNode = classNode.GetFirstStaticFunctionBy(procName, argCount);
                    }

                    if (procNode == null)
                    {
                        toResolveMethodOnClass = false;
                        classIndex = Constants.kInvalidIndex;
                        className = string.Empty;
                    }
                }

                if (toResolveMethodOnClass)
                {
                    dotCall.DotCall.FormalArguments[0] = new IntNode(classIndex);
                    inferedType.UID = dotCallType.UID = classIndex;

                    // Now the left hand side of dot call is a valid class name.
                    // There are three cases for the right hand side: calling a 
                    // function, getting a static property or getting a function 
                    // pointer. I.e.,
                    // 
                    //    x = Foo.foo();
                    //
                    // Or
                    //    
                    //    y = Bar.bar;   // static property or funciton pointer
                    //    Bar.bar_2 = z; // static property
                    // 
                    // For the latters, they are converted to getter/setter. 
                    // I.e., 
                    //
                    //    y = Bar.%get_bar();
                    //    %ret = Bar.%set_bar_2(z);
                    //
                    // We need to check each case. 

                    var classes = core.ClassTable.ClassNodes;
                    var classNode = classes[classIndex];

                    var property = String.Empty;
                    if (CoreUtils.TryGetPropertyName(procName, out property))
                    {
                        if (procCallNode == null)
                        {
                            procCallNode = classNode.GetFirstStaticFunctionBy(procName);
                            isStaticCall = procCallNode != null;
                        }

                        if (procCallNode == null)
                        {
                            if (subPass != ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone)
                            {
                                return null;
                            }

                            // Try static function firstly
                            procCallNode = classNode.GetFirstStaticFunctionBy(property);
                            if (procCallNode == null)
                            {
                                procCallNode = classNode.GetFirstMemberFunctionBy(property);
                            }

                            if (procCallNode == null)
                            {
                                procCallNode = classNode.GetFirstMemberFunctionBy(procName);
                            }

                            if (procCallNode != null)
                            {
                                EmitFunctionPointer(procCallNode);
                            }
                            else
                            {
                                string message = String.Format(ProtoCore.Properties.Resources.kCallingNonStaticProperty,
                                                               className,
                                                               property);

                                buildStatus.LogWarning(WarningID.kCallingNonStaticMethodOnClass,
                                                       message,
                                                       core.CurrentDSFileName,
                                                       dotCall.line,
                                                       dotCall.col, 
                                                       graphNode);

                                EmitNullNode(new NullNode(), ref inferedType);
                            }
                            
                            return null;
                        }
                    }
                    else
                    {
                        int argCount = dotCall.FunctionCall.FormalArguments.Count;
                        procCallNode = classNode.GetFirstConstructorBy(procName, argCount);
                        isConstructor = procCallNode != null;

                        if (procCallNode == null)
                        {
                            procCallNode = classNode.GetFirstStaticFunctionBy(procName, argCount);
                            isStaticCall = procCallNode != null;
                        }

                        if (!isStaticCall && !isConstructor)
                        {
                            if (subPass == ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone)
                            {
                                string message = String.Format(ProtoCore.Properties.Resources.kStaticMethodNotFound,
                                                               className,
                                                               procName);

                                buildStatus.LogWarning(WarningID.kFunctionNotFound,
                                                       message,
                                                       core.CurrentDSFileName,
                                                       dotCall.line,
                                                       dotCall.col, 
                                                       graphNode);

                                EmitNullNode(new NullNode(), ref inferedType);
                            }

                            return null;
                        }
                    }
                }
                else if (hasAllocated && symbolnode.datatype.UID != (int)PrimitiveType.kTypeVar)
                {
                    inferedType.UID = symbolnode.datatype.UID;
                    if (Constants.kInvalidIndex != inferedType.UID)
                    {
                        procCallNode = GetProcedureFromInstance(symbolnode.datatype.UID, dotCall.FunctionCall);
                    }

                    if (null != procCallNode)
                    {
                        if (procCallNode.IsConstructor)
                        {
                            if (subPass == ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone)
                            {
                                string message = String.Format(ProtoCore.Properties.Resources.KCallingConstructorOnInstance,
                                                               procName);
                                buildStatus.LogWarning(WarningID.kCallingConstructorOnInstance,
                                                       message,
                                                       core.CurrentDSFileName,
                                                       funcCall.line,
                                                       funcCall.col, 
                                                       graphNode);
                                EmitNullNode(new NullNode(), ref inferedType);
                            }
                            return null;
                        }

                        isAccessible = procCallNode.AccessModifier == ProtoCore.CompilerDefinitions.AccessModifier.kPublic
                             || (procCallNode.AccessModifier == ProtoCore.CompilerDefinitions.AccessModifier.kPrivate && procCallNode.ClassID == globalClassIndex);

                        if (!isAccessible)
                        {
                            if (subPass == ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone)
                            {
                                string message = String.Format(ProtoCore.Properties.Resources.kMethodIsInaccessible, procName);
                                buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kAccessViolation, message, core.CurrentDSFileName, funcCall.line, funcCall.col, graphNode);
                            }
                        }

                        var dynamicRhsIndex = (int)(dotCall.DotCall.FormalArguments[1] as IntNode).Value;
                        var dynFunc = core.DynamicFunctionTable.GetFunctionAtIndex(dynamicRhsIndex);
                        dynFunc.ClassIndex = procCallNode.ClassID;
                    }
                }
                else
                {
                    isUnresolvedDot = true;
                }
            }

            // Its an accceptable method at this point
            List<ProtoCore.Type> arglist = new List<ProtoCore.Type>();
            TraverseDotCallArguments(funcCall, 
                                     dotCall,
                                     procCallNode, 
                                     arglist,
                                     procName, 
                                     classIndex, 
                                     className, 
                                     isStaticCall, 
                                     isConstructor,
                                     graphNode, 
                                     subPass, 
                                     bnode);

            if (subPass == ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier)
            {
                return null;
            }

            if (!isConstructor && !isStaticCall)
            {
                Validity.Assert(dotCall.DotCall.FormalArguments[ProtoCore.DSASM.Constants.kDotArgIndexArrayArgs] is ExprListNode);
                ExprListNode functionArgs = dotCall.DotCall.FormalArguments[ProtoCore.DSASM.Constants.kDotArgIndexArrayArgs] as ExprListNode;
                functionArgs.Exprs.Insert(0, dotCall.DotCall.FormalArguments[ProtoCore.DSASM.Constants.kDotArgIndexPtr]);
            }
           
            // From here on, handle the actual procedure call 
            int type = ProtoCore.DSASM.Constants.kInvalidIndex;

            int refClassIndex = ProtoCore.DSASM.Constants.kInvalidIndex;
            if (parentNode != null && parentNode is IdentifierListNode)
            {
                var leftnode = (parentNode as IdentifierListNode).LeftNode;
                if (leftnode != null && leftnode is IdentifierNode)
                {
                    refClassIndex = core.ClassTable.IndexOf(leftnode.Name);
                }
            }

            if (firstArgument is FunctionCallNode ||
                firstArgument is FunctionDotCallNode ||
                firstArgument is ExprListNode)
            {
                inferedType.UID = arglist[0].UID;
            }

            // If lefttype is a valid class then check if calling a constructor
            if (procCallNode == null 
                && (int)PrimitiveType.kInvalidType != inferedType.UID
                && (int)PrimitiveType.kTypeVoid != inferedType.UID
                && procName != Constants.kFunctionPointerCall)
            {
                procCallNode = core.ClassTable.ClassNodes[inferedType.UID].GetFirstMemberFunctionBy(procName);
            }

            // Try function pointer firstly
            if ((procCallNode == null) && (procName != Constants.kFunctionPointerCall))
            {
                bool isAccessibleFp;
                ProtoCore.DSASM.SymbolNode symbolnode = null;
                bool isAllocated = VerifyAllocation(procName, globalClassIndex, globalProcIndex, out symbolnode, out isAccessibleFp);
                if (isAllocated) // not checking the type against function pointer, as the type could be var
                {
                    procName = Constants.kFunctionPointerCall;
                    // The graph node always depends on this function pointer
                    if (null != graphNode)
                    {
                        PushSymbolAsDependent(symbolnode, graphNode);
                    }
                }
            }

            // Always try global function firstly. Because we dont have syntax
            // support for calling global function (say, ::foo()), if we try
            // member function firstly, there is no way to call a global function
            // For member function, we can use this.foo() to distinguish it from 
            // global function. 
            if ((procCallNode == null) && (procName != Constants.kFunctionPointerCall))
            {
                procCallNode = CoreUtils.GetFunctionBySignature(procName, arglist, codeBlock);
                if (null != procCallNode)
                {
                    type = Constants.kGlobalScope;
                    if (core.TypeSystem.IsHigherRank(procCallNode.ReturnType.UID, inferedType.UID))
                    {
                        inferedType = procCallNode.ReturnType;
                    }
                }
            }

            // Try member functions in global class scope
            if ((procCallNode == null) && (procName != Constants.kFunctionPointerCall) && (parentNode == null))
            {
                if (globalClassIndex != Constants.kInvalidIndex)
                {
                    int realType;
                    bool isAccessible;
                    bool isStaticOrConstructor = refClassIndex != Constants.kInvalidIndex;
                    ProcedureNode memProcNode = core.ClassTable.ClassNodes[globalClassIndex].GetMemberFunction(procName, arglist, globalClassIndex, out isAccessible, out realType, isStaticOrConstructor);

                    if (memProcNode != null)
                    {
                        Validity.Assert(realType != Constants.kInvalidIndex);
                        procCallNode = memProcNode;
                        inferedType = procCallNode.ReturnType;
                        type = realType;

                        if (!isAccessible)
                        {
                            string message = String.Format(ProtoCore.Properties.Resources.kMethodIsInaccessible, procName);
                            buildStatus.LogWarning(WarningID.kAccessViolation, message, core.CurrentDSFileName, funcCall.line, funcCall.col, graphNode);

                            inferedType.UID = (int)PrimitiveType.kTypeNull;
                            EmitPushNull();
                            return procCallNode;
                        }
                    }
                }
            }

            if (isUnresolvedDot || procCallNode == null)
            {
                if (dotCallType.UID != (int)PrimitiveType.kTypeVar)
                {
                    inferedType.UID = dotCallType.UID;
                }

                var procNode = CoreUtils.GetFunctionByName(Constants.kDotMethodName, codeBlock);
                if (CoreUtils.IsGetter(procName))
                {
                    EmitFunctionCall(depth, type, arglist, procNode, funcCall, true);
                }
                else
                {
                    EmitFunctionCall(depth, type, arglist, procNode, funcCall, false, bnode);
                }
                return procNode;
            }
            else
            {
                if (procCallNode.IsConstructor &&
                    (globalClassIndex != Constants.kInvalidIndex) &&
                    (globalProcIndex != Constants.kInvalidIndex) &&
                    (globalClassIndex == inferedType.UID))
                {
                    ProcedureNode contextProcNode = core.ClassTable.ClassNodes[globalClassIndex].ProcTable.Procedures[globalProcIndex];
                    if (contextProcNode.IsConstructor &&
                        string.Equals(contextProcNode.Name, procCallNode.Name) &&
                        contextProcNode.RuntimeIndex == procCallNode.RuntimeIndex)
                    {
                        string message = String.Format(ProtoCore.Properties.Resources.kCallingConstructorInConstructor, procName);
                        buildStatus.LogWarning(WarningID.kCallingConstructorInConstructor, message, core.CurrentDSFileName, node.line, node.col, graphNode);
                        inferedType.UID = (int)PrimitiveType.kTypeNull;
                        EmitPushNull();
                        return procCallNode;
                    }
                }

                inferedType = procCallNode.ReturnType;

                // Get the dot call procedure
                if (isConstructor || isStaticCall)
                {
                    bool isGetter = CoreUtils.IsGetter(procName);
                    EmitFunctionCall(depth, procCallNode.ClassID, arglist, procCallNode, funcCall, isGetter, bnode);
                }
                else
                {
                    var procNode = CoreUtils.GetFunctionByName(Constants.kDotMethodName, codeBlock);
                    if (CoreUtils.IsSetter(procName))
                    {
                        EmitFunctionCall(depth, type, arglist, procNode, funcCall);
                    }
                    // Do not emit breakpoint at getters only - pratapa
                    else if (CoreUtils.IsGetter(procName))
                    {
                        EmitFunctionCall(depth, type, arglist, procNode, funcCall, true);
                    }
                    else
                    {
                        EmitFunctionCall(depth, type, arglist, procNode, funcCall, false, bnode);
                    }

                    if (dotCallType.UID != (int)PrimitiveType.kTypeVar)
                    {
                        inferedType.UID = dotCallType.UID;
                    }
                }

                if (isConstructor)
                {
                    foreach (AssociativeNode paramNode in dotCall.FunctionCall.FormalArguments)
                    {
                        // Get the lhs symbol list
                        ProtoCore.Type ltype = new ProtoCore.Type();
                        ltype.UID = globalClassIndex;
                        UpdateNodeRef argNodeRef = new UpdateNodeRef();
                        DFSGetSymbolList(paramNode, ref ltype, argNodeRef);

                        if (null != graphNode)
                        {
                            if (argNodeRef.nodeList.Count > 0)
                            {
                                graphNode.updatedArguments.Add(argNodeRef);
                            }
                        }
                    }

                    graphNode.firstProc = procCallNode;
                }
                
                return procCallNode;
            }
        }
Esempio n. 20
0
        //
        //  proc ResolveFinalNodeRefs()
        //      foreach graphnode in graphnodeList
        //          def firstproc = graphnode.firstproc
        //          // Auto-generate the updateNodeRefs for this graphnode given the 
        //          // list stored in the first procedure found in the assignment expression
        //          foreach noderef in firstProc.updatedProperties	
        //              def n = graphnode.firstProcRefIndex
        //              def autogenRef = updateNodeRef[n]
        //              autogenRef.append(noderef)
        //              graphnode.pushUpdateRef(autogenRef)
        //          end
        //      end
        //  end
        //
        private void ResolveFinalNodeRefs()
        {
            foreach (ProtoCore.AssociativeGraph.GraphNode graphNode in codeBlock.instrStream.dependencyGraph.GraphList)
            {
                ProtoCore.DSASM.ProcedureNode firstProc = graphNode.firstProc;
                if (null == firstProc || firstProc.IsAutoGenerated)
                {
                    continue;
                }

                // TODO: The following implementation is wrong.
                // Suppose for function call: x = foo().bar(); which converted
                // to x = %dot(foo(), bar(), ...); the following checking skips
                // it because %dot() is an internal function. -Yu Ke

                // Do this only for non auto-generated function calls 
                //if any local var is depend on global var
                if (core.Options.localDependsOnGlobalSet)
                {
                    if (!firstProc.Name.ToCharArray()[0].Equals('_') && !firstProc.Name.ToCharArray()[0].Equals('%'))
                    {
                        //for each node
                        foreach (ProtoCore.AssociativeGraph.GraphNode gNode in codeBlock.instrStream.dependencyGraph.GraphList)
                        {
                            if (gNode.updateNodeRefList != null && gNode.updateNodeRefList.Count != 0)
                            {
                                if (gNode.procIndex == firstProc.ID && !gNode.updateNodeRefList[0].nodeList[0].symbol.name.ToCharArray()[0].Equals('%'))
                                {
                                    foreach (ProtoCore.AssociativeGraph.GraphNode dNode in gNode.dependentList)
                                    {
                                        if (dNode.procIndex == ProtoCore.DSASM.Constants.kGlobalScope)
                                        {
                                            if (!dNode.updateNodeRefList[0].nodeList[0].symbol.name.ToCharArray()[0].Equals('%'))
                                            {
                                                graphNode.PushDependent(dNode);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                if (firstProc.ClassID == Constants.kGlobalScope)
                {
                    graphNode.updateNodeRefList.AddRange(firstProc.UpdatedGlobalVariables);
                }
                else
                {
                    // For each property modified
                    foreach (ProtoCore.AssociativeGraph.UpdateNodeRef updateRef in firstProc.UpdatedProperties)
                    {
                        int index = graphNode.firstProcRefIndex;

                        // Is it a global function
                        if (ProtoCore.DSASM.Constants.kInvalidIndex != index)
                        {
                            if (core.Options.GenerateSSA)
                            {
                                foreach (ProtoCore.AssociativeGraph.GraphNode dependent in graphNode.dependentList)
                                {
                                    // Do this only if first proc is a member function...
                                    ProtoCore.AssociativeGraph.UpdateNodeRef autogenRef = new ProtoCore.AssociativeGraph.UpdateNodeRef(dependent.updateNodeRefList[0]);
                                    autogenRef = autogenRef.GetUntilFirstProc();

                                    // ... and the first symbol is an instance of a user-defined type
                                    int last = autogenRef.nodeList.Count - 1;
                                    Validity.Assert(autogenRef.nodeList[last].nodeType != ProtoCore.AssociativeGraph.UpdateNodeType.kMethod && null != autogenRef.nodeList[last].symbol);
                                    if (autogenRef.nodeList[last].symbol.datatype.UID >= (int)PrimitiveType.kMaxPrimitives)
                                    {
                                        autogenRef.PushUpdateNodeRef(updateRef);
                                        graphNode.updateNodeRefList.Add(autogenRef);

                                        if (graphNode.lastGraphNode != null)
                                        {
                                            graphNode.lastGraphNode.updateNodeRefList.Add(autogenRef);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                // Do this only if first proc is a member function...
                                ProtoCore.AssociativeGraph.UpdateNodeRef autogenRef = new ProtoCore.AssociativeGraph.UpdateNodeRef(graphNode.dependentList[0].updateNodeRefList[0]);
                                autogenRef = autogenRef.GetUntilFirstProc();

                                // ... and the first symbol is an instance of a user-defined type
                                int last = autogenRef.nodeList.Count - 1;
                                Validity.Assert(autogenRef.nodeList[last].nodeType != ProtoCore.AssociativeGraph.UpdateNodeType.kMethod && null != autogenRef.nodeList[last].symbol);
                                if (autogenRef.nodeList[last].symbol.datatype.UID >= (int)PrimitiveType.kMaxPrimitives)
                                {
                                    autogenRef.PushUpdateNodeRef(updateRef);
                                    graphNode.updateNodeRefList.Add(autogenRef);
                                }
                            }
                        }
                    }
                }

                if (graphNode.updatedArguments.Count > 0)
                {
                    // For each argument modified
                    int n = 0;

                    // Create the current modified argument
                    foreach (KeyValuePair<string, List<ProtoCore.AssociativeGraph.UpdateNodeRef>> argNameModifiedStatementsPair in firstProc.UpdatedArgumentProperties)
                    {
                        // For every single arguments' modified statements
                        foreach (ProtoCore.AssociativeGraph.UpdateNodeRef nodeRef in argNameModifiedStatementsPair.Value)
                        {
                            if (core.Options.GenerateSSA)
                            {
                                //
                                // We just trigger update from whichever statement is dependent on the first pointer associatied with this SSA stmt
                                // Given:
                                //      p = C.C();
                                //      a = p.x;
                                //      i = f(p);
                                //
                                //      %t0 = C.C()
                                //      p = %t0
                                //      %t1 = p
                                //      %t2 = %t1.x
                                //      a = %t2
                                //      %t3 = p
                                //      %t4 = f(%t3)    -> Assume that function 'f' modifies the property 'x' of its argument
                                //                      -> The graph node of this stmt has 2 updatenoderefs 
                                //                      ->  there are %t4 and p ('p' because it is the first pointer of %t3
                                //      i = %t4
                                //
                                
                                // Get the modified property name 
                                string argname = graphNode.updatedArguments[n].nodeList[0].symbol.name;
                                if (ProtoCore.Utils.CoreUtils.IsSSATemp(argname) && ssaTempToFirstPointerMap.ContainsKey(argname))
                                {
                                    // The property is an SSA temp, Get the SSA first pointer associated with this temp
                                    argname = ssaTempToFirstPointerMap[argname];
                                }

                                bool isAccessible = false;
                                SymbolNode symbol = null;
                                bool isAllocated = VerifyAllocation(argname, globalClassIndex, globalProcIndex, out symbol, out isAccessible);
                                if (isAllocated)
                                {
                                    ProtoCore.AssociativeGraph.UpdateNode updateNode = new UpdateNode();
                                    updateNode.symbol = symbol;
                                    updateNode.nodeType = ProtoCore.AssociativeGraph.UpdateNodeType.kSymbol;

                                    ProtoCore.AssociativeGraph.UpdateNodeRef argNodeRef = new ProtoCore.AssociativeGraph.UpdateNodeRef();
                                    argNodeRef.PushUpdateNode(updateNode);
                                    graphNode.updateNodeRefList.Add(argNodeRef);
                                }
                                
                            }
                            else
                            {
                                ProtoCore.AssociativeGraph.UpdateNodeRef argNodeRef = new ProtoCore.AssociativeGraph.UpdateNodeRef();
                                argNodeRef.PushUpdateNodeRef(graphNode.updatedArguments[n]);
                                argNodeRef.PushUpdateNodeRef(nodeRef);
                                graphNode.updateNodeRefList.Add(argNodeRef);
                            }
                        }
                        ++n;
                    }
                }
            }
        }
Esempio n. 21
0
        public ProtoCore.DSASM.ProcedureNode TraverseDotFunctionCall(ProtoCore.AST.Node node, ProtoCore.AST.Node parentNode, int lefttype, int depth, ref ProtoCore.Type inferedType, 
            ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone,
            ProtoCore.AST.AssociativeAST.BinaryExpressionNode bnode = null)
        {
            FunctionCallNode funcCall = null;
            ProtoCore.DSASM.ProcedureNode procCallNode = null;
            ProtoCore.DSASM.ProcedureNode procDotCallNode = null;
            string procName = null;
            List<ProtoCore.Type> arglist = new List<ProtoCore.Type>();
            ProtoCore.Type dotCallType = new ProtoCore.Type();
            dotCallType.UID = (int)PrimitiveType.kTypeVar;
            dotCallType.IsIndexable = false;

            bool isConstructor = false;
            bool isStaticCall = false;
            bool isStaticCallAllowed = false;
            bool isUnresolvedDot = false;
            bool isUnresolvedMethod = false;

            int classIndex = ProtoCore.DSASM.Constants.kInvalidIndex;
            string className = string.Empty;

            ProtoCore.AST.AssociativeAST.FunctionDotCallNode dotCall = node as ProtoCore.AST.AssociativeAST.FunctionDotCallNode;
            funcCall = dotCall.DotCall;
            procName = dotCall.FunctionCall.Function.Name;

            List<AssociativeNode> replicationGuide = (dotCall.FunctionCall.Function as IdentifierNode).ReplicationGuides;

            var dotCallFirstArgument = dotCall.DotCall.FormalArguments[0];
            if (dotCallFirstArgument is FunctionDotCallNode)
            {
                isUnresolvedDot = true;
            }
            else if (dotCallFirstArgument is IdentifierNode || dotCallFirstArgument is ThisPointerNode)
            {
                // Check if the lhs identifer is a class name
                string lhsName = "";
                int ci = Constants.kInvalidIndex;

                if (dotCallFirstArgument is IdentifierNode)
                {
                    lhsName = (dotCallFirstArgument as IdentifierNode).Name;
                    ci = compileStateTracker.ClassTable.IndexOf(lhsName);
                    classIndex = ci;
                    className = lhsName;

                    // As a class name can be used as property name, we need to
                    // check if this identifier is a property or a class name.
                    //
                    if (ci != Constants.kInvalidIndex && globalClassIndex != Constants.kInvalidIndex)
                    {
                        ProtoCore.DSASM.SymbolNode symbolnode;
                        bool isAccessbile = false;
                        bool hasAllocated = VerifyAllocation(lhsName, globalClassIndex, globalProcIndex, out symbolnode, out isAccessbile);

                        // Well, found a property whose name is class name. Now
                        // we need to check if the RHS function call is
                        // constructor or not.
                        if (hasAllocated && isAccessbile && symbolnode.functionIndex == ProtoCore.DSASM.Constants.kInvalidIndex)
                        {
                            var procnode = GetProcedureFromInstance(ci, dotCall.FunctionCall);
                            if (procnode != null && !procnode.isConstructor)
                            {
                                ci = Constants.kInvalidIndex;
                                lhsName = "";
                            }
                        }
                    }
                }

                if (ci != ProtoCore.DSASM.Constants.kInvalidIndex)
                {
                    // It is a class name
                    dotCall.DotCall.FormalArguments[0] = new IntNode { value = ci.ToString() };
                    dotCallFirstArgument = dotCall.DotCall.FormalArguments[0];

                    inferedType.UID = dotCallType.UID = ci;

                    string rhsName = dotCall.FunctionCall.Function.Name;
                    procCallNode = GetProcedureFromInstance(ci, dotCall.FunctionCall, graphNode);
                    if (null != procCallNode)
                    {
                        isConstructor = procCallNode.isConstructor;

                        // It's a static call if its not a constructor
                        isStaticCall = !procCallNode.isConstructor;

                        // If this is a static call and the first method found was not static
                        // Look further
                        if (isStaticCall && !procCallNode.isStatic)
                        {
                            ProtoCore.DSASM.ProcedureNode staticProcCallNode = compileStateTracker.ClassTable.ClassNodes[ci].GetFirstStaticMemberFunction(procName);
                            if (null != staticProcCallNode)
                            {
                                procCallNode = staticProcCallNode;
                            }
                        }

                        isStaticCallAllowed = procCallNode.isStatic && isStaticCall;
                    }
                    else
                    {
                        ProtoCore.DSASM.ProcedureNode staticProcCallNode = compileStateTracker.ClassTable.ClassNodes[ci].GetFirstStaticMemberFunction(procName);
                        string functionName = dotCall.FunctionCall.Function.Name;
                        string property;

                        if (null != staticProcCallNode)
                        {
                            string message = String.Format(ProtoCore.BuildData.WarningMessage.kMethodHasInvalidArguments, functionName);
                            buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kCallingNonStaticMethodOnClass, message, compileStateTracker.CurrentDSFileName, dotCall.line, dotCall.col);
                        }
                        else if (CoreUtils.TryGetPropertyName(functionName, out property))
                        {
                            string message = String.Format(ProtoCore.BuildData.WarningMessage.kCallingNonStaticProperty, lhsName, property);
                            buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kCallingNonStaticMethodOnClass, message, compileStateTracker.CurrentDSFileName, dotCall.line, dotCall.col);
                        }
                        else
                        {
                            string message = String.Format(ProtoCore.BuildData.WarningMessage.kCallingNonStaticMethod, lhsName, functionName);
                            buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kCallingNonStaticMethodOnClass, message, compileStateTracker.CurrentDSFileName, dotCall.line, dotCall.col);
                        }
                    }
                }

                if (dotCall.DotCall.FormalArguments.Count == ProtoCore.DSASM.Constants.kDotCallArgCount)
                {
                    if (dotCallFirstArgument is IdentifierNode)
                    {
                        ProtoCore.DSASM.SymbolNode symbolnode = null;
                        bool isAccessible = false;
                        bool isAllocated = VerifyAllocation((dotCallFirstArgument as IdentifierNode).Name, globalClassIndex, globalProcIndex, out symbolnode, out isAccessible);
                        if (isAllocated && symbolnode.datatype.UID != (int)PrimitiveType.kTypeVar)
                        {
                            inferedType.UID = symbolnode.datatype.UID;

                            if (ProtoCore.DSASM.Constants.kInvalidIndex != inferedType.UID)
                            {
                                procCallNode = GetProcedureFromInstance(symbolnode.datatype.UID, dotCall.FunctionCall);
                            }

                            if (null != procCallNode)
                            {
                                if (procCallNode.isConstructor)
                                {
                                    if (subPass != ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier)
                                    {
                                        // A constructor cannot be called from an instance
                                        string message = String.Format(ProtoCore.BuildData.WarningMessage.KCallingConstructorOnInstance, procName);
                                        buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kCallingConstructorOnInstance, message, compileStateTracker.CurrentDSFileName, funcCall.line, funcCall.col);
                                    }

                                    isUnresolvedDot = true;
                                    isUnresolvedMethod = true;
                                }
                                else
                                {
                                   isAccessible =
                                       procCallNode.access == ProtoCore.DSASM.AccessSpecifier.kPublic
                                        || (procCallNode.access == ProtoCore.DSASM.AccessSpecifier.kPrivate && procCallNode.classScope == globalClassIndex);

                                    if (!isAccessible)
                                    {
                                        if (subPass != ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier)
                                        {
                                            string message = String.Format(ProtoCore.BuildData.WarningMessage.kMethodIsInaccessible, procName);
                                            buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kAccessViolation, message, compileStateTracker.CurrentDSFileName, funcCall.line, funcCall.col);
                                        }
                                    }

                                    if (null != procCallNode)
                                    {
                                        int dynamicRhsIndex = int.Parse((dotCall.DotCall.FormalArguments[1] as IntNode).value);
                                        compileStateTracker.DynamicFunctionTable.functionTable[dynamicRhsIndex].classIndex = procCallNode.classScope;
                                        compileStateTracker.DynamicFunctionTable.functionTable[dynamicRhsIndex].procedureIndex = procCallNode.procId;
                                        compileStateTracker.DynamicFunctionTable.functionTable[dynamicRhsIndex].pc = procCallNode.pc;
                                    }
                                }
                            }
                        }
                        else
                        {
                            isUnresolvedDot = true;
                        }
                    }
                    else if (dotCallFirstArgument is ThisPointerNode)
                    {
                        if (globalClassIndex != Constants.kInvalidIndex)
                        {
                            procCallNode = GetProcedureFromInstance(globalClassIndex, dotCall.FunctionCall);
                            if (null != procCallNode && procCallNode.isConstructor)
                            {
                                dotCall.DotCall.FormalArguments[0] = new IntNode { value = globalClassIndex.ToString() };
                                dotCallFirstArgument = dotCall.DotCall.FormalArguments[0];
                                inferedType.UID = dotCallType.UID = ci;
                            }
                        }
                    }
                }
            }
            else if (funcCall.FormalArguments[0] is IntNode)
            {
                inferedType.UID = dotCallType.UID = int.Parse((funcCall.FormalArguments[0] as IntNode).value);
                classIndex = inferedType.UID;
                procCallNode = GetProcedureFromInstance(dotCallType.UID, dotCall.FunctionCall, graphNode);

                if (null != procCallNode)
                {
                    // It's a static call if its not a constructor
                    isConstructor = procCallNode.isConstructor;
                    isStaticCall = !procCallNode.isConstructor;

                    // If this is a static call and the first method found was not static
                    // Look further
                    if (isStaticCall && !procCallNode.isStatic)
                    {
                        ProtoCore.DSASM.ProcedureNode staticProcCallNode = compileStateTracker.ClassTable.ClassNodes[inferedType.UID].GetFirstStaticMemberFunction(procName);
                        if (null != staticProcCallNode)
                        {
                            procCallNode = staticProcCallNode;
                        }
                    }

                    isStaticCallAllowed = procCallNode.isStatic && isStaticCall;
                    className = compileStateTracker.ClassTable.ClassNodes[dotCallType.UID].name;

                    if (isStaticCall && !isStaticCallAllowed)
                    {
                        if (subPass != ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier)
                        {
                            string property;
                            className = compileStateTracker.ClassTable.ClassNodes[dotCallType.UID].name;
                            ProtoCore.DSASM.ProcedureNode staticProcCallNode = compileStateTracker.ClassTable.ClassNodes[inferedType.UID].GetFirstStaticMemberFunction(procName);

                            if (null != staticProcCallNode)
                            {
                                string message = String.Format(ProtoCore.BuildData.WarningMessage.kMethodHasInvalidArguments, procName);
                                buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kCallingNonStaticMethodOnClass, message, compileStateTracker.CurrentDSFileName, dotCall.line, dotCall.col);
                            }
                            else if (CoreUtils.TryGetPropertyName(procName, out property))
                            {
                                string message = String.Format(ProtoCore.BuildData.WarningMessage.kCallingNonStaticProperty, property, className);
                                buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kCallingNonStaticMethodOnClass, message, compileStateTracker.CurrentDSFileName, dotCall.line, dotCall.col);
                            }
                            else
                            {
                                string message = String.Format(ProtoCore.BuildData.WarningMessage.kCallingNonStaticMethod, procName, className);
                                buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kCallingNonStaticMethodOnClass, message, compileStateTracker.CurrentDSFileName, dotCall.line, dotCall.col);
                            }
                        }
                        isUnresolvedMethod = true;
                    }
                    else
                    {
                        inferedType = procCallNode.returntype;
                    }
                }
            }

            // Its an accceptable method at this point
            if (!isUnresolvedMethod)
            {
                int funtionArgCount = 0;

                //foreach (AssociativeNode paramNode in funcCall.FormalArguments)
                for (int n = 0; n < funcCall.FormalArguments.Count; ++n)
                {
                    AssociativeNode paramNode = funcCall.FormalArguments[n];
                    ProtoCore.Type paramType = new ProtoCore.Type();
                    paramType.UID = (int)ProtoCore.PrimitiveType.kTypeVoid;
                    paramType.IsIndexable = false;

                    emitReplicationGuide = false;

                    // If it's a binary node then continue type check, otherwise disable type check and just take the type of paramNode itself
                    // f(1+2.0) -> type check enabled - param is typed as double
                    // f(2) -> type check disabled - param is typed as int
                    enforceTypeCheck = !(paramNode is BinaryExpressionNode);

                    // TODO Jun: Cleansify me
                    // What im doing is just taking the second parameter of the dot op (The method call)
                    // ...and adding it to the graph node dependencies
                    if (ProtoCore.DSASM.Constants.kDotArgIndexDynTableIndex == n)
                    {
                        if (subPass != ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier)
                        {
                            if (!isConstructor)
                            {
                                if (null != procCallNode)
                                {
                                    if (graphNode.dependentList.Count > 0)
                                    {
                                        ProtoCore.AssociativeGraph.UpdateNodeRef nodeRef = new ProtoCore.AssociativeGraph.UpdateNodeRef();
                                        ProtoCore.AssociativeGraph.UpdateNode updateNode = new ProtoCore.AssociativeGraph.UpdateNode();
                                        ProtoCore.DSASM.ProcedureNode procNodeDummy = new ProtoCore.DSASM.ProcedureNode();
                                        if (procCallNode.isAutoGenerated)
                                        {
                                            ProtoCore.DSASM.SymbolNode sym = new ProtoCore.DSASM.SymbolNode();
                                            sym.name = procName.Remove(0, ProtoCore.DSASM.Constants.kSetterPrefix.Length);
                                            updateNode.nodeType = ProtoCore.AssociativeGraph.UpdateNodeType.kSymbol;
                                            updateNode.symbol = sym;
                                        }
                                        else
                                        {
                                            procNodeDummy.name = procName;
                                            updateNode.nodeType = ProtoCore.AssociativeGraph.UpdateNodeType.kMethod;
                                            updateNode.procNode = procNodeDummy;
                                        }
                                        graphNode.dependentList[0].updateNodeRefList[0].nodeList.Add(updateNode);
                                    }
                                }
                                else
                                {
                                    // comment Jun:
                                    // This is dotarg whos first argument is also a dotarg
                                    // dotarg(dorarg...)...)
                                    if (graphNode.dependentList.Count > 0)
                                    {
                                        if (ProtoCore.Utils.CoreUtils.IsGetterSetter(procName))
                                        {
                                            ProtoCore.AssociativeGraph.UpdateNode updateNode = new ProtoCore.AssociativeGraph.UpdateNode();
                                            ProtoCore.DSASM.SymbolNode sym = new ProtoCore.DSASM.SymbolNode();
                                            sym.name = procName.Remove(0, ProtoCore.DSASM.Constants.kSetterPrefix.Length);
                                            updateNode.nodeType = ProtoCore.AssociativeGraph.UpdateNodeType.kSymbol;
                                            updateNode.symbol = sym;

                                            graphNode.dependentList[0].updateNodeRefList[0].nodeList.Add(updateNode);
                                        }
                                    }
                                }
                            }
                        }
                    }

                    // Traversing the first arg (the LHS pointer/Static instanct/Constructor
                    if (ProtoCore.DSASM.Constants.kDotArgIndexPtr == n)
                    {
                        // Comment Jun:
                        //      Allow guides only on 'this' pointers for non getter/setter methods
                        //      No guides for 'this' pointers in constructors calls (There is no this pointer yet)
                        //
                        /*
                            class C
                            {
                                def f(a : int)
                                {
                                    return = 10;
                                }
                            }
                            p = {C.C(), C.C()};
                            x = p<1>.f({1,2}<2>); // guides allowed on the pointer 'p'

                            class A
                            {
                                x : var[];
                                constructor A()
                                {
                                    x = {1,2};
                                }
                            }
                            a = A.A();
                            b = A.A();
                            c = a<1>.x<2>; // guides not allowed on getter

                         */
                        if (!ProtoCore.Utils.CoreUtils.IsGetterSetter(procName) && !isConstructor)
                        {
                            emitReplicationGuide = true;
                        }

                        DfsTraverse(paramNode, ref paramType, false, graphNode, subPass, bnode);
                        if (subPass != ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier)
                        {
                            if (isStaticCall && isStaticCallAllowed)
                            {
                                Validity.Assert(ProtoCore.DSASM.Constants.kInvalidIndex != classIndex);
                                Validity.Assert(string.Empty != className);
                                SymbolNode classSymbol = new SymbolNode();
                                classSymbol.name = className;
                                classSymbol.classScope = classIndex;

                                ProtoCore.AssociativeGraph.GraphNode dependentNode = new ProtoCore.AssociativeGraph.GraphNode();
                                dependentNode.PushSymbolReference(classSymbol, ProtoCore.AssociativeGraph.UpdateNodeType.kSymbol);
                                graphNode.PushDependent(dependentNode);
                            }
                        }
                    }

                    // Traversing the actual arguments passed into the function (not the dot function)
                    else if (ProtoCore.DSASM.Constants.kDotArgIndexArrayArgs == n)
                    {
                        int defaultAdded = 0;

                        // If its null this is the second call in a chained dot
                        if (null != procCallNode)
                        {
                            // Check how many args were passed in.... against what is expected
                            defaultAdded = procCallNode.argInfoList.Count - dotCall.FunctionCall.FormalArguments.Count;
                        }

                        // Enable graphnode dependencies if its a setter method
                        bool allowDependentState = null != graphNode ? graphNode.allowDependents : false;
                        if (ProtoCore.Utils.CoreUtils.IsSetter(procName))
                        {
                            // If the arguments are not temporaries
                            ProtoCore.AST.AssociativeAST.ExprListNode exprList = paramNode as ExprListNode;
                            Validity.Assert(1 == exprList.list.Count);

                            string varname = string.Empty;
                            if (exprList.list[0] is IdentifierNode)
                            {
                                varname = (exprList.list[0] as IdentifierNode).Name;

                                // Only allow the acutal function variables and SSA temp vars
                                // TODO Jun: determine what temp could be passed in that is autodegenerated and non-SSA
                                if (!ProtoCore.Utils.CoreUtils.IsAutoGeneratedVar(varname)
                                    || ProtoCore.Utils.CoreUtils.IsSSATemp(varname))
                                {
                                    graphNode.allowDependents = true;
                                }
                            }
                            else
                            {
                                graphNode.allowDependents = true;
                            }

                        }

                        emitReplicationGuide = true;

                        if (defaultAdded > 0)
                        {
                            ProtoCore.AST.AssociativeAST.ExprListNode exprList = paramNode as ExprListNode;

                            if (subPass != AssociativeSubCompilePass.kUnboundIdentifier)
                            {
                                for (int i = 0; i < defaultAdded; i++)
                                {
                                    exprList.list.Add(new DefaultArgNode());
                                }

                            }
                            DfsTraverse(paramNode, ref paramType, false, graphNode, subPass);
                            funtionArgCount = exprList.list.Count;
                        }
                        else
                        {
                            Validity.Assert(paramNode is ProtoCore.AST.AssociativeAST.ExprListNode);
                            ProtoCore.AST.AssociativeAST.ExprListNode exprList = paramNode as ProtoCore.AST.AssociativeAST.ExprListNode;

                            // Comment Jun: This is a getter/setter or a an auto-generated thisarg function...
                            // ...add the dynamic sv that will be resolved as a pointer at runtime
                            if (!isStaticCall && !isConstructor)
                            {
                                //if (null != procCallNode && ProtoCore.Utils.CoreUtils.IsGetterSetter(procCallNode.name) && AssociativeSubCompilePass.kNone == subPass)
                                // TODO Jun: pls get rid of subPass checking outside the core travesal
                                if (ProtoCore.DSASM.AssociativeSubCompilePass.kNone == subPass)
                                {
                                    exprList.list.Insert(0, new DynamicNode());
                                }
                            }

                            if (exprList.list.Count > 0)
                            {
                                foreach (ProtoCore.AST.AssociativeAST.AssociativeNode exprListNode in exprList.list)
                                {
                                    bool repGuideState = emitReplicationGuide;
                                    if (subPass != ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier)
                                    {
                                        if (exprListNode is ProtoCore.AST.AssociativeAST.ExprListNode
                                            || exprListNode is ProtoCore.AST.AssociativeAST.GroupExpressionNode)
                                        {
                                            if (compileStateTracker.Options.TempReplicationGuideEmptyFlag)
                                            {
                                                // Emit the replication guide for the exprlist
                                                List<ProtoCore.AST.AssociativeAST.AssociativeNode> repGuideList = GetReplicationGuides(exprListNode);
                                                EmitReplicationGuides(repGuideList, true);

                                                emitReplicationGuide = false;

                                                // Pop off the guide if the current element was an array
                                                if (null != repGuideList)
                                                {
                                                    EmitInstrConsole(ProtoCore.DSASM.kw.popg);
                                                    EmitPopGuide();
                                                }
                                            }
                                        }
                                    }
                                    else
                                    {
                                        emitReplicationGuide = false;
                                    }

                                    DfsTraverse(exprListNode, ref paramType, false, graphNode, subPass, bnode);
                                    emitReplicationGuide = repGuideState;
                                }

                                if (subPass != ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier)
                                {

                                    EmitInstrConsole(ProtoCore.DSASM.kw.alloca, exprList.list.Count.ToString());
                                    EmitPopArray(exprList.list.Count);

                                    if (exprList.ArrayDimensions != null)
                                    {
                                        int dimensions = DfsEmitArrayIndexHeap(exprList.ArrayDimensions, graphNode);
                                        EmitInstrConsole(ProtoCore.DSASM.kw.pushindex, dimensions.ToString() + "[dim]");
                                        EmitPushArrayIndex(dimensions);
                                    }
                                }
                            }
                            else
                            {
                                if (exprList != null)
                                {
                                    bool emitReplicationGuideState = emitReplicationGuide;
                                    emitReplicationGuide = false;
                                    DfsTraverse(paramNode, ref paramType, false, graphNode, subPass);
                                    emitReplicationGuide = emitReplicationGuideState;
                                }
                                else
                                {
                                    DfsTraverse(paramNode, ref paramType, false, graphNode, subPass);
                                }
                            }

                            funtionArgCount = exprList.list.Count;
                        }

                        emitReplicationGuide = false;

                        // Restore the state only if it is a setter method
                        if (ProtoCore.Utils.CoreUtils.IsSetter(procName))
                        {
                            graphNode.allowDependents = allowDependentState;
                        }
                    }
                    else if (ProtoCore.DSASM.Constants.kDotArgIndexArgCount == n)
                    {
                        ProtoCore.AST.AssociativeAST.IntNode argNumNode = new ProtoCore.AST.AssociativeAST.IntNode() { value = funtionArgCount.ToString() };
                        DfsTraverse(argNumNode, ref paramType, false, graphNode, subPass);
                    }
                    else
                    {
                        DfsTraverse(paramNode, ref paramType, false, graphNode, subPass);
                    }

                    emitReplicationGuide = false;
                    enforceTypeCheck = true;

                    arglist.Add(paramType);
                }
            }

            if (subPass == ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier)
            {
                return null;
            }

            // Comment Jun: Append the lhs pointer as an argument to the overloaded function
            if (!isConstructor && !isStaticCall)
            {
                Validity.Assert(dotCall.DotCall.FormalArguments[ProtoCore.DSASM.Constants.kDotArgIndexArrayArgs] is ExprListNode);
                ExprListNode functionArgs = dotCall.DotCall.FormalArguments[ProtoCore.DSASM.Constants.kDotArgIndexArrayArgs] as ExprListNode;
                functionArgs.list.Insert(0, dotCall.DotCall.FormalArguments[ProtoCore.DSASM.Constants.kDotArgIndexPtr]);
            }

            if (isUnresolvedMethod)
            {
                EmitNullNode(new NullNode(), ref inferedType);
                return null;
            }

            procDotCallNode = compileStateTracker.GetFirstVisibleProcedure(ProtoCore.DSASM.Constants.kDotArgMethodName, arglist, codeBlock);

            // From here on, handle the actual procedure call
            int type = ProtoCore.DSASM.Constants.kInvalidIndex;

            int refClassIndex = ProtoCore.DSASM.Constants.kInvalidIndex;
            if (parentNode != null && parentNode is ProtoCore.AST.AssociativeAST.IdentifierListNode)
            {
                ProtoCore.AST.Node leftnode = (parentNode as ProtoCore.AST.AssociativeAST.IdentifierListNode).LeftNode;
                if (leftnode != null && leftnode is ProtoCore.AST.AssociativeAST.IdentifierNode)
                {
                    refClassIndex = compileStateTracker.ClassTable.IndexOf(leftnode.Name);
                }
            }

            if (dotCallFirstArgument is FunctionCallNode ||
                dotCallFirstArgument is FunctionDotCallNode ||
                dotCallFirstArgument is ExprListNode)
            {
                inferedType.UID = arglist[0].UID;
            }

            // If lefttype is a valid class then check if calling a constructor
            if ((int)ProtoCore.PrimitiveType.kInvalidType != inferedType.UID
                && (int)ProtoCore.PrimitiveType.kTypeVoid != inferedType.UID
                && procName != ProtoCore.DSASM.Constants.kFunctionPointerCall)
            {
                bool isStaticOrConstructor = refClassIndex != ProtoCore.DSASM.Constants.kInvalidIndex;
                procCallNode = compileStateTracker.ClassTable.ClassNodes[inferedType.UID].GetFirstMemberFunction(procName);
            }

            // Try function pointer firstly
            if ((procCallNode == null) && (procName != ProtoCore.DSASM.Constants.kFunctionPointerCall))
            {
                bool isAccessibleFp;
                ProtoCore.DSASM.SymbolNode symbolnode = null;
                bool isAllocated = VerifyAllocation(procName, globalClassIndex, globalProcIndex, out symbolnode, out isAccessibleFp);
                if (isAllocated) // not checking the type against function pointer, as the type could be var
                {
                    procName = ProtoCore.DSASM.Constants.kFunctionPointerCall;
                    // The graph node always depends on this function pointer
                    if (null != graphNode)
                    {
                        ProtoCore.AssociativeGraph.GraphNode dependentNode = new ProtoCore.AssociativeGraph.GraphNode();
                        dependentNode.PushSymbolReference(symbolnode);
                        graphNode.PushDependent(dependentNode);
                    }
                }
            }

            // Always try global function firstly. Because we dont have syntax
            // support for calling global function (say, ::foo()), if we try
            // member function firstly, there is no way to call a global function
            // For member function, we can use this.foo() to distinguish it from
            // global function.
            if ((procCallNode == null) && (procName != ProtoCore.DSASM.Constants.kFunctionPointerCall))
            {
                procCallNode = compileStateTracker.GetFirstVisibleProcedure(procName, arglist, codeBlock);
                if (null != procCallNode)
                {
                    type = ProtoCore.DSASM.Constants.kGlobalScope;
                    if (compileStateTracker.TypeSystem.IsHigherRank(procCallNode.returntype.UID, inferedType.UID))
                    {
                        inferedType = procCallNode.returntype;
                    }
                }
            }

            // Try member functions in global class scope
            if ((procCallNode == null) && (procName != ProtoCore.DSASM.Constants.kFunctionPointerCall) && (parentNode == null))
            {
                if (globalClassIndex != ProtoCore.DSASM.Constants.kInvalidIndex)
                {
                    int realType;
                    bool isAccessible;
                    bool isStaticOrConstructor = refClassIndex != ProtoCore.DSASM.Constants.kInvalidIndex;
                    ProtoCore.DSASM.ProcedureNode memProcNode = compileStateTracker.ClassTable.ClassNodes[globalClassIndex].GetMemberFunction(procName, arglist, globalClassIndex, out isAccessible, out realType, isStaticOrConstructor);

                    if (memProcNode != null)
                    {
                        Debug.Assert(realType != ProtoCore.DSASM.Constants.kInvalidIndex);
                        procCallNode = memProcNode;
                        inferedType = procCallNode.returntype;
                        type = realType;

                        if (!isAccessible)
                        {
                            string message = String.Format(ProtoCore.BuildData.WarningMessage.kMethodIsInaccessible, procName);
                            buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kAccessViolation, message, compileStateTracker.CurrentDSFileName, funcCall.line, funcCall.col);

                            inferedType.UID = (int)PrimitiveType.kTypeNull;
                            EmitPushNull();
                            return procCallNode;
                        }
                    }
                }
            }

            if (isUnresolvedDot)
            {
                // Get the dot call procedure
                ProtoCore.DSASM.ProcedureNode procNode = procDotCallNode;
                if (!isConstructor && !isStaticCall)
                {
                    procNode = compileStateTracker.GetFirstVisibleProcedure(ProtoCore.DSASM.Constants.kDotMethodName, null, codeBlock);
                }

                if(CoreUtils.IsGetter(procName))
                {
                    EmitFunctionCall(depth, type, arglist, procNode, funcCall, true);
                }
                else
                    EmitFunctionCall(depth, type, arglist, procNode, funcCall, false, bnode);

                if (dotCallType.UID != (int)PrimitiveType.kTypeVar)
                {
                    inferedType.UID = dotCallType.UID;
                }

                return procCallNode;
            }

            if (null != procCallNode)
            {
                if (procCallNode.isConstructor &&
                        (globalClassIndex != ProtoCore.DSASM.Constants.kInvalidIndex) &&
                        (globalProcIndex != ProtoCore.DSASM.Constants.kInvalidIndex) &&
                        (globalClassIndex == inferedType.UID))
                {
                    ProtoCore.DSASM.ProcedureNode contextProcNode = compileStateTracker.ClassTable.ClassNodes[globalClassIndex].vtable.procList[globalProcIndex];
                    if (contextProcNode.isConstructor &&
                        string.Equals(contextProcNode.name, procCallNode.name) &&
                        contextProcNode.runtimeIndex == procCallNode.runtimeIndex)
                    {
                        string message = String.Format(ProtoCore.BuildData.WarningMessage.kCallingConstructorInConstructor, procName);
                        buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kCallingConstructorInConstructor, message, compileStateTracker.CurrentDSFileName, node.line, node.col);
                        inferedType.UID = (int)PrimitiveType.kTypeNull;
                        EmitPushNull();
                        return procCallNode;
                    }
                }

                inferedType = procCallNode.returntype;

                //if call is replication call
                if (procCallNode.isThisCallReplication)
                {
                    inferedType.IsIndexable = true;
                    inferedType.rank++;
                }

                // Get the dot call procedure
                ProtoCore.DSASM.ProcedureNode procNode = procDotCallNode;
                if (!isConstructor && !isStaticCall)
                {
                    procNode = compileStateTracker.GetFirstVisibleProcedure(ProtoCore.DSASM.Constants.kDotMethodName, null, codeBlock);
                }

                if (CoreUtils.IsSetter(procName))
                {
                    EmitFunctionCall(depth, type, arglist, procNode, funcCall);
                }
                // Do not emit breakpoint at getters only - pratapa
                else if (CoreUtils.IsGetter(procName))
                {
                    EmitFunctionCall(depth, type, arglist, procNode, funcCall, true);
                }
                else
                {
                    EmitFunctionCall(depth, type, arglist, procNode, funcCall, false, bnode);
                }

                if (dotCallType.UID != (int)PrimitiveType.kTypeVar)
                {
                    inferedType.UID = dotCallType.UID;
                }

                if (isConstructor)
                {
                    foreach (AssociativeNode paramNode in dotCall.FunctionCall.FormalArguments)
                    {
                        // Get the lhs symbol list
                        ProtoCore.Type ltype = new ProtoCore.Type();
                        ltype.UID = globalClassIndex;
                        ProtoCore.AssociativeGraph.UpdateNodeRef argNodeRef = new ProtoCore.AssociativeGraph.UpdateNodeRef();
                        DFSGetSymbolList(paramNode, ref ltype, argNodeRef);

                        if (null != graphNode)
                        {
                            graphNode.updatedArguments.Add(argNodeRef);
                        }
                    }

                    graphNode.firstProc = procCallNode;
                }

                return procCallNode;
            }
            else
            {
                // Function does not exist at this point but we try to reolve at runtime
                if (depth <= 0 && procName != ProtoCore.DSASM.Constants.kFunctionPointerCall)
                {
                    if (inferedType.UID != (int)PrimitiveType.kTypeVar)
                    {
                        if (!compileStateTracker.Options.SuppressFunctionResolutionWarning)
                        {
                            string property;
                            if (CoreUtils.TryGetPropertyName(procName, out property))
                            {
                                string message = String.Format(ProtoCore.BuildData.WarningMessage.kPropertyNotFound, property);
                                buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kPropertyNotFound, message, compileStateTracker.CurrentDSFileName, funcCall.line, funcCall.col);
                            }
                            else
                            {
                                string message = String.Format(ProtoCore.BuildData.WarningMessage.kMethodNotFound, procName);
                                buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kFunctionNotFound, message, compileStateTracker.CurrentDSFileName, funcCall.line, funcCall.col);
                            }
                        }
                        inferedType.UID = (int)PrimitiveType.kTypeNull;
                    }

                    // Get the dot call procedure
                    ProtoCore.DSASM.ProcedureNode procNode = procDotCallNode;
                    if (!isConstructor && !isStaticCall)
                    {
                        procNode = compileStateTracker.GetFirstVisibleProcedure(ProtoCore.DSASM.Constants.kDotMethodName, null, codeBlock);
                    }

                    if (CoreUtils.IsGetter(procName))
                    {
                        EmitFunctionCall(depth, type, arglist, procNode, funcCall, true);
                    }
                    else
                        EmitFunctionCall(depth, type, arglist, procNode, funcCall, false, bnode);

                    if (dotCallType.UID != (int)PrimitiveType.kTypeVar)
                    {
                        inferedType.UID = dotCallType.UID;
                    }
                }
                else
                {
                    if (procName == ProtoCore.DSASM.Constants.kFunctionPointerCall && depth == 0)
                    {
                        ProtoCore.DSASM.DynamicFunctionNode dynamicFunctionNode = new ProtoCore.DSASM.DynamicFunctionNode(procName, arglist, lefttype);
                        compileStateTracker.DynamicFunctionTable.functionTable.Add(dynamicFunctionNode);

                        var iNode = nodeBuilder.BuildIdentfier(funcCall.Function.Name);
                        EmitIdentifierNode(iNode, ref inferedType);
                    }
                    else
                    {
                        ProtoCore.DSASM.DynamicFunctionNode dynamicFunctionNode = new ProtoCore.DSASM.DynamicFunctionNode(funcCall.Function.Name, arglist, lefttype);
                        compileStateTracker.DynamicFunctionTable.functionTable.Add(dynamicFunctionNode);
                    }
                    // The function call
                    EmitInstrConsole(ProtoCore.DSASM.kw.callr, funcCall.Function.Name + "[dynamic]");
                    EmitDynamicCall(compileStateTracker.DynamicFunctionTable.functionTable.Count - 1, globalClassIndex, depth, funcCall.line, funcCall.col, funcCall.endLine, funcCall.endCol);

                    // The function return value
                    EmitInstrConsole(ProtoCore.DSASM.kw.push, ProtoCore.DSASM.kw.regRX);
                    ProtoCore.DSASM.StackValue opReturn = new ProtoCore.DSASM.StackValue();
                    opReturn.optype = ProtoCore.DSASM.AddressType.Register;
                    opReturn.opdata = (int)ProtoCore.DSASM.Registers.RX;
                    EmitPush(opReturn);

                    if (compileStateTracker.Options.TempReplicationGuideEmptyFlag && emitReplicationGuide)
                    {
                        int guides = EmitReplicationGuides(replicationGuide);
                        EmitInstrConsole(ProtoCore.DSASM.kw.pushindex, guides + "[guide]");
                        EmitPushReplicationGuide(guides);
                    }

                    //assign inferedType to var
                    inferedType.UID = (int)PrimitiveType.kTypeVar;
                }
            }
            return procDotCallNode;
        }
Esempio n. 22
0
        private ProtoCore.AssociativeGraph.UpdateNodeRef AutoGenerateUpdateArgumentArrayReference(AssociativeNode node, ProtoCore.AssociativeGraph.GraphNode graphNode)
        {
            // Get the lhs symbol list
            ProtoCore.Type type = new ProtoCore.Type();
            type.UID = globalClassIndex;
            ProtoCore.AssociativeGraph.UpdateNodeRef leftNodeRef = new ProtoCore.AssociativeGraph.UpdateNodeRef();
            DFSGetSymbolList(node, ref type, leftNodeRef);

            ProtoCore.DSASM.SymbolNode firstSymbol = null;

            // Check if we are inside a procedure
            if (null != localProcedure)
            {
                if (1 == leftNodeRef.nodeList.Count)
                {
                    firstSymbol = leftNodeRef.nodeList[0].symbol;

                    // Check if it is an array modification
                    if (graphNode.dimensionNodeList.Count > 0)
                    {
                        // There is only one, see if its an array modification
                        // Now check if the first element of the identifier list is an argument
                        foreach (ProtoCore.DSASM.ArgumentInfo argInfo in localProcedure.argInfoList)
                        {
                            // See if this modified variable is an argument
                            if (argInfo.Name == firstSymbol.name)
                            {
                                List<ProtoCore.AssociativeGraph.UpdateNode> dimensionList = null;
                                bool found = localProcedure.updatedArgumentArrays.TryGetValue(argInfo.Name, out dimensionList);
                                if (found)
                                {
                                    // Overwrite it
                                    dimensionList = graphNode.dimensionNodeList;
                                }
                                else
                                {
                                    // Create a new modified array entry
                                    localProcedure.updatedArgumentArrays.Add(argInfo.Name, graphNode.dimensionNodeList);
                                }
                            }
                        }
                    }
                }
            }
            return leftNodeRef;
        }
Esempio n. 23
0
        public bool DependsOn(UpdateNodeRef modifiedRef, ref GraphNode dependentNode)
        {
            bool match = false;

            foreach (GraphNode depNode in dependentList)
            {
                Validity.Assert(1 == depNode.updateNodeRefList.Count);
                //foreach (UpdateNodeRef depNodeRef in depNode.updateNodeRefList)
                //{
                UpdateNodeRef depNodeRef        = depNode.updateNodeRefList[0];
                bool          bothSymbolsMatch  = false;
                bool          bothSymbolsStatic = false;
                bool          inImperativeMatch = false;
                bool          inImperative      = false;
                if (depNodeRef != null)
                {
                    if (depNodeRef.nodeList != null && modifiedRef.nodeList != null && depNodeRef.nodeList.Count > 0 && modifiedRef.nodeList.Count > 0)
                    {
                        if (depNodeRef.nodeList.Count > modifiedRef.nodeList.Count)
                        {
                            for (int m = 0; m < depNodeRef.nodeList.Count; m++)
                            {
                                if (depNodeRef.nodeList[m] != null && modifiedRef.nodeList[0] != null && depNodeRef.nodeList[m].symbol != null && modifiedRef.nodeList[0].symbol != null)
                                {
                                    if (modifiedRef.nodeList[0].symbol.forArrayName != null && !modifiedRef.nodeList[0].symbol.forArrayName.Equals(""))
                                    {
                                        inImperative = true;
                                        if (modifiedRef.nodeList[0].symbol.functionIndex == Constants.kInvalidIndex)
                                        {
                                            inImperative = inImperative &&
                                                           (depNodeRef.nodeList[m].symbol.functionIndex == Constants.kInvalidIndex) &&
                                                           (modifiedRef.nodeList[0].symbol.codeBlockId == depNodeRef.nodeList[m].symbol.codeBlockId);
                                        }

                                        if (inImperative && modifiedRef.nodeList[0].symbol.functionIndex == depNodeRef.nodeList[m].symbol.functionIndex && (modifiedRef.nodeList[0].symbol.name == depNodeRef.nodeList[m].symbol.name || modifiedRef.nodeList[0].symbol.forArrayName == depNodeRef.nodeList[m].symbol.name))
                                        {
                                            inImperativeMatch = true;
                                        }
                                    }
                                }
                            }
                        }
                        else if (depNodeRef.nodeList.Count == modifiedRef.nodeList.Count)
                        {
                            for (int m = 0; m < depNodeRef.nodeList.Count && m < modifiedRef.nodeList.Count; m++)
                            {
                                if (depNodeRef.nodeList[m] != null && modifiedRef.nodeList[m] != null && depNodeRef.nodeList[m].symbol != null && modifiedRef.nodeList[m].symbol != null)
                                {
                                    if (modifiedRef.nodeList[0].symbol.forArrayName != null && !modifiedRef.nodeList[0].symbol.forArrayName.Equals(""))
                                    {
                                        inImperative = true;
                                        if (modifiedRef.nodeList[m].symbol.functionIndex == Constants.kInvalidIndex)
                                        {
                                            inImperative = inImperative &&
                                                           (depNodeRef.nodeList[m].symbol.functionIndex == Constants.kInvalidIndex) &&
                                                           (modifiedRef.nodeList[m].symbol.codeBlockId == depNodeRef.nodeList[m].symbol.codeBlockId);
                                        }
                                        if (inImperative && modifiedRef.nodeList[m].symbol.functionIndex == depNodeRef.nodeList[m].symbol.functionIndex && modifiedRef.nodeList[m].symbol.name == depNodeRef.nodeList[m].symbol.name)
                                        {
                                            inImperativeMatch = true;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }


                if (!inImperativeMatch)
                {
                    // Does first symbol match


                    if (null != modifiedRef.nodeList[0].symbol && null != depNodeRef.nodeList[0].symbol)
                    {
                        bothSymbolsMatch = modifiedRef.nodeList[0].symbol.Equals(depNodeRef.nodeList[0].symbol);


                        bothSymbolsStatic =
                            modifiedRef.nodeList[0].symbol.memregion == MemoryRegion.kMemStatic &&
                            depNodeRef.nodeList[0].symbol.memregion == MemoryRegion.kMemStatic &&
                            modifiedRef.nodeList[0].symbol.name == depNodeRef.nodeList[0].symbol.name;

                        // Check further if their array index match in literal values
                        if (bothSymbolsMatch)
                        {
                            // Are the indices the same number
                            bool areIndicesMatching = modifiedRef.nodeList[0].dimensionNodeList.Count >= depNodeRef.nodeList[0].dimensionNodeList.Count;
                            if (areIndicesMatching && depNodeRef.nodeList[0].dimensionNodeList.Count > 0)
                            {
                                for (int n = 0; n < depNodeRef.nodeList[0].dimensionNodeList.Count; ++n)
                                {
                                    // Is either a non-literal
                                    UpdateNode modDimNode = modifiedRef.nodeList[0].dimensionNodeList[n];
                                    UpdateNode depDimNode = depNodeRef.nodeList[0].dimensionNodeList[n];

                                    if (modDimNode.nodeType != depDimNode.nodeType)
                                    {
                                        bothSymbolsMatch = false;
                                    }
                                    else if (modDimNode.nodeType == UpdateNodeType.kLiteral)
                                    {
                                        bothSymbolsMatch = modDimNode.symbol.name.CompareTo(depDimNode.symbol.name) == 0;
                                    }
                                    else if (modDimNode.nodeType == UpdateNodeType.kSymbol)
                                    {
                                        bothSymbolsMatch = modDimNode.symbol.Equals(depDimNode.symbol);
                                    }
                                    else
                                    {
                                        bothSymbolsMatch = false;
                                    }

                                    if (!bothSymbolsMatch)
                                    {
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    if (bothSymbolsMatch || bothSymbolsStatic)
                    {
                        match = true;

                        // If it is static, then all symbols must match
                        if (bothSymbolsStatic)
                        {
                            // The number of symbols in the modifed reference...
                            //  ...must match
                            // The number of symbols in the current dependency noderef
                            if (modifiedRef.nodeList.Count == depNodeRef.nodeList.Count)
                            {
                                for (int n = 1; n < modifiedRef.nodeList.Count; ++n)
                                {
                                    //Validity.Assert(!modifiedRef.nodeList[n].isMethod);
                                    //Validity.Assert(!depNodeRef.nodeList[n].isMethod);

                                    if (UpdateNodeType.kMethod == modifiedRef.nodeList[n].nodeType || UpdateNodeType.kMethod == depNodeRef.nodeList[n].nodeType)
                                    {
                                        match = false;
                                        break;
                                    }

                                    if (modifiedRef.nodeList[n].symbol.index != depNodeRef.nodeList[n].symbol.index)
                                    {
                                        match = false;
                                        break;
                                    }
                                }
                            }
                            else
                            {
                                match = false;
                            }
                        }
                        else
                        {
                            if (modifiedRef.nodeList.Count >= depNodeRef.nodeList.Count)
                            {
                                //
                                // The modifed reference is either the same nodelist length or more than the current dependent
                                // a.x.y is being compared to a.x
                                //
                                for (int n = 1; n < modifiedRef.nodeList.Count; ++n)
                                {
                                    if (modifiedRef.nodeList.Count != depNodeRef.nodeList.Count)
                                    {
                                        if (n >= depNodeRef.nodeList.Count)
                                        {
                                            match = false;
                                            break;
                                        }
                                    }

                                    if (UpdateNodeType.kMethod == modifiedRef.nodeList[n].nodeType || UpdateNodeType.kMethod == depNodeRef.nodeList[n].nodeType)
                                    {
                                        match = false;
                                        break;
                                    }

                                    if (modifiedRef.nodeList[n].symbol.name != depNodeRef.nodeList[n].symbol.name)
                                    {
                                        match = false;
                                        break;
                                    }
                                }
                            }
                            else
                            {
                                //
                                // The modifed reference nodelist is less than than the current dependent nodelist
                                // a.x is being compared to a.x.y
                                //
                                for (int n = 1; n < depNodeRef.nodeList.Count; ++n)
                                {
                                    if (n >= modifiedRef.nodeList.Count)
                                    {
                                        break;
                                    }

                                    if (UpdateNodeType.kMethod == modifiedRef.nodeList[n].nodeType || UpdateNodeType.kMethod == depNodeRef.nodeList[n].nodeType)
                                    {
                                        match = false;
                                        break;
                                    }

                                    if (modifiedRef.nodeList[n].symbol.name != depNodeRef.nodeList[n].symbol.name)
                                    {
                                        match = false;
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    dependentNode = depNode;
                    if (match)
                    {
                        break;
                    }
                }
                else
                {
                    for (int m = 0; m < depNodeRef.nodeList.Count && m < modifiedRef.nodeList.Count; m++)
                    {
                        // Does first symbol match

                        if (null != modifiedRef.nodeList[m].symbol && null != depNodeRef.nodeList[m].symbol)
                        {
                            bothSymbolsMatch  = modifiedRef.nodeList[m].symbol.Equals(depNodeRef.nodeList[m].symbol);
                            bothSymbolsStatic =
                                modifiedRef.nodeList[m].symbol.memregion == MemoryRegion.kMemStatic &&
                                depNodeRef.nodeList[m].symbol.memregion == MemoryRegion.kMemStatic &&
                                modifiedRef.nodeList[m].symbol.name == depNodeRef.nodeList[m].symbol.name;

                            // Check further if their array index match in literal values
                            if (bothSymbolsMatch)
                            {
                                // Are the indices the same number
                                bool areIndicesMatching = modifiedRef.nodeList[m].dimensionNodeList.Count == depNodeRef.nodeList[m].dimensionNodeList.Count;
                                if (areIndicesMatching && modifiedRef.nodeList[m].dimensionNodeList.Count > 0)
                                {
                                    for (int n = 0; n < modifiedRef.nodeList[m].dimensionNodeList.Count; ++n)
                                    {
                                        // Is either a non-literal
                                        bool isEitherNonLiteral = modifiedRef.nodeList[m].dimensionNodeList[n].nodeType != UpdateNodeType.kLiteral ||
                                                                  depNodeRef.nodeList[m].dimensionNodeList[n].nodeType != UpdateNodeType.kLiteral;
                                        if (isEitherNonLiteral)
                                        {
                                            bothSymbolsMatch = false;
                                            break;
                                        }

                                        // They are both literal, now check for their literal values
                                        if (0 != modifiedRef.nodeList[m].dimensionNodeList[n].symbol.name.CompareTo(depNodeRef.nodeList[m].dimensionNodeList[n].symbol.name))
                                        {
                                            // They are not the same
                                            bothSymbolsMatch = false;
                                            break;
                                        }
                                    }
                                }
                            }
                        }

                        if (bothSymbolsMatch || bothSymbolsStatic || inImperativeMatch)
                        {
                            match = true;

                            // If it is static, then all symbols must match
                            if (bothSymbolsStatic)
                            {
                                // The number of symbols in the modifed reference...
                                //  ...must match
                                // The number of symbols in the current dependency noderef
                                if (modifiedRef.nodeList.Count == depNodeRef.nodeList.Count)
                                {
                                    for (int n = 1; n < modifiedRef.nodeList.Count; ++n)
                                    {
                                        //Validity.Assert(!modifiedRef.nodeList[n].isMethod);
                                        //Validity.Assert(!depNodeRef.nodeList[n].isMethod);

                                        if (UpdateNodeType.kMethod == modifiedRef.nodeList[n].nodeType || UpdateNodeType.kMethod == depNodeRef.nodeList[n].nodeType)
                                        {
                                            match = false;
                                            break;
                                        }

                                        if (modifiedRef.nodeList[n].symbol.index != depNodeRef.nodeList[n].symbol.index)
                                        {
                                            match = false;
                                            break;
                                        }
                                    }
                                }
                                else
                                {
                                    match = false;
                                }
                            }
                            else
                            {
                                if (modifiedRef.nodeList.Count >= depNodeRef.nodeList.Count)
                                {
                                    //
                                    // The modifed reference is either the same nodelist length or more than the current dependent
                                    // a.x.y is being compared to a.x
                                    //
                                    for (int n = 1; n < modifiedRef.nodeList.Count; ++n)
                                    {
                                        if (modifiedRef.nodeList.Count != depNodeRef.nodeList.Count)
                                        {
                                            if (n >= depNodeRef.nodeList.Count)
                                            {
                                                match = false;
                                                break;
                                            }
                                        }

                                        if (UpdateNodeType.kMethod == modifiedRef.nodeList[n].nodeType || UpdateNodeType.kMethod == depNodeRef.nodeList[n].nodeType)
                                        {
                                            match = false;
                                            break;
                                        }

                                        if (modifiedRef.nodeList[n].symbol.name != depNodeRef.nodeList[n].symbol.name)
                                        {
                                            match = false;
                                            break;
                                        }
                                    }
                                }
                                else
                                {
                                    //
                                    // The modifed reference nodelist is less than than the current dependent nodelist
                                    // a.x is being compared to a.x.y
                                    //
                                    for (int n = 1; n < depNodeRef.nodeList.Count; ++n)
                                    {
                                        if (n >= modifiedRef.nodeList.Count)
                                        {
                                            break;
                                        }

                                        if (UpdateNodeType.kMethod == modifiedRef.nodeList[n].nodeType || UpdateNodeType.kMethod == depNodeRef.nodeList[n].nodeType)
                                        {
                                            match = false;
                                            break;
                                        }

                                        if (modifiedRef.nodeList[n].symbol.name != depNodeRef.nodeList[n].symbol.name)
                                        {
                                            match = false;
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    dependentNode = depNode;
                    if (match)
                    {
                        break;
                    }
                }
                //}
            }
            return(match);
        }
Esempio n. 24
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);
                }
            }
        }
Esempio n. 25
0
        public void PushSymbolReference(ProtoCore.DSASM.SymbolNode symbol, ProtoCore.AssociativeGraph.UpdateNodeType type = UpdateNodeType.kSymbol)
        {
            Validity.Assert(null != symbol);
            Validity.Assert(null != updateNodeRefList);
            UpdateNode updateNode = new UpdateNode();
            updateNode.symbol = symbol;
            updateNode.nodeType = type;

            UpdateNodeRef nodeRef = new UpdateNodeRef();
            nodeRef.PushUpdateNode(updateNode);

            updateNodeRefList.Add(nodeRef);
        }
Esempio n. 26
0
        public void PushProcReference(ProtoCore.DSASM.ProcedureNode proc)
        {
            Validity.Assert(null != proc);
            Validity.Assert(null != updateNodeRefList);
            UpdateNode updateNode = new UpdateNode();
            updateNode.procNode = proc;
            updateNode.nodeType = UpdateNodeType.kMethod;

            UpdateNodeRef nodeRef = new UpdateNodeRef();
            nodeRef.PushUpdateNode(updateNode);

            updateNodeRefList.Add(nodeRef);
        }
Esempio n. 27
0
 public bool IsUpdateableBy(UpdateNodeRef modifiedRef)
 {
     // Function to check if the current graphnode can be modified by the modified reference
     bool isUpdateable = false;
     if (modifiedRef.nodeList.Count < updateNodeRefList[0].nodeList.Count)
     {
         isUpdateable = true;
         for (int n = 0; n < modifiedRef.nodeList.Count; ++n)
         {
             ProtoCore.AssociativeGraph.UpdateNode updateNode = modifiedRef.nodeList[n];
             if (!updateNode.IsEqual(updateNodeRefList[0].nodeList[n]))
             {
                 isUpdateable = false;
                 break;
             }
         }
     }
     return isUpdateable;
 }
Esempio n. 28
0
        public override ProtoCore.DSASM.ProcedureNode TraverseFunctionCall(ProtoCore.AST.Node node, ProtoCore.AST.Node parentNode, int lefttype, int depth, ref ProtoCore.Type inferedType,             
            ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone,
            ProtoCore.AST.Node bnode = null)
        {
            FunctionCallNode funcCall = null;
            string procName = null;
            List<ProtoCore.Type> arglist = new List<ProtoCore.Type>();
            ProtoCore.Type dotCallType = new ProtoCore.Type();
            dotCallType.UID = (int)PrimitiveType.kTypeVar;
            dotCallType.IsIndexable = false;

            ProtoCore.AssociativeGraph.UpdateNode updateNode = new ProtoCore.AssociativeGraph.UpdateNode();

            if (node is ProtoCore.AST.AssociativeAST.FunctionDotCallNode)
            {
                return TraverseDotFunctionCall(node, parentNode, lefttype, depth, ref inferedType, graphNode, subPass, bnode as BinaryExpressionNode);
            }
            else
            {
                funcCall = node as FunctionCallNode;
                procName = funcCall.Function.Name;

                int classIndex = compileStateTracker.ClassTable.IndexOf(procName);
                bool isAccessible;
                int dummy;

                // To support unamed constructor
                if (classIndex != Constants.kInvalidIndex)
                {
                    ProcedureNode constructor = compileStateTracker.ClassTable.ClassNodes[classIndex].GetMemberFunction(procName, arglist, globalClassIndex, out isAccessible, out dummy, true);
                    if (constructor != null && constructor.isConstructor)
                    {
                        FunctionCallNode rhsFNode = node as ProtoCore.AST.AssociativeAST.FunctionCallNode;
                        AssociativeNode classNode = nodeBuilder.BuildIdentfier(procName);
                        FunctionDotCallNode dotCallNode = ProtoCore.Utils.CoreUtils.GenerateCallDotNode(classNode, rhsFNode, compileStateTracker);
                        return TraverseDotFunctionCall(dotCallNode, parentNode, lefttype, depth, ref inferedType, graphNode, subPass, bnode as BinaryExpressionNode);
                    }
                }
            }

            foreach (AssociativeNode paramNode in funcCall.FormalArguments)
            {
                ProtoCore.Type paramType = new ProtoCore.Type();
                paramType.UID = (int)ProtoCore.PrimitiveType.kTypeVoid;
                paramType.IsIndexable = false;

                // The range expression function does not need replication guides
                emitReplicationGuide = !procName.Equals(ProtoCore.DSASM.Constants.kFunctionRangeExpression);

                // If it's a binary node then continue type check, otherwise disable type check and just take the type of paramNode itself
                // f(1+2.0) -> type check enabled - param is typed as double
                // f(2) -> type check disabled - param is typed as int
                enforceTypeCheck = !(paramNode is BinaryExpressionNode);

                DfsTraverse(paramNode, ref paramType, false, graphNode, subPass, bnode);

                emitReplicationGuide = false;
                enforceTypeCheck = true;

                arglist.Add(paramType);
            }

            if (subPass == ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier)
            {
                return null;
            }

            ProtoCore.DSASM.ProcedureNode procNode = null;
            int type = ProtoCore.DSASM.Constants.kInvalidIndex;

            int refClassIndex = ProtoCore.DSASM.Constants.kInvalidIndex;
            if (parentNode != null && parentNode is ProtoCore.AST.AssociativeAST.IdentifierListNode)
            {
                ProtoCore.AST.Node leftnode = (parentNode as ProtoCore.AST.AssociativeAST.IdentifierListNode).LeftNode;
                if (leftnode != null && leftnode is ProtoCore.AST.AssociativeAST.IdentifierNode)
                {
                    refClassIndex = compileStateTracker.ClassTable.IndexOf(leftnode.Name);
                }
            }

            // Check for the actual method, not the dot method
            // If lefttype is a valid class then check if calling a constructor
            if ((int)ProtoCore.PrimitiveType.kInvalidType != inferedType.UID
                && (int)ProtoCore.PrimitiveType.kTypeVoid != inferedType.UID
                && procName != ProtoCore.DSASM.Constants.kFunctionPointerCall)
            {

                bool isAccessible;
                int realType;

                bool isStaticOrConstructor = refClassIndex != ProtoCore.DSASM.Constants.kInvalidIndex;
                procNode = compileStateTracker.ClassTable.ClassNodes[inferedType.UID].GetMemberFunction(procName, arglist, globalClassIndex, out isAccessible, out realType, isStaticOrConstructor);

                if (procNode != null)
                {
                    Debug.Assert(realType != ProtoCore.DSASM.Constants.kInvalidIndex);
                    type = lefttype = realType;

                    if (!isAccessible)
                    {
                        type = lefttype = realType;
                        procNode = null;
                        string message = String.Format(ProtoCore.BuildData.WarningMessage.kMethodIsInaccessible, procName);
                        buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kAccessViolation, message, compileStateTracker.CurrentDSFileName, funcCall.line, funcCall.col);
                        inferedType.UID = (int)PrimitiveType.kTypeNull;

                        EmitPushNull();
                        return procNode;
                    }

                }
            }

            // Try function pointer firstly
            if ((procNode == null) && (procName != ProtoCore.DSASM.Constants.kFunctionPointerCall))
            {
                bool isAccessibleFp;
                ProtoCore.DSASM.SymbolNode symbolnode = null;
                bool isAllocated = VerifyAllocation(procName, globalClassIndex, globalProcIndex, out symbolnode, out isAccessibleFp);
                if (isAllocated) // not checking the type against function pointer, as the type could be var
                {
                    procName = ProtoCore.DSASM.Constants.kFunctionPointerCall;
                    // The graph node always depends on this function pointer
                    if (null != graphNode)
                    {
                        ProtoCore.AssociativeGraph.GraphNode dependentNode = new ProtoCore.AssociativeGraph.GraphNode();
                        dependentNode.PushSymbolReference(symbolnode);
                        graphNode.PushDependent(dependentNode);
                    }
                }
            }

            // Always try global function firstly. Because we dont have syntax
            // support for calling global function (say, ::foo()), if we try
            // member function firstly, there is no way to call a global function
            // For member function, we can use this.foo() to distinguish it from
            // global function.
            if ((procNode == null) && (procName != ProtoCore.DSASM.Constants.kFunctionPointerCall))
            {
                procNode = compileStateTracker.GetFirstVisibleProcedure(procName, arglist, codeBlock);
                if (null != procNode)
                {
                    type = ProtoCore.DSASM.Constants.kGlobalScope;
                    if (compileStateTracker.TypeSystem.IsHigherRank(procNode.returntype.UID, inferedType.UID))
                    {
                        inferedType = procNode.returntype;
                    }
                }
            }

            // Try member functions in global class scope
            if ((procNode == null) && (procName != ProtoCore.DSASM.Constants.kFunctionPointerCall) && (parentNode == null))
            {
                if (globalClassIndex != ProtoCore.DSASM.Constants.kInvalidIndex)
                {
                    int realType;
                    bool isAccessible;
                    bool isStaticOrConstructor = refClassIndex != ProtoCore.DSASM.Constants.kInvalidIndex;
                    ProtoCore.DSASM.ProcedureNode memProcNode = compileStateTracker.ClassTable.ClassNodes[globalClassIndex].GetMemberFunction(procName, arglist, globalClassIndex, out isAccessible, out realType, isStaticOrConstructor);

                    if (memProcNode != null)
                    {
                        Debug.Assert(realType != ProtoCore.DSASM.Constants.kInvalidIndex);
                        procNode = memProcNode;
                        inferedType = procNode.returntype;
                        type = realType;

                        if (!isAccessible)
                        {
                            string message = String.Format(ProtoCore.BuildData.WarningMessage.kMethodIsInaccessible, procName);
                            buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kAccessViolation, message, compileStateTracker.CurrentDSFileName, funcCall.line, funcCall.col);

                            inferedType.UID = (int)PrimitiveType.kTypeNull;
                            EmitPushNull();
                            return procNode;
                        }
                    }
                }
            }

            if (null != procNode)
            {
                if (procNode.isConstructor &&
                        (globalClassIndex != ProtoCore.DSASM.Constants.kInvalidIndex) &&
                        (globalProcIndex != ProtoCore.DSASM.Constants.kInvalidIndex) &&
                        (globalClassIndex == inferedType.UID))
                {
                    ProtoCore.DSASM.ProcedureNode contextProcNode = compileStateTracker.ClassTable.ClassNodes[globalClassIndex].vtable.procList[globalProcIndex];
                    if (contextProcNode.isConstructor &&
                        string.Equals(contextProcNode.name, procNode.name) &&
                        contextProcNode.runtimeIndex == procNode.runtimeIndex)
                    {
                        string message = String.Format(ProtoCore.BuildData.WarningMessage.kCallingConstructorInConstructor, procName);
                        buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kCallingConstructorInConstructor, message, compileStateTracker.CurrentDSFileName, node.line, node.col );
                        inferedType.UID = (int)PrimitiveType.kTypeNull;
                        EmitPushNull();
                        return procNode;
                    }
                }

                inferedType = procNode.returntype;

                //if call is replication call
                if (procNode.isThisCallReplication)
                {
                    inferedType.IsIndexable = true;
                    inferedType.rank++;
                }

                if (ProtoCore.DSASM.Constants.kInvalidIndex != procNode.procId)
                {

                    //
                    // ==============Establishing graphnode links in modified arguments=============
                    //
                    //  proc TraverseCall(node, graphnode)
                    //      ; Get the first procedure, this will only be the first visible procedure
                    //      ; Overloads will be handled at runtime
                    //      def fnode = getProcedure(node)
                    //
                    //      ; For every argument in the function call,
                    //      ; attach the modified property list and append it to the graphnode update list
                    //      foreach arg in node.args
                    //          if fnode.updatedArgProps is not null
                    //              def noderef = arg.ident (or identlist)
                    //              noderef.append(fnode.updatedArgProps)
                    //              graphnode.pushUpdateRef(noderef)
                    //          end
                    //      end
                    //  end
                    //
                    // =============================================================================
                    //

                    foreach (AssociativeNode paramNode in funcCall.FormalArguments)
                    {
                        // Get the lhs symbol list
                        ProtoCore.Type ltype = new ProtoCore.Type();
                        ltype.UID = globalClassIndex;
                        ProtoCore.AssociativeGraph.UpdateNodeRef argNodeRef = new ProtoCore.AssociativeGraph.UpdateNodeRef();
                        DFSGetSymbolList(paramNode, ref ltype, argNodeRef);

                        if (null != graphNode)
                        {
                            graphNode.updatedArguments.Add(argNodeRef);
                        }
                    }

                    // The function is at block 0 if its a constructor, member or at the globals scope.
                    // Its at block 1 if its inside a language block.
                    // Its limited to block 1 as of R1 since we dont support nested function declarations yet
                    int blockId = procNode.runtimeIndex;

                    //push value-not-provided default argument
                    for (int i = arglist.Count; i < procNode.argInfoList.Count; i++)
                    {
                        EmitDefaultArgNode();
                    }

                    // Push the function declaration block and indexed array
                    // Jun TODO: Implementeation of indexing into a function call:
                    //  x = f()[0][1]
                    int dimensions = 0;
                    EmitPushVarData(blockId, dimensions);

                    // The function call
                    EmitInstrConsole(ProtoCore.DSASM.kw.callr, procNode.name);

                    // Do not emit breakpoints at built-in methods like _add/_sub etc. - pratapa
                    if (procNode.isAssocOperator || procNode.name.Equals(ProtoCore.DSASM.Constants.kInlineConditionalMethodName))
                    {
                        EmitCall(procNode.procId, type, depth, ProtoCore.DSASM.Constants.kInvalidIndex, ProtoCore.DSASM.Constants.kInvalidIndex,
                                    ProtoCore.DSASM.Constants.kInvalidIndex, ProtoCore.DSASM.Constants.kInvalidIndex, procNode.pc);
                    }
                    // Break at function call inside dynamic lang block created for a 'true' or 'false' expression inside an inline conditional
                    else if (compileStateTracker.DebugProps.breakOptions.HasFlag(DebugProperties.BreakpointOptions.EmitInlineConditionalBreakpoint))
                    {
                        Validity.Assert(compileStateTracker.DebugProps.highlightRange != null);

                        ProtoCore.CodeModel.CodePoint startInclusive = compileStateTracker.DebugProps.highlightRange.StartInclusive;
                        ProtoCore.CodeModel.CodePoint endExclusive = compileStateTracker.DebugProps.highlightRange.EndExclusive;

                        EmitCall(procNode.procId, type, depth, startInclusive.LineNo, startInclusive.CharNo, endExclusive.LineNo, endExclusive.CharNo, procNode.pc);
                    }
                    // Use startCol and endCol of binary expression node containing function call except if it's a setter
                    else if (bnode != null && !procNode.name.StartsWith(Constants.kSetterPrefix))
                    {
                        EmitCall(procNode.procId, type, depth, bnode.line, bnode.col, bnode.endLine, bnode.endCol, procNode.pc);
                    }
                    else
                    {
                        EmitCall(procNode.procId, type, depth, funcCall.line, funcCall.col, funcCall.endLine, funcCall.endCol, procNode.pc);
                    }

                    // The function return value
                    EmitInstrConsole(ProtoCore.DSASM.kw.push, ProtoCore.DSASM.kw.regRX);
                    ProtoCore.DSASM.StackValue opReturn = new ProtoCore.DSASM.StackValue();
                    opReturn.optype = ProtoCore.DSASM.AddressType.Register;
                    opReturn.opdata = (int)ProtoCore.DSASM.Registers.RX;
                    EmitPush(opReturn);

                    if (dotCallType.UID != (int)PrimitiveType.kTypeVar)
                    {
                        inferedType.UID = dotCallType.UID;
                    }
                }
            }
            else
            {
                if (depth <= 0 && procName != ProtoCore.DSASM.Constants.kFunctionPointerCall)
                {
                    string property;
                    if (CoreUtils.TryGetPropertyName(procName, out property))
                    {
                        string message = String.Format(ProtoCore.BuildData.WarningMessage.kPropertyNotFound, property);
                        buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kPropertyNotFound, message, compileStateTracker.CurrentDSFileName, funcCall.line, funcCall.col);
                    }
                    else
                    {
                        string message = String.Format(ProtoCore.BuildData.WarningMessage.kMethodNotFound, procName);
                        buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kFunctionNotFound, message, compileStateTracker.CurrentDSFileName, funcCall.line, funcCall.col);
                    }

                    inferedType.UID = (int)PrimitiveType.kTypeNull;
                    EmitPushNull();
                }
                else
                {
                    if (procName == ProtoCore.DSASM.Constants.kFunctionPointerCall && depth == 0)
                    {
                        ProtoCore.DSASM.DynamicFunctionNode dynamicFunctionNode = new ProtoCore.DSASM.DynamicFunctionNode(procName, arglist, lefttype);
                        compileStateTracker.DynamicFunctionTable.functionTable.Add(dynamicFunctionNode);
                        var iNode = nodeBuilder.BuildIdentfier(funcCall.Function.Name);
                        EmitIdentifierNode(iNode, ref inferedType);
                    }
                    else
                    {
                        ProtoCore.DSASM.DynamicFunctionNode dynamicFunctionNode = new ProtoCore.DSASM.DynamicFunctionNode(funcCall.Function.Name, arglist, lefttype);
                        compileStateTracker.DynamicFunctionTable.functionTable.Add(dynamicFunctionNode);
                    }
                    // The function call
                    EmitInstrConsole(ProtoCore.DSASM.kw.callr, funcCall.Function.Name + "[dynamic]");
                    EmitDynamicCall(compileStateTracker.DynamicFunctionTable.functionTable.Count - 1, globalClassIndex, depth, funcCall.line, funcCall.col, funcCall.endLine, funcCall.endCol);

                    // The function return value
                    EmitInstrConsole(ProtoCore.DSASM.kw.push, ProtoCore.DSASM.kw.regRX);
                    ProtoCore.DSASM.StackValue opReturn = new ProtoCore.DSASM.StackValue();
                    opReturn.optype = ProtoCore.DSASM.AddressType.Register;
                    opReturn.opdata = (int)ProtoCore.DSASM.Registers.RX;
                    EmitPush(opReturn);

                    //assign inferedType to var
                    inferedType.UID = (int)PrimitiveType.kTypeVar;
                }
            }
            return procNode;
        }
Esempio n. 29
0
 public UpdateNodeRef(UpdateNodeRef rhs)
 {
     nodeList = new List<UpdateNode>();
     if (null != rhs && null != rhs.nodeList)
     {
         foreach (UpdateNode node in rhs.nodeList)
         {
             PushUpdateNode(node);
         }
     }
 }
Esempio n. 30
0
        private ProtoCore.AssociativeGraph.UpdateNodeRef AutoGenerateUpdateReference(AssociativeNode node, ProtoCore.AssociativeGraph.GraphNode graphNode)
        {
            // Get the lhs symbol list
            ProtoCore.Type type = new ProtoCore.Type();
            type.UID = globalClassIndex;
            ProtoCore.AssociativeGraph.UpdateNodeRef leftNodeRef = new ProtoCore.AssociativeGraph.UpdateNodeRef();
            DFSGetSymbolList(node, ref type, leftNodeRef);

            // Auto-generate the updateNodeRefs for this graphnode given the list
            // stored in the first procedure found in the assignment expression
            if (functionCallStack.Count > 0)
            {
                ProtoCore.DSASM.ProcedureNode firstProc = functionCallStack[0];
                if (!firstProc.isAutoGenerated)
                {
                    foreach (ProtoCore.AssociativeGraph.UpdateNodeRef updateRef in firstProc.updatedProperties)
                    {
                        ProtoCore.AssociativeGraph.UpdateNodeRef autogenRef = leftNodeRef;
                        autogenRef.PushUpdateNodeRef(updateRef);
                        graphNode.updateNodeRefList.Add(autogenRef);
                    }
                    graphNode.firstProc = firstProc;
                }
            }
            ProtoCore.DSASM.SymbolNode firstSymbol = null;

            // See if the leftmost symbol(updateNodeRef) of the lhs expression is a property of the current class.
            // If it is, then push the lhs updateNodeRef to the list of modified properties in the procedure node
            if (null != localProcedure && leftNodeRef.nodeList.Count > 0)
            {
                firstSymbol = leftNodeRef.nodeList[0].symbol;
                if (null != firstSymbol && leftNodeRef.nodeList[0].nodeType != ProtoCore.AssociativeGraph.UpdateNodeType.kMethod)
                {
                    if (firstSymbol.functionIndex == ProtoCore.DSASM.Constants.kGlobalScope)
                    {
                        // Does the symbol belong on the same class or class heirarchy as the function calling it
                        if (firstSymbol.classScope == localProcedure.classScope)
                        {
                            localProcedure.updatedProperties.Push(leftNodeRef);
                        }
                        else
                        {
                            if (localProcedure.classScope > 0)
                            {
                                if (compileStateTracker.ClassTable.ClassNodes[localProcedure.classScope].IsMyBase(firstSymbol.classScope))
                                {
                                    localProcedure.updatedProperties.Push(leftNodeRef);
                                }
                            }
                        }
                    }
                }
            }
            return leftNodeRef;
        }
Esempio n. 31
0
 public void PushUpdateNodeRef(UpdateNodeRef nodeRef)
 {
     Validity.Assert(null != nodeList);
     foreach (UpdateNode node in nodeRef.nodeList)
     {
         nodeList.Add(node);
     }
 }
Esempio n. 32
0
        //
        //  proc ResolveFinalNodeRefs()
        //      foreach graphnode in graphnodeList
        //          def firstproc = graphnode.firstproc
        //          // Auto-generate the updateNodeRefs for this graphnode given the
        //          // list stored in the first procedure found in the assignment expression
        //          foreach noderef in firstProc.updatedProperties
        //              def n = graphnode.firstProcRefIndex
        //              def autogenRef = updateNodeRef[n]
        //              autogenRef.append(noderef)
        //              graphnode.pushUpdateRef(autogenRef)
        //          end
        //      end
        //  end
        //
        private void ResolveFinalNodeRefs()
        {
            foreach (ProtoCore.AssociativeGraph.GraphNode graphNode in codeBlock.instrStream.dependencyGraph.GraphList)
            {
                ProtoCore.DSASM.ProcedureNode firstProc = graphNode.firstProc;
                if (null == firstProc || firstProc.isAutoGenerated)
                {
                    continue;
                }

                // TODO: The following implementation is wrong.
                // Suppose for function call: x = foo().bar(); which converted
                // to x = %dot(foo(), bar(), ...); the following checking skips
                // it because %dot() is an internal function. -Yu Ke

                // Do this only for non auto-generated function calls
                //if any local var is depend on global var
                if (compileStateTracker.Options.localDependsOnGlobalSet)
                {
                    if (!firstProc.name.ToCharArray()[0].Equals('_') && !firstProc.name.ToCharArray()[0].Equals('%'))
                    {
                        //for each node
                        foreach (ProtoCore.AssociativeGraph.GraphNode gNode in codeBlock.instrStream.dependencyGraph.GraphList)
                        {
                            if (gNode.updateNodeRefList != null && gNode.updateNodeRefList.Count != 0)
                            {
                                if (gNode.procIndex == firstProc.procId && !gNode.updateNodeRefList[0].nodeList[0].symbol.name.ToCharArray()[0].Equals('%'))
                                {
                                    foreach (ProtoCore.AssociativeGraph.GraphNode dNode in gNode.dependentList)
                                    {
                                        if (dNode.procIndex == ProtoCore.DSASM.Constants.kGlobalScope)
                                        {
                                            if (!dNode.updateNodeRefList[0].nodeList[0].symbol.name.ToCharArray()[0].Equals('%'))
                                            {
                                                graphNode.PushDependent(dNode);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                // For each property modified
                foreach (ProtoCore.AssociativeGraph.UpdateNodeRef updateRef in firstProc.updatedProperties)
                {
                    int index = graphNode.firstProcRefIndex;

                    // Is it a global function
                    if (ProtoCore.DSASM.Constants.kGlobalScope == firstProc.classScope)
                    {
                        graphNode.updateNodeRefList.AddRange(firstProc.updatedGlobals);
                    }
                    else if (ProtoCore.DSASM.Constants.kInvalidIndex != index && ProtoCore.DSASM.Constants.kGlobalScope != firstProc.classScope)
                    {
                        foreach (ProtoCore.AssociativeGraph.GraphNode dependent in graphNode.dependentList)
                        {
                            // Do this only if first proc is a member function...
                            ProtoCore.AssociativeGraph.UpdateNodeRef autogenRef = new ProtoCore.AssociativeGraph.UpdateNodeRef(dependent.updateNodeRefList[0]);
                            autogenRef = autogenRef.GetUntilFirstProc();

                            // ... and the first symbol is an instance of a user-defined type
                            int last = autogenRef.nodeList.Count - 1;
                            Validity.Assert(autogenRef.nodeList[last].nodeType != ProtoCore.AssociativeGraph.UpdateNodeType.kMethod && null != autogenRef.nodeList[last].symbol);
                            if (autogenRef.nodeList[last].symbol.datatype.UID >= (int)PrimitiveType.kMaxPrimitives)
                            {
                                autogenRef.PushUpdateNodeRef(updateRef);
                                graphNode.updateNodeRefList.Add(autogenRef);
                            }
                        }
                    }
                }

                if (graphNode.updatedArguments.Count > 0)
                {
                    // For each argument modified
                    int n = 0;

                    // Create the current modified argument
                    foreach (KeyValuePair<string, List<ProtoCore.AssociativeGraph.UpdateNodeRef>> argNameModifiedStatementsPair in firstProc.updatedArgumentProperties)
                    {
                        // For every single arguments' modified statements
                        foreach (ProtoCore.AssociativeGraph.UpdateNodeRef nodeRef in argNameModifiedStatementsPair.Value)
                        {
                            ProtoCore.AssociativeGraph.UpdateNodeRef argNodeRef = new ProtoCore.AssociativeGraph.UpdateNodeRef();
                            argNodeRef.PushUpdateNodeRef(graphNode.updatedArguments[n]);
                            argNodeRef.PushUpdateNodeRef(nodeRef);
                            graphNode.updateNodeRefList.Add(argNodeRef);
                        }
                        ++n;
                    }
                }
            }
        }
Esempio n. 33
0
 public UpdateNodeRef GetUntilFirstProc()
 {
     Validity.Assert(null != nodeList);
     UpdateNodeRef newRef = new UpdateNodeRef();
     foreach (UpdateNode node in nodeList)
     {
         if (node.nodeType != UpdateNodeType.kMethod)
         {
             newRef.nodeList.Add(node);
         }
     }
     return newRef;
 }
Esempio n. 34
0
        public override ProcedureNode TraverseFunctionCall(
            ProtoCore.AST.Node node, 
            ProtoCore.AST.Node parentNode, 
            int lefttype, 
            int depth, 
            ref ProtoCore.Type inferedType,             
            GraphNode graphNode = null,
            ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass = ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone,                 
            ProtoCore.AST.Node bnode = null)
        {
            ProcedureNode procNode = null;
            if (node is FunctionDotCallNode)
            {
                procNode = TraverseDotFunctionCall(node, 
                                               parentNode, 
                                               lefttype, 
                                               depth, 
                                               graphNode, 
                                               subPass, 
                                               bnode as BinaryExpressionNode,
                                               ref inferedType);

                if (graphNode != null && procNode != null)
                {
                    GenerateCallsiteIdentifierForGraphNode(graphNode, procNode.Name);
                }
                return procNode;
            }

            var arglist = new List<ProtoCore.Type>();
            var funcCall = node as FunctionCallNode;
            var procName = funcCall.Function.Name;
            int classIndex = core.ClassTable.IndexOf(procName);

            // To support unamed constructor
            if (classIndex != Constants.kInvalidIndex)
            {
                bool isAccessible;
                int dummy;

                ProcedureNode constructor = core.ClassTable.ClassNodes[classIndex].GetMemberFunction(procName, arglist, globalClassIndex, out isAccessible, out dummy, true);
                if (constructor != null && constructor.IsConstructor)
                {
                    var rhsFNode = node as FunctionCallNode;
                    var classNode = AstFactory.BuildIdentifier(procName);
                    var dotCallNode = CoreUtils.GenerateCallDotNode(classNode, rhsFNode, core);

                    procNode = TraverseDotFunctionCall(dotCallNode, 
                                                   parentNode, 
                                                   lefttype, 
                                                   depth, 
                                                   graphNode, 
                                                   subPass, 
                                                   bnode as BinaryExpressionNode,
                                                   ref inferedType);
                    if (graphNode != null && procNode != null)
                    {
                        GenerateCallsiteIdentifierForGraphNode(graphNode, procNode.Name);
                    }
                    return procNode;
                }
            }

            foreach (AssociativeNode paramNode in funcCall.FormalArguments)
            {
                var paramType = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeVar, 0);

                // The range expression function does not need replication guides
                emitReplicationGuide = !procName.Equals(Constants.kFunctionRangeExpression)  
                                    && !CoreUtils.IsGetterSetter(procName);

                // If it's a binary node then continue type check, otherwise 
                // disable type check and just take the type of paramNode itself
                // f(1+2.0) -> type check enabled - param is typed as double
                // f(2) -> type check disabled - param is typed as int
                enforceTypeCheck = !(paramNode is BinaryExpressionNode);

                DfsTraverse(paramNode, ref paramType, false, graphNode, subPass, bnode);

                emitReplicationGuide = false;
                enforceTypeCheck = true;

                arglist.Add(paramType);
            }
           
            if (subPass == ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier)
            {
                return null;   
            }
                    
            int refClassIndex = Constants.kInvalidIndex;
            if (parentNode != null && parentNode is IdentifierListNode)
            {
                var leftnode = (parentNode as IdentifierListNode).LeftNode;
                if (leftnode != null && leftnode is IdentifierNode)
                {
                    refClassIndex = core.ClassTable.IndexOf(leftnode.Name);
                }
            }

            int type = Constants.kInvalidIndex;

            // Check for the actual method, not the dot method
            // If lefttype is a valid class then check if calling a constructor
            if ((int)PrimitiveType.kInvalidType != inferedType.UID
                && (int)PrimitiveType.kTypeVoid != inferedType.UID
                && procName != Constants.kFunctionPointerCall)
            {

                bool isAccessible;
                int realType;

                bool isStaticOrConstructor = refClassIndex != Constants.kInvalidIndex;
                procNode = core.ClassTable.ClassNodes[inferedType.UID].GetMemberFunction(procName, arglist, globalClassIndex, out isAccessible, out realType, isStaticOrConstructor);

                if (procNode != null)
                {
                    Validity.Assert(realType != Constants.kInvalidIndex);
                    type = lefttype = realType;

                    if (!isAccessible)
                    {
                        type = lefttype = realType;
                        procNode = null;
                        string message = String.Format(ProtoCore.Properties.Resources.kMethodIsInaccessible, procName);
                        buildStatus.LogWarning(WarningID.kAccessViolation, message, core.CurrentDSFileName, funcCall.line, funcCall.col, graphNode);
                        inferedType.UID = (int)PrimitiveType.kTypeNull;

                        EmitPushNull();
                        if (graphNode != null && procNode != null)
                        {
                            GenerateCallsiteIdentifierForGraphNode(graphNode, procNode.Name);
                        }
                        return procNode;
                    }

                }
            }

            // Try function pointer firstly
            if ((procNode == null) && (procName != ProtoCore.DSASM.Constants.kFunctionPointerCall))
            {
                bool isAccessibleFp;
                SymbolNode symbolnode = null;
                bool isAllocated = VerifyAllocation(procName, globalClassIndex, globalProcIndex, out symbolnode, out isAccessibleFp);

                if (isAllocated) 
                {
                    // The graph node always depends on this function pointer
                    if (null != graphNode)
                    {
                        PushSymbolAsDependent(symbolnode, graphNode);
                        GenerateCallsiteIdentifierForGraphNode(graphNode, procName);
                    }

                    // not checking the type against function pointer, as the 
                    // type could be var
                    procName = Constants.kFunctionPointerCall;
                }
            }

            // Always try global function firstly. Because we dont have syntax
            // support for calling global function (say, ::foo()), if we try
            // member function firstly, there is no way to call a global function
            // For member function, we can use this.foo() to distinguish it from 
            // global function. 
            if ((procNode == null) && (procName != Constants.kFunctionPointerCall))
            {
                procNode = CoreUtils.GetFunctionBySignature(procName, arglist, codeBlock);
                if (null != procNode)
                {
                    type = ProtoCore.DSASM.Constants.kGlobalScope;
                    if (core.TypeSystem.IsHigherRank(procNode.ReturnType.UID, inferedType.UID))
                    {
                        inferedType = procNode.ReturnType;
                    }
                }
            }

            // Try member functions in global class scope
            if ((procNode == null) && (procName != Constants.kFunctionPointerCall) && (parentNode == null))
            {
                if (globalClassIndex != Constants.kInvalidIndex)
                {
                    int realType;
                    bool isAccessible;
                    bool isStaticOrConstructor = refClassIndex != Constants.kInvalidIndex;
                    ProtoCore.DSASM.ProcedureNode memProcNode = core.ClassTable.ClassNodes[globalClassIndex].GetMemberFunction(procName, arglist, globalClassIndex, out isAccessible, out realType, isStaticOrConstructor);

                    if (memProcNode != null)
                    {
                        Validity.Assert(realType != Constants.kInvalidIndex);
                        procNode = memProcNode;
                        inferedType = procNode.ReturnType;
                        type = realType;

                        if (!isAccessible)
                        {
                            string message = String.Format(ProtoCore.Properties.Resources.kMethodIsInaccessible, procName);
                            buildStatus.LogWarning(WarningID.kAccessViolation, message, core.CurrentDSFileName, funcCall.line, funcCall.col, graphNode);

                            inferedType.UID = (int)PrimitiveType.kTypeNull;
                            EmitPushNull();
                            if (graphNode != null && procNode != null)
                            {
                                GenerateCallsiteIdentifierForGraphNode(graphNode, procNode.Name);
                            }
                            return procNode;
                        }
                    }
                }
            }

            if (null != procNode)
            {
                if (procNode.IsConstructor && 
                    (globalClassIndex != Constants.kInvalidIndex) && 
                    (globalProcIndex != Constants.kInvalidIndex) && 
                    (globalClassIndex == inferedType.UID))
                {
                    ProcedureNode contextProcNode = core.ClassTable.ClassNodes[globalClassIndex].ProcTable.Procedures[globalProcIndex];
                    if (contextProcNode.IsConstructor &&
                        string.Equals(contextProcNode.Name, procNode.Name) &&
                        contextProcNode.RuntimeIndex == procNode.RuntimeIndex)
                    {
                        string message = String.Format(ProtoCore.Properties.Resources.kCallingConstructorInConstructor, procName);
                        buildStatus.LogWarning(WarningID.kCallingConstructorInConstructor, message, core.CurrentDSFileName, node.line, node.col, graphNode);
                        inferedType.UID = (int)PrimitiveType.kTypeNull;
                        EmitPushNull();
                        if (graphNode != null && procNode != null)
                        {
                            GenerateCallsiteIdentifierForGraphNode(graphNode, procNode.Name);
                        }
                        return procNode;
                    }
                }

                inferedType = procNode.ReturnType;

                if (procNode.ID != Constants.kInvalidIndex)
                {
                    foreach (AssociativeNode paramNode in funcCall.FormalArguments)
                    {
                        // Get the lhs symbol list
                        ProtoCore.Type ltype = new ProtoCore.Type();
                        ltype.UID = globalClassIndex;
                        UpdateNodeRef argNodeRef = new UpdateNodeRef();
                        DFSGetSymbolList(paramNode, ref ltype, argNodeRef);

                        if (null != graphNode)
                        {
                            if (argNodeRef.nodeList.Count > 0)
                            {
                                graphNode.updatedArguments.Add(argNodeRef);
                            }
                        }
                    }

                    // The function is at block 0 if its a constructor, member 
                    // or at the globals scope.  Its at block 1 if its inside a 
                    // language block. Its limited to block 1 as of R1 since we 
                    // dont support nested function declarations yet
                    int blockId = procNode.RuntimeIndex;

                    //push value-not-provided default argument
                    for (int i = arglist.Count; i < procNode.ArgumentInfos.Count; i++)
                    {
                        EmitDefaultArgNode();
                    }
                    
                    // Push the function declaration block and indexed array
                    // Jun TODO: Implementeation of indexing into a function call:
                    //  x = f()[0][1]
                    int dimensions = 0;
                    EmitPushVarData(dimensions);

                    // Emit depth
                    EmitInstrConsole(kw.push, depth + "[depth]");
                    EmitPush(StackValue.BuildInt(depth));

                    // The function call
                    EmitInstrConsole(kw.callr, procNode.Name);

                    // Do not emit breakpoints at built-in methods like _add/_sub etc. - pratapa
                    if (procNode.IsAssocOperator || procNode.Name.Equals(Constants.kInlineConditionalMethodName))
                    {
                        EmitCall(procNode.ID, 
                                 blockId,
                                 type, 
                                 Constants.kInvalidIndex, 
                                 Constants.kInvalidIndex, 
                                 Constants.kInvalidIndex, 
                                 Constants.kInvalidIndex, 
                                 procNode.PC);
                    }
                    // Break at function call inside dynamic lang block created for a 'true' or 'false' expression inside an inline conditional
                    else if (core.DebuggerProperties.breakOptions.HasFlag(DebugProperties.BreakpointOptions.EmitInlineConditionalBreakpoint))
                    {
                        var codeRange = core.DebuggerProperties.highlightRange;

                        var startInclusive = codeRange.StartInclusive;
                        var endExclusive = codeRange.EndExclusive;

                        EmitCall(procNode.ID, 
                                 blockId,
                                 type, 
                                 startInclusive.LineNo, 
                                 startInclusive.CharNo, 
                                 endExclusive.LineNo, 
                                 endExclusive.CharNo, 
                                 procNode.PC);
                    }
                    // Use startCol and endCol of binary expression node containing function call except if it's a setter
                    else if (bnode != null && !procNode.Name.StartsWith(Constants.kSetterPrefix))
                    {
                        EmitCall(procNode.ID, 
                                 blockId,
                                 type, 
                                 bnode.line, 
                                 bnode.col, 
                                 bnode.endLine, 
                                 bnode.endCol, 
                                 procNode.PC);
                    }
                    else
                    {
                        EmitCall(procNode.ID, 
                                 blockId,
                                 type, 
                                 funcCall.line, 
                                 funcCall.col, 
                                 funcCall.endLine, 
                                 funcCall.endCol, 
                                 procNode.PC);
                    }

                    // The function return value
                    EmitInstrConsole(kw.push, kw.regRX);
                    StackValue opReturn = StackValue.BuildRegister(Registers.RX);
                    EmitPush(opReturn);
                }
            }
            else
            {
                if (depth <= 0 && procName != ProtoCore.DSASM.Constants.kFunctionPointerCall)
                {
                    string property;
                    if (CoreUtils.TryGetPropertyName(procName, out property))
                    {
                        string message = String.Format(ProtoCore.Properties.Resources.kPropertyNotFound, property);
                        buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kPropertyNotFound, message, core.CurrentDSFileName, funcCall.line, funcCall.col, graphNode);
                    }
                    else
                    {
                        string message = String.Format(ProtoCore.Properties.Resources.kMethodNotFound, procName);
                        buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kFunctionNotFound, message, core.CurrentDSFileName, funcCall.line, funcCall.col, graphNode);
                    }

                    inferedType.UID = (int)PrimitiveType.kTypeNull;
                    EmitPushNull();
                }
                else
                {
                    DynamicFunction dynFunc = null;
                    if (procName == Constants.kFunctionPointerCall && depth == 0)
                    {
                        if (!core.DynamicFunctionTable.TryGetFunction(procName, arglist.Count, lefttype, out dynFunc))
                        {
                            dynFunc = core.DynamicFunctionTable.AddNewFunction(procName, arglist.Count, lefttype);
                        }
                        var iNode =AstFactory.BuildIdentifier(funcCall.Function.Name);
                        EmitIdentifierNode(iNode, ref inferedType);
                    }
                    else
                    {
                        if (!core.DynamicFunctionTable.TryGetFunction(procName, arglist.Count, lefttype, out dynFunc))
                        {
                            dynFunc = core.DynamicFunctionTable.AddNewFunction(procName, arglist.Count, lefttype);
                        }
                    }

                    // Emit depth
                    EmitInstrConsole(kw.push, depth + "[depth]");
                    EmitPush(StackValue.BuildInt(depth));

                    // The function call
                    EmitInstrConsole(kw.callr, funcCall.Function.Name + "[dynamic]");
                    EmitDynamicCall(dynFunc.Index, 
                                    globalClassIndex, 
                                    funcCall.line, 
                                    funcCall.col, 
                                    funcCall.endLine, 
                                    funcCall.endCol);

                    // The function return value
                    EmitInstrConsole(kw.push, kw.regRX);
                    StackValue opReturn = StackValue.BuildRegister(Registers.RX);
                    EmitPush(opReturn);

                    //assign inferedType to var
                    inferedType.UID = (int)PrimitiveType.kTypeVar;
                }
            }

            if (graphNode != null && procNode != null)
            {
                GenerateCallsiteIdentifierForGraphNode(graphNode, procNode.Name);
            }
            
            return procNode;
        }
Esempio n. 35
0
        public bool IsEqual(UpdateNodeRef rhs)
        {
            if (nodeList.Count != rhs.nodeList.Count)
            {
                return false;
            }

            for (int n = 0; n < nodeList.Count; ++n)
            {
                if (nodeList[n].dimensionNodeList.Count != rhs.nodeList[n].dimensionNodeList.Count)
                {
                    return false;
                }
                else if (nodeList[n].dimensionNodeList.Count != 0)
                {
                    for (int m = 0; m < nodeList[n].dimensionNodeList.Count; m++)
                    {
                        if (nodeList[n].dimensionNodeList[m].symbol.name != rhs.nodeList[n].dimensionNodeList[m].symbol.name)
                        {
                            return false;
                        }
                    }
                }
                if (!nodeList[n].IsEqual(rhs.nodeList[n]))
                {
                    return false;
                }
            }
            return true;
        }
Esempio n. 36
0
        // 
        //  proc TraverseFunctionDef(node)
        //      ...
        //      def argList
        //      foreach arg in node.argdefinition
        //          ; Store not just the argument types, but also the argument identifier
        //          def argtype = buildtype(arg)
        //          argtype.name = arg.identname
        //          argList.push(argtype)
        //      end
        //      ...
        //  end
        //  

        private ProtoCore.AssociativeGraph.UpdateNodeRef __To__Deprecate__AutoGenerateUpdateArgumentReference(AssociativeNode node, ProtoCore.AssociativeGraph.GraphNode graphNode)
        {
            // Get the lhs symbol list
            ProtoCore.Type type = new ProtoCore.Type();
            type.UID = globalClassIndex;
            ProtoCore.AssociativeGraph.UpdateNodeRef leftNodeRef = new ProtoCore.AssociativeGraph.UpdateNodeRef();
            DFSGetSymbolList(node, ref type, leftNodeRef);

            ProtoCore.DSASM.SymbolNode firstSymbol = null;


            // Check if we are inside a procedure
            if (null != localProcedure)
            {
                // Check if there are at least 2 symbols in the list
                if (leftNodeRef.nodeList.Count >= 2)
                {
                    firstSymbol = leftNodeRef.nodeList[0].symbol;
                    if (null != firstSymbol && leftNodeRef.nodeList[0].nodeType != ProtoCore.AssociativeGraph.UpdateNodeType.kMethod)
                    {
                        // Now check if the first element of the identifier list is an argument
                        foreach (ProtoCore.DSASM.ArgumentInfo argInfo in localProcedure.ArgumentInfos)
                        {
                            if (argInfo.Name == firstSymbol.name)
                            {
                                leftNodeRef.nodeList.RemoveAt(0);

                                List<ProtoCore.AssociativeGraph.UpdateNodeRef> refList = null;
                                bool found = localProcedure.UpdatedArgumentProperties.TryGetValue(argInfo.Name, out refList);
                                if (found)
                                {
                                    refList.Add(leftNodeRef);
                                }
                                else
                                {
                                    refList = new List<ProtoCore.AssociativeGraph.UpdateNodeRef>();
                                    refList.Add(leftNodeRef);
                                    localProcedure.UpdatedArgumentProperties.Add(argInfo.Name, refList);
                                }
                            }
                        }
                    }
                }
            }
            return leftNodeRef;
        }
Esempio n. 37
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);
            }
        }
Esempio n. 38
0
        private ProtoCore.AssociativeGraph.UpdateNodeRef AutoGenerateUpdateReference(AssociativeNode node, ProtoCore.AssociativeGraph.GraphNode graphNode)
        {
            // Get the lhs symbol list
            ProtoCore.Type type = new ProtoCore.Type();
            type.UID = globalClassIndex;
            ProtoCore.AssociativeGraph.UpdateNodeRef leftNodeRef = new ProtoCore.AssociativeGraph.UpdateNodeRef();
            DFSGetSymbolList(node, ref type, leftNodeRef);


            // Auto-generate the updateNodeRefs for this graphnode given the list 
            // stored in the first procedure found in the assignment expression
            if (functionCallStack.Count > 0)
            {
                ProtoCore.DSASM.ProcedureNode firstProc = functionCallStack[0];
                if (!firstProc.IsAutoGenerated)
                {
                    graphNode.firstProc = firstProc;
                }
            }
            ProtoCore.DSASM.SymbolNode firstSymbol = null;

            // See if the leftmost symbol(updateNodeRef) of the lhs expression is a property of the current class. 
            // If it is, then push the lhs updateNodeRef to the list of modified properties in the procedure node
            if (null != localProcedure && leftNodeRef.nodeList.Count > 0)
            {
                firstSymbol = leftNodeRef.nodeList[0].symbol;

                // Check if this symbol being modified in this function is allocated in the current scope.
                // If it is, then it means this symbol is not a member and is local to this function
                ProtoCore.DSASM.SymbolNode symbolnode = null;
                bool isAccessible = false;
                bool isLocalVariable = VerifyAllocationInScope(firstSymbol.name, globalClassIndex, globalProcIndex, out symbolnode, out isAccessible);
                if (!isLocalVariable)
                {
                    if (null != firstSymbol && leftNodeRef.nodeList[0].nodeType != ProtoCore.AssociativeGraph.UpdateNodeType.kMethod)
                    {
                        if (firstSymbol.functionIndex == ProtoCore.DSASM.Constants.kGlobalScope)
                        {
                            // Does the symbol belong on the same class or class heirarchy as the function calling it
                            if (firstSymbol.classScope == localProcedure.ClassID)
                            {
                                localProcedure.UpdatedProperties.Push(leftNodeRef);
                            }
                            else
                            {
                                if (localProcedure.ClassID > 0)
                                {
                                    if (core.ClassTable.ClassNodes[localProcedure.ClassID].IsMyBase(firstSymbol.classScope))
                                    {
                                        localProcedure.UpdatedProperties.Push(leftNodeRef);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return leftNodeRef;
        }
Esempio n. 39
0
 public UpdateNodeRef GetUntilFirstProc()
 {
     UpdateNodeRef newRef = new UpdateNodeRef();
     foreach (UpdateNode node in nodeList)
     {
         if (node.nodeType != UpdateNodeType.Method)
         {
             newRef.nodeList.Add(node);
         }
     }
     return newRef;
 }