Example #1
0
        public ClassNode(ClassNode rhs)
        {
            IsImportedClass = rhs.IsImportedClass;
            name = rhs.name;
            size = rhs.size;
            hasCachedDisposeMethod = rhs.hasCachedDisposeMethod;
            disposeMethod = rhs.disposeMethod;
            rank = rhs.rank;
            symbols = new SymbolTable("classscope", 0);
            if (rhs.symbols != null)
            {
                symbols = new SymbolTable(rhs.symbols.ScopeName, rhs.symbols.RuntimeIndex);
            }
            defaultArgExprList = new List<AST.AssociativeAST.AssociativeNode>();
            classId = rhs.classId;

            int classRuntimProc = ProtoCore.DSASM.Constants.kInvalidIndex;
            vtable = new ProcedureTable(classRuntimProc);
            if (rhs.vtable != null)
            {
                vtable = new ProcedureTable(rhs.vtable);
            }
            baseList = new List<int>(rhs.baseList);
            ExternLib = rhs.ExternLib;
            typeSystem = rhs.typeSystem;
            coerceTypes = new Dictionary<int, int>(rhs.coerceTypes);
        }
        public static ProcedureNode GetClassAndProcFromGlobalInstance(ProcedureNode procNode, Core core, out int classIndex, List <Type> argTypeList)
        {
            string className = ProtoCore.Utils.CoreUtils.GetClassDeclarationName(procNode, core);

            classIndex = core.ClassTable.IndexOf(className);


            int removelength = 0;

            if (ProtoCore.Utils.CoreUtils.IsGlobalInstanceGetterSetter(procNode.name))
            {
                if (ProtoCore.Utils.CoreUtils.IsGlobalInstanceSetter(procNode.name))
                {
                    removelength = procNode.name.IndexOf(ProtoCore.DSASM.Constants.kSetterPrefix);
                }
                else
                {
                    removelength = procNode.name.IndexOf(ProtoCore.DSASM.Constants.kGetterPrefix);
                }
            }
            else
            {
                removelength  = procNode.name.IndexOf(ProtoCore.DSASM.Constants.kGlobalInstanceFunctionPrefix);
                removelength += ProtoCore.DSASM.Constants.kGlobalInstanceFunctionPrefix.Length;
            }

            string functionName = procNode.name.Remove(0, removelength);
            //ProtoCore.DSASM.ProcedureNode tmpProcNode = core.ClassTable.list[classIndex].GetFirstMemberFunction(functionName, procNode.argTypeList.Count - 1);

            int functionIndex = core.ClassTable.ClassNodes[classIndex].vtable.IndexOfExact(functionName, argTypeList, procNode.isAutoGeneratedThisProc);

            ProtoCore.DSASM.ProcedureNode tmpProcNode = core.ClassTable.ClassNodes[classIndex].vtable.procList[functionIndex];

            return(tmpProcNode);
        }
Example #3
0
        public ClassNode(ClassNode rhs)
        {
            IsImportedClass = rhs.IsImportedClass;
            Name = rhs.Name;
            Size = rhs.Size;
            hasCachedDisposeMethod = rhs.hasCachedDisposeMethod;
            disposeMethod = rhs.disposeMethod;
            Rank = rhs.Rank;
            Symbols = new SymbolTable("classscope", 0);
            if (rhs.Symbols != null)
            {
                Symbols = new SymbolTable(rhs.Symbols.ScopeName, rhs.Symbols.RuntimeIndex);
            }
            DefaultArgExprList = new List<AST.AssociativeAST.AssociativeNode>();
            ID = rhs.ID;

            int classRuntimProc = ProtoCore.DSASM.Constants.kInvalidIndex;
            ProcTable = new ProcedureTable(classRuntimProc);
            if (rhs.ProcTable != null)
            {
                ProcTable = new ProcedureTable(rhs.ProcTable);
            }
            Bases = new List<int>(rhs.Bases);
            ExternLib = rhs.ExternLib;
            TypeSystem = rhs.TypeSystem;
            CoerceTypes = new Dictionary<int, int>(rhs.CoerceTypes);
        }
Example #4
0
        public DSFunction(ProcedureNode dsProcedure)
        {
            procedure = dsProcedure;
            foreach (var arg in procedure.argInfoList)
            {
                InPortData.Add(new PortData(arg.Name, "parameter", typeof(object)));
            }
            OutPortData.Add(new PortData("", "Object inspected", typeof(object)));
            RegisterAllPorts();

            NickName = procedure.name;
        }
Example #5
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);
        }
        public FunctionPointerEvaluator(StackValue pointer, Interpreter dsi)
        {
            Validity.Assert(pointer.optype == AddressType.FunctionPointer);
            mRunTime = dsi;
            Core core = dsi.runtime.Core;

            int fptr = (int)pointer.opdata;
            ProtoCore.DSASM.FunctionPointerNode fptrNode;
            if (core.FunctionPointerTable.functionPointerDictionary.TryGetByFirst(fptr, out fptrNode))
            {
                int blockId = fptrNode.blockId;
                int procId = fptrNode.procId;
                mProcNode = dsi.runtime.exe.procedureTable[blockId].procList[procId];
            }

            mCallSite = new ProtoCore.CallSite(ProtoCore.DSASM.Constants.kGlobalScope, Name, core.FunctionTable, core.Options.ExecutionMode);
        }
        public FunctionPointerEvaluator(StackValue pointer, Interpreter dsi)
        {
            Validity.Assert(pointer.IsFunctionPointer);
            interpreter = dsi;
            RuntimeCore runtimeCore = dsi.runtime.RuntimeCore;

            int fptr = (int)pointer.opdata;
            FunctionPointerNode fptrNode;
            int classScope = Constants.kGlobalScope;

            if (runtimeCore.DSExecutable.FuncPointerTable.functionPointerDictionary.TryGetByFirst(fptr, out fptrNode))
            {
                int blockId = fptrNode.blockId;
                int procId = fptrNode.procId;
                classScope = fptrNode.classScope;
                procNode = dsi.runtime.GetProcedureNode(blockId, classScope, procId);
            }

            callsite = new ProtoCore.CallSite(classScope, Name, interpreter.runtime.exe.FunctionTable, runtimeCore.Options.ExecutionMode);
        }
Example #8
0
        public ProcedureNode GetFirstStaticFunctionBy(string procName, int argCount)
        {
            if (ProcTable == null)
            {
                return(null);
            }

            ProcedureNode procNode = ProcTable.GetFunctionsByNameAndArgumentNumber(procName, argCount)
                                     .Where(p => p.IsStatic)
                                     .FirstOrDefault();

            if (procNode != null)
            {
                return(procNode);
            }

            if (Base != Constants.kInvalidIndex)
            {
                var baseClass = TypeSystem.classTable.ClassNodes[Base];
                procNode = baseClass.GetFirstStaticFunctionBy(procName, argCount);
            }
            return(procNode);
        }
Example #9
0
 public ProcedureNode GetDisposeMethod()
 {
     if (!hasCachedDisposeMethod)
     {
         hasCachedDisposeMethod = true;
         if (ProcTable == null)
         {
             disposeMethod = null;
         }
         else
         {
             foreach (ProcedureNode procNode in ProcTable.Procedures)
             {
                 if (CoreUtils.IsDisposeMethod(procNode.Name) && procNode.ArgumentInfos.Count == 0)
                 {
                     disposeMethod = procNode;
                     break;
                 }
             }
         }
     }
     return(disposeMethod);
 }
Example #10
0
 public ProcedureNode GetDisposeMethod()
 {
     if (!hasCachedDisposeMethod)
     {
         hasCachedDisposeMethod = true;
         if (vtable == null)
         {
             disposeMethod = null;
         }
         else
         {
             foreach (ProcedureNode procNode in vtable.procList)
             {
                 if (procNode.name == ProtoCore.DSDefinitions.Kw.kw_Dispose && procNode.argInfoList.Count == 0)
                 {
                     disposeMethod = procNode;
                     break;
                 }
             }
         }
     }
     return(disposeMethod);
 }
Example #11
0
        public ClassNode()
        {
            IsImportedClass = false;
            Name = null;
            Size = 0;
            hasCachedDisposeMethod = false;
            disposeMethod = null;
            Rank = ProtoCore.DSASM.Constants.kDefaultClassRank;
            Symbols = new SymbolTable("classscope", 0);
            ID = (int)PrimitiveType.InvalidType;

            // Jun TODO: how significant is runtime index for class procedures?
            int classRuntimProc = ProtoCore.DSASM.Constants.kInvalidIndex;
            ProcTable = new ProcedureTable(classRuntimProc);
            Base = Constants.kInvalidIndex;
            ExternLib = string.Empty;

            // Set default allowed coerce types
            CoerceTypes = new Dictionary<int, int>();
            CoerceTypes.Add((int)ProtoCore.PrimitiveType.Var, (int)ProtoCore.DSASM.ProcedureDistance.CoerceScore);
            CoerceTypes.Add((int)ProtoCore.PrimitiveType.Array, (int)ProtoCore.DSASM.ProcedureDistance.CoerceScore);
            CoerceTypes.Add((int)ProtoCore.PrimitiveType.Null, (int)ProtoCore.DSASM.ProcedureDistance.CoerceScore);
        }
Example #12
0
 public ProcedureNode GetDisposeMethod()
 {
     if (!hasCachedDisposeMethod)
     {
         hasCachedDisposeMethod = true;
         if (vtable == null)
         {
             disposeMethod = null;
         }
         else
         {
             foreach (ProcedureNode procNode in vtable.procList)
             {
                 if (CoreUtils.IsDisposeMethod(procNode.name) && procNode.argInfoList.Count == 0)
                 {
                     disposeMethod = procNode;
                     break;
                 }
             }
         }
     }
     return(disposeMethod);
 }
Example #13
0
        public ClassNode()
        {
            IsImportedClass = false;
            name = null;
            size = 0;
            hasCachedDisposeMethod = false;
            disposeMethod = null;
            rank = ProtoCore.DSASM.Constants.kDefaultClassRank;
            symbols = new SymbolTable("classscope", 0);
            defaultArgExprList = new List<AST.AssociativeAST.BinaryExpressionNode>();
            classId = (int)PrimitiveType.kInvalidType;

            // Jun TODO: how significant is runtime index for class procedures?
            int classRuntimProc = ProtoCore.DSASM.Constants.kInvalidIndex;
            vtable = new ProcedureTable(classRuntimProc);
            baseList = new List<int>();
            ExternLib = string.Empty;

            // Set default allowed coerce types
            coerceTypes = new Dictionary<int, int>();
            coerceTypes.Add((int)ProtoCore.PrimitiveType.kTypeVar, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            coerceTypes.Add((int)ProtoCore.PrimitiveType.kTypeArray, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            coerceTypes.Add((int)ProtoCore.PrimitiveType.kTypeNull, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
        }
Example #14
0
        public ClassNode()
        {
            IsImportedClass        = false;
            Name                   = null;
            Size                   = 0;
            hasCachedDisposeMethod = false;
            disposeMethod          = null;
            Rank                   = ProtoCore.DSASM.Constants.kDefaultClassRank;
            Symbols                = new SymbolTable("classscope", 0);
            ID = (int)PrimitiveType.InvalidType;

            // Jun TODO: how significant is runtime index for class procedures?
            int classRuntimProc = ProtoCore.DSASM.Constants.kInvalidIndex;

            ProcTable = new ProcedureTable(classRuntimProc);
            Base      = Constants.kInvalidIndex;
            ExternLib = string.Empty;

            // Set default allowed coerce types
            CoerceTypes = new Dictionary <int, int>();
            CoerceTypes.Add((int)ProtoCore.PrimitiveType.Var, (int)ProtoCore.DSASM.ProcedureDistance.CoerceScore);
            CoerceTypes.Add((int)ProtoCore.PrimitiveType.Array, (int)ProtoCore.DSASM.ProcedureDistance.CoerceScore);
            CoerceTypes.Add((int)ProtoCore.PrimitiveType.Null, (int)ProtoCore.DSASM.ProcedureDistance.CoerceScore);
        }
Example #15
0
        public ProcedureNode GetFirstMemberFunctionBy(string procName, int argCount)
        {
            if (ProcTable == null)
            {
                return(null);
            }
            ProcedureNode procNode = ProcTable.GetFunctionsBy(procName, argCount).FirstOrDefault();

            if (procNode != null)
            {
                return(procNode);
            }

            foreach (int baseClassIndex in Bases)
            {
                var baseClass = TypeSystem.classTable.ClassNodes[baseClassIndex];
                procNode = baseClass.GetFirstMemberFunctionBy(procName, argCount);
                if (null != procNode)
                {
                    break;
                }
            }
            return(procNode);
        }
Example #16
0
        /// <summary>
        /// Try to get the original procedure node that the function pointer
        /// points to.
        /// </summary>
        /// <param name="functionPointer">Function pointer</param>
        /// <param name="core">Core</param>
        /// <param name="procNode">Procedure node</param>
        /// <returns></returns>
        public bool TryGetFunction(StackValue functionPointer, RuntimeCore runtimeCore, out ProcedureNode procNode)
        {
            procNode = null;

            int index = functionPointer.FunctionPointer;
            FunctionPointerNode fptrNode;

            if (functionPointerDictionary.TryGetByFirst(index, out fptrNode))
            {
                var blockId       = fptrNode.blockId;
                var classScope    = fptrNode.classScope;
                var functionIndex = fptrNode.procId;

                if (classScope != Constants.kGlobalScope)
                {
                    procNode = runtimeCore.DSExecutable.classTable.ClassNodes[classScope].ProcTable.Procedures[functionIndex];
                }
                else
                {
                    bool found = runtimeCore.DSExecutable.CompleteCodeBlockDict.TryGetValue(blockId, out CodeBlock codeBlock);
                    Validity.Assert(found, $"Could find code block with codeBlockId {blockId}");

                    procNode = codeBlock.procedureTable.Procedures[functionIndex];
                }

                return(true);
            }

            return(false);
        }
Example #17
0
        private void ReturnToCallSiteForReplication(ProcedureNode procNode, int ci, int fi)
        {
            // Jump back to Callr to call ResolveForReplication and recompute fep with next argument
            // Need to push new arguments, then cache block, dim and type, push them before calling callr - pratapa

            // This functionality has to be common for both Serial mode execution and the debugger - pratap
            List<StackValue> nextArgs = core.ContinuationStruct.NextDispatchArgs;

            foreach (var arg in nextArgs)
            {
                rmem.Push(arg);
            }

            // TODO: Currently functions can be defined only in the global and level 1 blocks (BlockIndex = 0 or 1)
            // Ideally the procNode.runtimeIndex should capture this information but this needs to be tested - pratapa
            //rmem.Push(StackValue.BuildNode(AddressType.BlockIndex, core.DebugProps.CurrentBlockId));
            rmem.Push(StackValue.BuildBlockIndex(procNode.runtimeIndex));

            // The function call dimension for the subsequent feps are assumed to be 0 for now
            // This is not being used currently except for stack alignment - pratapa
            rmem.Push(StackValue.BuildArrayDimension(0));

            // This is unused in Callr() but needed for stack alignment
            rmem.Push(StackValue.BuildStaticType((int)PrimitiveType.kTypeVar));

            bool explicitCall = true;
            Callr(fi, ci, core.ContinuationStruct.InitialDepth, ref explicitCall);
        }
Example #18
0
        private void SerialReplication(ProcedureNode procNode, ref int exeblock, int ci, int fi, DebugFrame debugFrame = null)
        {
            // TODO: Decide where to insert this common code block for Serial mode and Debugging - pratapa
            if (core.Options.ExecutionMode == ProtoCore.ExecutionMode.Serial || core.Options.IDEDebugMode)
            {
                RX = CallSite.PerformReturnTypeCoerce(procNode, core, RX);

                core.ContinuationStruct.RunningResult.Add(RX);
                core.ContinuationStruct.Result = RX;

                pc = core.ContinuationStruct.InitialPC;

                if (core.ContinuationStruct.Done)
                {
                    RX = HeapUtils.StoreArray(core.ContinuationStruct.RunningResult.ToArray(), null, core);
                    GCUtils.GCRetain(RX, core);

                    core.ContinuationStruct.RunningResult.Clear();
                    core.ContinuationStruct.IsFirstCall = true;

                    if (core.Options.IDEDebugMode)
                    {
                        // If stepping over function call in debug mode
                        if (core.DebugProps.RunMode == Runmode.StepNext)
                        {
                            // if stepping over outermost function call
                            if (!core.DebugProps.DebugStackFrameContains(DebugProperties.StackFrameFlagOptions.IsFunctionStepOver))
                            {
                                core.DebugProps.SetUpStepOverFunctionCalls(core, procNode, debugFrame.ExecutingGraphNode, debugFrame.HasDebugInfo);
                            }
                        }
                        // The DebugFrame passed here is the previous one that was popped off before this call
                        // In the case of Dot call the debugFrame obtained here is the one for the member function
                        // for both Break and non Break cases - pratapa
                        DebugPerformCoercionAndGC(debugFrame);

                        // If call returns to Dot Call, restore debug props for Dot call
                        debugFrame = core.DebugProps.DebugStackFrame.Peek();
                        if (debugFrame.IsDotCall)
                        {
                            List<Instruction> instructions = istream.instrList;
                            bool wasPopped = RestoreDebugPropsOnReturnFromBuiltIns(ref exeblock, ref instructions);
                            if (wasPopped)
                            {
                                executingBlock = exeblock;
                                core.DebugProps.CurrentBlockId = exeblock;
                            }
                            else
                            {
                                core.DebugProps.RestoreCallrForNoBreak(core, procNode, false);
                            }
                            DebugPerformCoercionAndGC(debugFrame);
                        }

                        //core.DebugProps.DebugEntryPC = currentPC;
                    }
                    // Perform return type coercion, GC and/or GC for Dot methods for Non-debug, Serial mode replication case
                    else
                    {
                        // If member function
                        // 1. Release array arguments to Member function
                        // 2. Release this pointer
                        bool isBaseCall = false;
                        StackValue? thisPtr = null;
                        if (thisPtr != null)
                        {
                            // Replicating member function
                            PerformCoercionAndGC(null, false, thisPtr, core.ContinuationStruct.InitialArguments, core.ContinuationStruct.InitialDotCallDimensions);

                            // Perform coercion and GC for Dot call
                            ProcedureNode dotCallprocNode = null;
                            List<StackValue> dotCallArgs = new List<StackValue>();
                            List<StackValue> dotCallDimensions = new List<StackValue>();
                            PerformCoercionAndGC(dotCallprocNode, false, null, dotCallArgs, dotCallDimensions);
                        }
                        else
                        {
                            PerformCoercionAndGC(procNode, isBaseCall, null, core.ContinuationStruct.InitialArguments, core.ContinuationStruct.InitialDotCallDimensions);
                        }
                    }

                    pc++;
                    return;

                }
                else
                {
                    // Jump back to Callr to call ResolveForReplication and recompute fep with next argument
                    core.ContinuationStruct.IsFirstCall = false;

                    ReturnToCallSiteForReplication(procNode, ci, fi);
                    return;
                }

            }
        }
Example #19
0
        private void EmitFunctionCall(int depth, 
                                      int type,
                                      List<ProtoCore.Type> arglist, 
                                      ProcedureNode procNode, 
                                      FunctionCallNode funcCall, 
                                      bool isGetter = false, 
                                      BinaryExpressionNode parentExpression = null)
        {
            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(ProtoCore.DSASM.kw.callr, procNode.Name);

            if (isGetter)
            {
                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))
            {
                ProtoCore.CodeModel.CodePoint startInclusive = core.DebuggerProperties.highlightRange.StartInclusive;
                ProtoCore.CodeModel.CodePoint endExclusive = core.DebuggerProperties.highlightRange.EndExclusive;

                EmitCall(procNode.ID, blockId, type, startInclusive.LineNo, startInclusive.CharNo, endExclusive.LineNo, endExclusive.CharNo, procNode.PC);
            }
            else if (parentExpression != null)
            {
                EmitCall(procNode.ID, blockId, type, parentExpression.line, parentExpression.col, parentExpression.endLine, parentExpression.endCol, procNode.PC);
            }
            else
            {
                EmitCall(procNode.ID, blockId, type, funcCall.line, funcCall.col, funcCall.endLine, funcCall.endCol, procNode.PC);
            }

            // The function return value
            EmitInstrConsole(ProtoCore.DSASM.kw.push, ProtoCore.DSASM.kw.regRX);
            StackValue opReturn = StackValue.BuildRegister(Registers.RX);
            EmitPush(opReturn);
        }
Example #20
0
        private void EmitFunctionDefinitionNode(AssociativeNode node, ref ProtoCore.Type inferedType, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone)
        {
            bool parseGlobalFunctionBody = null == localProcedure && ProtoCore.DSASM.AssociativeCompilePass.kGlobalFuncBody == compilePass;
            bool parseMemberFunctionBody = ProtoCore.DSASM.Constants.kGlobalScope != globalClassIndex && ProtoCore.DSASM.AssociativeCompilePass.kClassMemFuncBody == compilePass;

            FunctionDefinitionNode funcDef = node as FunctionDefinitionNode;
            localFunctionDefNode = funcDef;

            if (funcDef.IsAssocOperator)
            {
                isAssocOperator = true;
            }
            else
            {
                isAssocOperator = false;
            }

            bool hasReturnStatement = false;
            ProtoCore.DSASM.CodeBlockType origCodeBlockType = codeBlock.blockType;
            codeBlock.blockType = ProtoCore.DSASM.CodeBlockType.kFunction;
            if (IsParsingGlobalFunctionSig() || IsParsingMemberFunctionSig())
            {
                Debug.Assert(null == localProcedure);
                localProcedure = new ProtoCore.DSASM.ProcedureNode();

                localProcedure.name = funcDef.Name;
                localProcedure.pc = ProtoCore.DSASM.Constants.kInvalidIndex;
                localProcedure.localCount = 0; // Defer till all locals are allocated
                localProcedure.returntype.UID = compileStateTracker.TypeSystem.GetType(funcDef.ReturnType.Name);
                if (localProcedure.returntype.UID == (int)PrimitiveType.kInvalidType)
                {
                    string message = String.Format(ProtoCore.BuildData.WarningMessage.kReturnTypeUndefined, funcDef.ReturnType.Name, funcDef.Name);
                    buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kTypeUndefined, message, compileStateTracker.CurrentDSFileName, funcDef.line, funcDef.col);
                    localProcedure.returntype.UID = (int)PrimitiveType.kTypeVar;
                }
                localProcedure.returntype.IsIndexable = funcDef.ReturnType.IsIndexable;
                localProcedure.returntype.rank = funcDef.ReturnType.rank;
                localProcedure.isConstructor = false;
                localProcedure.isStatic = funcDef.IsStatic;
                localProcedure.runtimeIndex = codeBlock.codeBlockId;
                localProcedure.access = funcDef.access;
                localProcedure.isExternal = funcDef.IsExternLib;
                localProcedure.isAutoGenerated = funcDef.IsAutoGenerated;
                localProcedure.classScope = globalClassIndex;
                localProcedure.isAssocOperator = funcDef.IsAssocOperator;
                localProcedure.isAutoGeneratedThisProc = funcDef.IsAutoGeneratedThisProc;

                int peekFunctionindex = ProtoCore.DSASM.Constants.kInvalidIndex;

                if (ProtoCore.DSASM.Constants.kInvalidIndex == globalClassIndex)
                {
                    peekFunctionindex = codeBlock.procedureTable.procList.Count;
                }
                else
                {
                    peekFunctionindex = compileStateTracker.ClassTable.ClassNodes[globalClassIndex].vtable.procList.Count;
                }

                // Append arg symbols
                List<KeyValuePair<string, ProtoCore.Type>> argsToBeAllocated = new List<KeyValuePair<string, ProtoCore.Type>>();
                if (null != funcDef.Singnature)
                {
                    int argNumber = 0;
                    foreach (VarDeclNode argNode in funcDef.Singnature.Arguments)
                    {
                        ++argNumber;

                        IdentifierNode paramNode = null;
                        bool aIsDefault = false;
                        ProtoCore.AST.Node aDefaultExpression = null;
                        if (argNode.NameNode is IdentifierNode)
                        {
                            paramNode = argNode.NameNode as IdentifierNode;
                        }
                        else if (argNode.NameNode is BinaryExpressionNode)
                        {
                            BinaryExpressionNode bNode = argNode.NameNode as BinaryExpressionNode;
                            paramNode = bNode.LeftNode as IdentifierNode;
                            aIsDefault = true;
                            aDefaultExpression = bNode;
                            //buildStatus.LogSemanticError("Defualt parameters are not supported");
                            //throw new BuildHaltException();
                        }
                        else
                        {
                            Debug.Assert(false, "Check generated AST");
                        }

                        ProtoCore.Type argType = BuildArgumentTypeFromVarDeclNode(argNode);
                        // We dont directly allocate arguments now
                        argsToBeAllocated.Add(new KeyValuePair<string, ProtoCore.Type>(paramNode.Value, argType));

                        localProcedure.argTypeList.Add(argType);
                        ProtoCore.DSASM.ArgumentInfo argInfo = new ProtoCore.DSASM.ArgumentInfo { Name = paramNode.Value, isDefault = aIsDefault, defaultExpression = aDefaultExpression };
                        localProcedure.argInfoList.Add(argInfo);
                    }
                }

                if (ProtoCore.DSASM.Constants.kInvalidIndex == globalClassIndex)
                {
                    globalProcIndex = codeBlock.procedureTable.Append(localProcedure);
                }
                else
                {
                    globalProcIndex = compileStateTracker.ClassTable.ClassNodes[globalClassIndex].vtable.Append(localProcedure);
                }

                // Comment Jun: Catch this assert given the condition as this type of mismatch should never occur
                if (ProtoCore.DSASM.Constants.kInvalidIndex != globalProcIndex)
                {
                    Debug.Assert(peekFunctionindex == localProcedure.procId);

                    argsToBeAllocated.ForEach(arg =>
                    {
                        int symbolIndex = AllocateArg(arg.Key, globalProcIndex, arg.Value);
                        if (ProtoCore.DSASM.Constants.kInvalidIndex == symbolIndex)
                        {
                            throw new BuildHaltException("B2CB2093");
                        }
                    });

                    // TODO Jun: Remove this once agree that alltest cases assume the default assoc block is block 0
                    // NOTE: Only affects mirror, not actual execution
                    if (null == codeBlock.parent && pc <= 0)
                    {
                        // The first node in the top level block is a function
                        compileStateTracker.DSExecutable.isSingleAssocBlock = false;
                    }

            #if ENABLE_EXCEPTION_HANDLING
                    core.ExceptionHandlingManager.Register(codeBlock.codeBlockId, globalProcIndex, globalClassIndex);
            #endif
                }
                else
                {
                    string message = String.Format(ProtoCore.BuildData.WarningMessage.kMethodAlreadyDefined, localProcedure.name);
                    buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kFunctionAlreadyDefined, message, compileStateTracker.CurrentDSFileName, funcDef.line, funcDef.col);
                    funcDef.skipMe = true;
                }
            }
            else if (parseGlobalFunctionBody || parseMemberFunctionBody)
            {
                if (compileStateTracker.Options.DisableDisposeFunctionDebug)
                {
                    if (node.Name.Equals(ProtoCore.DSDefinitions.Keyword.Dispose))
                    {
                        compileStateTracker.Options.EmitBreakpoints = false;
                    }
                }

                // Build arglist for comparison
                List<ProtoCore.Type> argList = new List<ProtoCore.Type>();
                if (null != funcDef.Singnature)
                {
                    foreach (VarDeclNode argNode in funcDef.Singnature.Arguments)
                    {
                        ProtoCore.Type argType = BuildArgumentTypeFromVarDeclNode(argNode);
                        argList.Add(argType);
                    }
                }

                // Get the exisitng procedure that was added on the previous pass
                if (ProtoCore.DSASM.Constants.kInvalidIndex == globalClassIndex)
                {
                    globalProcIndex = codeBlock.procedureTable.IndexOfExact(funcDef.Name, argList);
                    localProcedure = codeBlock.procedureTable.procList[globalProcIndex];
                }
                else
                {
                    globalProcIndex = compileStateTracker.ClassTable.ClassNodes[globalClassIndex].vtable.IndexOfExact(funcDef.Name, argList);
                    localProcedure = compileStateTracker.ClassTable.ClassNodes[globalClassIndex].vtable.procList[globalProcIndex];
                }

                Debug.Assert(null != localProcedure);

                // code gen the attribute
                localProcedure.Attributes = PopulateAttributes(funcDef.Attributes);
                // Its only on the parse body pass where the real pc is determined. Update this procedures' pc
                //Debug.Assert(ProtoCore.DSASM.Constants.kInvalidIndex == localProcedure.pc);
                localProcedure.pc = pc;

                // Copy the active function to the core so nested language blocks can refer to it
                compileStateTracker.ProcNode = localProcedure;

                ProtoCore.FunctionEndPoint fep = null;
                if (!funcDef.IsExternLib)
                {
                    //Traverse default argument
                    emitDebugInfo = false;
                    foreach (ProtoCore.DSASM.ArgumentInfo argNode in localProcedure.argInfoList)
                    {
                        if (!argNode.isDefault)
                        {
                            continue;
                        }
                        BinaryExpressionNode bNode = argNode.defaultExpression as BinaryExpressionNode;
                        // build a temporay node for statement : temp = defaultarg;
                        var iNodeTemp = nodeBuilder.BuildTempVariable();
                        var bNodeTemp = nodeBuilder.BuildBinaryExpression(iNodeTemp, bNode.LeftNode) as BinaryExpressionNode;
                        EmitBinaryExpressionNode(bNodeTemp, ref inferedType, false, null, AssociativeSubCompilePass.kUnboundIdentifier);
                        //duild an inline conditional node for statement: defaultarg = (temp == DefaultArgNode) ? defaultValue : temp;
                        InlineConditionalNode icNode = new InlineConditionalNode();
                        icNode.IsAutoGenerated = true;
                        BinaryExpressionNode cExprNode = new BinaryExpressionNode();
                        cExprNode.Optr = ProtoCore.DSASM.Operator.eq;
                        cExprNode.LeftNode = iNodeTemp;
                        cExprNode.RightNode = new DefaultArgNode();
                        icNode.ConditionExpression = cExprNode;
                        icNode.TrueExpression = bNode.RightNode;
                        icNode.FalseExpression = iNodeTemp;
                        bNodeTemp.LeftNode = bNode.LeftNode;
                        bNodeTemp.RightNode = icNode;
                        EmitBinaryExpressionNode(bNodeTemp, ref inferedType, false, null, AssociativeSubCompilePass.kUnboundIdentifier);
                    }
                    emitDebugInfo = true;

                    EmitCompileLogFunctionStart(GetFunctionSignatureString(funcDef.Name, funcDef.ReturnType, funcDef.Singnature));

                    // Traverse definition
                    foreach (AssociativeNode bnode in funcDef.FunctionBody.Body)
                    {

                        //
                        // TODO Jun:    Handle stand alone language blocks
                        //              Integrate the subPass into a proper pass
                        //

                        ProtoCore.Type itype = new ProtoCore.Type();
                        itype.UID = (int)PrimitiveType.kTypeVar;

                        if (bnode is LanguageBlockNode)
                        {
                            // Build a binaryn node with a temporary lhs for every stand-alone language block
                            BinaryExpressionNode langBlockNode = new BinaryExpressionNode();
                            langBlockNode.LeftNode = nodeBuilder.BuildIdentfier(compileStateTracker.GenerateTempLangageVar());
                            langBlockNode.Optr = ProtoCore.DSASM.Operator.assign;
                            langBlockNode.RightNode = bnode;

                            //DfsTraverse(bnode, ref itype, false, null, ProtoCore.DSASM.AssociativeSubCompilePass.kNone);
                            DfsTraverse(langBlockNode, ref itype, false, null, subPass);
                        }
                        else
                        {
                            DfsTraverse(bnode, ref itype, false, null, subPass);
                        }

                        if (NodeUtils.IsReturnExpressionNode(bnode))
                            hasReturnStatement = true;
                    }
                    EmitCompileLogFunctionEnd();

                    // All locals have been stack allocated, update the local count of this function
                    localProcedure.localCount = compileStateTracker.BaseOffset;

                    if (ProtoCore.DSASM.Constants.kInvalidIndex == globalClassIndex)
                    {
                        localProcedure.localCount = compileStateTracker.BaseOffset;

                        // Update the param stack indices of this function
                        foreach (ProtoCore.DSASM.SymbolNode symnode in codeBlock.symbolTable.symbolList.Values)
                        {
                            if (symnode.functionIndex == localProcedure.procId && symnode.isArgument)
                            {
                                symnode.index -= localProcedure.localCount;
                            }
                        }
                    }
                    else
                    {
                        compileStateTracker.ClassTable.ClassNodes[globalClassIndex].vtable.procList[localProcedure.procId].localCount = compileStateTracker.BaseOffset;

                        // Update the param stack indices of this function
                        foreach (ProtoCore.DSASM.SymbolNode symnode in compileStateTracker.ClassTable.ClassNodes[globalClassIndex].symbols.symbolList.Values)
                        {
                            if (symnode.functionIndex == localProcedure.procId && symnode.isArgument)
                            {
                                symnode.index -= localProcedure.localCount;
                            }
                        }
                    }

                    ProtoCore.Lang.JILActivationRecord record = new ProtoCore.Lang.JILActivationRecord();
                    record.pc = localProcedure.pc;
                    record.locals = localProcedure.localCount;
                    record.classIndex = globalClassIndex;
                    record.funcIndex = localProcedure.procId;
                    fep = new ProtoCore.Lang.JILFunctionEndPoint(record);
                }
                else if (funcDef.BuiltInMethodId != ProtoCore.Lang.BuiltInMethods.MethodID.kInvalidMethodID)
                {
                    fep = new ProtoCore.Lang.BuiltInFunctionEndPoint(funcDef.BuiltInMethodId);
                }
                else
                {
                    ProtoCore.Lang.JILActivationRecord jRecord = new ProtoCore.Lang.JILActivationRecord();
                    jRecord.pc = localProcedure.pc;
                    jRecord.locals = localProcedure.localCount;
                    jRecord.classIndex = globalClassIndex;
                    jRecord.funcIndex = localProcedure.procId;

                    // TODO Jun/Luke: Wrap this into Core.Options and extend if needed
                  /*  bool isCSFFI = false;
                    if (isCSFFI)
                    {
                        ProtoCore.Lang.CSFFIActivationRecord record = new ProtoCore.Lang.CSFFIActivationRecord();
                        record.JILRecord = jRecord;
                        record.FunctionName = funcDef.Name;
                        record.ModuleName = funcDef.ExternLibName;
                        record.ModuleType = "dll";
                        record.IsDNI = funcDef.IsDNI;
                        record.ReturnType = funcDef.ReturnType;
                        record.ParameterTypes = localProcedure.argTypeList;
                        fep = new ProtoCore.Lang.CSFFIFunctionEndPoint(record);
                    }
                    else
                    {*/
                        ProtoCore.Lang.FFIActivationRecord record = new ProtoCore.Lang.FFIActivationRecord();
                        record.JILRecord = jRecord;
                        record.FunctionName = funcDef.Name;
                        record.ModuleName = funcDef.ExternLibName;
                        record.ModuleType = "dll";
                        record.IsDNI = funcDef.IsDNI;
                        record.ReturnType = funcDef.ReturnType;
                        record.ParameterTypes = localProcedure.argTypeList;
                        fep = new ProtoCore.Lang.FFIFunctionEndPoint(record);
                    //}
                }

                // Construct the fep arguments
                fep.FormalParams = new ProtoCore.Type[localProcedure.argTypeList.Count];
                fep.BlockScope = codeBlock.codeBlockId;
                fep.ClassOwnerIndex = localProcedure.classScope;
                fep.procedureNode = localProcedure;
                localProcedure.argTypeList.CopyTo(fep.FormalParams, 0);

                // TODO Jun: 'classIndexAtCallsite' is the class index as it is stored at the callsite function tables
                // Determine whether this still needs to be aligned to the actual 'classIndex' variable
                // The factors that will affect this is whether the 2 function tables (compiler and callsite) need to be merged
                int classIndexAtCallsite = globalClassIndex + 1;
                FunctionGroup functionGroup = compileStateTracker.FunctionTable.GetFunctionGroup(classIndexAtCallsite, funcDef.Name);
                if (functionGroup != null)
                {
                    functionGroup.FunctionEndPoints.Add(fep);
                }
                else
                {
                    // If any functions in the base class have the same name, append them here
                    FunctionGroup basegroup = null;

                    int ci = classIndexAtCallsite - 1;
                    if (ci != Constants.kInvalidIndex)
                    {
                        ProtoCore.DSASM.ClassNode cnode = compileStateTracker.ClassTable.ClassNodes[ci];
                        if (cnode.baseList.Count > 0)
                        {
                            Validity.Assert(1 == cnode.baseList.Count, "We don't support multiple inheritance yet");
                            basegroup = compileStateTracker.FunctionTable.GetFunctionGroup(cnode.baseList[0] + 1, funcDef.Name);
                        }
                    }

                    if (basegroup == null)
                    {
                        compileStateTracker.FunctionTable.AddFunctionEndPointer(classIndexAtCallsite, funcDef.Name, fep);
                    }
                    else
                    {
                        // Copy all non-private feps from the basegroup into this the new group
                        FunctionGroup newGroup = new FunctionGroup();
                        newGroup.CopyVisible(basegroup.FunctionEndPoints);
                        newGroup.FunctionEndPoints.Add(fep);

                        foreach (var newfep in newGroup.FunctionEndPoints)
                        {
                            compileStateTracker.FunctionTable.AddFunctionEndPointer(classIndexAtCallsite, funcDef.Name, newfep);
                        }

                    }
                }

                if (!hasReturnStatement && !funcDef.IsExternLib)
                {
                    if (!compileStateTracker.Options.SuppressFunctionResolutionWarning)
                    {
                        string message = String.Format(ProtoCore.BuildData.WarningMessage.kFunctionNotReturnAtAllCodePaths, localProcedure.name);
                        buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kMissingReturnStatement, message, compileStateTracker.CurrentDSFileName, funcDef.line, funcDef.col);
                    }
                    EmitReturnNull();
                }

                if (compileStateTracker.Options.DisableDisposeFunctionDebug)
                {
                    if (node.Name.Equals(ProtoCore.DSDefinitions.Keyword.Dispose))
                    {
                        compileStateTracker.Options.EmitBreakpoints = true;
                    }
                }
            }

            compileStateTracker.ProcNode = localProcedure = null;
            codeBlock.blockType = origCodeBlockType;
            globalProcIndex = ProtoCore.DSASM.Constants.kGlobalScope;
            localFunctionDefNode = null;
            compileStateTracker.BaseOffset = 0;
            argOffset = 0;
            isAssocOperator = false;
        }
Example #21
0
        // Comment Jun: 
        // Instead of this method, consider storing the name mangled methods original class name and varname
        public static string GetClassDeclarationName(ProcedureNode procNode, Core core)
        {
            string mangledName = procNode.name;
            mangledName = mangledName.Remove(0, ProtoCore.DSASM.Constants.kGlobalInstanceNamePrefix.Length);

            int start = mangledName.IndexOf(ProtoCore.DSASM.Constants.kGlobalInstanceFunctionPrefix);
            mangledName = mangledName.Remove(start);
            return mangledName;

            if (ProtoCore.DSASM.Constants.kInvalidIndex == procNode.classScope)
            {
                return string.Empty;
            }

            Validity.Assert(core.ClassTable.ClassNodes.Count > procNode.classScope);
            return core.ClassTable.ClassNodes[procNode.classScope].name;
        }
Example #22
0
 public bool IsEqual(ProcedureNode rhs)
 {
     return(procId == rhs.procId && classScope == rhs.classScope && localCount == rhs.localCount && name == rhs.name);
 }
Example #23
0
        private void EmitFunctionDefinitionNode(ImperativeNode node, ref ProtoCore.Type inferedType)
        {
            bool parseGlobalFunctionSig = null == localProcedure && ProtoCore.CompilerDefinitions.Imperative.CompilePass.kGlobalFuncSig == compilePass;
            bool parseGlobalFunctionBody = null == localProcedure && ProtoCore.CompilerDefinitions.Imperative.CompilePass.kGlobalFuncBody == compilePass;

            FunctionDefinitionNode funcDef = node as FunctionDefinitionNode;
            localFunctionDefNode = funcDef;

            ProtoCore.DSASM.CodeBlockType originalBlockType = codeBlock.blockType;
            codeBlock.blockType = ProtoCore.DSASM.CodeBlockType.kFunction;
            if (parseGlobalFunctionSig)
            {
                Validity.Assert(null == localProcedure);


                // TODO jun: Add semantics for checking overloads (different parameter types)
                localProcedure = new ProtoCore.DSASM.ProcedureNode();
                localProcedure.Name = funcDef.Name;
                localProcedure.PC = pc;
                localProcedure.LocalCount = funcDef.localVars;
                var returnType = new ProtoCore.Type();
                returnType.UID = core.TypeSystem.GetType(funcDef.ReturnType.Name);
                if (returnType.UID == (int)PrimitiveType.kInvalidType)
                {
                    string message = String.Format(ProtoCore.Properties.Resources.kReturnTypeUndefined, funcDef.ReturnType.Name, funcDef.Name);
                    buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kTypeUndefined, message, null, funcDef.line, funcDef.col, firstSSAGraphNode);
                    returnType.UID = (int)PrimitiveType.kTypeVar;
                }
                returnType.rank = funcDef.ReturnType.rank;
                localProcedure.ReturnType = returnType;
                localProcedure.RuntimeIndex = codeBlock.codeBlockId;
                globalProcIndex = codeBlock.procedureTable.Append(localProcedure);
                core.ProcNode = localProcedure;


                // Append arg symbols
                if (null != funcDef.Signature)
                {
                    foreach (VarDeclNode argNode in funcDef.Signature.Arguments)
                    {
                        IdentifierNode paramNode = null;
                        ProtoCore.AST.Node aDefaultExpression = null;
                        if (argNode.NameNode is IdentifierNode)
                        {
                            paramNode = argNode.NameNode as IdentifierNode;
                        }
                        else if (argNode.NameNode is BinaryExpressionNode)
                        {
                            BinaryExpressionNode bNode = argNode.NameNode as BinaryExpressionNode;
                            paramNode = bNode.LeftNode as IdentifierNode;
                            aDefaultExpression = bNode;
                        }
                        else
                        {
                            Validity.Assert(false, "Check generated AST");
                        }

                        ProtoCore.Type argType = BuildArgumentTypeFromVarDeclNode(argNode, firstSSAGraphNode);
                        int symbolIndex = AllocateArg(paramNode.Value, localProcedure.ID, argType);
                        if (ProtoCore.DSASM.Constants.kInvalidIndex == symbolIndex)
                        {
                            throw new BuildHaltException("26384684");
                        }

                        localProcedure.ArgumentTypes.Add(argType);
                        ProtoCore.DSASM.ArgumentInfo argInfo = new ProtoCore.DSASM.ArgumentInfo { DefaultExpression = aDefaultExpression };
                        localProcedure.ArgumentInfos.Add(argInfo);
                    }
                }         
            }
            else if (parseGlobalFunctionBody)
            {
                EmitCompileLogFunctionStart(GetFunctionSignatureString(funcDef.Name, funcDef.ReturnType, funcDef.Signature));

                // Build arglist for comparison
                List<ProtoCore.Type> argList = new List<ProtoCore.Type>();
                if (null != funcDef.Signature)
                {
                    foreach (VarDeclNode argNode in funcDef.Signature.Arguments)
                    {
                        ProtoCore.Type argType = BuildArgumentTypeFromVarDeclNode(argNode, firstSSAGraphNode);
                        argList.Add(argType);
                    }
                }

                // Get the exisitng procedure that was added on the previous pass
                globalProcIndex = codeBlock.procedureTable.IndexOfExact(funcDef.Name, argList, false);
                localProcedure = codeBlock.procedureTable.procList[globalProcIndex];


                Validity.Assert(null != localProcedure);
                localProcedure.Attributes = PopulateAttributes(funcDef.Attributes);
                // Its only on the parse body pass where the real pc is determined. Update this procedures' pc
                //Validity.Assert(ProtoCore.DSASM.Constants.kInvalidIndex == localProcedure.pc);
                localProcedure.PC = pc;

                // Copy the active function to the core so nested language blocks can refer to it
                core.ProcNode = localProcedure;

                // Arguments have been allocated, update the baseOffset
                localProcedure.LocalCount = core.BaseOffset;


                ProtoCore.FunctionEndPoint fep = null;
                                
                //Traverse default argument
                emitDebugInfo = false;
                foreach (ProtoCore.DSASM.ArgumentInfo argNode in localProcedure.ArgumentInfos)
                {
                    if (!argNode.IsDefault)
                    {
                        continue;
                    }
                    BinaryExpressionNode bNode = argNode.DefaultExpression as BinaryExpressionNode;

                    // build a temporay node for statement : temp = defaultarg;
                    var iNodeTemp = nodeBuilder.BuildIdentfier(Constants.kTempDefaultArg);
                    BinaryExpressionNode bNodeTemp = nodeBuilder.BuildBinaryExpression(iNodeTemp, bNode.LeftNode) as BinaryExpressionNode;
                    EmitBinaryExpressionNode(bNodeTemp, ref inferedType);

                    //duild an inline conditional node for statement: defaultarg = (temp == DefaultArgNode) ? defaultValue : temp;
                    InlineConditionalNode icNode = new InlineConditionalNode();
                    icNode.ConditionExpression = nodeBuilder.BuildBinaryExpression(iNodeTemp, new DefaultArgNode(), Operator.eq);
                    icNode.TrueExpression = bNode.RightNode;
                    icNode.FalseExpression = iNodeTemp;
                    bNodeTemp.LeftNode = bNode.LeftNode;
                    bNodeTemp.RightNode = icNode;
                    EmitBinaryExpressionNode(bNodeTemp, ref inferedType);
                }
                emitDebugInfo = true;

                // Traverse definition
                bool hasReturnStatement = false;
                foreach (ImperativeNode bnode in funcDef.FunctionBody.Body)
                {
                    DfsTraverse(bnode, ref inferedType);
                    if (ProtoCore.Utils.NodeUtils.IsReturnExpressionNode(bnode))
                    {
                        hasReturnStatement = true;
                    }

                    if (bnode is FunctionCallNode)
                    {
                        EmitSetExpressionUID(core.ExpressionUID++);
                    }
                }

                // All locals have been stack allocated, update the local count of this function
                localProcedure.LocalCount = core.BaseOffset;

                // Update the param stack indices of this function
                foreach (ProtoCore.DSASM.SymbolNode symnode in codeBlock.symbolTable.symbolList.Values)
                {
                    if (symnode.functionIndex == localProcedure.ID && symnode.isArgument)
                    {
                        symnode.index -= localProcedure.LocalCount;
                    }
                }

                ProtoCore.Lang.JILActivationRecord record = new ProtoCore.Lang.JILActivationRecord();
                record.pc = localProcedure.PC;
                record.locals = localProcedure.LocalCount;
                record.classIndex = ProtoCore.DSASM.Constants.kInvalidIndex;
                record.funcIndex = localProcedure.ID;
                fep = new ProtoCore.Lang.JILFunctionEndPoint(record);



                // Construct the fep arguments
                fep.FormalParams = new ProtoCore.Type[localProcedure.ArgumentTypes.Count];
                fep.BlockScope = codeBlock.codeBlockId;
                fep.procedureNode = localProcedure;
                localProcedure.ArgumentTypes.CopyTo(fep.FormalParams, 0);

                // TODO Jun: 'classIndexAtCallsite' is the class index as it is stored at the callsite function tables
                // Determine whether this still needs to be aligned to the actual 'classIndex' variable
                // The factors that will affect this is whether the 2 function tables (compiler and callsite) need to be merged
                int classIndexAtCallsite = ProtoCore.DSASM.Constants.kInvalidIndex + 1;
                if (!core.FunctionTable.GlobalFuncTable.ContainsKey(classIndexAtCallsite))
                {
                    Dictionary<string, FunctionGroup> funcList = new Dictionary<string, FunctionGroup>();
                    core.FunctionTable.GlobalFuncTable.Add(classIndexAtCallsite, funcList);
                }

                Dictionary<string, FunctionGroup> fgroup = core.FunctionTable.GlobalFuncTable[classIndexAtCallsite];
                if (!fgroup.ContainsKey(funcDef.Name))
                {
                    // Create a new function group in this class
                    ProtoCore.FunctionGroup funcGroup = new ProtoCore.FunctionGroup();
                    funcGroup.FunctionEndPoints.Add(fep);

                    // Add this group to the class function tables
                    core.FunctionTable.GlobalFuncTable[classIndexAtCallsite].Add(funcDef.Name, funcGroup);
                }
                else
                {
                    // Add this fep into the exisitng function group
                    core.FunctionTable.GlobalFuncTable[classIndexAtCallsite][funcDef.Name].FunctionEndPoints.Add(fep);
                }

                if (!hasReturnStatement)
                {
                    if (!core.Options.SuppressFunctionResolutionWarning)
                    {
                        string message = String.Format(ProtoCore.Properties.Resources.kFunctionNotReturnAtAllCodePaths, localProcedure.Name);
                        core.BuildStatus.LogWarning(ProtoCore.BuildData.WarningID.kMissingReturnStatement, message, core.CurrentDSFileName, funcDef.line, funcDef.col, firstSSAGraphNode);
                    }

                    EmitReturnNull();
                }

                EmitCompileLogFunctionEnd();
                //Fuqiang: return is already done in traversing the function body
                //// function return
                //EmitInstrConsole(ProtoCore.DSASM.kw.ret);
                //EmitReturn();
            }

            core.ProcNode = localProcedure = null;
            globalProcIndex = ProtoCore.DSASM.Constants.kGlobalScope;
            argOffset = 0;
            core.BaseOffset = 0;
            codeBlock.blockType = originalBlockType;
            localFunctionDefNode = null;
        }
Example #24
0
 public ProcedureNode GetDisposeMethod()
 {
     if (!hasCachedDisposeMethod)
     {
         hasCachedDisposeMethod = true;
         if (ProcTable == null)
         {
             disposeMethod = null;
         }
         else
         {
             foreach (ProcedureNode procNode in ProcTable.Procedures)
             {
                 if (CoreUtils.IsDisposeMethod(procNode.Name) && procNode.ArgumentInfos.Count == 0)
                 {
                     disposeMethod = procNode;
                     break;
                 }
             }
         }
     }
     return disposeMethod;
 }
Example #25
0
        public CodeGen(Core coreObj, ProtoCore.DSASM.CodeBlock parentBlock = null)
        {
            Validity.Assert(coreObj != null);
            core = coreObj;
            buildStatus = core.BuildStatus;
            isEntrySet = false;

            emitReplicationGuide = false;

            dumpByteCode = core.Options.DumpByteCode;
            isAssocOperator = false;

            pc = 0;
            argOffset = 0;
            globalClassIndex = core.ClassIndex;

            context = new ProtoCore.CompileTime.Context();

            targetLangBlock = ProtoCore.DSASM.Constants.kInvalidIndex;

            enforceTypeCheck = true;

            localProcedure = core.ProcNode;
            globalProcIndex = null != localProcedure ? localProcedure.ID : ProtoCore.DSASM.Constants.kGlobalScope;

            tryLevel = 0;

            functionCallStack = new List<DSASM.ProcedureNode>();

            IsAssociativeArrayIndexing = false;

            if (core.AsmOutput == null)
            {
                if (core.Options.CompileToLib)
                {
                    string path = "";
                    if (core.Options.LibPath == null)
                    {
                        path += core.Options.RootModulePathName + "ASM";
                    }
                    else
                    {
                        path = Path.Combine(core.Options.LibPath, Path.GetFileNameWithoutExtension(core.Options.RootModulePathName) + ".dsASM");
                    }

                    core.AsmOutput = new StreamWriter(File.Open(path, FileMode.Create));
                }
                else
                {
                    core.AsmOutput = Console.Out;
                }
            }

            ssaPointerStack = new Stack<List<AST.AssociativeAST.AssociativeNode>>();
        }
Example #26
0
        // Deperecate this function after further regression testing and just use DFSGetSymbolList
        public void DFSGetSymbolList_Simple(Node pNode, ref ProtoCore.Type lefttype, ref int functionindex, ProtoCore.AssociativeGraph.UpdateNodeRef nodeRef)
        {
            dynamic node = pNode;
            if (node is ProtoCore.AST.ImperativeAST.IdentifierListNode || node is ProtoCore.AST.AssociativeAST.IdentifierListNode)
            {
                dynamic bnode = node;
                DFSGetSymbolList_Simple(bnode.LeftNode, ref lefttype, ref functionindex, nodeRef);
                node = bnode.RightNode;
            }

            if (node is ProtoCore.AST.ImperativeAST.IdentifierNode || node is ProtoCore.AST.AssociativeAST.IdentifierNode)
            {
                dynamic identnode = node;
                ProtoCore.DSASM.SymbolNode symbolnode = null;

                bool isAccessible = false;

                bool isAllocated = VerifyAllocation(identnode.Value, lefttype.UID, functionindex, out symbolnode, out isAccessible);
                if (isAllocated)
                {
                    if (null == symbolnode)
                    {
                        // It is inaccessible from here due to access modifier.
                        // Just attempt to retrieve the symbol
                        int symindex = core.ClassTable.ClassNodes[lefttype.UID].GetFirstVisibleSymbolNoAccessCheck(identnode.Value);
                        if (ProtoCore.DSASM.Constants.kInvalidIndex != symindex)
                        {
                            symbolnode = core.ClassTable.ClassNodes[lefttype.UID].Symbols.symbolList[symindex];
                        }
                    }

                    // Since the variable was found, all succeeding nodes in the ident list are class members
                    // Class members have a function scope of kGlobalScope as they are only local to the class, not with any member function
                    functionindex = ProtoCore.DSASM.Constants.kGlobalScope;

                    lefttype = symbolnode.datatype;

                    ProtoCore.AssociativeGraph.UpdateNode updateNode = new AssociativeGraph.UpdateNode();
                    updateNode.symbol = symbolnode;
                    updateNode.nodeType = ProtoCore.AssociativeGraph.UpdateNodeType.kSymbol;
                    nodeRef.PushUpdateNode(updateNode);
                }
                else
                {
                    // Is it a class?
                    int ci = core.ClassTable.IndexOf(identnode.Value);
                    if (ProtoCore.DSASM.Constants.kInvalidIndex != ci)
                    {
                        lefttype.UID = ci;

                        // Comment Jun:
                        // Create a symbol node that contains information about the class type that contains static properties
                        ProtoCore.DSASM.SymbolNode classSymbol = new DSASM.SymbolNode();
                        classSymbol.memregion = DSASM.MemoryRegion.kMemStatic;
                        classSymbol.name = identnode.Value;
                        classSymbol.classScope = ci;

                        ProtoCore.AssociativeGraph.UpdateNode updateNode = new AssociativeGraph.UpdateNode();
                        updateNode.symbol = classSymbol;
                        updateNode.nodeType = ProtoCore.AssociativeGraph.UpdateNodeType.kSymbol;
                        nodeRef.PushUpdateNode(updateNode);

                    }
                    else
                    {
                        // In this case, the lhs type is undefined
                        // Just attempt to create a symbol node
                        string ident = identnode.Value;
                        if (0 != ident.CompareTo(ProtoCore.DSDefinitions.Keyword.This))
                        {
                            symbolnode = new SymbolNode();
                            symbolnode.name = identnode.Value;

                            ProtoCore.AssociativeGraph.UpdateNode updateNode = new AssociativeGraph.UpdateNode();
                            updateNode.symbol = symbolnode;
                            updateNode.nodeType = AssociativeGraph.UpdateNodeType.kSymbol;
                            nodeRef.PushUpdateNode(updateNode);
                        }
                    }
                }
            }
            else if (node is ProtoCore.AST.ImperativeAST.FunctionCallNode || node is ProtoCore.AST.AssociativeAST.FunctionCallNode)
            {
                string functionName = node.Function.Value;
                if (ProtoCore.Utils.CoreUtils.IsGetterSetter(functionName))
                {
                    string property;
                    if (CoreUtils.TryGetPropertyName(functionName, out property))
                    {
                        functionName = property;
                    }
                    ProtoCore.DSASM.SymbolNode symbolnode = null;


                    bool isAccessible = false;
                    bool isAllocated = VerifyAllocation(functionName, lefttype.UID, globalProcIndex, out symbolnode, out isAccessible);
                    if (isAllocated)
                    {
                        if (null == symbolnode)
                        {
                            // It is inaccessible from here due to access modifier.
                            // Just attempt to retrieve the symbol
                            int symindex = core.ClassTable.ClassNodes[lefttype.UID].GetFirstVisibleSymbolNoAccessCheck(functionName);
                            if (ProtoCore.DSASM.Constants.kInvalidIndex != symindex)
                            {
                                symbolnode = core.ClassTable.ClassNodes[lefttype.UID].Symbols.symbolList[symindex];
                            }
                        }

                        lefttype = symbolnode.datatype;

                        ProtoCore.AssociativeGraph.UpdateNode updateNode = new AssociativeGraph.UpdateNode();
                        updateNode.symbol = symbolnode;
                        updateNode.nodeType = AssociativeGraph.UpdateNodeType.kSymbol;
                        nodeRef.PushUpdateNode(updateNode);
                    }
                }
                else
                {
                    ProtoCore.AssociativeGraph.UpdateNode updateNode = new AssociativeGraph.UpdateNode();
                    ProtoCore.DSASM.ProcedureNode procNodeDummy = new DSASM.ProcedureNode();
                    procNodeDummy.Name = functionName;
                    updateNode.procNode = procNodeDummy;
                    updateNode.nodeType = AssociativeGraph.UpdateNodeType.kMethod;
                    nodeRef.PushUpdateNode(updateNode);
                }
            }
        }
Example #27
0
        /// <summary>
        /// Get function by its signature.
        /// </summary>
        /// <param name="opts">Matching options</param>
        /// <param name="outputProcNode">Output procedure node. Null if nothing is found</param>
        /// <returns>Index of the ProcedureNode in the Procedures list. Returns -1 If nothing is found</returns>
        internal int GetFunctionBySignature(ProcedureMatchOptions opts, out ProcedureNode outputProcNode)
        {
            int outputProcNodeIndex = Constants.kInvalidIndex;

            outputProcNode = null;

            // how many default parameters are used
            int smallestDefaultArgNum = int.MaxValue;

            for (int ii = 0; ii < Procedures.Count; ++ii)
            {
                var f = Procedures[ii];

                if (opts.FilterCallback(f) == false)
                {
                    continue;
                }

                if ((opts.FunctionName != f.Name) ||
                    (opts.ExcludeAutoGeneratedThisProc && f.IsAutoGeneratedThisProc) ||
                    (opts.IsStatic != null) && (opts.IsStatic != f.IsStatic) ||
                    (opts.IsConstructor != null) && (opts.IsConstructor != f.IsConstructor))
                {
                    goto NotMatch;
                }

                if (!f.IsActive)
                {
                    goto NotMatch;
                }

                if (opts.ParameterTypes != null)
                {
                    var argNum   = f.ArgumentTypes.Count;
                    var paramNum = opts.ParameterTypes.Count;

                    if (opts.ExactMatchWithNumArgs && (argNum != paramNum))
                    {
                        goto NotMatch;
                    }

                    if (opts.ExactMatchWithArgTypes)
                    {
                        for (int k = 0; k < paramNum; k++)
                        {
                            if (f.ArgumentTypes[k].Name != opts.ParameterTypes[k].Name || f.ArgumentTypes[k].UID != opts.ParameterTypes[k].UID)
                            {
                                goto NotMatch;
                            }
                        }
                    }

                    int defaultArgs = f.ArgumentInfos.Count(X => X.DefaultExpression != null);
                    if ((argNum < paramNum) || (defaultArgs < argNum - paramNum))
                    {
                        // The current procedure has either:
                        // too less arguments that we are looking for.
                        // or
                        // too many arguments(even with defaults) than we are looking for
                        goto NotMatch;
                    }

                    // Look for the function with the least amount of default arguments
                    var num = argNum - paramNum;
                    if (num <= smallestDefaultArgNum)
                    {
                        smallestDefaultArgNum = num;

                        outputProcNodeIndex = ii;
                        outputProcNode      = Procedures[ii];
                    }

                    if (smallestDefaultArgNum == 0)
                    {
                        break;
                    }
                }
                else
                {
                    outputProcNodeIndex = ii;
                    outputProcNode      = Procedures[ii];

                    break;
                }

NotMatch:
                ;
            }
            return(outputProcNodeIndex);
        }
Example #28
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;
        }
Example #29
0
 internal MethodMirror(ProcedureNode procNode)
 {
     MethodName = procNode.Name;
     this.Name = MethodName;
     IsConstructor = procNode.IsConstructor;
     IsStatic = procNode.IsStatic;
     this.procNode = procNode;
 }
Example #30
0
        private void EmitConstructorDefinitionNode(AssociativeNode node, ref ProtoCore.Type inferedType, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone)
        {
            ConstructorDefinitionNode funcDef = node as ConstructorDefinitionNode;
            ProtoCore.DSASM.CodeBlockType originalBlockType = codeBlock.blockType;
            codeBlock.blockType = ProtoCore.DSASM.CodeBlockType.kFunction;

            if (IsParsingMemberFunctionSig())
            {
                Debug.Assert(null == localProcedure);
                localProcedure = new ProtoCore.DSASM.ProcedureNode();

                localProcedure.name = funcDef.Name;
                localProcedure.pc = ProtoCore.DSASM.Constants.kInvalidIndex;
                localProcedure.localCount = 0;// Defer till all locals are allocated
                localProcedure.returntype.UID = globalClassIndex;
                localProcedure.returntype.IsIndexable = false;
                localProcedure.isConstructor = true;
                localProcedure.runtimeIndex = 0;
                localProcedure.isExternal = funcDef.IsExternLib;
                Debug.Assert(ProtoCore.DSASM.Constants.kInvalidIndex != globalClassIndex, "A constructor node must be associated with class");
                localProcedure.localCount = 0;
                localProcedure.classScope = globalClassIndex;

                int peekFunctionindex = compileStateTracker.ClassTable.ClassNodes[globalClassIndex].vtable.procList.Count;

                // Append arg symbols
                List<KeyValuePair<string, ProtoCore.Type>> argsToBeAllocated = new List<KeyValuePair<string, ProtoCore.Type>>();
                if (null != funcDef.Signature)
                {
                    int argNumber = 0;
                    foreach (VarDeclNode argNode in funcDef.Signature.Arguments)
                    {
                        ++argNumber;

                        IdentifierNode paramNode = null;
                        bool aIsDefault = false;
                        ProtoCore.AST.Node aDefaultExpression = null;
                        if (argNode.NameNode is IdentifierNode)
                        {
                            paramNode = argNode.NameNode as IdentifierNode;
                        }
                        else if (argNode.NameNode is BinaryExpressionNode)
                        {
                            BinaryExpressionNode bNode = argNode.NameNode as BinaryExpressionNode;
                            paramNode = bNode.LeftNode as IdentifierNode;
                            aIsDefault = true;
                            aDefaultExpression = bNode;
                            //buildStatus.LogSemanticError("Default parameters are not supported");
                            //throw new BuildHaltException();
                        }
                        else
                        {
                            Debug.Assert(false, "Check generated AST");
                        }

                        ProtoCore.Type argType = BuildArgumentTypeFromVarDeclNode(argNode);
                        argsToBeAllocated.Add(new KeyValuePair<string, ProtoCore.Type>(paramNode.Value, argType));
                        localProcedure.argTypeList.Add(argType);
                        ProtoCore.DSASM.ArgumentInfo argInfo = new ProtoCore.DSASM.ArgumentInfo { Name = paramNode.Value, isDefault = aIsDefault, defaultExpression = aDefaultExpression };
                        localProcedure.argInfoList.Add(argInfo);
                    }
                }

                int findex = compileStateTracker.ClassTable.ClassNodes[globalClassIndex].vtable.Append(localProcedure);

                // Comment Jun: Catch this assert given the condition as this type of mismatch should never occur
                if (ProtoCore.DSASM.Constants.kInvalidIndex != findex)
                {
                    Debug.Assert(peekFunctionindex == localProcedure.procId);
                    argsToBeAllocated.ForEach(arg =>
                    {
                        int symbolIndex = AllocateArg(arg.Key, findex, arg.Value);
                        if (ProtoCore.DSASM.Constants.kInvalidIndex == symbolIndex)
                        {
                            throw new BuildHaltException("44B557F1");
                        }
                    });
                }
                else
                {
                    string message = String.Format(ProtoCore.BuildData.WarningMessage.kMethodAlreadyDefined, localProcedure.name);
                    buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kFunctionAlreadyDefined, message, compileStateTracker.CurrentDSFileName, funcDef.line, funcDef.col);
                    funcDef.skipMe = true;
                }
            }
            else if (IsParsingMemberFunctionBody())
            {
                EmitCompileLogFunctionStart(GetFunctionSignatureString(funcDef.Name, funcDef.ReturnType, funcDef.Signature, true));
                // Build arglist for comparison
                List<ProtoCore.Type> argList = new List<ProtoCore.Type>();
                if (null != funcDef.Signature)
                {
                    foreach (VarDeclNode argNode in funcDef.Signature.Arguments)
                    {
                        ProtoCore.Type argType = BuildArgumentTypeFromVarDeclNode(argNode);
                        argList.Add(argType);
                    }
                }

                globalProcIndex = compileStateTracker.ClassTable.ClassNodes[globalClassIndex].vtable.IndexOfExact(funcDef.Name, argList);

                Debug.Assert(null == localProcedure);
                localProcedure = compileStateTracker.ClassTable.ClassNodes[globalClassIndex].vtable.procList[globalProcIndex];

                Debug.Assert(null != localProcedure);
                localProcedure.Attributes = PopulateAttributes(funcDef.Attributes);
                // Its only on the parse body pass where the real pc is determined. Update this procedures' pc
                //Debug.Assert(ProtoCore.DSASM.Constants.kInvalidIndex == localProcedure.pc);
                localProcedure.pc = pc;

                EmitInstrConsole(ProtoCore.DSASM.kw.allocc, localProcedure.name);
                EmitAllocc(globalClassIndex);
                setConstructorStartPC = true;

                EmitCallingForBaseConstructor(globalClassIndex, funcDef.baseConstr);

                ProtoCore.FunctionEndPoint fep = null;
                if (!funcDef.IsExternLib)
                {
                    // Traverse default assignment for the class
                    emitDebugInfo = false;
                    foreach (BinaryExpressionNode bNode in compileStateTracker.ClassTable.ClassNodes[globalClassIndex].defaultArgExprList)
                    {

                        ProtoCore.AssociativeGraph.GraphNode graphNode = new ProtoCore.AssociativeGraph.GraphNode();
                        graphNode.isParent = true;
                        graphNode.exprUID = bNode.exprUID;
                        graphNode.modBlkUID = bNode.modBlkUID;
                        graphNode.procIndex = globalProcIndex;
                        graphNode.classIndex = globalClassIndex;
                        graphNode.isAutoGenerated = true;

                        EmitBinaryExpressionNode(bNode, ref inferedType, false, graphNode, subPass);
                    }

                    //Traverse default argument for the constructor
                    foreach (ProtoCore.DSASM.ArgumentInfo argNode in localProcedure.argInfoList)
                    {
                        if (!argNode.isDefault)
                        {
                            continue;
                        }
                        BinaryExpressionNode bNode = argNode.defaultExpression as BinaryExpressionNode;
                        // build a temporay node for statement : temp = defaultarg;
                        var iNodeTemp = nodeBuilder.BuildIdentfier(Constants.kTempDefaultArg);
                        BinaryExpressionNode bNodeTemp = new BinaryExpressionNode();
                        bNodeTemp.LeftNode = iNodeTemp;
                        bNodeTemp.Optr = ProtoCore.DSASM.Operator.assign;
                        bNodeTemp.RightNode = bNode.LeftNode;
                        EmitBinaryExpressionNode(bNodeTemp, ref inferedType);
                        //duild an inline conditional node for statement: defaultarg = (temp == DefaultArgNode) ? defaultValue : temp;
                        InlineConditionalNode icNode = new InlineConditionalNode();
                        icNode.IsAutoGenerated = true;
                        BinaryExpressionNode cExprNode = new BinaryExpressionNode();
                        cExprNode.Optr = ProtoCore.DSASM.Operator.eq;
                        cExprNode.LeftNode = iNodeTemp;
                        cExprNode.RightNode = new DefaultArgNode();
                        icNode.ConditionExpression = cExprNode;
                        icNode.TrueExpression = bNode.RightNode;
                        icNode.FalseExpression = iNodeTemp;
                        bNodeTemp.LeftNode = bNode.LeftNode;
                        bNodeTemp.RightNode = icNode;
                        EmitBinaryExpressionNode(bNodeTemp, ref inferedType);
                    }
                    emitDebugInfo = true;

                    // Traverse definition
                    foreach (AssociativeNode bnode in funcDef.FunctionBody.Body)
                    {
                        inferedType.UID = (int)PrimitiveType.kTypeVoid;
                        inferedType.rank = 0;

                        if (bnode is LanguageBlockNode)
                        {
                            // Build a binaryn node with a temporary lhs for every stand-alone language block
                            var iNode = nodeBuilder.BuildIdentfier(compileStateTracker.GenerateTempLangageVar());
                            BinaryExpressionNode langBlockNode = new BinaryExpressionNode();
                            langBlockNode.LeftNode = iNode;
                            langBlockNode.Optr = ProtoCore.DSASM.Operator.assign;
                            langBlockNode.RightNode = bnode;
                            DfsTraverse(langBlockNode, ref inferedType, false, null, subPass);
                        }
                        else
                        {
                            DfsTraverse(bnode, ref inferedType, false, null, subPass);
                        }
                    }

                    // All locals have been stack allocated, update the local count of this function
                    localProcedure.localCount = compileStateTracker.BaseOffset;
                    compileStateTracker.ClassTable.ClassNodes[globalClassIndex].vtable.procList[globalProcIndex].localCount = compileStateTracker.BaseOffset;

                    // Update the param stack indices of this function
                    foreach (ProtoCore.DSASM.SymbolNode symnode in compileStateTracker.ClassTable.ClassNodes[globalClassIndex].symbols.symbolList.Values)
                    {
                        if (symnode.functionIndex == globalProcIndex && symnode.isArgument)
                        {
                            symnode.index -= localProcedure.localCount;
                        }
                    }

                    // JIL FEP
                    ProtoCore.Lang.JILActivationRecord record = new ProtoCore.Lang.JILActivationRecord();
                    record.pc = localProcedure.pc;
                    record.locals = localProcedure.localCount;
                    record.classIndex = globalClassIndex;
                    record.funcIndex = globalProcIndex;

                    // Construct the fep arguments
                    fep = new ProtoCore.Lang.JILFunctionEndPoint(record);
                }
                else
                {
                    ProtoCore.Lang.JILActivationRecord jRecord = new ProtoCore.Lang.JILActivationRecord();
                    jRecord.pc = localProcedure.pc;
                    jRecord.locals = localProcedure.localCount;
                    jRecord.classIndex = globalClassIndex;
                    jRecord.funcIndex = localProcedure.procId;

                    ProtoCore.Lang.FFIActivationRecord record = new ProtoCore.Lang.FFIActivationRecord();
                    record.JILRecord = jRecord;
                    record.FunctionName = funcDef.Name;
                    record.ModuleName = funcDef.ExternLibName;
                    record.ModuleType = "dll";
                    record.IsDNI = false;
                    record.ReturnType = funcDef.ReturnType;
                    record.ParameterTypes = localProcedure.argTypeList;
                    fep = new ProtoCore.Lang.FFIFunctionEndPoint(record);
                }

                // Construct the fep arguments
                fep.FormalParams = new ProtoCore.Type[localProcedure.argTypeList.Count];
                fep.procedureNode = localProcedure;
                localProcedure.argTypeList.CopyTo(fep.FormalParams, 0);

                // TODO Jun: 'classIndexAtCallsite' is the class index as it is stored at the callsite function tables
                // Determine whether this still needs to be aligned to the actual 'classIndex' variable
                // The factors that will affect this is whether the 2 function tables (compiler and callsite) need to be merged
                int classIndexAtCallsite = globalClassIndex + 1;
                compileStateTracker.FunctionTable.AddFunctionEndPointer(classIndexAtCallsite, funcDef.Name, fep);

                int startpc = pc;

                // Constructors auto return
                EmitInstrConsole(ProtoCore.DSASM.kw.retc);

                // Stepping out of a constructor body will have the execution cursor
                // placed right at the closing curly bracket of the constructor definition.
                //
                int closeCurlyBracketLine = 0, closeCurlyBracketColumn = -1;
                if (null != funcDef.FunctionBody)
                {
                    closeCurlyBracketLine = funcDef.FunctionBody.endLine;
                    closeCurlyBracketColumn = funcDef.FunctionBody.endCol;
                }

                // The execution cursor covers exactly one character -- the closing
                // curly bracket. Note that we decrement the start-column by one here
                // because end-column of "FunctionBody" here is *after* the closing
                // curly bracket, so we want one before that.
                //
                EmitRetc(closeCurlyBracketLine, closeCurlyBracketColumn - 1,
                    closeCurlyBracketLine, closeCurlyBracketColumn);

                // Build and append a graphnode for this return statememt
                ProtoCore.DSASM.SymbolNode returnNode = new ProtoCore.DSASM.SymbolNode();
                returnNode.name = ProtoCore.DSDefinitions.Keyword.Return;

                ProtoCore.AssociativeGraph.GraphNode retNode = new ProtoCore.AssociativeGraph.GraphNode();
                //retNode.symbol = returnNode;
                retNode.PushSymbolReference(returnNode);
                retNode.procIndex = globalProcIndex;
                retNode.classIndex = globalClassIndex;
                retNode.updateBlock.startpc = startpc;
                retNode.updateBlock.endpc = pc - 1;

                codeBlock.instrStream.dependencyGraph.Push(retNode);
                EmitCompileLogFunctionEnd();
            }

            // Constructors have no return statemetns, reset variables here
            compileStateTracker.ProcNode = localProcedure = null;
            globalProcIndex = ProtoCore.DSASM.Constants.kGlobalScope;
            compileStateTracker.BaseOffset = 0;
            argOffset = 0;
            classOffset = 0;
            codeBlock.blockType = originalBlockType;
        }
Example #31
0
        private void EmitConstructorDefinitionNode(AssociativeNode node, ref ProtoCore.Type inferedType, ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass = ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone, GraphNode gNode = null)
        {
            ConstructorDefinitionNode funcDef = node as ConstructorDefinitionNode;
            ProtoCore.DSASM.CodeBlockType originalBlockType = codeBlock.blockType;
            codeBlock.blockType = ProtoCore.DSASM.CodeBlockType.kFunction;

            if (IsParsingMemberFunctionSig())
            {
                Validity.Assert(null == localProcedure);
                localProcedure = new ProtoCore.DSASM.ProcedureNode();

                localProcedure.Name = funcDef.Name;
                localProcedure.PC = ProtoCore.DSASM.Constants.kInvalidIndex;
                localProcedure.LocalCount = 0;// Defer till all locals are allocated
                ProtoCore.Type returnType = localProcedure.ReturnType; 
                if (globalClassIndex != -1)
                    returnType.Name = core.ClassTable.ClassNodes[globalClassIndex].Name;
                returnType.UID = globalClassIndex;
                returnType.rank = 0;
                localProcedure.ReturnType = returnType;
                localProcedure.IsConstructor = true;
                localProcedure.RuntimeIndex = 0;
                localProcedure.IsExternal = funcDef.IsExternLib;
                Validity.Assert(ProtoCore.DSASM.Constants.kInvalidIndex != globalClassIndex, "A constructor node must be associated with class");
                localProcedure.LocalCount = 0;
                localProcedure.ClassID = globalClassIndex;

                localProcedure.MethodAttribute = funcDef.MethodAttributes;

                int peekFunctionindex = core.ClassTable.ClassNodes[globalClassIndex].ProcTable.Procedures.Count;

                // Append arg symbols
                List<KeyValuePair<string, ProtoCore.Type>> argsToBeAllocated = new List<KeyValuePair<string, ProtoCore.Type>>();
                if (null != funcDef.Signature)
                {
                    foreach (VarDeclNode argNode in funcDef.Signature.Arguments)
                    {
                        var argInfo = BuildArgumentInfoFromVarDeclNode(argNode); 
                        localProcedure.ArgumentInfos.Add(argInfo);

                        var argType = BuildArgumentTypeFromVarDeclNode(argNode, gNode);
                        localProcedure.ArgumentTypes.Add(argType);

                        argsToBeAllocated.Add(new KeyValuePair<string, ProtoCore.Type>(argInfo.Name, argType));
                    }

                    localProcedure.IsVarArg = funcDef.Signature.IsVarArg;
                }

                int findex = core.ClassTable.ClassNodes[globalClassIndex].ProcTable.Append(localProcedure);

                // Comment Jun: Catch this assert given the condition as this type of mismatch should never occur
                if (ProtoCore.DSASM.Constants.kInvalidIndex != findex)
                {
                    Validity.Assert(peekFunctionindex == localProcedure.ID);
                    argsToBeAllocated.ForEach(arg =>
                    {
                        int symbolIndex = AllocateArg(arg.Key, findex, arg.Value);
                        if (ProtoCore.DSASM.Constants.kInvalidIndex == symbolIndex)
                        {
                            throw new BuildHaltException("44B557F1");
                        }
                    });
                }
                else
                {
                    string message = String.Format(ProtoCore.Properties.Resources.kMethodAlreadyDefined, localProcedure.Name);
                    buildStatus.LogWarning(WarningID.kFunctionAlreadyDefined, message, core.CurrentDSFileName, funcDef.line, funcDef.col, gNode);
                    funcDef.skipMe = true;
                }
            }
            else if (IsParsingMemberFunctionBody())
            {
                EmitCompileLogFunctionStart(GetFunctionSignatureString(funcDef.Name, funcDef.ReturnType, funcDef.Signature, true));
                // Build arglist for comparison
                List<ProtoCore.Type> argList = new List<ProtoCore.Type>();
                if (null != funcDef.Signature)
                {
                    foreach (VarDeclNode argNode in funcDef.Signature.Arguments)
                    {
                        ProtoCore.Type argType = BuildArgumentTypeFromVarDeclNode(argNode, gNode);
                        argList.Add(argType);
                    }
                }

                var procNode = core.ClassTable.ClassNodes[globalClassIndex].ProcTable.GetFunctionBySignature(funcDef.Name, argList);
                globalProcIndex = procNode == null ? Constants.kInvalidIndex : procNode.ID;

                Validity.Assert(null == localProcedure);
                localProcedure = core.ClassTable.ClassNodes[globalClassIndex].ProcTable.Procedures[globalProcIndex];

                Validity.Assert(null != localProcedure);
                localProcedure.Attributes = PopulateAttributes(funcDef.Attributes);
                // Its only on the parse body pass where the real pc is determined. Update this procedures' pc
                //Validity.Assert(ProtoCore.DSASM.Constants.kInvalidIndex == localProcedure.pc);
                localProcedure.PC = pc;

                EmitInstrConsole(ProtoCore.DSASM.kw.allocc, localProcedure.Name);
                EmitAllocc(globalClassIndex);
                setConstructorStartPC = true;

                EmitCallingForBaseConstructor(globalClassIndex, funcDef.BaseConstructor);

                ProtoCore.FunctionEndPoint fep = null;
                if (!funcDef.IsExternLib)
                {
                    // Traverse default assignment for the class
                    emitDebugInfo = false;

                    List<AssociativeNode> defaultArgList = core.ClassTable.ClassNodes[globalClassIndex].DefaultArgExprList;
                    defaultArgList = BuildSSA(defaultArgList, context);
                    foreach (BinaryExpressionNode bNode in defaultArgList)
                    {
                        ProtoCore.AssociativeGraph.GraphNode graphNode = new ProtoCore.AssociativeGraph.GraphNode();
                        graphNode.exprUID = bNode.ExpressionUID;
                        graphNode.ssaExpressionUID = bNode.SSAExpressionUID;
                        graphNode.procIndex = globalProcIndex;
                        graphNode.classIndex = globalClassIndex;
                        graphNode.languageBlockId = codeBlock.codeBlockId;
                        graphNode.isAutoGenerated = true;
                        bNode.IsProcedureOwned = graphNode.ProcedureOwned = true;

                        EmitBinaryExpressionNode(bNode, ref inferedType, false, graphNode, subPass);
                    }

                    //Traverse default argument for the constructor
                    foreach (ProtoCore.DSASM.ArgumentInfo argNode in localProcedure.ArgumentInfos)
                    {
                        if (!argNode.IsDefault)
                        {
                            continue;
                        }
                        BinaryExpressionNode bNode = argNode.DefaultExpression as BinaryExpressionNode;
                        // build a temporay node for statement : temp = defaultarg;
                        var iNodeTemp =AstFactory.BuildIdentifier(Constants.kTempDefaultArg);
                        BinaryExpressionNode bNodeTemp = new BinaryExpressionNode();
                        bNodeTemp.LeftNode = iNodeTemp;
                        bNodeTemp.Optr = ProtoCore.DSASM.Operator.assign;
                        bNodeTemp.RightNode = bNode.LeftNode;
                        EmitBinaryExpressionNode(bNodeTemp, ref inferedType);
                        //duild an inline conditional node for statement: defaultarg = (temp == DefaultArgNode) ? defaultValue : temp;
                        InlineConditionalNode icNode = new InlineConditionalNode();
                        icNode.IsAutoGenerated = true;
                        BinaryExpressionNode cExprNode = new BinaryExpressionNode();
                        cExprNode.Optr = ProtoCore.DSASM.Operator.eq;
                        cExprNode.LeftNode = iNodeTemp;
                        cExprNode.RightNode = new DefaultArgNode();
                        icNode.ConditionExpression = cExprNode;
                        icNode.TrueExpression = bNode.RightNode;
                        icNode.FalseExpression = iNodeTemp;
                        bNodeTemp.LeftNode = bNode.LeftNode;
                        bNodeTemp.RightNode = icNode;
                        EmitBinaryExpressionNode(bNodeTemp, ref inferedType);
                    }
                    emitDebugInfo = true;

                    EmitCodeBlock(funcDef.FunctionBody.Body, ref inferedType, subPass, true);

                    // Build dependency within the function
                    ProtoCore.AssociativeEngine.Utils.BuildGraphNodeDependencies(
                        codeBlock.instrStream.dependencyGraph.GetGraphNodesAtScope(globalClassIndex, globalProcIndex));

                    // All locals have been stack allocated, update the local count of this function
                    localProcedure.LocalCount = core.BaseOffset;
                    core.ClassTable.ClassNodes[globalClassIndex].ProcTable.Procedures[globalProcIndex].LocalCount = core.BaseOffset;

                    // Update the param stack indices of this function
                    foreach (ProtoCore.DSASM.SymbolNode symnode in core.ClassTable.ClassNodes[globalClassIndex].Symbols.symbolList.Values)
                    {
                        if (symnode.functionIndex == globalProcIndex && symnode.isArgument)
                        {
                            symnode.index -= localProcedure.LocalCount;
                        }
                    }

                    // JIL FEP
                    ProtoCore.Lang.JILActivationRecord record = new ProtoCore.Lang.JILActivationRecord();
                    record.pc = localProcedure.PC;
                    record.locals = localProcedure.LocalCount;
                    record.classIndex = globalClassIndex;
                    record.funcIndex = globalProcIndex;

                    // Construct the fep arguments
                    fep = new ProtoCore.Lang.JILFunctionEndPoint(record);
                }
                else
                {
                    ProtoCore.Lang.JILActivationRecord jRecord = new ProtoCore.Lang.JILActivationRecord();
                    jRecord.pc = localProcedure.PC;
                    jRecord.locals = localProcedure.LocalCount;
                    jRecord.classIndex = globalClassIndex;
                    jRecord.funcIndex = localProcedure.ID;

                    ProtoCore.Lang.FFIActivationRecord record = new ProtoCore.Lang.FFIActivationRecord();
                    record.JILRecord = jRecord;
                    record.FunctionName = funcDef.Name;
                    record.ModuleName = funcDef.ExternLibName;
                    record.ModuleType = "dll";
                    record.IsDNI = false;
                    record.ReturnType = funcDef.ReturnType;
                    record.ParameterTypes = localProcedure.ArgumentTypes;
                    fep = new ProtoCore.Lang.FFIFunctionEndPoint(record);
                }

                // Construct the fep arguments
                fep.FormalParams = new ProtoCore.Type[localProcedure.ArgumentTypes.Count];
                fep.procedureNode = localProcedure;
                localProcedure.ArgumentTypes.CopyTo(fep.FormalParams, 0);

                // 'classIndexAtCallsite' is the class index as it is stored at the callsite function tables
                int classIndexAtCallsite = globalClassIndex + 1;
                core.FunctionTable.InitGlobalFunctionEntry(classIndexAtCallsite);

                Dictionary<string, FunctionGroup> fgroup = core.FunctionTable.GlobalFuncTable[classIndexAtCallsite];
                if (!fgroup.ContainsKey(funcDef.Name))
                {
                    // Create a new function group in this class
                    ProtoCore.FunctionGroup funcGroup = new ProtoCore.FunctionGroup();
                    funcGroup.FunctionEndPoints.Add(fep);

                    // Add this group to the class function tables
                    core.FunctionTable.GlobalFuncTable[classIndexAtCallsite].Add(funcDef.Name, funcGroup);
                }
                else
                {
                    // Add this fep into the exisitng function group
                    core.FunctionTable.GlobalFuncTable[classIndexAtCallsite][funcDef.Name].FunctionEndPoints.Add(fep);
                }

                int startpc = pc;

                // Constructors auto return
                EmitInstrConsole(ProtoCore.DSASM.kw.retc);

                // Stepping out of a constructor body will have the execution cursor 
                // placed right at the closing curly bracket of the constructor definition.
                // 
                int closeCurlyBracketLine = 0, closeCurlyBracketColumn = -1;
                if (null != funcDef.FunctionBody)
                {
                    closeCurlyBracketLine = funcDef.FunctionBody.endLine;
                    closeCurlyBracketColumn = funcDef.FunctionBody.endCol;
                }

                // The execution cursor covers exactly one character -- the closing 
                // curly bracket. Note that we decrement the start-column by one here 
                // because end-column of "FunctionBody" here is *after* the closing 
                // curly bracket, so we want one before that.
                // 
                EmitRetc(closeCurlyBracketLine, closeCurlyBracketColumn - 1,
                    closeCurlyBracketLine, closeCurlyBracketColumn);

                // Build and append a graphnode for this return statememt
                ProtoCore.DSASM.SymbolNode returnNode = new ProtoCore.DSASM.SymbolNode();
                returnNode.name = ProtoCore.DSDefinitions.Keyword.Return;

                ProtoCore.AssociativeGraph.GraphNode retNode = new ProtoCore.AssociativeGraph.GraphNode();
                //retNode.symbol = returnNode;
                retNode.PushSymbolReference(returnNode);
                retNode.procIndex = globalProcIndex;
                retNode.classIndex = globalClassIndex;
                retNode.updateBlock.startpc = startpc;
                retNode.updateBlock.endpc = pc - 1;

                PushGraphNode(retNode);
                EmitCompileLogFunctionEnd();
            }

            // Constructors have no return statemetns, reset variables here
            core.ProcNode = localProcedure = null;
            globalProcIndex = ProtoCore.DSASM.Constants.kGlobalScope;
            core.BaseOffset = 0;
            argOffset = 0;
            classOffset = 0;
            codeBlock.blockType = originalBlockType;
        }
Example #32
0
        private void EmitFunctionDefinitionNode(ImperativeNode node, ref ProtoCore.Type inferedType)
        {
            bool parseGlobalFunctionSig = null == localProcedure && ProtoCore.DSASM.ImperativeCompilePass.kGlobalFuncSig == compilePass;
            bool parseGlobalFunctionBody = null == localProcedure && ProtoCore.DSASM.ImperativeCompilePass.kGlobalFuncBody == compilePass;

            FunctionDefinitionNode funcDef = node as FunctionDefinitionNode;
            localFunctionDefNode = funcDef;

            ProtoCore.DSASM.CodeBlockType originalBlockType = codeBlock.blockType;
            codeBlock.blockType = ProtoCore.DSASM.CodeBlockType.kFunction;
            if (parseGlobalFunctionSig)
            {
                Debug.Assert(null == localProcedure);

                // TODO jun: Add semantics for checking overloads (different parameter types)
                localProcedure = new ProtoCore.DSASM.ProcedureNode();
                localProcedure.name = funcDef.Name;
                localProcedure.pc = pc;
                localProcedure.localCount = funcDef.localVars;
                localProcedure.returntype.UID = compileStateTracker.TypeSystem.GetType(funcDef.ReturnType.Name);
                if (localProcedure.returntype.UID == (int)PrimitiveType.kInvalidType)
                {
                    string message = String.Format(ProtoCore.BuildData.WarningMessage.kReturnTypeUndefined, funcDef.ReturnType.Name, funcDef.Name);
                    buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kTypeUndefined, message, null, funcDef.line, funcDef.col);
                    localProcedure.returntype.UID = (int)PrimitiveType.kTypeVar;
                }
                localProcedure.returntype.IsIndexable = funcDef.ReturnType.IsIndexable;
                localProcedure.returntype.rank = funcDef.ReturnType.rank;
                localProcedure.runtimeIndex = codeBlock.codeBlockId;
                globalProcIndex = codeBlock.procedureTable.Append(localProcedure);
                compileStateTracker.ProcNode = localProcedure;

                // Append arg symbols
                if (null != funcDef.Signature)
                {
                    foreach (VarDeclNode argNode in funcDef.Signature.Arguments)
                    {
                        IdentifierNode paramNode = null;
                        bool aIsDefault = false;
                        ProtoCore.AST.Node aDefaultExpression = null;
                        if (argNode.NameNode is IdentifierNode)
                        {
                            paramNode = argNode.NameNode as IdentifierNode;
                        }
                        else if (argNode.NameNode is BinaryExpressionNode)
                        {
                            BinaryExpressionNode bNode = argNode.NameNode as BinaryExpressionNode;
                            paramNode = bNode.LeftNode as IdentifierNode;
                            aIsDefault = true;
                            aDefaultExpression = bNode;
                            //buildStatus.LogSemanticError("Defualt parameters are not supported");
                            //throw new BuildHaltException();
                        }
                        else
                        {
                            Debug.Assert(false, "Check generated AST");
                        }

                        ProtoCore.Type argType = BuildArgumentTypeFromVarDeclNode(argNode);
                        int symbolIndex = AllocateArg(paramNode.Value, localProcedure.procId, argType);
                        if (ProtoCore.DSASM.Constants.kInvalidIndex == symbolIndex)
                        {
                            throw new BuildHaltException("26384684");
                        }

                        localProcedure.argTypeList.Add(argType);
                        ProtoCore.DSASM.ArgumentInfo argInfo = new ProtoCore.DSASM.ArgumentInfo { isDefault = aIsDefault, defaultExpression = aDefaultExpression };
                        localProcedure.argInfoList.Add(argInfo);
                    }
                }

                // TODO Jun: Remove this once agree that alltest cases assume the default assoc block is block 0
                // NOTE: Only affects mirror, not actual execution
                if (null == codeBlock.parent && pc <= 0)
                {
                    // The first node in the top level block is a function
                    compileStateTracker.DSExecutable.isSingleAssocBlock = false;
                }
            #if ENABLE_EXCEPTION_HANDLING
                core.ExceptionHandlingManager.Register(codeBlock.codeBlockId, globalProcIndex, globalClassIndex);
            #endif
            }
            else if (parseGlobalFunctionBody)
            {
                EmitCompileLogFunctionStart(GetFunctionSignatureString(funcDef.Name, funcDef.ReturnType, funcDef.Signature));

                // Build arglist for comparison
                List<ProtoCore.Type> argList = new List<ProtoCore.Type>();
                if (null != funcDef.Signature)
                {
                    foreach (VarDeclNode argNode in funcDef.Signature.Arguments)
                    {
                        ProtoCore.Type argType = BuildArgumentTypeFromVarDeclNode(argNode);
                        argList.Add(argType);
                    }
                }

                // Get the exisitng procedure that was added on the previous pass
                globalProcIndex = codeBlock.procedureTable.IndexOfExact(funcDef.Name, argList);
                localProcedure = codeBlock.procedureTable.procList[globalProcIndex];

                Debug.Assert(null != localProcedure);
                localProcedure.Attributes = PopulateAttributes(funcDef.Attributes);
                // Its only on the parse body pass where the real pc is determined. Update this procedures' pc
                //Debug.Assert(ProtoCore.DSASM.Constants.kInvalidIndex == localProcedure.pc);
                localProcedure.pc = pc;

                // Copy the active function to the core so nested language blocks can refer to it
                compileStateTracker.ProcNode = localProcedure;

                // Arguments have been allocated, update the baseOffset
                localProcedure.localCount = compileStateTracker.BaseOffset;

                ProtoCore.FunctionEndPoint fep = null;

                //Traverse default argument
                emitDebugInfo = false;
                foreach (ProtoCore.DSASM.ArgumentInfo argNode in localProcedure.argInfoList)
                {
                    if (!argNode.isDefault)
                    {
                        continue;
                    }
                    BinaryExpressionNode bNode = argNode.defaultExpression as BinaryExpressionNode;

                    // build a temporay node for statement : temp = defaultarg;
                    var iNodeTemp = nodeBuilder.BuildIdentfier(Constants.kTempDefaultArg);
                    BinaryExpressionNode bNodeTemp = nodeBuilder.BuildBinaryExpression(iNodeTemp, bNode.LeftNode) as BinaryExpressionNode;
                    EmitBinaryExpressionNode(bNodeTemp, ref inferedType);

                    //duild an inline conditional node for statement: defaultarg = (temp == DefaultArgNode) ? defaultValue : temp;
                    InlineConditionalNode icNode = new InlineConditionalNode();
                    icNode.ConditionExpression = nodeBuilder.BuildBinaryExpression(iNodeTemp, new DefaultArgNode(), Operator.eq);
                    icNode.TrueExpression = bNode.RightNode;
                    icNode.FalseExpression = iNodeTemp;
                    bNodeTemp.LeftNode = bNode.LeftNode;
                    bNodeTemp.RightNode = icNode;
                    EmitBinaryExpressionNode(bNodeTemp, ref inferedType);
                }
                emitDebugInfo = true;

                // Traverse definition
                bool hasReturnStatement = false;
                foreach (ImperativeNode bnode in funcDef.FunctionBody.Body)
                {
                    DfsTraverse(bnode, ref inferedType);
                    if (ProtoCore.Utils.NodeUtils.IsReturnExpressionNode(bnode))
                    {
                        hasReturnStatement = true;
                    }

                    if (bnode is FunctionCallNode)
                    {
                        EmitSetExpressionUID(compileStateTracker.ExpressionUID++);
                    }
                }

                // All locals have been stack allocated, update the local count of this function
                localProcedure.localCount = compileStateTracker.BaseOffset;

                // Update the param stack indices of this function
                foreach (ProtoCore.DSASM.SymbolNode symnode in codeBlock.symbolTable.symbolList.Values)
                {
                    if (symnode.functionIndex == localProcedure.procId && symnode.isArgument)
                    {
                        symnode.index -= localProcedure.localCount;
                    }
                }

                ProtoCore.Lang.JILActivationRecord record = new ProtoCore.Lang.JILActivationRecord();
                record.pc = localProcedure.pc;
                record.locals = localProcedure.localCount;
                record.classIndex = ProtoCore.DSASM.Constants.kInvalidIndex;
                record.funcIndex = localProcedure.procId;
                fep = new ProtoCore.Lang.JILFunctionEndPoint(record);

                // Construct the fep arguments
                fep.FormalParams = new ProtoCore.Type[localProcedure.argTypeList.Count];
                fep.BlockScope = codeBlock.codeBlockId;
                fep.procedureNode = localProcedure;
                localProcedure.argTypeList.CopyTo(fep.FormalParams, 0);

                // TODO Jun: 'classIndexAtCallsite' is the class index as it is stored at the callsite function tables
                // Determine whether this still needs to be aligned to the actual 'classIndex' variable
                // The factors that will affect this is whether the 2 function tables (compiler and callsite) need to be merged
                int classIndexAtCallsite = ProtoCore.DSASM.Constants.kInvalidIndex + 1;
                compileStateTracker.FunctionTable.AddFunctionEndPointer(classIndexAtCallsite, funcDef.Name, fep);

                if (!hasReturnStatement)
                {
                    if (!compileStateTracker.Options.SuppressFunctionResolutionWarning)
                    {
                        string message = String.Format(ProtoCore.BuildData.WarningMessage.kFunctionNotReturnAtAllCodePaths, localProcedure.name);
                        compileStateTracker.BuildStatus.LogWarning(ProtoCore.BuildData.WarningID.kMissingReturnStatement, message, compileStateTracker.CurrentDSFileName, funcDef.line, funcDef.col);
                    }

                    EmitReturnNull();
                }

                EmitCompileLogFunctionEnd();
                //Fuqiang: return is already done in traversing the function body
                //// function return
                //EmitInstrConsole(ProtoCore.DSASM.kw.ret);
                //EmitReturn();
            }

            compileStateTracker.ProcNode = localProcedure = null;
            globalProcIndex = ProtoCore.DSASM.Constants.kGlobalScope;
            argOffset = 0;
            compileStateTracker.BaseOffset = 0;
            codeBlock.blockType = originalBlockType;
            localFunctionDefNode = null;
        }
Example #33
0
 public FunctionPointerNode(ProcedureNode procNode)
 {
     this.procId     = procNode.procId;
     this.classScope = procNode.classScope;
     this.blockId    = procNode.runtimeIndex;
 }
        /// <summary>
        /// Try to get the original procedure node that the function pointer
        /// points to.
        /// </summary>
        /// <param name="functionPointer">Function pointer</param>
        /// <param name="core">Core</param>
        /// <param name="procNode">Procedure node</param>
        /// <returns></returns>
        public bool TryGetFunction(StackValue functionPointer, RuntimeCore runtimeCore, out ProcedureNode procNode)
        {
            procNode = null;

            int index = (int)functionPointer.RawIntValue;
            FunctionPointerNode fptrNode;

            if (functionPointerDictionary.TryGetByFirst(index, out fptrNode))
            {
                var blockId       = fptrNode.blockId;
                var classScope    = fptrNode.classScope;
                var functionIndex = fptrNode.procId;

                if (classScope != Constants.kGlobalScope)
                {
                    procNode = runtimeCore.DSExecutable.classTable.ClassNodes[classScope].vtable.procList[functionIndex];
                }
                else
                {
                    procNode = runtimeCore.DSExecutable.CompleteCodeBlocks[blockId].procedureTable.procList[functionIndex];
                }

                return(true);
            }

            return(false);
        }
Example #35
0
        private bool DebugReturn(ProcedureNode procNode, int currentPC)
        {
            //
            // TODO: Aparajit, Jun - Determine an alternative to the waspopped flag
            // 
            bool waspopped = false;

            bool isReplicating;
            int exeblock = Constants.kInvalidIndex;
            int ci;
            int fi;

            DebugFrame debugFrame = null;
            if (runtimeCore.Options.IDEDebugMode && runtimeCore.Options.RunMode != InterpreterMode.kExpressionInterpreter)
            {
                waspopped = DebugReturnFromFunctionCall(currentPC, ref exeblock, out ci, out fi, out isReplicating, out debugFrame);

                if (!waspopped)
                {
                    runtimeCore.DebugProps.RestoreCallrForNoBreak(runtimeCore, procNode, isReplicating);
                }
            }

            return waspopped;
        }
Example #36
0
            internal PropertyMirror(ProcedureNode procNode, bool isSetter = false)
            {
                this.procNode = procNode;

                string getterPrefix = ProtoCore.DSASM.Constants.kGetterPrefix;
                int prefixLength = getterPrefix.Length;
                PropertyName = procNode.Name.Substring(prefixLength);
                this.Name = PropertyName;
                this.isSetter = isSetter;
            }
Example #37
0
 private void RestoreGraphNodeExecutionStates(ProcedureNode procNode, List<bool> execStateRestore)
 {
     if (execStateRestore.Count > 0 )
     {
         Validity.Assert(execStateRestore.Count == procNode.GraphNodeList.Count);
         for (int n = 0; n < execStateRestore.Count; ++n)
         {
             procNode.GraphNodeList[n].isDirty = execStateRestore[n];
         }
     }
 }
Example #38
0
        private void EmitFunctionDefinitionNode(AssociativeNode node, ref ProtoCore.Type inferedType, ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass = ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone, GraphNode graphNode = null)
        {
            bool parseGlobalFunctionBody = null == localProcedure && ProtoCore.CompilerDefinitions.Associative.CompilePass.kGlobalFuncBody == compilePass;
            bool parseMemberFunctionBody = ProtoCore.DSASM.Constants.kGlobalScope != globalClassIndex && ProtoCore.CompilerDefinitions.Associative.CompilePass.kClassMemFuncBody == compilePass;

            FunctionDefinitionNode funcDef = node as FunctionDefinitionNode;
            localFunctionDefNode = funcDef;

            if (funcDef.IsAssocOperator)
            {
                isAssocOperator = true;
            }
            else
            {
                isAssocOperator = false;
            }

            bool hasReturnStatement = false;
            ProtoCore.DSASM.CodeBlockType origCodeBlockType = codeBlock.blockType;
            codeBlock.blockType = ProtoCore.DSASM.CodeBlockType.kFunction;
            if (IsParsingGlobalFunctionSig() || IsParsingMemberFunctionSig())
            {
                Validity.Assert(null == localProcedure);
                localProcedure = new ProtoCore.DSASM.ProcedureNode();

                localProcedure.Name = funcDef.Name;
                localProcedure.PC = ProtoCore.DSASM.Constants.kInvalidIndex;
                localProcedure.LocalCount = 0; // Defer till all locals are allocated
                var uid = core.TypeSystem.GetType(funcDef.ReturnType.Name);
                var rank = funcDef.ReturnType.rank;
                var returnType = core.TypeSystem.BuildTypeObject(uid, rank); 
                if (returnType.UID == (int)PrimitiveType.kInvalidType)
                {
                    string message = String.Format(ProtoCore.Properties.Resources.kReturnTypeUndefined, funcDef.ReturnType.Name, funcDef.Name);
                    buildStatus.LogWarning(WarningID.kTypeUndefined, message, core.CurrentDSFileName, funcDef.line, funcDef.col, graphNode);
                    returnType = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeVar, rank);
                }
                localProcedure.ReturnType = returnType;
                localProcedure.IsConstructor = false;
                localProcedure.IsStatic = funcDef.IsStatic;
                localProcedure.RuntimeIndex = codeBlock.codeBlockId;
                localProcedure.AccessModifier = funcDef.Access;
                localProcedure.IsExternal = funcDef.IsExternLib;
                localProcedure.IsAutoGenerated = funcDef.IsAutoGenerated;
                localProcedure.ClassID = globalClassIndex;
                localProcedure.IsAssocOperator = funcDef.IsAssocOperator;
                localProcedure.IsAutoGeneratedThisProc = funcDef.IsAutoGeneratedThisProc;

                localProcedure.MethodAttribute = funcDef.MethodAttributes;

                int peekFunctionindex = ProtoCore.DSASM.Constants.kInvalidIndex;

                if (ProtoCore.DSASM.Constants.kInvalidIndex == globalClassIndex)
                {
                    peekFunctionindex = codeBlock.procedureTable.Procedures.Count;
                }
                else
                {
                    peekFunctionindex = core.ClassTable.ClassNodes[globalClassIndex].ProcTable.Procedures.Count;
                }

                // Append arg symbols
                List<KeyValuePair<string, ProtoCore.Type>> argsToBeAllocated = new List<KeyValuePair<string, ProtoCore.Type>>();
                string functionDescription = localProcedure.Name;
                if (null != funcDef.Signature)
                {
                    foreach (VarDeclNode argNode in funcDef.Signature.Arguments)
                    {
                        var argInfo = BuildArgumentInfoFromVarDeclNode(argNode);
                        localProcedure.ArgumentInfos.Add(argInfo);

                        var argType = BuildArgumentTypeFromVarDeclNode(argNode, graphNode);
                        localProcedure.ArgumentTypes.Add(argType);

                        argsToBeAllocated.Add(new KeyValuePair<string, ProtoCore.Type>(argInfo.Name, argType));

                        functionDescription += argNode.ArgumentType.ToString();
                    }
                    localProcedure.HashID = functionDescription.GetHashCode();
                    localProcedure.IsVarArg = funcDef.Signature.IsVarArg;
                }

                if (ProtoCore.DSASM.Constants.kInvalidIndex == globalClassIndex)
                {
                    globalProcIndex = codeBlock.procedureTable.Append(localProcedure);
                }
                else
                {
                    globalProcIndex = core.ClassTable.ClassNodes[globalClassIndex].ProcTable.Append(localProcedure);
                }

                // Comment Jun: Catch this assert given the condition as this type of mismatch should never occur
                if (ProtoCore.DSASM.Constants.kInvalidIndex != globalProcIndex)
                {
                    argsToBeAllocated.ForEach(arg =>
                    {
                        int symbolIndex = AllocateArg(arg.Key, globalProcIndex, arg.Value);
                        if (ProtoCore.DSASM.Constants.kInvalidIndex == symbolIndex)
                        {
                            throw new BuildHaltException("B2CB2093");
                        }
                    });                   
                }
                else
                {
                    string message = String.Format(ProtoCore.Properties.Resources.kMethodAlreadyDefined, localProcedure.Name);
                    buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kFunctionAlreadyDefined, message, core.CurrentDSFileName, funcDef.line, funcDef.col, graphNode);
                    funcDef.skipMe = true;
                }
            }
            else if (parseGlobalFunctionBody || parseMemberFunctionBody)
            {
                if (CoreUtils.IsDisposeMethod(node.Name))
                {
                    core.Options.EmitBreakpoints = false;
                }

                // Build arglist for comparison
                List<ProtoCore.Type> argList = new List<ProtoCore.Type>();
                if (null != funcDef.Signature)
                {
                    foreach (VarDeclNode argNode in funcDef.Signature.Arguments)
                    {
                        ProtoCore.Type argType = BuildArgumentTypeFromVarDeclNode(argNode, graphNode);
                        argList.Add(argType);
                    }
                }

                // Get the exisitng procedure that was added on the previous pass
                if (ProtoCore.DSASM.Constants.kInvalidIndex == globalClassIndex)
                {
                    var procNode = codeBlock.procedureTable.GetFunctionBySignature(funcDef.Name, argList);
                    globalProcIndex = procNode == null ? Constants.kInvalidIndex : procNode.ID;
                    localProcedure = codeBlock.procedureTable.Procedures[globalProcIndex];
                }
                else
                {
                    var procNode = core.ClassTable.ClassNodes[globalClassIndex].ProcTable.GetFunctionBySignature(funcDef.Name, argList);
                    globalProcIndex = procNode == null ? Constants.kInvalidIndex : procNode.ID;
                    localProcedure = core.ClassTable.ClassNodes[globalClassIndex].ProcTable.Procedures[globalProcIndex];
                }

                Validity.Assert(null != localProcedure);

                // code gen the attribute 
                localProcedure.Attributes = PopulateAttributes(funcDef.Attributes);
                // Its only on the parse body pass where the real pc is determined. Update this procedures' pc
                //Validity.Assert(ProtoCore.DSASM.Constants.kInvalidIndex == localProcedure.pc);
                localProcedure.PC = pc;

                // Copy the active function to the core so nested language blocks can refer to it
                core.ProcNode = localProcedure;

                ProtoCore.FunctionEndPoint fep = null;
                if (!funcDef.IsExternLib)
                {
                    //Traverse default argument
                    emitDebugInfo = false;
                    foreach (ProtoCore.DSASM.ArgumentInfo argNode in localProcedure.ArgumentInfos)
                    {
                        if (!argNode.IsDefault)
                        {
                            continue;
                        }
                        BinaryExpressionNode bNode = argNode.DefaultExpression as BinaryExpressionNode;
                        // build a temporay node for statement : temp = defaultarg;
                        var iNodeTemp = AstFactory.BuildIdentifier(core.GenerateTempVar());
                        var bNodeTemp = AstFactory.BuildAssignment(iNodeTemp, bNode.LeftNode);
                        bNodeTemp.IsProcedureOwned = true;
                        EmitBinaryExpressionNode(bNodeTemp, ref inferedType, false, null, ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier);
                        //duild an inline conditional node for statement: defaultarg = (temp == DefaultArgNode) ? defaultValue : temp;
                        InlineConditionalNode icNode = new InlineConditionalNode();
                        icNode.IsAutoGenerated = true;
                        BinaryExpressionNode cExprNode = new BinaryExpressionNode();
                        cExprNode.Optr = ProtoCore.DSASM.Operator.eq;
                        cExprNode.LeftNode = iNodeTemp;
                        cExprNode.RightNode = new DefaultArgNode();
                        icNode.ConditionExpression = cExprNode;
                        icNode.TrueExpression = bNode.RightNode;
                        icNode.FalseExpression = iNodeTemp;
                        bNodeTemp.LeftNode = bNode.LeftNode;
                        bNodeTemp.RightNode = icNode;
                        EmitBinaryExpressionNode(bNodeTemp, ref inferedType, false, null, ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier);
                    }
                    emitDebugInfo = true;

                    EmitCompileLogFunctionStart(GetFunctionSignatureString(funcDef.Name, funcDef.ReturnType, funcDef.Signature));

                    ProtoCore.Type itype = new ProtoCore.Type();

                    hasReturnStatement = EmitCodeBlock(funcDef.FunctionBody.Body, ref itype, subPass, true);

                    // Build dependency within the function
                    ProtoCore.AssociativeEngine.Utils.BuildGraphNodeDependencies(
                        codeBlock.instrStream.dependencyGraph.GetGraphNodesAtScope(globalClassIndex, globalProcIndex));


                    EmitCompileLogFunctionEnd();

                    // All locals have been stack allocated, update the local count of this function
                    localProcedure.LocalCount = core.BaseOffset;

                    if (ProtoCore.DSASM.Constants.kInvalidIndex == globalClassIndex)
                    {
                        localProcedure.LocalCount = core.BaseOffset;

                        // Update the param stack indices of this function
                        foreach (ProtoCore.DSASM.SymbolNode symnode in codeBlock.symbolTable.symbolList.Values)
                        {
                            if (symnode.functionIndex == localProcedure.ID && symnode.isArgument)
                            {
                                symnode.index -= localProcedure.LocalCount;
                            }
                        }
                    }
                    else
                    {
                        core.ClassTable.ClassNodes[globalClassIndex].ProcTable.Procedures[localProcedure.ID].LocalCount = core.BaseOffset;

                        // Update the param stack indices of this function
                        foreach (ProtoCore.DSASM.SymbolNode symnode in core.ClassTable.ClassNodes[globalClassIndex].Symbols.symbolList.Values)
                        {
                            if (symnode.functionIndex == localProcedure.ID && symnode.isArgument)
                            {
                                symnode.index -= localProcedure.LocalCount;
                            }
                        }
                    }

                    ProtoCore.Lang.JILActivationRecord record = new ProtoCore.Lang.JILActivationRecord();
                    record.pc = localProcedure.PC;
                    record.locals = localProcedure.LocalCount;
                    record.classIndex = globalClassIndex;
                    record.funcIndex = localProcedure.ID;
                    fep = new ProtoCore.Lang.JILFunctionEndPoint(record);
                }
                else if (funcDef.BuiltInMethodId != ProtoCore.Lang.BuiltInMethods.MethodID.kInvalidMethodID)
                {
                    fep = new ProtoCore.Lang.BuiltInFunctionEndPoint(funcDef.BuiltInMethodId);
                }
                else
                {
                    ProtoCore.Lang.JILActivationRecord jRecord = new ProtoCore.Lang.JILActivationRecord();
                    jRecord.pc = localProcedure.PC;
                    jRecord.locals = localProcedure.LocalCount;
                    jRecord.classIndex = globalClassIndex;
                    jRecord.funcIndex = localProcedure.ID;

                    ProtoCore.Lang.FFIActivationRecord record = new ProtoCore.Lang.FFIActivationRecord();
                    record.JILRecord = jRecord;
                    record.FunctionName = funcDef.Name;
                    record.ModuleName = funcDef.ExternLibName;
                    record.ModuleType = "dll";
                    record.IsDNI = funcDef.IsDNI;
                    record.ReturnType = funcDef.ReturnType;
                    record.ParameterTypes = localProcedure.ArgumentTypes;
                    fep = new ProtoCore.Lang.FFIFunctionEndPoint(record);
                }

                // Construct the fep arguments
                fep.FormalParams = new ProtoCore.Type[localProcedure.ArgumentTypes.Count];
                fep.BlockScope = codeBlock.codeBlockId;
                fep.ClassOwnerIndex = localProcedure.ClassID;
                fep.procedureNode = localProcedure;
                localProcedure.ArgumentTypes.CopyTo(fep.FormalParams, 0);

                // 'classIndexAtCallsite' is the class index as it is stored at the callsite function tables
                int classIndexAtCallsite = globalClassIndex + 1;
                core.FunctionTable.InitGlobalFunctionEntry(classIndexAtCallsite);

                // Get the function group of the current class and see if the current function exists
                Dictionary<string, FunctionGroup> fgroup = core.FunctionTable.GlobalFuncTable[classIndexAtCallsite];
                if (!fgroup.ContainsKey(funcDef.Name))
                {
                    // If any functions in the base class have the same name, append them here
                    int ci = classIndexAtCallsite - 1;
                    if (ProtoCore.DSASM.Constants.kInvalidIndex != ci)
                    {
                        ProtoCore.DSASM.ClassNode cnode = core.ClassTable.ClassNodes[ci];
                        if (cnode.Bases.Count > 0)
                        {
                            Validity.Assert(1 == cnode.Bases.Count, "We don't support multiple inheritance yet");

                            ci = cnode.Bases[0];

                            Dictionary<string, FunctionGroup> tgroup = new Dictionary<string, FunctionGroup>();
                            int callsiteCI = ci + 1;
                            bool bSucceed = core.FunctionTable.GlobalFuncTable.TryGetValue(callsiteCI, out tgroup);
                            if (bSucceed)
                            {
                                if (tgroup.ContainsKey(funcDef.Name))
                                {
                                    // Get that base group - the group of function from the baseclass
                                    FunctionGroup basegroup = new FunctionGroup();
                                    bSucceed = tgroup.TryGetValue(funcDef.Name, out basegroup);
                                    if (bSucceed)
                                    {
                                        // Copy all non-private feps from the basegroup into this the new group
                                        FunctionGroup newGroup = new FunctionGroup();
                                        newGroup.CopyVisible(basegroup.FunctionEndPoints);

                                        // Append the new fep 
                                        newGroup.FunctionEndPoints.Add(fep);

                                        // Copy the new group to this class table
                                        core.FunctionTable.GlobalFuncTable[classIndexAtCallsite].Add(funcDef.Name, newGroup);
                                    }
                                }
                                else
                                {
                                    // Create a new function group in this class
                                    ProtoCore.FunctionGroup funcGroup = new ProtoCore.FunctionGroup();
                                    funcGroup.FunctionEndPoints.Add(fep);

                                    // Add this group to the class function tables
                                    core.FunctionTable.GlobalFuncTable[classIndexAtCallsite].Add(funcDef.Name, funcGroup);
                                }
                            }
                            else
                            {
                                // Create a new function group in this class
                                ProtoCore.FunctionGroup funcGroup = new ProtoCore.FunctionGroup();
                                funcGroup.FunctionEndPoints.Add(fep);

                                // Add this group to the class function tables
                                core.FunctionTable.GlobalFuncTable[classIndexAtCallsite].Add(funcDef.Name, funcGroup);
                            }
                            cnode = core.ClassTable.ClassNodes[ci];
                        }
                        else
                        {
                            // Create a new function group in this class
                            ProtoCore.FunctionGroup funcGroup = new ProtoCore.FunctionGroup();
                            funcGroup.FunctionEndPoints.Add(fep);

                            // Add this group to the class function tables
                            core.FunctionTable.GlobalFuncTable[classIndexAtCallsite].Add(funcDef.Name, funcGroup);
                        }
                    }
                    else
                    {
                        // Create a new function group in this class
                        ProtoCore.FunctionGroup funcGroup = new ProtoCore.FunctionGroup();
                        funcGroup.FunctionEndPoints.Add(fep);

                        // Add this group to the class function tables
                        core.FunctionTable.GlobalFuncTable[classIndexAtCallsite].Add(funcDef.Name, funcGroup);
                    }
                }
                else
                {
                    // Add this fep into the exisitng function group
                    core.FunctionTable.GlobalFuncTable[classIndexAtCallsite][funcDef.Name].FunctionEndPoints.Add(fep);
                }

                if (!hasReturnStatement && !funcDef.IsExternLib)
                {
                    if (!core.Options.SuppressFunctionResolutionWarning)
                    {
                        string message = String.Format(ProtoCore.Properties.Resources.kFunctionNotReturnAtAllCodePaths, localProcedure.Name);
                        buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kMissingReturnStatement, message, core.CurrentDSFileName, funcDef.line, funcDef.col, graphNode);
                    }
                    EmitReturnNull();
                }

                if (CoreUtils.IsDisposeMethod(node.Name))
                {
                    core.Options.EmitBreakpoints = true;
                }
            }

            core.ProcNode = localProcedure = null;
            codeBlock.blockType = origCodeBlockType;
            globalProcIndex = ProtoCore.DSASM.Constants.kGlobalScope;
            localFunctionDefNode = null;
            core.BaseOffset = 0;
            argOffset = 0;
            isAssocOperator = false;
        }
Example #39
0
        private void PerformCoercionAndGC(ProcedureNode procNode, bool isBaseCall, StackValue? thisPtr, List<StackValue> Arguments, List<StackValue> DotCallDimensions)
        {
            // finalFep is forced to be null for base class constructor calls
            // and for such calls 'PerformReturnTypeCoerce' is not called 
            if (!isBaseCall)
            {
                RX = ProtoCore.CallSite.PerformReturnTypeCoerce(procNode, core, RX);

                for (int i = 0; i < Arguments.Count; ++i)
                {
                    GCUtils.GCRelease(Arguments[i], core);
                }

                if (thisPtr != null)
                {
                    GCRelease((StackValue)thisPtr);
                }
                else
                {
                    //if (debugFrame.IsDotArgCall || debugFrame.IsDotCall)
                    {
                        StackValue sv = RX;
                        GCDotMethods(procNode.name, ref sv, DotCallDimensions, Arguments);
                        RX = sv;
                    }
                    DecRefCounter(RX);
                    isGlobScope = true;
                }

            }
        }
Example #40
0
        private void TraverseDotCallArguments(FunctionCallNode funcCall, 
                                              FunctionDotCallNode dotCall,
                                              ProcedureNode procCallNode,
                                              List<ProtoCore.Type> arglist,
                                              string procName,
                                              int classIndex,
                                              string className,
                                              bool isStaticCall,
                                              bool isConstructor,
                                              GraphNode graphNode,
                                              ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass,
                                              BinaryExpressionNode bnode)
        {
            // Update graph dependencies
            if (subPass != ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier && graphNode != null)
            {
                if (isStaticCall)
                {
                    Validity.Assert(classIndex != Constants.kInvalidIndex);
                    Validity.Assert(!string.IsNullOrEmpty(className));

                    SymbolNode classSymbol = new SymbolNode();
                    classSymbol.name = className;
                    classSymbol.classScope = classIndex;
                    PushSymbolAsDependent(classSymbol, graphNode);
                }
            }

            int funtionArgCount = 0;
            for (int n = 0; n < funcCall.FormalArguments.Count; ++n)
            {
                if (isStaticCall || isConstructor)
                {
                    if (n != Constants.kDotArgIndexArrayArgs)
                    {
                        continue;
                    }
                }

                AssociativeNode paramNode = funcCall.FormalArguments[n];
                ProtoCore.Type paramType = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeVar, 0);

                emitReplicationGuide = false;

                // If it's a binary node then continue type check, otherwise 
                // disable type check and just take the type of paramNode itself
                enforceTypeCheck = !(paramNode is BinaryExpressionNode);

                if (ProtoCore.DSASM.Constants.kDotArgIndexPtr == n)
                {
                    // Traversing the first arg (the LHS pointer/Static instanct/Constructor
                    
                    // Replication guides only allowed on method, e.g.,
                    // 
                    //    x = p<1>.f({1,2}<2>); 
                    //
                    // But not on getter, e.g.,
                    // 
                    //    c = a<1>.x<2>; 
                    if (!CoreUtils.IsGetterSetter(procName) && !isConstructor)
                    {
                        emitReplicationGuide = true;
                    }

                    DfsTraverse(paramNode, ref paramType, false, graphNode, subPass, bnode);
                }
                else if (ProtoCore.DSASM.Constants.kDotArgIndexArrayArgs == n)
                {
                    // Traversing the actual arguments passed into the function 
                    // (not the dot function)
                    int defaultArgNumber = 0;

                    // If its null this is the second call in a chained dot
                    if (null != procCallNode)
                    {
                        defaultArgNumber = procCallNode.ArgumentInfos.Count - dotCall.FunctionCall.FormalArguments.Count;
                    }

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

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

                            if (!CoreUtils.IsAutoGeneratedVar(varname))
                            {
                                graphNode.allowDependents = true;
                            }
                            else if (CoreUtils.IsSSATemp(varname) && core.Options.GenerateSSA)
                            {
                                graphNode.allowDependents = true;
                            }
                        }
                        else
                        {
                            graphNode.allowDependents = true;
                        }

                    }

                    emitReplicationGuide = true;

                    if (defaultArgNumber > 0)
                    {
                        ExprListNode exprList = paramNode as ExprListNode;

                        if (subPass != ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier)
                        {
                            for (int i = 0; i < defaultArgNumber; i++)
                            {
                                exprList.Exprs.Add(new DefaultArgNode());
                            }

                        }

                        if (!isStaticCall && !isConstructor)
                        {
                            DfsTraverse(paramNode, ref paramType, false, graphNode, subPass);
                            funtionArgCount = exprList.Exprs.Count;
                        }
                        else
                        {
                            foreach (AssociativeNode exprListNode in exprList.Exprs)
                            {
                                bool repGuideState = emitReplicationGuide;
                                if (subPass == ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier)
                                {
                                    emitReplicationGuide = false;
                                }

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

                                arglist.Add(paramType);
                            }
                        }
                    }
                    else
                    {
                        ExprListNode exprList = paramNode as 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)
                        {
                            // TODO Jun: pls get rid of subPass checking outside the core travesal
                            if (ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone == subPass)
                            {
                                exprList.Exprs.Insert(0, new DynamicNode());
                            }
                        }

                        if (exprList.Exprs.Count > 0)
                        {
                            foreach (AssociativeNode exprListNode in exprList.Exprs)
                            {
                                bool repGuideState = emitReplicationGuide;
                                if (subPass == ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier)
                                {
                                    emitReplicationGuide = false;
                                }

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

                                arglist.Add(paramType);
                            }

                            if (subPass != ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier &&
                                !isStaticCall &&
                                !isConstructor)
                            {
                                EmitInstrConsole(ProtoCore.DSASM.kw.alloca, exprList.Exprs.Count.ToString());
                                EmitPopArray(exprList.Exprs.Count);

                                if (exprList.ArrayDimensions != null)
                                {
                                    int dimensions = DfsEmitArrayIndexHeap(exprList.ArrayDimensions, graphNode);
                                    EmitInstrConsole(ProtoCore.DSASM.kw.pushindex, dimensions.ToString() + "[dim]");
                                    EmitPushArrayIndex(dimensions);
                                }
                            }
                        }
                        else
                        {
                            if (!isStaticCall && !isConstructor)
                            {
                                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.Exprs.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)
                {
                    IntNode argNumNode = new IntNode(funtionArgCount);
                    DfsTraverse(argNumNode, ref paramType, false, graphNode, subPass);
                }
                else
                {
                    DfsTraverse(paramNode, ref paramType, false, graphNode, subPass);
                }

                emitReplicationGuide = false;
                enforceTypeCheck = true;

                if (!isStaticCall || !isConstructor)
                {
                    arglist.Add(paramType);
                }
            } 
        }
Example #41
0
        private bool DebugReturn(ProcedureNode procNode, int currentPC)
        {
            //
            // TODO: Aparajit, Jun - Determine an alternative to the waspopped flag
            // 
            bool waspopped = false;

            bool isReplicating = false;
            int exeblock = ProtoCore.DSASM.Constants.kInvalidIndex;
            int ci = ProtoCore.DSASM.Constants.kInvalidIndex;
            int fi = ProtoCore.DSASM.Constants.kInvalidIndex;

            DebugFrame debugFrame = null;
            if (core.Options.IDEDebugMode && core.ExecMode != InterpreterMode.kExpressionInterpreter)
            {
                waspopped = DebugReturnFromFunctionCall(currentPC, ref exeblock, out ci, out fi, out isReplicating, out debugFrame);

                if (!waspopped)
                {
                    core.DebugProps.RestoreCallrForNoBreak(core, procNode, isReplicating);
                }
            }

            // TODO: This call is common to both Debug as well as Serial mode of execution. Currently this will work only in Debug mode - pratapa
#if __DEBUG_REPLICATE

            if (isReplicating)
            {
                SerialReplication(procNode, ref exeblock, ci, fi, debugFrame);
                waspopped = true;
            }
#endif
            return waspopped;
        }
Example #42
0
        public static ProcedureNode GetClassAndProcFromGlobalInstance(ProcedureNode procNode, Core core, out int classIndex, List<Type> argTypeList)
        {
            string className = ProtoCore.Utils.CoreUtils.GetClassDeclarationName(procNode, core);
            classIndex = core.ClassTable.IndexOf(className);


            int removelength = 0;
            if (ProtoCore.Utils.CoreUtils.IsGlobalInstanceGetterSetter(procNode.name))
            {
                if (ProtoCore.Utils.CoreUtils.IsGlobalInstanceSetter(procNode.name))
                {
                    removelength = procNode.name.IndexOf(ProtoCore.DSASM.Constants.kSetterPrefix);
                }
                else
                {
                    removelength = procNode.name.IndexOf(ProtoCore.DSASM.Constants.kGetterPrefix);
                }
            }
            else
            {
                removelength = procNode.name.IndexOf(ProtoCore.DSASM.Constants.kGlobalInstanceFunctionPrefix);
                removelength += ProtoCore.DSASM.Constants.kGlobalInstanceFunctionPrefix.Length;
            }

            string functionName = procNode.name.Remove(0, removelength);
            //ProtoCore.DSASM.ProcedureNode tmpProcNode = core.ClassTable.list[classIndex].GetFirstMemberFunction(functionName, procNode.argTypeList.Count - 1);

            int functionIndex = core.ClassTable.ClassNodes[classIndex].vtable.IndexOfExact(functionName, argTypeList, procNode.isAutoGeneratedThisProc);
            ProtoCore.DSASM.ProcedureNode tmpProcNode = core.ClassTable.ClassNodes[classIndex].vtable.procList[functionIndex];

            return tmpProcNode;
        }
Example #43
0
        private void PerformCoercionAndGC(ProcedureNode procNode, bool isBaseCall, StackValue? thisPtr, List<StackValue> Arguments, List<StackValue> DotCallDimensions)
        {
            // finalFep is forced to be null for base class constructor calls
            // and for such calls 'PerformReturnTypeCoerce' is not called 
            if (!isBaseCall)
            {
                RX = CallSite.PerformReturnTypeCoerce(procNode, runtimeCore, RX);

                if (thisPtr == null)
                {
                    StackValue sv = RX;
                    GCDotMethods(procNode.Name, ref sv, DotCallDimensions, Arguments);
                    RX = sv;
                }
            }
        }