Esempio n. 1
0
        public static LLVMTypeRef AsLLVMType(this NIType niType)
        {
            if (niType.IsInteger())
            {
                switch (niType.GetKind())
                {
                case NITypeKind.UInt8:
                case NITypeKind.Int8:
                    return(LLVMTypeRef.Int8Type());

                case NITypeKind.UInt16:
                case NITypeKind.Int16:
                    return(LLVMTypeRef.Int16Type());

                case NITypeKind.UInt32:
                case NITypeKind.Int32:
                    return(LLVMTypeRef.Int32Type());

                case NITypeKind.UInt64:
                case NITypeKind.Int64:
                    return(LLVMTypeRef.Int64Type());
                }
            }
            if (niType.IsBoolean())
            {
                return(LLVMTypeRef.Int1Type());
            }
            if (niType.IsString())
            {
                return(StringType);
            }
            if (niType.IsRebarReferenceType())
            {
                NIType referentType = niType.GetReferentType();
                if (referentType == DataTypes.StringSliceType)
                {
                    return(StringSliceReferenceType);
                }
                return(LLVMTypeRef.PointerType(referentType.AsLLVMType(), 0u));
            }
            if (niType == DataTypes.FileHandleType)
            {
                return(FileHandleType);
            }
            NIType innerType;

            if (niType.TryDestructureOptionType(out innerType))
            {
                return(CreateLLVMOptionType(innerType.AsLLVMType()));
            }
            if (niType == DataTypes.RangeIteratorType)
            {
                return(RangeIteratorType);
            }
            throw new NotSupportedException("Unsupported type: " + niType);
        }
Esempio n. 2
0
        public CommonExternalFunctions(Module addTo)
        {
            LLVMTypeRef bytePointerType = LLVMTypeRef.PointerType(LLVMTypeRef.Int8Type(), 0);

            // NB: this will get resolved to the Win32 RtlCopyMemory function.
            LLVMTypeRef copyMemoryFunctionType = LLVMSharp.LLVM.FunctionType(
                LLVMSharp.LLVM.VoidType(),
                new LLVMTypeRef[] { bytePointerType, bytePointerType, LLVMTypeRef.Int64Type() },
                false);

            CopyMemoryFunction = addTo.AddFunction("CopyMemory", copyMemoryFunctionType);
            CopyMemoryFunction.SetLinkage(LLVMLinkage.LLVMExternalLinkage);

            OutputBoolFunction   = CreateSingleParameterVoidFunction(addTo, LLVMTypeRef.Int1Type(), "output_bool");
            OutputInt8Function   = CreateSingleParameterVoidFunction(addTo, LLVMTypeRef.Int8Type(), "output_int8");
            OutputUInt8Function  = CreateSingleParameterVoidFunction(addTo, LLVMTypeRef.Int8Type(), "output_uint8");
            OutputInt16Function  = CreateSingleParameterVoidFunction(addTo, LLVMTypeRef.Int16Type(), "output_int16");
            OutputUInt16Function = CreateSingleParameterVoidFunction(addTo, LLVMTypeRef.Int16Type(), "output_uint16");
            OutputInt32Function  = CreateSingleParameterVoidFunction(addTo, LLVMTypeRef.Int32Type(), "output_int32");
            OutputUInt32Function = CreateSingleParameterVoidFunction(addTo, LLVMTypeRef.Int32Type(), "output_uint32");
            OutputInt64Function  = CreateSingleParameterVoidFunction(addTo, LLVMTypeRef.Int64Type(), "output_int64");
            OutputUInt64Function = CreateSingleParameterVoidFunction(addTo, LLVMTypeRef.Int64Type(), "output_uint64");

            LLVMTypeRef outputStringFunctionType = LLVMSharp.LLVM.FunctionType(
                LLVMSharp.LLVM.VoidType(),
                new LLVMTypeRef[] { bytePointerType, LLVMTypeRef.Int32Type() },
                false);

            OutputStringFunction = addTo.AddFunction("output_string", outputStringFunctionType);
            OutputStringFunction.SetLinkage(LLVMLinkage.LLVMExternalLinkage);

            LLVMTypeRef closeHandleFunctionType = LLVMSharp.LLVM.FunctionType(
                LLVMTypeRef.Int32Type(),    // bool
                new LLVMTypeRef[] { LLVMExtensions.VoidPointerType },
                false);

            CloseHandleFunction = addTo.AddFunction("CloseHandle", closeHandleFunctionType);

            LLVMTypeRef createFileAFunctionType = LLVMSharp.LLVM.FunctionType(
                LLVMExtensions.VoidPointerType,
                new LLVMTypeRef[]
            {
                bytePointerType,                // filename
                LLVMTypeRef.Int32Type(),        // access
                LLVMTypeRef.Int32Type(),        // share
                LLVMExtensions.VoidPointerType, // securityAttributes
                LLVMTypeRef.Int32Type(),        // creationDisposition
                LLVMTypeRef.Int32Type(),        // flagsAndAttributes
                LLVMExtensions.VoidPointerType, // templateFile
            },
                false);

            CreateFileAFunction = addTo.AddFunction("CreateFileA", createFileAFunctionType);

            LLVMTypeRef readFileFunctionType = LLVMSharp.LLVM.FunctionType(
                LLVMTypeRef.Int32Type(),    // bool
                new LLVMTypeRef[]
            {
                LLVMExtensions.VoidPointerType,                      // hFile
                LLVMExtensions.VoidPointerType,                      // lpBuffer
                LLVMTypeRef.Int32Type(),                             // nNumberOfBytesToRead
                LLVMTypeRef.PointerType(LLVMTypeRef.Int32Type(), 0), // lpNumberOfBytesRead
                LLVMExtensions.VoidPointerType,                      // lpOverlapped
            },
                false);

            ReadFileFunction = addTo.AddFunction("ReadFile", readFileFunctionType);

            LLVMTypeRef writeFileFunctionType = LLVMSharp.LLVM.FunctionType(
                LLVMTypeRef.Int32Type(),    // bool
                new LLVMTypeRef[]
            {
                LLVMExtensions.VoidPointerType,                      // hFile
                LLVMExtensions.VoidPointerType,                      // lpBuffer
                LLVMTypeRef.Int32Type(),                             // nNumberOfBytesToWrite,
                LLVMTypeRef.PointerType(LLVMTypeRef.Int32Type(), 0), // lpNumberOfBytesWritten
                LLVMExtensions.VoidPointerType,                      // lpOverlapped
            },
                false);

            WriteFileFunction = addTo.AddFunction("WriteFile", writeFileFunctionType);
        }
Esempio n. 3
0
        private static void BuildReadLineFromFileHandleFunction(Module fileModule, CommonExternalFunctions externalFunctions)
        {
            LLVMValueRef      readLineFromFileHandleFunction = fileModule.AddFunction(ReadLineFromFileHandleName, CommonModuleSignatures[ReadLineFromFileHandleName]);
            LLVMBasicBlockRef entryBlock = readLineFromFileHandleFunction.AppendBasicBlock("entry");
            var builder = new IRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);

            LLVMBasicBlockRef loopStartBlock      = readLineFromFileHandleFunction.AppendBasicBlock("loopStart"),
                              handleByteBlock     = readLineFromFileHandleFunction.AppendBasicBlock("handleByte"),
                              byteIsCRBlock       = readLineFromFileHandleFunction.AppendBasicBlock("byteIsCR"),
                              byteIsNotCRBlock    = readLineFromFileHandleFunction.AppendBasicBlock("byteIsNotCR"),
                              notNewLineBlock     = readLineFromFileHandleFunction.AppendBasicBlock("notNewLine"),
                              appendCRBlock       = readLineFromFileHandleFunction.AppendBasicBlock("appendCR"),
                              appendByteBlock     = readLineFromFileHandleFunction.AppendBasicBlock("appendByte"),
                              loopEndBlock        = readLineFromFileHandleFunction.AppendBasicBlock("loopEnd"),
                              nonEmptyStringBlock = readLineFromFileHandleFunction.AppendBasicBlock("nonEmptyString"),
                              emptyStringBlock    = readLineFromFileHandleFunction.AppendBasicBlock("emptyString");

            LLVMValueRef fileHandlePtr     = readLineFromFileHandleFunction.GetParam(0u),
                         stringPtr         = builder.CreateAlloca(LLVMExtensions.StringType, "stringPtr"),
                         carriageReturnPtr = builder.CreateAlloca(LLVMTypeRef.Int8Type(), "carriageReturnPtr"),
                         carriageReturn    = ((byte)0xD).AsLLVMValue(),
                         byteReadPtr       = builder.CreateAlloca(LLVMTypeRef.Int8Type(), "byteReadPtr"),
                         bytesReadPtr      = builder.CreateAlloca(LLVMTypeRef.Int32Type(), "bytesReadPtr"),
                         nonEmptyStringPtr = builder.CreateAlloca(LLVMTypeRef.Int1Type(), "nonEmptyStringPtr"),
                         seenCRPtr         = builder.CreateAlloca(LLVMTypeRef.Int1Type(), "seenCRPtr");

            builder.CreateStore(carriageReturn, carriageReturnPtr);
            builder.CreateStore(false.AsLLVMValue(), seenCRPtr);
            builder.CreateStore(false.AsLLVMValue(), nonEmptyStringPtr);
            builder.CreateCall(_createEmptyStringFunction, new LLVMValueRef[] { stringPtr }, string.Empty);
            builder.CreateBr(loopStartBlock);

            builder.PositionBuilderAtEnd(loopStartBlock);
            LLVMValueRef hFilePtr       = builder.CreateStructGEP(fileHandlePtr, 0u, "hFilePtr"),
                         hFile          = builder.CreateLoad(hFilePtr, "hFile");
            LLVMValueRef readFileResult = builder.CreateCall(
                externalFunctions.ReadFileFunction,
                new LLVMValueRef[] { hFile, byteReadPtr, 1.AsLLVMValue(), bytesReadPtr, LLVMExtensions.NullVoidPointer },
                "readFileResult"),
                         readFileResultBool = builder.CreateICmp(LLVMIntPredicate.LLVMIntNE, readFileResult, 0.AsLLVMValue(), "readFileResultBool"),
                         bytesRead          = builder.CreateLoad(bytesReadPtr, "bytesRead"),
                         zeroBytesRead      = builder.CreateICmp(LLVMIntPredicate.LLVMIntEQ, bytesRead, 0.AsLLVMValue(), "zeroBytesRead"),
                         eof = builder.CreateAnd(readFileResultBool, zeroBytesRead, "eof");

            builder.CreateCondBr(eof, loopEndBlock, handleByteBlock);

            builder.PositionBuilderAtEnd(handleByteBlock);
            LLVMValueRef byteRead     = builder.CreateLoad(byteReadPtr, "byteRead"),
                         byteReadIsCR = builder.CreateICmp(LLVMIntPredicate.LLVMIntEQ, byteRead, carriageReturn, "byteReadIsCR");

            builder.CreateCondBr(byteReadIsCR, byteIsCRBlock, byteIsNotCRBlock);

            builder.PositionBuilderAtEnd(byteIsCRBlock);
            builder.CreateStore(true.AsLLVMValue(), seenCRPtr);
            builder.CreateBr(loopStartBlock);

            builder.PositionBuilderAtEnd(byteIsNotCRBlock);
            LLVMValueRef byteIsLF = builder.CreateICmp(LLVMIntPredicate.LLVMIntEQ, byteRead, ((byte)0xA).AsLLVMValue(), "byteIsLF"),
                         seenCR   = builder.CreateLoad(seenCRPtr, "seenCR"),
                         newLine  = builder.CreateAnd(byteIsLF, seenCR, "newLine");

            builder.CreateCondBr(newLine, loopEndBlock, notNewLineBlock);

            builder.PositionBuilderAtEnd(notNewLineBlock);
            builder.CreateCondBr(seenCR, appendCRBlock, appendByteBlock);

            builder.PositionBuilderAtEnd(appendCRBlock);
            LLVMValueRef crSlice = builder.BuildStringSliceReferenceValue(carriageReturnPtr, 1.AsLLVMValue());

            builder.CreateCall(_stringAppendFunction, new LLVMValueRef[] { stringPtr, crSlice }, string.Empty);
            builder.CreateBr(appendByteBlock);

            builder.PositionBuilderAtEnd(appendByteBlock);
            LLVMValueRef byteSlice = builder.BuildStringSliceReferenceValue(byteReadPtr, 1.AsLLVMValue());

            builder.CreateCall(_stringAppendFunction, new LLVMValueRef[] { stringPtr, byteSlice }, string.Empty);
            builder.CreateStore(true.AsLLVMValue(), nonEmptyStringPtr);
            builder.CreateStore(false.AsLLVMValue(), seenCRPtr);
            builder.CreateBr(loopStartBlock);

            builder.PositionBuilderAtEnd(loopEndBlock);
            LLVMValueRef optionStringPtr       = readLineFromFileHandleFunction.GetParam(1u),
                         optionStringIsSomePtr = builder.CreateStructGEP(optionStringPtr, 0u, "optionStringIsSomePtr"),
                         nonEmptyString        = builder.CreateLoad(nonEmptyStringPtr, "nonEmptyString");

            builder.CreateCondBr(nonEmptyString, nonEmptyStringBlock, emptyStringBlock);

            builder.PositionBuilderAtEnd(nonEmptyStringBlock);
            builder.CreateStore(true.AsLLVMValue(), optionStringIsSomePtr);
            LLVMValueRef optionStringInnerValuePtr = builder.CreateStructGEP(optionStringPtr, 1u, "optionStringInnerValuePtr"),
                         stringValue = builder.CreateLoad(stringPtr, "string");

            builder.CreateStore(stringValue, optionStringInnerValuePtr);
            builder.CreateRetVoid();

            builder.PositionBuilderAtEnd(emptyStringBlock);
            builder.CreateStore(false.AsLLVMValue(), optionStringIsSomePtr);
            builder.CreateCall(_dropStringFunction, new LLVMValueRef[] { stringPtr }, string.Empty);
            builder.CreateRetVoid();
        }
Esempio n. 4
0
 public static LLVMValueRef AsLLVMValue(this bool booleanValue)
 {
     return(LLVMSharp.LLVM.ConstInt(LLVMTypeRef.Int1Type(), (booleanValue ? 1u : 0u), false));
 }
Esempio n. 5
0
 internal static LLVMTypeRef CreateLLVMOptionType(this LLVMTypeRef innerType)
 {
     return(LLVMTypeRef.StructType(new LLVMTypeRef[] { LLVMTypeRef.Int1Type(), innerType }, false));
 }