Пример #1
0
        // This constructor is only called for Preloading of assemblies and
        // precompilation of CodeBlockNode nodes in GraphUI for global language blocks - pratapa
        public CodeGen(ProtoLanguage.CompileStateTracker compileState)
            : base(compileState)
        {
            Validity.Assert(compileStateTracker.IsParsingPreloadedAssembly || compileStateTracker.IsParsingCodeBlockNode);

            classOffset = 0;

            //  either of these should set the console to flood
            //
            ignoreRankCheck = false;
            emitReplicationGuide = false;

            astNodes = new List<AssociativeNode>();
            globalInstanceProcList = new List<GlobalInstanceProc>();
            setConstructorStartPC = false;

            // Re-use the existing procedureTable and symbolTable to access the built-in and predefined functions
            ProcedureTable procTable = compileStateTracker.CodeBlockList[0].procedureTable;
            codeBlock = BuildNewCodeBlock(procTable);

            // Remove global symbols from existing symbol table for subsequent run in Graph UI
            //SymbolTable sTable = core.CodeBlockList[0].symbolTable;
            //sTable.RemoveGlobalSymbols();
            //codeBlock = core.CodeBlockList[0];

            compilePass = ProtoCore.DSASM.AssociativeCompilePass.kClassName;

            // Bouncing to this language codeblock from a function should immediately set the first instruction as the entry point
            if (ProtoCore.DSASM.Constants.kGlobalScope != globalProcIndex)
            {
                isEntrySet = true;
                codeBlock.instrStream.entrypoint = 0;
            }

            nodeBuilder = new NodeBuilder(compileStateTracker);
            unPopulatedClasses = new Dictionary<int, ClassDeclNode>();
        }
Пример #2
0
        public CodeGen(ProtoLanguage.CompileStateTracker compileState, ProtoCore.DSASM.CodeBlock parentBlock = null)
            : base(compileState, parentBlock)
        {
            classOffset = 0;

            //  either of these should set the console to flood
            //
            ignoreRankCheck = false;
            emitReplicationGuide = false;

            astNodes = new List<AssociativeNode>();
            globalInstanceProcList = new List<GlobalInstanceProc>();
            setConstructorStartPC = false;

            // Comment Jun: Get the codeblock to use for this codegenerator
            if (compileStateTracker.Options.IsDeltaExecution)
            {
                codeBlock = GetDeltaCompileCodeBlock();
                pc = compileStateTracker.deltaCompileStartPC;
            }
            else
            {
                codeBlock = BuildNewCodeBlock();
            }

            if (null == parentBlock)
            {
                if (!compileStateTracker.Options.IsDeltaExecution)
                {
                    // This is a top level block
                    compileStateTracker.CodeBlockList.Add(codeBlock);
                }
            }
            else
            {
                // TODO Jun: Handle nested codeblock here when we support scoping in the graph

                // This is a nested block

                // parentBlock == codeBlock happens when the core is in
                // delta exectuion and at the same time we create a dynamic
                // code block (e.g., inline condition)
                if  (parentBlock == codeBlock)
                {
                    codeBlock = BuildNewCodeBlock();
                    pc = 0;
                }
                parentBlock.children.Add(codeBlock);
                codeBlock.parent = parentBlock;
            }

            compileStateTracker.CompleteCodeBlockList.Add(codeBlock);
            compilePass = ProtoCore.DSASM.AssociativeCompilePass.kClassName;

            // Bouncing to this language codeblock from a function should immediately set the first instruction as the entry point
            if (ProtoCore.DSASM.Constants.kGlobalScope != globalProcIndex)
            {
                isEntrySet = true;
                codeBlock.instrStream.entrypoint = 0;
            }

            nodeBuilder = new NodeBuilder(compileStateTracker);
            unPopulatedClasses = new Dictionary<int, ClassDeclNode>();

            // For sub code block, say in inline condition, do we need context?
            /*
            if (core.assocCodegen != null)
            {
                context = core.assocCodegen.context;
            }
            */
        }
Пример #3
0
        private int EmitExpressionInterpreter(ProtoCore.AST.Node codeBlockNode)
        {
            compileStateTracker.startPC = this.pc;
            compilePass = AssociativeCompilePass.kGlobalScope;
            ProtoCore.AST.AssociativeAST.CodeBlockNode codeblock = codeBlockNode as ProtoCore.AST.AssociativeAST.CodeBlockNode;

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

            globalClassIndex = ProtoCore.DSASM.Constants.kInvalidIndex;
            globalProcIndex = ProtoCore.DSASM.Constants.kGlobalScope;

            // check if currently inside a function when the break was called
            if (compileStateTracker.DebugProps.DebugStackFrameContains(DebugProperties.StackFrameFlagOptions.FepRun))
            {
                // Save the current scope for the expression interpreter
                globalClassIndex = compileStateTracker.watchClassScope = (int)compileStateTracker.Rmem.GetAtRelative(compileStateTracker.Rmem.GetStackIndex(ProtoCore.DSASM.StackFrame.kFrameIndexClass)).opdata;
                globalProcIndex = compileStateTracker.watchFunctionScope = (int)compileStateTracker.Rmem.GetAtRelative(compileStateTracker.Rmem.GetStackIndex(ProtoCore.DSASM.StackFrame.kFrameIndexFunction)).opdata;
                int functionBlock = (int)compileStateTracker.Rmem.GetAtRelative(compileStateTracker.Rmem.GetStackIndex(ProtoCore.DSASM.StackFrame.kFrameIndexFunctionBlock)).opdata;

                if (globalClassIndex != -1)
                    localProcedure = compileStateTracker.ClassTable.ClassNodes[globalClassIndex].vtable.procList[globalProcIndex];
                else
                {
                    // TODO: to investigate whethter to use the table under executable or in core.FuncTable - Randy, Jun
                    localProcedure = compileStateTracker.DSExecutable.procedureTable[functionBlock].procList[globalProcIndex];
                }
            }

            foreach (AssociativeNode node in codeblock.Body)
            {
                inferedType = new ProtoCore.Type();
                inferedType.UID = (int)ProtoCore.PrimitiveType.kTypeVar;
                inferedType.IsIndexable = false;

                DfsTraverse(node, ref inferedType, false, null, ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier);

                BinaryExpressionNode binaryNode = node as BinaryExpressionNode;
            }

            compileStateTracker.InferedType = inferedType;

            this.pc = compileStateTracker.startPC;

            return codeBlock.codeBlockId;
        }
Пример #4
0
        public override int Emit(ProtoCore.AST.Node codeBlockNode, ProtoCore.AssociativeGraph.GraphNode graphNode = null)
        {
            if (compileStateTracker.Options.IsDeltaExecution)
            {
                if (context != null && context.symbolTable != null)
                {
                    Validity.Assert(context.symbolTable.symbolList != null && context.symbolTable.symbolList.Count > 0);
                    codeBlock.symbolTable = context.symbolTable;
                }
            }

            AllocateContextGlobals();

            compileStateTracker.startPC = this.pc;
            if (compileStateTracker.ExecMode == ProtoCore.DSASM.InterpreterMode.kExpressionInterpreter)
            {
                return EmitExpressionInterpreter(codeBlockNode);
            }

            this.localCodeBlockNode = codeBlockNode;
            ProtoCore.AST.AssociativeAST.CodeBlockNode codeblock = codeBlockNode as ProtoCore.AST.AssociativeAST.CodeBlockNode;
            bool isTopBlock = null == codeBlock.parent;
            if (!isTopBlock)
            {
                // If this is an inner block where there can be no classes, we can start at parsing at the global function state
                compilePass = ProtoCore.DSASM.AssociativeCompilePass.kGlobalFuncSig;
            }
            codeblock.Body = SplitMulitpleAssignment(codeblock.Body);
            codeblock.Body = BuildSSA(codeblock.Body, context);

            if (compileStateTracker.Options.DumpIL)
            {
                CodeGenDS codegenDS = new CodeGenDS(codeblock.Body);
                EmitCompileLog(codegenDS.GenerateCode());
            }

            bool hasReturnStatement = false;
            ProtoCore.Type inferedType = new ProtoCore.Type();
            while (ProtoCore.DSASM.AssociativeCompilePass.kDone != compilePass)
            {
                foreach (AssociativeNode node in codeblock.Body)
                {
                    inferedType = new ProtoCore.Type();
                    inferedType.UID = (int)ProtoCore.PrimitiveType.kTypeVar;
                    inferedType.IsIndexable = false;

                    //
                    // TODO Jun:    Handle stand alone language blocks
                    //              Integrate the subPass into a proper pass
                    //
                    //              **Need to take care of EmitImportNode, in which I used the same code to handle imported language block nodes - Randy
                    //
                    if (node is LanguageBlockNode)
                    {
                        // Build a binaryn node with a temporary lhs for every stand-alone language block
                        var iNode = nodeBuilder.BuildIdentfier(compileStateTracker.GenerateTempLangageVar());
                        var langBlockNode = nodeBuilder.BuildBinaryExpression(iNode, node);

                        DfsTraverse(langBlockNode, ref inferedType, false, graphNode, ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier);
                    }
                    else
                    {
                        DfsTraverse(node, ref inferedType, false, graphNode, ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier);
                        SetDeltaCompilePC(node);
                    }

                    if (NodeUtils.IsReturnExpressionNode(node))
                        hasReturnStatement = true;
                }
                if (compilePass == ProtoCore.DSASM.AssociativeCompilePass.kGlobalScope && !hasReturnStatement)
                {
                    EmitReturnNull();
                }

                compilePass++;

                // We have compiled all classes
                if (compilePass == ProtoCore.DSASM.AssociativeCompilePass.kGlobalScope && isTopBlock)
                {
                    EmitFunctionCallToInitStaticProperty(codeblock.Body);
                }

            }

            ResolveFinalNodeRefs();

            if (codeBlock.parent == null)  // top-most langauge block
            {
                ResolveFunctionGroups();
            }

            compileStateTracker.InferedType = inferedType;

            if (compileStateTracker.AsmOutput != Console.Out)
            {
                compileStateTracker.AsmOutput.Flush();
            }

            this.localCodeBlockNode = codeBlockNode;

            return codeBlock.codeBlockId;
        }
Пример #5
0
        public override int Emit(ProtoCore.AST.Node codeBlockNode, ProtoCore.AssociativeGraph.GraphNode graphNode = null)
        {
            if (core.Options.IsDeltaExecution)
            {
                if (context != null && context.symbolTable != null)
                {
                    Validity.Assert(context.symbolTable.symbolList != null && context.symbolTable.symbolList.Count > 0);
                    codeBlock.symbolTable = context.symbolTable;
                }
            }

            AllocateContextGlobals();

            core.startPC = this.pc;
            if (core.ExecMode == ProtoCore.DSASM.InterpreterMode.kExpressionInterpreter)
            {
                return EmitExpressionInterpreter(codeBlockNode);
            }

            this.localCodeBlockNode = codeBlockNode;
            ProtoCore.AST.AssociativeAST.CodeBlockNode codeblock = codeBlockNode as ProtoCore.AST.AssociativeAST.CodeBlockNode;
            bool isTopBlock = null == codeBlock.parent;
            if (!isTopBlock)
            {
                // If this is an inner block where there can be no classes, we can start at parsing at the global function state
                compilePass = ProtoCore.DSASM.AssociativeCompilePass.kGlobalFuncSig;
            }

            codeblock.Body = SplitMulitpleAssignment(codeblock.Body);
            
            bool hasReturnStatement = false;
            ProtoCore.Type inferedType = new ProtoCore.Type();
            bool ssaTransformed = false;
            while (ProtoCore.DSASM.AssociativeCompilePass.kDone != compilePass)
            {
                // Emit SSA only after generating the class definitions
                if (core.Options.GenerateSSA)
                {
                    if (compilePass > AssociativeCompilePass.kClassName && !ssaTransformed)
                    {
                        if (!core.IsParsingCodeBlockNode && !core.Options.IsDeltaExecution)
                        {
                            //Audit class table for multiple symbol definition and emit warning.
                            this.core.ClassTable.AuditMultipleDefinition(this.core.BuildStatus, graphNode == null ? default(Guid) : graphNode.guid);
                        }
                        codeblock.Body = BuildSSA(codeblock.Body, context);
                        core.CachedSSANodes.Clear();
                        core.CachedSSANodes.AddRange(codeblock.Body);
                        ssaTransformed = true;
                        if (core.Options.DumpIL)
                        {
                            CodeGenDS codegenDS = new CodeGenDS(codeblock.Body);
                            EmitCompileLog(codegenDS.GenerateCode());
                        }
                    }
                }

                foreach (AssociativeNode node in codeblock.Body)
                {
                    inferedType = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeVar, 0); 

                    //
                    // TODO Jun:    Handle stand alone language blocks
                    //              Integrate the subPass into a proper pass
                    //              
                    //              **Need to take care of EmitImportNode, in which I used the same code to handle imported language block nodes - Randy
                    //
                    if (node is LanguageBlockNode)
                    {
                        // Build a binaryn node with a temporary lhs for every stand-alone language block
                        var iNode = nodeBuilder.BuildIdentfier(core.GenerateTempLangageVar());
                        var langBlockNode = nodeBuilder.BuildBinaryExpression(iNode, node);

                        DfsTraverse(langBlockNode, ref inferedType, false, graphNode, ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier);
                    }
                    else
                    {
                        DfsTraverse(node, ref inferedType, false, graphNode, ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier);
                        SetDeltaCompilePC(node);
                    }

                    if (NodeUtils.IsReturnExpressionNode(node))
                        hasReturnStatement = true;
                }

                if (compilePass == ProtoCore.DSASM.AssociativeCompilePass.kGlobalScope && !hasReturnStatement)
                {
                    EmitReturnNull();
                }

                compilePass++;

                // We have compiled all classes
                if (compilePass == ProtoCore.DSASM.AssociativeCompilePass.kGlobalScope && isTopBlock)
                {
                    EmitFunctionCallToInitStaticProperty(codeblock.Body);
                }

            }

            ResolveFinalNodeRefs();
            ResolveSSADependencies();

            if (codeBlock.parent == null)  // top-most langauge block
            {
                ResolveFunctionGroups();
            }

            core.InferedType = inferedType;

            if (core.AsmOutput != Console.Out)
            {
                core.AsmOutput.Flush();
            }

            this.localCodeBlockNode = codeBlockNode;

            // Reset the callsite guids in preparation for the next compilation
            core.CallsiteGuidMap = new Dictionary<Guid, int>();

            return codeBlock.codeBlockId;
        }