// 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 // emitReplicationGuide = false; 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.CompilerDefinitions.CompilePass.ClassName; // 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; } unPopulatedClasses = new Dictionary<int, ClassDeclNode>(); }
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 emitReplicationGuide = false; 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.CompilerDefinitions.CompilePass.ClassName; // 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; } unPopulatedClasses = new Dictionary<int, ClassDeclNode>(); }
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.watchStartPC = this.pc; if (core.Options.RunMode == ProtoCore.DSASM.InterpreterMode.Expression) { 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.CompilerDefinitions.CompilePass.GlobalScope; } codeblock.Body = ApplyTransform(codeblock.Body); bool hasReturnStatement = false; ProtoCore.Type inferedType = new ProtoCore.Type(); bool ssaTransformed = false; while (ProtoCore.CompilerDefinitions.CompilePass.Done != compilePass) { // Emit SSA only after generating the class definitions if (core.Options.GenerateSSA) { if (compilePass > ProtoCore.CompilerDefinitions.CompilePass.ClassName && !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); ssaTransformed = true; if (core.Options.DumpIL) { CodeGenDS codegenDS = new CodeGenDS(codeblock.Body); EmitCompileLog(codegenDS.GenerateCode()); } } } inferedType = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.Var, 0); hasReturnStatement = EmitCodeBlock(codeblock.Body, ref inferedType, ProtoCore.CompilerDefinitions.SubCompilePass.UnboundIdentifier, false); if (compilePass == ProtoCore.CompilerDefinitions.CompilePass.GlobalScope && !hasReturnStatement) { EmitReturnNull(); } compilePass++; } ResolveSSADependencies(); ProtoCore.AssociativeEngine.Utils.BuildGraphNodeDependencies( codeBlock.instrStream.dependencyGraph.GetGraphNodesAtScope(Constants.kInvalidIndex, Constants.kGlobalScope)); 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; }
private int EmitExpressionInterpreter(ProtoCore.AST.Node codeBlockNode) { core.watchStartPC = this.pc; compilePass = ProtoCore.CompilerDefinitions.CompilePass.GlobalScope; 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 (context.DebugProps.DebugStackFrameContains(DebugProperties.StackFrameFlagOptions.FepRun)) { // Save the current scope for the expression interpreter globalClassIndex = context.WatchClassScope = context.MemoryState.CurrentStackFrame.ClassScope; globalProcIndex = core.watchFunctionScope = context.MemoryState.CurrentStackFrame.FunctionScope; int functionBlock = context.MemoryState.CurrentStackFrame.FunctionBlock; if (globalClassIndex != -1) localProcedure = core.ClassTable.ClassNodes[globalClassIndex].ProcTable.Procedures[globalProcIndex]; else { // TODO: to investigate whethter to use the table under executable or in core.FuncTable - Randy, Jun localProcedure = core.DSExecutable.procedureTable[functionBlock].Procedures[globalProcIndex]; } } foreach (AssociativeNode node in codeblock.Body) { inferedType = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.Var, 0); DfsTraverse(node, ref inferedType, false, null, ProtoCore.CompilerDefinitions.SubCompilePass.UnboundIdentifier); } core.InferedType = inferedType; this.pc = core.watchStartPC; return codeBlock.codeBlockId; }