Beispiel #1
0
        public override Value?Visit(FunctionDefinition definition)
        {
            definition.ValidateNotNull(nameof(definition));
            var function = GetOrDeclareFunction(definition.Signature);

            if (!function.IsDeclaration)
            {
                throw new CodeGeneratorException($"Function {function.Name} cannot be redefined in the same module");
            }

            try
            {
                var entryBlock = function.AppendBasicBlock("entry");
                InstructionBuilder.PositionAtEnd(entryBlock);
                using (NamedValues.EnterScope( ))
                {
                    foreach (var param in definition.Signature.Parameters)
                    {
                        var argSlot = InstructionBuilder.Alloca(function.Context.DoubleType)
                                      .RegisterName(param.Name);
                        InstructionBuilder.Store(function.Parameters[param.Index], argSlot);
                        NamedValues[param.Name] = argSlot;
                    }

                    foreach (LocalVariableDeclaration local in definition.LocalVariables)
                    {
                        var localSlot = InstructionBuilder.Alloca(function.Context.DoubleType)
                                        .RegisterName(local.Name);
                        NamedValues[local.Name] = localSlot;
                    }

                    EmitBranchToNewBlock("body");

                    var funcReturn = definition.Body.Accept(this) ?? throw new CodeGeneratorException(ExpectValidFunc);
                    InstructionBuilder.Return(funcReturn);
                    function.Verify( );

                    FunctionPassManager.Run(function);

                    if (definition.IsAnonymous)
                    {
                        function.AddAttribute(FunctionAttributeIndex.Function, AttributeKind.AlwaysInline)
                        .Linkage(Linkage.Private);

                        AnonymousFunctions.Add(function);
                    }

                    return(function);
                }
            }
            catch (CodeGeneratorException)
            {
                function.EraseFromParent( );
                throw;
            }
        }
Beispiel #2
0
        //public AnonymousFunctionData GetAnonymousFunctionData(AnonymousFunctionExpressionSyntax node, bool create = false)
        //{
        //	var symbol = TypeData.NamespaceData.DocumentData.SemanticModel.GetSymbolInfo(node).Symbol as IMethodSymbol;
        //	return GetAnonymousFunctionData(node, symbol, create);
        //}

        public AnonymousFunctionData GetAnonymousFunctionData(AnonymousFunctionExpressionSyntax node, IMethodSymbol symbol, bool create = false)
        {
            AnonymousFunctionData functionData;

            if (AnonymousFunctions.TryGetValue(node, out functionData))
            {
                return(functionData);
            }
            return(!create ? null : AnonymousFunctions.GetOrAdd(node, syntax => new AnonymousFunctionData(this, symbol, node)));
        }
Beispiel #3
0
        public override Value?Visit(FunctionDefinition definition)
        {
            definition.ValidateNotNull(nameof(definition));
            var function = GetOrDeclareFunction(definition.Signature);

            if (!function.IsDeclaration)
            {
                throw new CodeGeneratorException($"Function {function.Name} cannot be redefined in the same module");
            }

            Debug.Assert(function.DISubProgram != null, "Expected function with non-null DISubProgram");
            LexicalBlocks.Push(function.DISubProgram);
            try
            {
                var entryBlock = function.AppendBasicBlock("entry");
                InstructionBuilder.PositionAtEnd(entryBlock);

                // Unset the location for the prologue emission (leading instructions with no
                // location in a function are considered part of the prologue and the debugger
                // will run past them when breaking on a function)
                EmitLocation(null);

                using (NamedValues.EnterScope( ))
                {
                    foreach (var param in definition.Signature.Parameters)
                    {
                        var argSlot = InstructionBuilder.Alloca(function.Context.DoubleType)
                                      .RegisterName(param.Name);
                        AddDebugInfoForAlloca(argSlot, function, param);
                        InstructionBuilder.Store(function.Parameters[param.Index], argSlot);
                        NamedValues[param.Name] = argSlot;
                    }

                    foreach (LocalVariableDeclaration local in definition.LocalVariables)
                    {
                        var localSlot = InstructionBuilder.Alloca(function.Context.DoubleType)
                                        .RegisterName(local.Name);
                        AddDebugInfoForAlloca(localSlot, function, local);
                        NamedValues[local.Name] = localSlot;
                    }

                    EmitBranchToNewBlock("body");

                    var funcReturn = definition.Body.Accept(this) ?? throw new CodeGeneratorException(ExpectValidFunc);
                    InstructionBuilder.Return(funcReturn);
                    Module.DIBuilder.Finish(function.DISubProgram);
                    function.Verify( );

                    FunctionPassManager.Run(function);

                    if (definition.IsAnonymous)
                    {
                        function.AddAttribute(FunctionAttributeIndex.Function, AttributeKind.AlwaysInline)
                        .Linkage(Linkage.Private);

                        AnonymousFunctions.Add(function);
                    }

                    return(function);
                }
            }
            catch (CodeGeneratorException)
            {
                function.EraseFromParent( );
                throw;
            }
        }