internal int AddLexicalScope(LexicalScope scope) { int ret = lexicalScopes.Count; this.lexicalScopes.Add(scope); return(ret); }
public void AddFunction(Function function) { // Store the function. functions.Add(function); // Register the local scopes. for (int i = 0; i < function.GetLexicalScopeCount(); ++i) { LexicalScope scope = function.GetLexicalScope(i); // Register the position filename. TokenPosition pos = scope.Position; if (pos == null) { pos = NullPosition; } AddFileName(pos.GetFileName()); } // Register the variables names and positions. foreach (LocalVariable local in function.GetLocals()) { // Register the local name. AddString(local.GetName()); // Register the position filename TokenPosition localPos = local.Position; if (localPos == null) { localPos = NullPosition; } AddFileName(localPos.GetFileName()); } // Register the filenames. string lastFilename = null; foreach (BasicBlock bb in function.GetBasicBlocks()) { foreach (Instruction instruction in bb.GetInstructions()) { // Ignore instructions without position. TokenPosition position = instruction.GetPosition(); if (position == null) { position = NullPosition; } // Set the filename. string filename = position.GetFileName(); if (position != null && lastFilename != filename) { AddFileName(filename); lastFilename = filename; } } } }
protected LexicalScope CreateLexicalScope(AstNode where, Function parentFunction) { LexicalScope ret = new LexicalScope(currentContainer, parentFunction); ret.Position = where.GetPosition(); return ret; }
internal int AddLexicalScope(LexicalScope scope) { int ret = lexicalScopes.Count; this.lexicalScopes.Add(scope); return ret; }
private void PrepareReturning(AstNode where, Function function, LexicalScope scope) { // Get the definition node and check for generator. FunctionDefinition defNode = function.DefinitionNode; bool isGenerator = false; if(defNode != null) isGenerator = defNode.IsGenerator; // Use standard return. if(function.GetExceptionContext() == null && !isGenerator) return; // Create the return block. BasicBlock returnBlock = new BasicBlock(function); returnBlock.SetName("retBlock"); function.ReturnBlock = returnBlock; // Create the return value local. FunctionType functionType = function.GetFunctionType(); IChelaType retType = functionType.GetReturnType(); if(retType != ChelaType.GetVoidType() && !isGenerator) function.ReturnValueVar = new LocalVariable(GenSym() + "_retval", scope, retType); // Create the is returning flag. function.ReturningVar = new LocalVariable(GenSym() + "_isret", scope, ChelaType.GetBoolType(), isGenerator); function.ReturningVar.Type = LocalType.Return; // Create the field for generators. if(isGenerator) { FieldVariable returningField = new FieldVariable("returning", MemberFlags.Private, ChelaType.GetBoolType(), defNode.GeneratorClass); defNode.GeneratorClass.AddField(returningField); function.ReturningVar.ActualVariable = returningField; } // Initializer the returning flag to false. builder.CreateLoadBool(false); PerformAssignment(where, function.ReturningVar); }
private void DefineFunctionBody(FunctionDefinition node, Function function, LexicalScope topScope) { // Create the top basic block. BasicBlock topBlock = CreateBasicBlock(); topBlock.SetName("top"); builder.SetBlock(topBlock); // Prepare returning. PrepareReturning(node, function, topScope); // Store the arguments into local variables. FunctionPrototype prototype = node.GetPrototype(); AstNode argument = prototype.GetArguments(); byte index = 0; while(argument != null) { FunctionArgument argNode = (FunctionArgument) argument; LocalVariable argVar = argNode.GetVariable(); if(argVar != null && !argVar.IsPseudoScope()) { // Load the argument. builder.CreateLoadArg(index); // Store it into the local. builder.CreateStoreLocal(argVar); } // Process the next argument. argument = argument.GetNext(); index++; } // Generate constructor initialization. if(function.IsConstructor()) { Method ctor = (Method)function; ConstructorInitializer ctorInit = prototype.GetConstructorInitializer(); if(ctorInit != null) ctorInit.Accept(this); else CreateImplicitBaseConstructor(node, ctor); // Initialize some field. if(ctor.IsCtorLeaf()) { Structure building = (Structure)ctor.GetParentScope(); GenerateFieldInitializations(node, building); } } else if(function.IsStaticConstructor()) { // Generate static field initialization. Scope parent = function.GetParentScope(); Structure pbuilding = parent as Structure; if(pbuilding != null) GenerateStaticFieldInitializations(node, function, pbuilding); } // Visit his children. VisitList(node.GetChildren()); // Finish return. FinishReturn(node, function); }
private void EmitFunctionDebugInfo(ModuleWriter writer, Function function) { // Emit the function id. uint functionId = function.GetSerialId(); writer.Write(functionId); // Emit the function position. EmitPosition(writer, function.Position); // Emit the lexical scopes. byte numscopes = (byte)function.GetLexicalScopeCount(); writer.Write(numscopes); for (int i = 0; i < numscopes; ++i) { // Get the lexical scope. LexicalScope scope = function.GetLexicalScope(i); // Find the parent index. byte parentIndex = 0; LexicalScope parentScope = scope.GetParentScope() as LexicalScope; if (parentScope != null) { parentIndex = (byte)parentScope.Index; } // Emit the parent scope. writer.Write(parentIndex); // Write the scope position. EmitPosition(writer, scope.Position); } // Emit the local data and positions. ushort localCount = (ushort)function.GetLocalCount(); writer.Write(localCount); foreach (LocalVariable local in function.GetLocals()) { // Get the local scope. byte localScope = 0; LexicalScope scope = local.GetParentScope() as LexicalScope; if (scope != null) { localScope = (byte)scope.Index; } // Write the variable data. writer.Write(AddString(local.GetName())); writer.Write(localScope); writer.Write((byte)local.Type); writer.Write((byte)local.ArgumentIndex); EmitPosition(writer, local.Position); } // Emit each basic block position information. ushort blockCount = (ushort)function.GetBasicBlockCount(); writer.Write(blockCount); foreach (BasicBlock bb in function.GetBasicBlocks()) { EmitBasicBlockDebugInfo(writer, bb); } }