Esempio n. 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(Core coreObj) : base(coreObj)
        {
            Validity.Assert(core.IsParsingPreloadedAssembly || core.IsParsingCodeBlockNode);

            classOffset = 0;

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

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

            // Re-use the existing procedureTable and symbolTable to access the built-in and predefined functions
            ProcedureTable procTable = core.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.Compiler.Associative.CompilePass.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(core);
            unPopulatedClasses = new Dictionary<int, ClassDeclNode>();
            expressionSSATempSymbolList = new Stack<SymbolNode>();
        }
Esempio n. 2
0
        private int EmitExpressionInterpreter(ProtoCore.AST.Node codeBlockNode)
        {
            core.startPC = this.pc;
            compilePass = ProtoCore.Compiler.Associative.CompilePass.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 (core.DebugProps.DebugStackFrameContains(DebugProperties.StackFrameFlagOptions.FepRun))
            {
                // Save the current scope for the expression interpreter
                globalClassIndex = core.watchClassScope = core.Rmem.CurrentStackFrame.ClassScope;
                globalProcIndex = core.watchFunctionScope = core.Rmem.CurrentStackFrame.FunctionScope;
                int functionBlock = core.Rmem.CurrentStackFrame.FunctionBlock;

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

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

                DfsTraverse(node, ref inferedType, false, null, ProtoCore.Compiler.Associative.SubCompilePass.kUnboundIdentifier);

                BinaryExpressionNode binaryNode = node as BinaryExpressionNode;
            }

            core.InferedType = inferedType;

            this.pc = core.startPC;

            return codeBlock.codeBlockId;
        }
Esempio n. 3
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.Compiler.Associative.CompilePass.kGlobalFuncSig;
            }

            codeblock.Body = SplitMulitpleAssignment(codeblock.Body);
            
            bool hasReturnStatement = false;
            ProtoCore.Type inferedType = new ProtoCore.Type();
            bool ssaTransformed = false;
            while (ProtoCore.Compiler.Associative.CompilePass.kDone != compilePass)
            {
                // Emit SSA only after generating the class definitions
                if (core.Options.GenerateSSA)
                {
                    if (compilePass > ProtoCore.Compiler.Associative.CompilePass.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);
                        }
                        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.Compiler.Associative.SubCompilePass.kUnboundIdentifier);
                    }
                    else
                    {
                        DfsTraverse(node, ref inferedType, false, graphNode, ProtoCore.Compiler.Associative.SubCompilePass.kUnboundIdentifier);
                        SetDeltaCompilePC(node);
                    }

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

                if (compilePass == ProtoCore.Compiler.Associative.CompilePass.kGlobalScope && !hasReturnStatement)
                {
                    EmitReturnNull();
                }

                compilePass++;

                // We have compiled all classes
                if (compilePass == ProtoCore.Compiler.Associative.CompilePass.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;
        }
Esempio n. 4
0
        public CodeGen(Core coreObj, ProtoCore.CompileTime.Context callContext, ProtoCore.DSASM.CodeBlock parentBlock = null) : base(coreObj, parentBlock)
        {
            context = callContext;
            classOffset = 0;

            //  either of these should set the console to flood
            //
            ignoreRankCheck = false;
            emitReplicationGuide = false;
            astNodes = new List<AssociativeNode>();
            setConstructorStartPC = false;


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

            if (null == parentBlock)
            {
                if (!core.Options.IsDeltaExecution)
                {
                    // This is a top level block
                    core.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;
            }

            compilePass = ProtoCore.Compiler.Associative.CompilePass.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(core);
            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;
            }
            */
            expressionSSATempSymbolList = new Stack<SymbolNode>();
        }