Пример #1
0
        internal int AddLexicalScope(LexicalScope scope)
        {
            int ret = lexicalScopes.Count;

            this.lexicalScopes.Add(scope);
            return(ret);
        }
Пример #2
0
        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;
                    }
                }
            }
        }
Пример #3
0
 protected LexicalScope CreateLexicalScope(AstNode where, Function parentFunction)
 {
     LexicalScope ret = new LexicalScope(currentContainer, parentFunction);
     ret.Position = where.GetPosition();
     return ret;
 }
Пример #4
0
 internal int AddLexicalScope(LexicalScope scope)
 {
     int ret = lexicalScopes.Count;
     this.lexicalScopes.Add(scope);
     return ret;
 }
Пример #5
0
        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);
        }
Пример #6
0
        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);
        }
Пример #7
0
        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);
            }
        }