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)); }
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)); }
/// <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);