Exemple #1
0
 public void Initialize()
 {
     this.codeGenerator = new LLVMCodeGenerator(this);
     ParentMethod       = GetParentMethod(this);
     if (ParentMethod == this &&
         this.GetIsVirtual() &&
         !DeclaringType.GetIsInterface())
     {
         ParentType.RelativeVTable.CreateRelativeSlot(this);
     }
 }
 /// <inheritdoc/>
 public override CodeBlock EmitTryCatchFinally(
     LLVMCodeGenerator CodeGenerator,
     CodeBlock TryBody,
     CodeBlock FinallyBody,
     IReadOnlyList <CatchClause> CatchClauses)
 {
     return(new ItaniumCxxFinallyBlock(
                CodeGenerator,
                new ItaniumCxxCatchBlock(CodeGenerator, TryBody, CatchClauses),
                FinallyBody));
 }
Exemple #3
0
        private static bool GenerateAndCompileCode(CompilerOptions options, Workspace workspace, IErrorHandler errorHandler)
        {
            using var generator = new LLVMCodeGenerator(options.EnableStackTrace);
            bool success = generator.GenerateCode(workspace, options.IntDir, options.OutDir, options.OutName, options.Optimize, options.EmitLLVMIR);

            if (!success)
            {
                return(false);
            }

            return(generator.CompileCode(options.LibraryIncludeDirectories, options.Libraries, options.SubSystem.ToString(), errorHandler, options.PrintLinkerArguments));
        }
Exemple #4
0
        /// <summary>
        /// Auto-implements this method.
        /// </summary>
        private IStatement AutoImplement()
        {
            var delegateAttribute = ParentType.GetAttribute(
                MethodType.DelegateAttributeType) as IntrinsicAttribute;

            string methodName = PreMangledName.Unmangle(Name).ToString();

            var parameters = this.GetParameters();

            if (delegateAttribute != null &&
                delegateAttribute.Arguments[0].GetValue <string>() == methodName)
            {
                // Implement this method using a simple invocation expression.
                var args = new IExpression[parameters.Length];
                for (int i = 0; i < args.Length; i++)
                {
                    args[i] = new ArgumentVariable(parameters[i], i).CreateGetExpression();
                }

                return(new ReturnStatement(
                           new InvocationExpression(
                               new ReinterpretCastExpression(
                                   new ThisVariable(DeclaringType).CreateGetExpression(),
                                   MethodType.Create(this)),
                               args)));
            }
            else if (methodName == "LoadDelegateHasContextInternal" &&
                     IsStatic &&
                     ReturnType == PrimitiveTypes.Boolean &&
                     parameters.Length == 1)
            {
                return(new ReturnStatement(
                           LLVMCodeGenerator.ToExpression(
                               new UnaryBlock(
                                   codeGenerator,
                                   (CodeBlock) new ArgumentVariable(parameters[0], 0)
                                   .CreateGetExpression()
                                   .Emit(codeGenerator),
                                   PrimitiveTypes.Boolean,
                                   DelegateBlock.BuildLoadHasContext))));
            }
            else if (methodName == "LoadDelegateFunctionPointerInternal" &&
                     IsStatic &&
                     ReturnType.GetIsPointer() &&
                     parameters.Length == 1)
            {
                return(new ReturnStatement(
                           LLVMCodeGenerator.ToExpression(
                               new UnaryBlock(
                                   codeGenerator,
                                   (CodeBlock) new ArgumentVariable(parameters[0], 0)
                                   .CreateGetExpression()
                                   .Emit(codeGenerator),
                                   ReturnType,
                                   DelegateBlock.BuildLoadFunctionPointer))));
            }
            else if (methodName == "CompareExchange" &&
                     IsStatic &&
                     parameters.Length == 3)
            {
                return(new ReturnStatement(
                           LLVMCodeGenerator.ToExpression(
                               new CompareExchangeBlock(
                                   (CodeBlock) new ArgumentVariable(parameters[0], 0)
                                   .CreateGetExpression()
                                   .Emit(codeGenerator),
                                   (CodeBlock) new ArgumentVariable(parameters[1], 1)
                                   .CreateGetExpression()
                                   .Emit(codeGenerator),
                                   (CodeBlock) new ArgumentVariable(parameters[2], 2)
                                   .CreateGetExpression()
                                   .Emit(codeGenerator),
                                   codeGenerator))));
            }
            else if (methodName.StartsWith("AtomicRMW") &&
                     IsStatic &&
                     parameters.Length == 2)
            {
                return(new ReturnStatement(
                           LLVMCodeGenerator.ToExpression(
                               new ReadModifyWriteBlock(
                                   (CodeBlock) new ArgumentVariable(parameters[0], 0)
                                   .CreateGetExpression()
                                   .Emit(codeGenerator),
                                   (CodeBlock) new ArgumentVariable(parameters[1], 1)
                                   .CreateGetExpression()
                                   .Emit(codeGenerator),
                                   ReadModifyWriteBlock.ParseOperator(
                                       methodName.Substring("AtomicRMW".Length)),
                                   codeGenerator))));
            }
            else
            {
                throw new NotSupportedException(
                          "Runtime doesn't know how to implement method '" +
                          this.FullName.ToString() + "'.");
            }
        }
        /// <inheritdoc/>
        public override CodeBlock EmitThrow(LLVMCodeGenerator CodeGenerator, CodeBlock Exception)
        {
            // Generate something more or less like this:
            //
            //     %1 = call i8* @__cxa_allocate_exception(i64 <sizeof(value-to-throw)>)
            //     %2 = bitcast i8* %1 to <typeof(value-to-throw)>*
            //     store i8* <value-to-throw>, <typeof(value-to-throw)>* %2
            //     call void @__cxa_throw(i8* %1, i8* bitcast (i8** @_ZTIPv to i8*), i8* null)
            //     unreachable
            //

            var exceptionType = Exception.Type;

            var exceptionStorageSpec = new DescribedVariableMember(
                "exception_storage",
                PrimitiveTypes.Void.MakePointerType(PointerKind.TransientPointer));

            var exceptionStorage = CodeGenerator.DeclareLocal(
                new UniqueTag(exceptionStorageSpec.Name.ToString()),
                exceptionStorageSpec);

            var allocStmt = exceptionStorage.EmitSet(
                new InvocationBlock(
                    CodeGenerator,
                    new IntrinsicBlock(CodeGenerator, IntrinsicValue.CxaAllocateException),
                    new CodeBlock[]
            {
                (CodeBlock)CodeGenerator.EmitTypeBinary(
                    CodeGenerator.EmitSizeOf(exceptionType),
                    MethodType
                    .GetMethod(IntrinsicValue.CxaAllocateException.Type)
                    .GetParameters()[0].ParameterType,
                    Operator.StaticCast)
            },
                    false));

            var storeStmt = CodeGenerator.EmitStoreAtAddress(
                CodeGenerator.EmitTypeBinary(
                    exceptionStorage.EmitGet(),
                    exceptionType.MakePointerType(PointerKind.TransientPointer),
                    Operator.ReinterpretCast),
                Exception);

            var throwStmt = new InvocationBlock(
                CodeGenerator,
                new IntrinsicBlock(CodeGenerator, IntrinsicValue.CxaThrow),
                new CodeBlock[]
            {
                (CodeBlock)exceptionStorage.EmitGet(),
                (CodeBlock)CodeGenerator.EmitTypeBinary(
                    new IntrinsicBlock(CodeGenerator, IntrinsicValue.CxaVoidPointerRtti),
                    PrimitiveTypes.Void.MakePointerType(PointerKind.TransientPointer),
                    Operator.ReinterpretCast),
                (CodeBlock)CodeGenerator.EmitTypeBinary(
                    CodeGenerator.EmitNull(),
                    PrimitiveTypes.Void.MakePointerType(PointerKind.TransientPointer),
                    Operator.ReinterpretCast)
            },
                true);

            return((CodeBlock)CodeGenerator.EmitSequence(
                       allocStmt,
                       CodeGenerator.EmitSequence(
                           storeStmt,
                           CodeGenerator.EmitSequence(
                               throwStmt,
                               new UnreachableBlock(CodeGenerator, PrimitiveTypes.Void)))));
        }
 /// <summary>
 /// Creates a try-catch-finally block.
 /// </summary>
 /// <param name="CodeGenerator">The code generator.</param>
 /// <param name="TryBody">The try block's body.</param>
 /// <param name="FinallyBody">The finally block's body.</param>
 /// <param name="CatchClauses">The catch clauses.</param>
 /// <returns>A try-catch-finally block.</returns>
 public abstract CodeBlock EmitTryCatchFinally(
     LLVMCodeGenerator CodeGenerator,
     CodeBlock TryBody,
     CodeBlock FinallyBody,
     IReadOnlyList <CatchClause> CatchClauses);
 /// <summary>
 /// Creates a code block that throws an exception object.
 /// </summary>
 /// <param name="CodeGenerator">The code generator.</param>
 /// <param name="Exception">The exception to throw.</param>
 /// <returns>A code block that throws the given exception object.</returns>
 public abstract CodeBlock EmitThrow(LLVMCodeGenerator CodeGenerator, CodeBlock Exception);