/// <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;
        }
Esempio n. 2
0
        /// <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;
        }