Esempio n. 1
0
        private static void BuildStringConcatFunction(Module stringModule, CommonExternalFunctions externalFunctions)
        {
            LLVMValueRef      stringConcatFunction = stringModule.AddFunction(StringConcatName, CommonModuleSignatures[StringConcatName]);
            LLVMBasicBlockRef entryBlock           = stringConcatFunction.AppendBasicBlock("entry");
            var builder = new IRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);

            LLVMValueRef slice0                    = stringConcatFunction.GetParam(0u),
                         slice1                    = stringConcatFunction.GetParam(1u),
                         sliceSize0                = builder.CreateExtractValue(slice0, 1u, "sliceSize0"),
                         sliceSize1                = builder.CreateExtractValue(slice1, 1u, "sliceSize1"),
                         concatSize                = builder.CreateAdd(sliceSize0, sliceSize1, "concatSize"),
                         concatAllocationPtr       = builder.CreateArrayMalloc(LLVMTypeRef.Int8Type(), concatSize, "concatAllocationPtr"),
                         concatAllocationOffsetPtr = builder.CreateGEP(concatAllocationPtr, new LLVMValueRef[] { sliceSize0 }, "concatAllocationOffsetPtr"),
                         stringPtr                 = stringConcatFunction.GetParam(2u),
                         stringAllocationPtrPtr    = builder.CreateStructGEP(stringPtr, 0u, "stringAllocationPtrPtr"),
                         stringSizePtr             = builder.CreateStructGEP(stringPtr, 1u, "stringSizePtr");

            builder.CreateCall(_copySliceToPointerFunction, new LLVMValueRef[] { slice0, concatAllocationPtr }, string.Empty);
            builder.CreateCall(_copySliceToPointerFunction, new LLVMValueRef[] { slice1, concatAllocationOffsetPtr }, string.Empty);
            builder.CreateStore(concatAllocationPtr, stringAllocationPtrPtr);
            builder.CreateStore(concatSize, stringSizePtr);
            builder.CreateRetVoid();
        }
Esempio n. 2
0
        public LLVMModuleRef GenerateLLVM()
        {
            LLVMTypeRef stringType = LLVMTypeRef.PointerType(LLVMTypeRef.Int8Type(), 0);

            var printfArguments = new LLVMTypeRef[] { stringType };
            var printf          = LLVM.AddFunction(_module, "printf", LLVM.FunctionType(LLVMTypeRef.Int32Type(), printfArguments, LLVMBoolTrue));

            LLVM.SetLinkage(printf, LLVMLinkage.LLVMExternalLinkage);

            var scanfArguments = new LLVMTypeRef[] { stringType };
            var scanf          = LLVM.AddFunction(_module, "scanf", LLVM.FunctionType(LLVMTypeRef.Int32Type(), scanfArguments, LLVMBoolTrue));

            LLVM.SetLinkage(scanf, LLVMLinkage.LLVMExternalLinkage);

            // Generate functions, globals, etc.
            for (int i = 0; i < _statements.Count; i++)
            {
                _statements[i].Accept(this);
            }

            // Generate everything inside the functions
            while (_valueStack.Count > 0)
            {
                _valueStack.Peek().Item2.Accept(this);
            }

            return(_module);
        }
Esempio n. 3
0
        private static void BuildStringFromSliceFunction(Module stringModule, CommonExternalFunctions externalFunctions)
        {
            LLVMValueRef      stringFromSliceFunction = stringModule.AddFunction(StringFromSliceName, CommonModuleSignatures[StringFromSliceName]);
            LLVMBasicBlockRef entryBlock = stringFromSliceFunction.AppendBasicBlock("entry");
            var builder = new IRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);

            LLVMValueRef stringSliceReference   = stringFromSliceFunction.GetParam(0u),
                         stringPtr              = stringFromSliceFunction.GetParam(1u),
                         stringAllocationPtrPtr = builder.CreateStructGEP(stringPtr, 0u, "stringAllocationPtrPtr"),
                         stringSizePtr          = builder.CreateStructGEP(stringPtr, 1u, "stringSizePtr");

            LLVMValueRef sliceAllocationPtr = builder.CreateExtractValue(stringSliceReference, 0u, "sliceAllocationPtr");
            LLVMValueRef sliceSize          = builder.CreateExtractValue(stringSliceReference, 1u, "sliceSize");

            // Get a pointer to a heap allocation big enough for the string
            LLVMValueRef allocationPtr = builder.CreateArrayMalloc(LLVMTypeRef.Int8Type(), sliceSize, "allocationPtr");

            builder.CreateStore(allocationPtr, stringAllocationPtrPtr);

            // Copy the data from the string slice to the heap allocation
            LLVMValueRef sizeExtend = builder.CreateSExt(sliceSize, LLVMTypeRef.Int64Type(), "sizeExtend");

            builder.CreateCall(externalFunctions.CopyMemoryFunction, new LLVMValueRef[] { allocationPtr, sliceAllocationPtr, sizeExtend }, string.Empty);

            // Copy actual size into string handle
            builder.CreateStore(sliceSize, stringSizePtr);

            builder.CreateRetVoid();
        }
Esempio n. 4
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. 5
0
        public static LLVMTypeRef ToLLVMType(this Type type)
        {
            if (type.IsConstructedGenericType && type.GetGenericTypeDefinition() == typeof(Vector128 <>))
            {
                var et = type.GetGenericArguments()[0];
                return(LLVMTypeRef.VectorType(et.ToLLVMType(), 16U / (uint)Marshal.SizeOf(et)));
            }
            if (typeof(MulticastDelegate).IsAssignableFrom(type))
            {
                var mi = type.GetMethod("Invoke");
                return(LLVMTypeRef.FunctionType(mi.ReturnType.ToLLVMType(),
                                                mi.GetParameters().Select(x => x.ParameterType.ToLLVMType()).ToArray(), false));
            }
            if (type == typeof(void))
            {
                return(LLVMTypeRef.VoidType());
            }
            if (type.IsPointer)
            {
                return(LLVMTypeRef.Int64Type());
            }
            switch (Activator.CreateInstance(type))
            {
            case sbyte _:
            case byte _: return(LLVMTypeRef.Int8Type());

            case short _:
            case ushort _: return(LLVMTypeRef.Int16Type());

            case int _:
            case uint _: return(LLVMTypeRef.Int32Type());

            case long _:
            case ulong _: return(LLVMTypeRef.Int64Type());

            case Int128 _:
            case UInt128 _: return(LLVMTypeRef.IntType(128));

            case float _: return(LLVMTypeRef.FloatType());

            case double _: return(LLVMTypeRef.DoubleType());

            case bool _: return(LLVMTypeRef.IntType(1));

            default: throw new NotSupportedException(type.Name);
            }
        }
Esempio n. 6
0
        private static void BuildCreateEmptyStringFunction(Module stringModule)
        {
            _createEmptyStringFunction = stringModule.AddFunction(CreateEmptyStringName, CommonModuleSignatures[CreateEmptyStringName]);
            LLVMBasicBlockRef entryBlock = _createEmptyStringFunction.AppendBasicBlock("entry");
            var builder = new IRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);

            LLVMValueRef stringPtr = _createEmptyStringFunction.GetParam(0u),
                         stringAllocationPtrPtr = builder.CreateStructGEP(stringPtr, 0u, "stringAllocationPtrPtr"),
                         stringLengthPtr        = builder.CreateStructGEP(stringPtr, 1u, "stringLengthPtr"),
                         allocationPtr          = builder.CreateArrayMalloc(LLVMTypeRef.Int8Type(), 4.AsLLVMValue(), "allocationPtr");

            builder.CreateStore(allocationPtr, stringAllocationPtrPtr);
            builder.CreateStore(0.AsLLVMValue(), stringLengthPtr);
            builder.CreateRetVoid();
        }
Esempio n. 7
0
        public static LLVMTypeRef LlvmTypeFromName(string name)
        {
            // TODO: Implement functionality for pointer types.
            // Special case for string type.
            if (name == TypeName.String)
            {
                return(LLVMTypeRef.PointerType(LLVMTypeRef.Int8Type(), 0));
            }
            // Otherwise, use LLVM type map.
            else if (LlvmTypeMap.ContainsKey(name))
            {
                return(LlvmTypeMap[name]());
            }

            // Throw an exception.
            throw new Exception($"Non-registered type resolver for type '{name}'");
        }
Esempio n. 8
0
        private static LLVMTypeRef GetLlvmType([NotNull] Type lambdaTypeParam)
        {
            switch (lambdaTypeParam)
            {
            case PrimaryType primaryType:
                if (string.Equals(primaryType.Name, "f64", Ordinal))
                {
                    return(LLVMSharp.LLVM.DoubleType());
                }
                if (string.Equals(primaryType.Name, "f32", Ordinal))
                {
                    return(LLVMTypeRef.FloatType());
                }
                if (string.Equals(primaryType.Name, "i8", Ordinal))
                {
                    return(LLVMTypeRef.Int8Type());
                }
                if (string.Equals(primaryType.Name, "i16", Ordinal))
                {
                    return(LLVMTypeRef.Int16Type());
                }
                if (string.Equals(primaryType.Name, "i32", Ordinal))
                {
                    return(LLVMTypeRef.Int32Type());
                }
                if (string.Equals(primaryType.Name, "i64", Ordinal))
                {
                    return(LLVMTypeRef.Int64Type());
                }
                break;

            case LambdaType lambdaType:
                return(LLVMTypeRef.FunctionType(GetLlvmType(lambdaType.RetType),
                                                (from type in lambdaType.ParamsList select GetLlvmType(type)).ToArray(), false));

            case SecondaryType secondaryType:
                break;
            }
            throw new NotImplementedException();
        }
Esempio n. 9
0
        private static void BuildStringAppendFunction(Module stringModule, CommonExternalFunctions externalFunctions)
        {
            _stringAppendFunction = stringModule.AddFunction(StringAppendName, CommonModuleSignatures[StringAppendName]);
            LLVMBasicBlockRef entryBlock = _stringAppendFunction.AppendBasicBlock("entry");
            var builder = new IRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);

            LLVMValueRef stringPtr      = _stringAppendFunction.GetParam(0u),
                         sliceReference = _stringAppendFunction.GetParam(1u);

            // for now, always create a new allocation, rather than trying to use existing one
            // compute the new allocation size and allocate it
            LLVMValueRef stringAllocationPtrPtr = builder.CreateStructGEP(stringPtr, 0u, "stringAllocationPtrPtr"),
                         stringSizePtr          = builder.CreateStructGEP(stringPtr, 1u, "stringSizePtr"),
                         stringAllocationPtr    = builder.CreateLoad(stringAllocationPtrPtr, "stringAllocationPtr"),
                         stringSize             = builder.CreateLoad(stringSizePtr, "stringSize"),
                         sliceSize        = builder.CreateExtractValue(sliceReference, 1u, "sliceSize"),
                         appendedSize     = builder.CreateAdd(stringSize, sliceSize, "appendedSize"),
                         newAllocationPtr = builder.CreateArrayMalloc(LLVMTypeRef.Int8Type(), appendedSize, "newAllocationPtr");

            // copy from old allocation to new allocation
            LLVMValueRef stringSlice = builder.CreateCall(_stringFromSliceRetFunction, new LLVMValueRef[] { stringPtr }, "stringSlice");

            builder.CreateCall(_copySliceToPointerFunction, new LLVMValueRef[] { stringSlice, newAllocationPtr }, string.Empty);

            // copy from slice to offset in new allocation
            LLVMValueRef newAllocationOffsetPtr = builder.CreateGEP(newAllocationPtr, new LLVMValueRef[] { stringSize }, "newAllocationOffsetPtr");

            builder.CreateCall(_copySliceToPointerFunction, new LLVMValueRef[] { sliceReference, newAllocationOffsetPtr }, string.Empty);

            // free old allocation and update string fields
            builder.CreateFree(stringAllocationPtr);
            builder.CreateStore(newAllocationPtr, stringAllocationPtrPtr);
            builder.CreateStore(appendedSize, stringSizePtr);

            builder.CreateRetVoid();
        }
Esempio n. 10
0
        public static LLVMTypeRef ToLLVMType(this BaseType baseType)
        {
            switch (baseType)
            {
            case BaseType.String:   return(LLVM.PointerType(LLVMTypeRef.Int8Type(), 0));

            case BaseType.Int1:     return(LLVM.Int1Type());

            case BaseType.Int8:     return(LLVM.Int8Type());

            case BaseType.Int16:    return(LLVM.Int16Type());

            case BaseType.Int32:    return(LLVM.Int32Type());

            case BaseType.Int64:    return(LLVM.Int64Type());

            case BaseType.Int128:   return(LLVM.Int128Type());

            case BaseType.Float16:  return(LLVM.HalfType());

            case BaseType.Float32:  return(LLVM.FloatType());

            case BaseType.Float64:  return(LLVM.DoubleType());

            case BaseType.Float80:  return(LLVM.X86FP80Type());

            case BaseType.Float128: return(LLVM.PPCFP128Type());

            case BaseType.True:     return(LLVM.Int1Type());

            case BaseType.False:    return(LLVM.Int1Type());

            default:
                throw new Exception("Variable type can't be converted to LLVM type.");
            }
        }
Esempio n. 11
0
        private void ImportStoreField(int token, bool isStatic)
        {
            if (isStatic)
            {
                throw new NotImplementedException("static stfld");
            }

            FieldDesc field = (FieldDesc)_methodIL.GetObject(token);

            StackEntry valueEntry  = _stack.Pop();
            StackEntry objectEntry = _stack.Pop();

            LLVMValueRef value = valueEntry.LLVMValue;

            // All integers are int32 on the stack, but need to be resized to fit fields
            if (valueEntry.Kind == StackValueKind.Int32)
            {
                value = LLVM.BuildIntCast(_builder, value, GetLLVMTypeForTypeDesc(field.FieldType), "intfieldcast");
            }

            var untypedObjectPointer = LLVM.BuildPointerCast(_builder, objectEntry.LLVMValue, LLVM.PointerType(LLVMTypeRef.Int8Type(), 0), "stfld");
            var storeLocation        = LLVM.BuildGEP(_builder, untypedObjectPointer,
                                                     new LLVMValueRef[] { LLVM.ConstInt(LLVM.Int32Type(), (ulong)field.Offset.AsInt, LLVMMisc.False) }, "stfld");
            var typedStoreLocation = LLVM.BuildPointerCast(_builder, storeLocation, LLVM.PointerType(GetLLVMTypeForTypeDesc(field.FieldType), 0), "stfld");

            LLVM.BuildStore(_builder, value, typedStoreLocation);
        }
Esempio n. 12
0
 public static LLVMValueRef AsLLVMValue(this byte intValue)
 {
     return(LLVMSharp.LLVM.ConstInt(LLVMTypeRef.Int8Type(), intValue, false));
 }
Esempio n. 13
0
        public bool VisitConstant(Constant constant)
        {
            ValueSource outputAllocation = GetTerminalValueSource(constant.OutputTerminal);

            if (constant.DataType.IsInteger())
            {
                LLVMValueRef constantValueRef;
                switch (constant.DataType.GetKind())
                {
                case NITypeKind.Int8:
                    constantValueRef = ((sbyte)constant.Value).AsLLVMValue();
                    break;

                case NITypeKind.UInt8:
                    constantValueRef = ((byte)constant.Value).AsLLVMValue();
                    break;

                case NITypeKind.Int16:
                    constantValueRef = ((short)constant.Value).AsLLVMValue();
                    break;

                case NITypeKind.UInt16:
                    constantValueRef = ((ushort)constant.Value).AsLLVMValue();
                    break;

                case NITypeKind.Int32:
                    constantValueRef = ((int)constant.Value).AsLLVMValue();
                    break;

                case NITypeKind.UInt32:
                    constantValueRef = ((uint)constant.Value).AsLLVMValue();
                    break;

                case NITypeKind.Int64:
                    constantValueRef = ((long)constant.Value).AsLLVMValue();
                    break;

                case NITypeKind.UInt64:
                    constantValueRef = ((ulong)constant.Value).AsLLVMValue();
                    break;

                default:
                    throw new NotSupportedException("Unsupported numeric constant type: " + constant.DataType);
                }
                outputAllocation.UpdateValue(_builder, constantValueRef);
            }
            else if (constant.Value is bool)
            {
                LLVMValueRef constantValueRef = ((bool)constant.Value).AsLLVMValue();
                outputAllocation.UpdateValue(_builder, constantValueRef);
            }
            else if (constant.Value is string)
            {
                VariableReference output = constant.OutputTerminal.GetTrueVariable();
                if (output.Type.IsRebarReferenceType() && output.Type.GetReferentType() == DataTypes.StringSliceType)
                {
                    string       stringValue         = (string)constant.Value;
                    int          length              = Encoding.UTF8.GetByteCount(stringValue);
                    LLVMValueRef stringValueConstant = LLVMSharp.LLVM.ConstString(stringValue, (uint)length, true);
                    LLVMValueRef stringConstantPtr   = Module.AddGlobal(stringValueConstant.TypeOf(), $"string{constant.UniqueId}");
                    stringConstantPtr.SetInitializer(stringValueConstant);

                    LLVMValueRef castPointer = _builder.CreateBitCast(
                        stringConstantPtr,
                        LLVMTypeRef.PointerType(LLVMTypeRef.Int8Type(), 0),
                        "ptrCast");
                    LLVMValueRef[] stringSliceFields = new LLVMValueRef[]
                    {
                        castPointer,
                        length.AsLLVMValue()
                    };
                    LLVMValueRef stringSliceValue = LLVMValueRef.ConstStruct(stringSliceFields, false);
                    outputAllocation.UpdateValue(_builder, stringSliceValue);
                }
            }
            else
            {
                throw new NotImplementedException();
            }
            return(true);
        }
        private void ImportStoreField(int token, bool isStatic)
        {
            if (isStatic)
            {
                throw new NotImplementedException("static stfld");
            }

            FieldDesc field = (FieldDesc)_methodIL.GetObject(token);

            StackEntry valueEntry  = _stack.Pop();
            StackEntry objectEntry = _stack.Pop();

            var untypedObjectPointer = LLVM.BuildPointerCast(_builder, objectEntry.LLVMValue, LLVM.PointerType(LLVMTypeRef.Int8Type(), 0), "stfld");
            var storeLocation        = LLVM.BuildGEP(_builder, untypedObjectPointer,
                                                     new LLVMValueRef[] { LLVM.ConstInt(LLVM.Int32Type(), (ulong)field.Offset.AsInt, LLVMMisc.False) }, "stfld");
            var typedStoreLocation = LLVM.BuildPointerCast(_builder, storeLocation, LLVM.PointerType(GetLLVMTypeForTypeDesc(valueEntry.Type), 0), "stfld");

            LLVM.BuildStore(_builder, valueEntry.LLVMValue, typedStoreLocation);
        }
Esempio n. 15
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. 16
0
        private static void CreateStringModule(Module stringModule)
        {
            var externalFunctions = new CommonExternalFunctions(stringModule);

            CommonModuleSignatures[CopySliceToPointerName] = LLVMSharp.LLVM.FunctionType(
                LLVMSharp.LLVM.VoidType(),
                new LLVMTypeRef[] { LLVMExtensions.StringSliceReferenceType, LLVMTypeRef.PointerType(LLVMTypeRef.Int8Type(), 0) },
                false);
            BuildCopySliceToPointerFunction(stringModule, externalFunctions);

            CommonModuleSignatures[CreateEmptyStringName] = LLVMSharp.LLVM.FunctionType(
                LLVMSharp.LLVM.VoidType(),
                new LLVMTypeRef[] { LLVMTypeRef.PointerType(LLVMExtensions.StringType, 0) },
                false);
            BuildCreateEmptyStringFunction(stringModule);

            CommonModuleSignatures[CreateNullTerminatedStringFromSliceName] = LLVMSharp.LLVM.FunctionType(
                LLVMExtensions.BytePointerType,
                new LLVMTypeRef[] { LLVMExtensions.StringSliceReferenceType },
                false);
            BuildCreateNullTerminatedStringFromSlice(stringModule);

            CommonModuleSignatures[DropStringName] = LLVMSharp.LLVM.FunctionType(
                LLVMSharp.LLVM.VoidType(),
                new LLVMTypeRef[] { LLVMTypeRef.PointerType(LLVMExtensions.StringType, 0) },
                false);
            BuildDropStringFunction(stringModule);

            CommonModuleSignatures[OutputStringSliceName] = LLVMSharp.LLVM.FunctionType(
                LLVMSharp.LLVM.VoidType(),
                new LLVMTypeRef[] { LLVMExtensions.StringSliceReferenceType },
                false);
            BuildOutputStringSliceFunction(stringModule, externalFunctions);

            CommonModuleSignatures[StringFromSliceName] = LLVMSharp.LLVM.FunctionType(
                LLVMSharp.LLVM.VoidType(),
                new LLVMTypeRef[] { LLVMExtensions.StringSliceReferenceType, LLVMTypeRef.PointerType(LLVMExtensions.StringType, 0) },
                false);
            BuildStringFromSliceFunction(stringModule, externalFunctions);

            CommonModuleSignatures[StringToSliceRetName] = LLVMSharp.LLVM.FunctionType(
                LLVMExtensions.StringSliceReferenceType,
                new LLVMTypeRef[] { LLVMTypeRef.PointerType(LLVMExtensions.StringType, 0), },
                false);
            BuildStringToSliceRetFunction(stringModule);

            CommonModuleSignatures[StringToSliceName] = LLVMSharp.LLVM.FunctionType(
                LLVMSharp.LLVM.VoidType(),
                new LLVMTypeRef[] { LLVMTypeRef.PointerType(LLVMExtensions.StringType, 0), LLVMTypeRef.PointerType(LLVMExtensions.StringSliceReferenceType, 0) },
                false);
            BuildStringToSliceFunction(stringModule);

            CommonModuleSignatures[StringAppendName] = LLVMSharp.LLVM.FunctionType(
                LLVMSharp.LLVM.VoidType(),
                new LLVMTypeRef[] { LLVMTypeRef.PointerType(LLVMExtensions.StringType, 0), LLVMExtensions.StringSliceReferenceType },
                false);
            BuildStringAppendFunction(stringModule, externalFunctions);

            CommonModuleSignatures[StringConcatName] = LLVMSharp.LLVM.FunctionType(
                LLVMSharp.LLVM.VoidType(),
                new LLVMTypeRef[] { LLVMExtensions.StringSliceReferenceType, LLVMExtensions.StringSliceReferenceType, LLVMTypeRef.PointerType(LLVMExtensions.StringType, 0) },
                false);
            BuildStringConcatFunction(stringModule, externalFunctions);

            stringModule.VerifyAndThrowIfInvalid();
        }
Esempio n. 17
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. 18
0
 public static LLVMValueRef AsLLVMValue(this sbyte intValue)
 {
     return(LLVMSharp.LLVM.ConstInt(LLVMTypeRef.Int8Type(), (ulong)intValue, true));
 }
Esempio n. 19
0
        private static void BuildCreateNullTerminatedStringFromSlice(Module stringModule)
        {
            _createNullTerminatedStringFromSliceFunction = stringModule.AddFunction(CreateNullTerminatedStringFromSliceName, CommonModuleSignatures[CreateNullTerminatedStringFromSliceName]);
            LLVMBasicBlockRef entryBlock = _createNullTerminatedStringFromSliceFunction.AppendBasicBlock("entry");
            var builder = new IRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);

            LLVMValueRef stringSliceReference              = _createNullTerminatedStringFromSliceFunction.GetParam(0u),
                         stringSliceAllocationPtr          = builder.CreateExtractValue(stringSliceReference, 0u, "stringSliceAllocationPtr"),
                         stringSliceLength                 = builder.CreateExtractValue(stringSliceReference, 1u, "stringSliceLength"),
                         nullTerminatedStringLength        = builder.CreateAdd(stringSliceLength, 1.AsLLVMValue(), "nullTerminatedStringLength"),
                         nullTerminatedStringAllocationPtr = builder.CreateArrayMalloc(LLVMTypeRef.Int8Type(), nullTerminatedStringLength, "nullTerminatedStringAllocationPtr"),
                         nullBytePtr = builder.CreateGEP(nullTerminatedStringAllocationPtr, new LLVMValueRef[] { stringSliceLength }, "nullBytePtr");

            builder.CreateCall(_copySliceToPointerFunction, new LLVMValueRef[] { stringSliceReference, nullTerminatedStringAllocationPtr }, string.Empty);
            builder.CreateStore(((byte)0).AsLLVMValue(), nullBytePtr);
            builder.CreateRet(nullTerminatedStringAllocationPtr);
        }