/// <summary> /// </summary> /// <param name="llvmWriter"> /// </param> /// <param name="opCode"> /// </param> /// <param name="exceptionHandlingClause"> /// </param> public static void WriteThrow( this LlvmWriter llvmWriter, OpCodePart opCode, CatchOfFinallyClause exceptionHandlingClause) { var writer = llvmWriter.Output; writer.WriteLine("; Throw"); var exceptionPointerType = exceptionHandlingClause != null ? WriteThrowInvoke(llvmWriter, opCode, exceptionHandlingClause) : WriteThrowCall(llvmWriter, opCode); llvmWriter.typeRttiPointerDeclRequired.Add(exceptionPointerType); llvmWriter.CheckIfExternalDeclarationIsRequired(exceptionPointerType); }
/// <summary> /// </summary> /// <param name="llvmWriter"> /// </param> /// <param name="opCodeMethodInfo"> /// </param> /// <param name="methodInfo"> /// </param> /// <param name="isVirtual"> /// </param> /// <param name="hasThis"> /// </param> /// <param name="isCtor"> /// </param> /// <param name="thisResultNumber"> /// </param> /// <param name="tryClause"> /// </param> public static void WriteCall( this LlvmWriter llvmWriter, OpCodePart opCodeMethodInfo, IMethod methodInfo, bool isVirtual, bool hasThis, bool isCtor, FullyDefinedReference thisResultNumber, TryClause tryClause) { var writer = llvmWriter.Output; IType thisType; bool hasThisArgument; OpCodePart opCodeFirstOperand; BaseWriter.ReturnResult resultOfFirstOperand; bool isIndirectMethodCall; IType ownerOfExplicitInterface; IType requiredType; methodInfo.WriteFunctionCallProlog( opCodeMethodInfo, isVirtual, hasThis, llvmWriter, out thisType, out hasThisArgument, out opCodeFirstOperand, out resultOfFirstOperand, out isIndirectMethodCall, out ownerOfExplicitInterface, out requiredType); llvmWriter.CheckIfMethodExternalDeclarationIsRequired(methodInfo, ownerOfExplicitInterface); llvmWriter.CheckIfExternalDeclarationIsRequired(methodInfo.DeclaringType); if (hasThisArgument) { opCodeMethodInfo.WriteFunctionCallPrepareThisExpression( thisType, opCodeFirstOperand, resultOfFirstOperand, llvmWriter); } FullyDefinedReference methodAddressResultNumber = null; if (isIndirectMethodCall) { methodAddressResultNumber = llvmWriter.GenerateVirtualCall( opCodeMethodInfo, methodInfo, thisType, opCodeFirstOperand, resultOfFirstOperand, ref requiredType); } methodInfo.WriteFunctionCallLoadFunctionAddress( opCodeMethodInfo, thisType, ref methodAddressResultNumber, llvmWriter); methodInfo.PreProcessCallParameters(opCodeMethodInfo, llvmWriter); if (llvmWriter.ProcessPluggableMethodCall(opCodeMethodInfo, methodInfo)) { return; } var returnFullyDefinedReference = methodInfo.WriteFunctionCallResult(opCodeMethodInfo, llvmWriter); writer.WriteFunctionCall(tryClause); methodInfo.WriteFunctionCallAttributes(writer); if (methodInfo.CallingConvention.HasFlag(CallingConventions.VarArgs)) { llvmWriter.WriteMethodPointerType(writer, methodInfo); writer.Write(" "); } else { methodInfo.WriteFunctionCallReturnType(llvmWriter); writer.Write(' '); // extra support if (methodInfo.IsExternalLibraryMethod()) { writer.Write("(...)* "); } } methodInfo.WriteFunctionNameExpression(methodAddressResultNumber, ownerOfExplicitInterface, llvmWriter); methodInfo.GetParameters() .WriteFunctionCallArguments( opCodeMethodInfo.OpCodeOperands, isVirtual, hasThis, isCtor, thisResultNumber, thisType, returnFullyDefinedReference, methodInfo != null ? methodInfo.ReturnType : null, llvmWriter, methodInfo.CallingConvention.HasFlag(CallingConventions.VarArgs)); tryClause.WriteFunctionCallUnwind(opCodeMethodInfo, llvmWriter); }
/// <summary> /// </summary> /// <param name="llvmWriter"> /// </param> /// <param name="opCode"> /// </param> /// <param name="options"> /// </param> /// <param name="finallyOrFaultClause"> /// </param> /// <param name="catch"> /// </param> /// <param name="filter"> /// </param> /// <param name="exceptionAllocationResultNumber"> /// </param> public static void WriteLandingPad( this LlvmWriter llvmWriter, OpCodePart opCode, LandingPadOptions options, CatchOfFinallyClause finallyOrFaultClause, IType[] @catch = null, int[] filter = null, int? exceptionAllocationResultNumber = null) { var writer = llvmWriter.Output; llvmWriter.WriteLandingPadVariables(); var landingPadResult = llvmWriter.WriteSetResultNumber( opCode, llvmWriter.System.System_Byte.ToPointerType()); writer.WriteLine( "landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)"); if (options.HasFlag(LandingPadOptions.Cleanup)) { writer.Indent++; writer.WriteLine("cleanup"); writer.Indent--; } if (options.HasFlag(LandingPadOptions.EmptyFilter)) { writer.Indent++; writer.WriteLine("filter [0 x i8*] zeroinitializer"); writer.Indent--; } if (@catch != null && @catch.Any()) { foreach (var catchType in @catch) { writer.Indent++; if (catchType != null) { writer.Write("catch i8* bitcast ("); catchType.WriteRttiPointerClassInfoDeclaration(writer); writer.WriteLine("* @\"{0}\" to i8*)", catchType.GetRttiPointerInfoName()); llvmWriter.typeRttiPointerDeclRequired.Add(catchType); llvmWriter.CheckIfExternalDeclarationIsRequired(catchType); } else { writer.Write("catch i8* null"); } writer.Indent--; } } else if (finallyOrFaultClause != null) { // default catch with rethrowing it writer.Indent++; writer.WriteLine("catch i8* null"); writer.Indent--; finallyOrFaultClause.EmptyFinallyRethrowRequired = true; } var getErrorObjectResultNumber = llvmWriter.WriteSetResultNumber( opCode, llvmWriter.System.System_Byte.ToPointerType()); writer.WriteLine("extractvalue {1} {0}, 0", landingPadResult, "{ i8*, i32 }"); writer.WriteLine("store i8* {0}, i8** %.error_object", getErrorObjectResultNumber); var getErrorTypeIdResultNumber = llvmWriter.WriteSetResultNumber( opCode, llvmWriter.System.System_Int32); writer.WriteLine("extractvalue {1} {0}, 1", landingPadResult, "{ i8*, i32 }"); writer.Write("store i32 {0}, i32* %.error_typeid", getErrorTypeIdResultNumber); if (exceptionAllocationResultNumber.HasValue) { writer.WriteLine(string.Empty); writer.Write("call void @__cxa_free_exception(i8* {0})", exceptionAllocationResultNumber.Value); } opCode.Result = landingPadResult; }
/// <summary> /// </summary> /// <param name="llvmWriter"> /// </param> /// <param name="opCode"> /// </param> /// <param name="declaringType"> /// </param> /// <returns> /// </returns> public static bool WriteUnboxObject(this LlvmWriter llvmWriter, OpCodePart opCode, IType declaringType) { var writer = llvmWriter.Output; var isStruct = declaringType.IsStructureType(); writer.WriteLine("; Unboxing"); writer.WriteLine(string.Empty); llvmWriter.CheckIfExternalDeclarationIsRequired(declaringType); writer.WriteLine("; Copy data"); if (!isStruct) { // write access to a field if (!llvmWriter.WriteFieldAccess( writer, opCode, declaringType.ToClass(), declaringType.ToClass(), 0, opCode.Result)) { writer.WriteLine("; No data"); return false; } writer.WriteLine(string.Empty); } // load value from field var memberAccessResultNumber = opCode.Result; if (!isStruct) { opCode.Result = null; } llvmWriter.WriteLlvmLoad(opCode, memberAccessResultNumber.Type.ToNormal(), memberAccessResultNumber); writer.WriteLine(string.Empty); writer.WriteLine("; End of Copy data"); return true; }
/// <summary> /// </summary> /// <param name="llvmWriter"> /// </param> /// <param name="opCode"> /// </param> /// <param name="declaringType"> /// </param> public static void WriteGetHashCodeObjectForEnum(this LlvmWriter llvmWriter, OpCodePart opCode, IType declaringType) { var writer = llvmWriter.Output; var isStruct = declaringType.IsStructureType(); writer.WriteLine("; Returning Hash Code"); writer.WriteLine(string.Empty); llvmWriter.CheckIfExternalDeclarationIsRequired(declaringType); writer.WriteLine("; Get data"); if (!isStruct) { // write access to a field if (!llvmWriter.WriteFieldAccess(writer, opCode, declaringType.ToClass(), declaringType.ToClass(), 0, opCode.Result)) { writer.WriteLine("; No data"); return; } writer.WriteLine(string.Empty); } else { Debug.Fail("Not implemented yet"); throw new NotImplementedException(); } // load value from field var memberAccessResultNumber = opCode.Result; opCode.Result = null; llvmWriter.WriteLlvmLoad(opCode, memberAccessResultNumber.Type.ToNormal(), memberAccessResultNumber); writer.WriteLine(string.Empty); if (opCode.Result.Type.IntTypeBitSize() != llvmWriter.ResolveType("System.Int32").IntTypeBitSize()) { var storeResult = opCode.Result; var retResult = llvmWriter.WriteSetResultNumber(opCode, llvmWriter.ResolveType("System.Int32")); opCode.Result = storeResult; llvmWriter.AdjustIntConvertableTypes(writer, opCode, llvmWriter.ResolveType("System.Int32")); opCode.Result = retResult; writer.WriteLine(string.Empty); } writer.WriteLine("; End of Getting data"); }
/// <summary> /// </summary> /// <param name="llvmWriter"> /// </param> /// <param name="opCode"> /// </param> /// <param name="declaringType"> /// </param> /// <param name="newObjectResult"> /// </param> /// <param name="callInit"> /// </param> public static void WriteBoxObject( this LlvmWriter llvmWriter, OpCodePart opCode, IType declaringType, FullyDefinedReference newObjectResult = null, bool callInit = false) { var writer = llvmWriter.Output; var valueLoadResult = opCode.Result; var isStruct = declaringType.ToNormal().IsStructureType(); opCode.Result = null; writer.WriteLine("; Boxing"); writer.WriteLine(string.Empty); llvmWriter.CheckIfExternalDeclarationIsRequired(declaringType); // call new if null if (newObjectResult == null) { declaringType.WriteCallNewObjectMethod(llvmWriter, opCode); newObjectResult = opCode.Result; } else { opCode.Result = newObjectResult; } writer.WriteLine(string.Empty); writer.WriteLine("; Copy data"); if (!isStruct) { // write access to a field if (!llvmWriter.WriteFieldAccess( writer, opCode, declaringType.ToClass(), declaringType.ToClass(), 0, opCode.Result)) { writer.WriteLine("; No data"); return; } writer.WriteLine(string.Empty); } var fieldType = declaringType.ToNormal(); opCode.OpCodeOperands = new[] { new OpCodePart(OpCodesEmit.Ldarg_0, 0, 0) }; opCode.OpCodeOperands[0].Result = valueLoadResult; if (valueLoadResult == null) { llvmWriter.ActualWrite(writer, opCode.OpCodeOperands[0]); } llvmWriter.SaveToField(opCode, fieldType, 0); writer.WriteLine(string.Empty); writer.WriteLine("; End of Copy data"); if (callInit) { opCode.Result = newObjectResult; declaringType.WriteCallInitObjectMethod(llvmWriter, opCode); writer.WriteLine(string.Empty); } opCode.Result = newObjectResult.ToClassType(); }
private static void WriteFunctionCallVarArgument(this LlvmWriter llvmWriter, OpCodePart opArg, IType type) { var writer = llvmWriter.Output; llvmWriter.CheckIfExternalDeclarationIsRequired(type); type.WriteTypePrefix(llvmWriter, type.IsStructureType()); if (type.IsStructureType()) { writer.Write(" byval align " + llvmWriter.ByValAlign); } writer.Write(' '); llvmWriter.WriteResult(opArg); }
private static void WriteFunctionCallParameterArgument( this LlvmWriter llvmWriter, OpCodePart opArg, IParameter parameter) { var writer = llvmWriter.Output; llvmWriter.CheckIfExternalDeclarationIsRequired(parameter.ParameterType); parameter.ParameterType.WriteTypePrefix(llvmWriter, parameter.ParameterType.IsStructureType()); if (parameter.ParameterType.IsStructureType() && !parameter.IsOut && !parameter.IsRef) { writer.Write(" byval align " + llvmWriter.ByValAlign); } writer.Write(' '); llvmWriter.WriteResult(opArg); }