Пример #1
0
        /// <summary>
        /// Maps internal debug assertions to <see cref="AssertFailed(string, string,
        /// int, string, int)"/> method calls.
        /// </summary>

        protected override void Implement(
            IRContext context,
            Method.Builder methodBuilder,
            BasicBlock.Builder builder,
            DebugAssertOperation debugAssert)
        {
            var location = debugAssert.Location;

            // Create a call to the debug-implementation wrapper while taking the
            // current source location into account
            var nextBlock  = builder.SplitBlock(debugAssert);
            var innerBlock = methodBuilder.CreateBasicBlock(
                location,
                nameof(AssertFailed));

            builder.CreateIfBranch(
                location,
                debugAssert.Condition,
                nextBlock,
                innerBlock);

            // Create a call to the assert implementation
            var innerBuilder = methodBuilder[innerBlock];
            var assertFailed = innerBuilder.CreateCall(
                location,
                context.Declare(AssertFailedMethod, out var _));

            // Move the debug assertion to this block
            var sourceMessage = debugAssert.Message.ResolveAs <StringValue>();
            var message       = innerBuilder.CreatePrimitiveValue(
                location,
                sourceMessage.String,
                sourceMessage.Encoding);

            assertFailed.Add(message);

            // Append source location information
            var debugLocation = debugAssert.GetLocationInfo();

            assertFailed.Add(
                innerBuilder.CreatePrimitiveValue(location, debugLocation.FileName));
            assertFailed.Add(
                innerBuilder.CreatePrimitiveValue(location, debugLocation.Line));
            assertFailed.Add(
                innerBuilder.CreatePrimitiveValue(location, debugLocation.Method));
            assertFailed.Add(
                innerBuilder.CreatePrimitiveValue(location, 1));

            // Finish the actual assertion call and branch
            assertFailed.Seal();
            innerBuilder.CreateBranch(location, nextBlock);

            // Remove the debug assertion value
            debugAssert.Replace(builder.CreateUndefined());
        }
Пример #2
0
            internal CFGBuilder(
                CodeGenerator codeGenerator,
                Method.Builder methodBuilder)
            {
                CodeGenerator = codeGenerator;
                Builder       = methodBuilder;

                var mainEntry = methodBuilder.EntryBlockBuilder;

                EntryBlock = new Block(
                    codeGenerator,
                    mainEntry)
                {
                    InstructionCount = 0
                };
                basicBlockMapping.Add(EntryBlock.BasicBlock, EntryBlock);

                // Create a temporary entry block to ensure that we have a single entry
                // block without any predecessors in all cases
                var internalEntryBlock = new Block(
                    codeGenerator,
                    methodBuilder.CreateBasicBlock(
                        mainEntry.BasicBlock.Location,
                        mainEntry.BasicBlock.Name));

                blockMapping.Add(0, internalEntryBlock);
                basicBlockMapping.Add(internalEntryBlock.BasicBlock, internalEntryBlock);
                BuildBasicBlocks();

                var visited = new HashSet <Block>();

                SetupBasicBlocks(visited, internalEntryBlock, 0);
                WireBlocks();

                // Wire the main entry block with the actual entry block
                mainEntry.CreateBranch(
                    mainEntry.BasicBlock.Location,
                    internalEntryBlock.BasicBlock);

                // Update control-flow structure to refresh all successor/predecessor
                // edge relations
                Blocks = methodBuilder.UpdateControlFlow();
            }