/// <summary> /// Creates the System.String::get_Chars(int32) function. /// </summary> /// <param name="builder">The builder.</param> private void createStringGetCharsFunction(BuilderRef builder) { const string funcName = "System_Char_System_String_get_Chars_System_Int32"; // Create function and set linkage. TypeRef type = LLVM.FunctionType(TypeHelper.Int8, new TypeRef[] { TypeHelper.String, TypeHelper.Int32 }, false); ValueRef func = LLVM.AddFunction(mCompiler.Module, funcName, type); LLVM.SetLinkage(func, Linkage.LinkOnceAnyLinkage); LLVM.AddAttributeAtIndex(func, (uint)LLVM.AttributeFunctionIndex, LLVM.CreateEnumAttribute(mCompiler.ModuleContext, LLVM.GetEnumAttributeKindForName("alwaysinline", 12), 1)); // Arguments. ValueRef str = LLVM.GetParam(func, 0); ValueRef index = LLVM.GetParam(func, 1); // Create function body. BasicBlockRef entry = LLVM.AppendBasicBlock(func, string.Empty); LLVM.PositionBuilderAtEnd(builder, entry); ValueRef ch = LLVM.BuildGEP(builder, str, new ValueRef[] { index }, "charptr"); ValueRef returnVal = LLVM.BuildLoad(builder, ch, "character"); LLVM.BuildRet(builder, returnVal); mCompiler.Lookup.AddFunction(funcName, func); }
/// <summary> /// Emits a Ldind instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="context">The context.</param> /// <param name="builder">The builder.</param> public void Emit(Instruction instruction, MethodContext context, BuilderRef builder) { Code code = instruction.OpCode.Code; StackElement pointer = context.CurrentStack.Pop(); ValueRef ptr = pointer.Value; TypeRef ptrType = LLVM.PointerType(TypeHelper.GetTypeRefFromStOrLdind(code), 0); if (pointer.Type != ptrType) { CastHelper.HelpIntAndPtrCast(builder, ref ptr, ref pointer.Type, ptrType, "ldindcast"); } ValueRef res = LLVM.BuildLoad(builder, ptr, "elem"); // Some need to be pushed as an int32 on the stack. if (code == Code.Ldind_I1 || code == Code.Ldind_I2 || code == Code.Ldind_I4 || code == Code.Ldind_U1 || code == Code.Ldind_U2 || code == Code.Ldind_U4) { res = LLVM.BuildIntCast(builder, res, TypeHelper.Int32, "tmp"); } TypeRef type = LLVM.TypeOf(res); context.CurrentStack.Push(new StackElement(res, TypeHelper.GetBasicTypeFromTypeRef(type), type)); }
/// <summary> /// Compiles the builtin runtime functions. /// </summary> public void Compile() { BuilderRef builder = LLVM.CreateBuilderInContext(mCompiler.ModuleContext); createStringGetCharsFunction(builder); LLVM.DisposeBuilder(builder); }
/// <summary> /// Emits a rem instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="context">The context.</param> /// <param name="builder">The builder.</param> public void Emit(Instruction instruction, MethodContext context, BuilderRef builder) { StackElement value2 = context.CurrentStack.Pop(); StackElement value1 = context.CurrentStack.Pop(); if (TypeHelper.IsFloatingPoint(value1) || TypeHelper.IsFloatingPoint(value2)) { ValueRef result = LLVM.BuildFRem(builder, value1.Value, value2.Value, "remfp"); context.CurrentStack.Push(new StackElement(result, value1.ILType, value1.Type)); } else { CastHelper.HelpIntCast(builder, ref value1, ref value2); ValueRef result; if (instruction.OpCode.Code == Code.Rem) { result = LLVM.BuildSRem(builder, value1.Value, value2.Value, "remsi"); } else /* Rem_Un */ { result = LLVM.BuildURem(builder, value1.Value, value2.Value, "remui"); } context.CurrentStack.Push(new StackElement(result, value1.ILType, value1.Type)); } }
/// <summary> /// Emits a stloc instruction /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="context">The context.</param> /// <param name="builder">The builder.</param> public void Emit(Instruction instruction, MethodContext context, BuilderRef builder) { Code code = instruction.OpCode.Code; int index; if (code >= Code.Stloc_0 && code <= Code.Stloc_3) { index = instruction.OpCode.Code - Code.Stloc_0; } else { VariableDefinition def = (VariableDefinition)instruction.Operand; index = def.Index; } StackElement element = context.CurrentStack.Pop(); ValueRef data = element.Value; TypeRef destType = context.LocalTypes[index]; // Possible cast needed. if (element.Type != destType) { CastHelper.HelpIntAndPtrCast(builder, ref data, ref element.Type, destType, "stloccast"); } LLVM.BuildStore(builder, data, context.LocalValues[index]); }
/// <summary> /// Emits a ldfld instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="context">The context.</param> /// <param name="builder">The builder.</param> public void Emit(Instruction instruction, MethodContext context, BuilderRef builder) { StackElement obj = context.CurrentStack.Pop(); FieldReference field = (FieldReference)instruction.Operand; uint index = context.Compiler.Lookup.GetFieldIndex(field); // Create pointer if not yet a pointer. if (obj.ILType.IsValueType && !obj.ILType.IsPointer) { ValueRef objPtr = LLVM.BuildAlloca(builder, obj.Type, "objptr"); LLVM.BuildStore(builder, obj.Value, objPtr); obj.Value = objPtr; } ValueRef ptr = LLVM.BuildInBoundsGEP(builder, obj.Value, new ValueRef[] { LLVM.ConstInt(TypeHelper.Int32, 0, false), LLVM.ConstInt(TypeHelper.Int32, index, false) }, "field"); ValueRef result = LLVM.BuildLoad(builder, ptr, "field"); if (instruction.HasPrefix(Code.Volatile)) { LLVM.SetVolatile(result, true); } context.CurrentStack.Push(new StackElement(result, field.FieldType)); }
/// <summary> /// Emits a stfld instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="context">The context.</param> /// <param name="builder">The builder.</param> public void Emit(Instruction instruction, MethodContext context, BuilderRef builder) { StackElement value = context.CurrentStack.Pop(); StackElement obj = context.CurrentStack.Pop(); FieldReference field = (FieldReference)instruction.Operand; uint index = context.Compiler.Lookup.GetFieldIndex(field); ValueRef ptr = LLVM.BuildInBoundsGEP(builder, obj.Value, new ValueRef[] { LLVM.ConstInt(TypeHelper.Int32, 0, false), LLVM.ConstInt(TypeHelper.Int32, index, false) }, "field"); // Possible cast needed. TypeRef destType = TypeHelper.GetTypeRefFromType(field.FieldType); if (value.Type != destType) { CastHelper.HelpIntAndPtrCast(builder, ref value.Value, ref value.Type, destType, "stfldcast"); } ValueRef store = LLVM.BuildStore(builder, value.Value, ptr); if (instruction.HasPrefix(Code.Volatile)) { LLVM.SetVolatile(store, true); } }
/// <summary> /// Emits a compare instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="context">The context.</param> /// <param name="builder">The builder.</param> public void Emit(Instruction instruction, MethodContext context, BuilderRef builder) { StackElement value2 = context.CurrentStack.Pop(); StackElement value1 = context.CurrentStack.Pop(); ValueRef ret; if (TypeHelper.IsFloatingPoint(value2) || TypeHelper.IsFloatingPoint(value1)) { ret = LLVM.BuildFCmp(builder, PredicateHelper.GetRealPredicateFromCode(instruction.OpCode.Code), value1.Value, value2.Value, "fcmp"); } else { if (value2.Type != value1.Type) { ValueRef tmp = LLVM.BuildIntCast(builder, value2.Value, value1.Type, "tmp"); ret = LLVM.BuildICmp(builder, PredicateHelper.GetIntPredicateFromCode(instruction.OpCode.Code), value1.Value, tmp, "icmp"); } else { ret = LLVM.BuildICmp(builder, PredicateHelper.GetIntPredicateFromCode(instruction.OpCode.Code), value1.Value, value2.Value, "icmp"); } } context.CurrentStack.Push(new StackElement(ret, typeof(bool).GetTypeReference(), TypeHelper.Boolean)); }
/// <summary> /// Emits a not instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="context">The context.</param> /// <param name="builder">The builder.</param> public void Emit(Instruction instruction, MethodContext context, BuilderRef builder) { StackElement value = context.CurrentStack.Pop(); ValueRef result = LLVM.BuildNot(builder, value.Value, "not"); context.CurrentStack.Push(new StackElement(result, value.ILType, value.Type)); }
/// <summary> /// Prepares the arguments. /// </summary> private void prepareArguments() { BuilderRef builder = LLVM.CreateBuilderInContext(Compiler.ModuleContext); LLVM.PositionBuilderAtEnd(builder, Branches[0].Block); uint count = LLVM.CountParams(Function); ArgumentValues = new ValueRef[count]; ArgumentILTypes = new TypeReference[count]; // It is possible that the first argument is an instance reference. int offset = (Method.HasThis) ? 1 : 0; for (int i = offset; i < count; i++) { ValueRef param = LLVM.GetParam(Function, (uint)i); ArgumentILTypes[i] = Method.Parameters[i - offset].ParameterType; ArgumentValues[i] = LLVM.BuildAlloca(builder, LLVM.TypeOf(param), "arg" + i); LLVM.BuildStore(builder, param, ArgumentValues[i]); } // Instance reference. if (Method.HasThis) { ValueRef param = LLVM.GetParam(Function, 0); ArgumentILTypes[0] = new PointerType(Method.DeclaringType); ArgumentValues[0] = LLVM.BuildAlloca(builder, LLVM.TypeOf(param), "arginstance"); LLVM.BuildStore(builder, param, ArgumentValues[0]); } LLVM.DisposeBuilder(builder); }
/// <summary> /// Emits a stind instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="context">The context.</param> /// <param name="builder">The builder.</param> public void Emit(Instruction instruction, MethodContext context, BuilderRef builder) { StackElement value = context.CurrentStack.Pop(); StackElement pointer = context.CurrentStack.Pop(); ValueRef val = value.Value; ValueRef ptr = pointer.Value; TypeRef destType = TypeHelper.GetTypeRefFromStOrLdind(instruction.OpCode.Code); TypeRef destPtrType = LLVM.PointerType(destType, 0); if (destPtrType != pointer.Type) { // There is no instruction for a Stind to store a boolean, so we need to check manually. if (pointer.Type == LLVM.PointerType(TypeHelper.Boolean, 0)) { destType = TypeHelper.Boolean; } // We treat char as 8-bit. else if (pointer.Type == LLVM.PointerType(TypeHelper.Int8, 0)) { destType = TypeHelper.Int8; } val = LLVM.BuildIntCast(builder, val, destType, "stindcast"); // If the pointer is a native int, convert to a pointer of the appropriate type. if (pointer.Type == TypeHelper.NativeIntType) { ptr = LLVM.BuildIntToPtr(builder, ptr, destPtrType, "int2ptr"); } } LLVM.BuildStore(builder, val, ptr); }
/// <summary> /// Emits an add instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="context">The context.</param> /// <param name="builder">The builder.</param> public void Emit(Instruction instruction, MethodContext context, BuilderRef builder) { StackElement value2 = context.CurrentStack.Pop(); StackElement value1 = context.CurrentStack.Pop(); if (TypeHelper.IsFloatingPoint(value1) || TypeHelper.IsFloatingPoint(value2)) { ValueRef result = LLVM.BuildFAdd(builder, value1.Value, value2.Value, "addfp"); context.CurrentStack.Push(new StackElement(result, value1.ILType, value1.Type)); } else { bool isPtrVal1, isPtrVal2; CastHelper.HelpPossiblePtrCast(builder, ref value1, ref value2, out isPtrVal1, out isPtrVal2, "addcast"); // If one of the two values is a pointer, then the result will be a pointer as well. if (isPtrVal1 || isPtrVal2) { ValueRef result = LLVM.BuildAdd(builder, value1.Value, value2.Value, "addptr"); TypeRef resultingType = (isPtrVal1 ? value1.Type : value2.Type); TypeReference resultingILType = (isPtrVal1 ? value1.ILType : value2.ILType); ValueRef ptr = LLVM.BuildIntToPtr(builder, result, resultingType, "ptr"); context.CurrentStack.Push(new StackElement(ptr, resultingILType, resultingType)); } // Cast to different int size. else { CastHelper.HelpIntCast(builder, ref value1, ref value2); ValueRef result = LLVM.BuildAdd(builder, value1.Value, value2.Value, "addi"); context.CurrentStack.Push(new StackElement(result, value1.ILType, value1.Type)); } } }
/// <summary> /// Helps with the pointer casting so that both values are of the same type. /// </summary> /// <param name="builder">The builder.</param> /// <param name="value1">The first value.</param> /// <param name="value2">The second value.</param> /// <param name="isPtrVal1">If the first value was a pointer.</param> /// <param name="isPtrVal2">If the second value was a pointer.</param> /// <param name="name">The name of the cast.</param> public static void HelpPossiblePtrCast(BuilderRef builder, ref StackElement value1, ref StackElement value2, out bool isPtrVal1, out bool isPtrVal2, string name) { isPtrVal1 = TypeHelper.IsPointer(value1); isPtrVal2 = TypeHelper.IsPointer(value2); if (isPtrVal1 || isPtrVal2) { if (isPtrVal1) { value1.Value = LLVM.BuildPtrToInt(builder, value1.Value, TypeHelper.NativeIntType, "tmp"); } else { value1.Value = LLVM.BuildIntCast(builder, value1.Value, TypeHelper.NativeIntType, "tmp"); } if (isPtrVal2) { value2.Value = LLVM.BuildPtrToInt(builder, value2.Value, TypeHelper.NativeIntType, "tmp"); } else { value2.Value = LLVM.BuildIntCast(builder, value2.Value, TypeHelper.NativeIntType, "tmp"); } } }
/// <summary> /// Helps int and ptr casting to a destination type. /// </summary> /// <param name="builder">The builder.</param> /// <param name="data">The data (int or pointer).</param> /// <param name="dataType">The data type.</param> /// <param name="destType">The destination type.</param> /// <param name="name">The name of the cast.</param> public static void HelpIntAndPtrCast(BuilderRef builder, ref ValueRef data, ref TypeRef dataType, TypeRef destType, string name) { // Two cases: int to different size, or int to pointer. TypeKind kind = LLVM.GetTypeKind(destType); // Convert to pointer. if (kind == TypeKind.PointerTypeKind) { // Two cases: pointer to pointer, or int to ptr. if (LLVM.GetTypeKind(dataType) == TypeKind.PointerTypeKind) { data = LLVM.BuildPointerCast(builder, data, destType, name); } else { data = LLVM.BuildIntToPtr(builder, data, destType, name); } } // Convert to int of different size. else { data = LLVM.BuildIntCast(builder, data, destType, name); } dataType = destType; }
/// <summary> /// Emits a Ldc_I4 instruction. /// </summary> /// <param name="context">The context.</param> /// <param name="builder">The builder.</param> public void Emit(Instruction instruction, MethodContext context, BuilderRef builder) { ValueRef result; Code code = instruction.OpCode.Code; if (code >= Code.Ldc_I4_0 && code <= Code.Ldc_I4_8) { result = LLVM.ConstInt(TypeHelper.Int32, (ulong)(instruction.OpCode.Code - Code.Ldc_I4_0), true); } else if (code == Code.Ldc_I4_M1) { unchecked { result = LLVM.ConstInt(TypeHelper.Int32, (uint)-1, true); } } else { if (instruction.Operand is sbyte) { result = LLVM.ConstInt(TypeHelper.Int32, (ulong)(sbyte)instruction.Operand, true); } else { unchecked { result = LLVM.ConstInt(TypeHelper.Int32, (uint)(int)instruction.Operand, true); } } } context.CurrentStack.Push(new StackElement(result, typeof(int).GetTypeReference(), TypeHelper.Int32)); }
/// <summary> /// Updates the stack of this branch using the incoming source branches. /// </summary> /// <param name="builder">The builder.</param> public void UpdateStack(BuilderRef builder) { foreach (Branch source in Sources) { Stack.Update(builder, source.Stack, source.Block, Block, References); } }
/// <summary> /// Emits a localloc instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="context">The context.</param> /// <param name="builder">The builder.</param> public void Emit(Instruction instruction, MethodContext context, BuilderRef builder) { StackElement size = context.CurrentStack.Pop(); ValueRef result = LLVM.BuildArrayAlloca(builder, TypeHelper.Int8, size.Value, "stackalloc"); context.CurrentStack.Push(new StackElement(result, typeof(byte[]).GetTypeReference())); }
/// <summary> /// Emits a ldftn instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="context">The context.</param> /// <param name="builder">The builder.</param> public void Emit(Instruction instruction, MethodContext context, BuilderRef builder) { MethodDefinition method = (MethodDefinition)instruction.Operand; ValueRef result = LLVM.BuildIntToPtr(builder, context.Compiler.Lookup.GetFunction(NameHelper.CreateMethodName(method)).Value, TypeHelper.NativeIntType, "ldftn"); StackElement element = new StackElement(result, typeof(IntPtr).GetTypeReference(), TypeHelper.NativeIntType); context.CurrentStack.Push(element); }
/// <summary> /// Emits a ldloca instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="context">The context.</param> /// <param name="builder">The builder.</param> public void Emit(Instruction instruction, MethodContext context, BuilderRef builder) { Code code = instruction.OpCode.Code; VariableDefinition def = (VariableDefinition)instruction.Operand; int index = def.Index; context.CurrentStack.Push(new StackElement(context.LocalValues[index], new PointerType(context.LocalILTypes[index]))); }
/// <summary> /// Emits a ldelema instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="context">The context.</param> /// <param name="builder">The builder.</param> public void Emit(Instruction instruction, MethodContext context, BuilderRef builder) { StackElement index = context.CurrentStack.Pop(); StackElement array = context.CurrentStack.Pop(); ValueRef gep = LLVM.BuildGEP(builder, array.Value, new ValueRef[] { index.Value }, "arrayelemptr"); context.CurrentStack.Push(new StackElement(gep, array.ILType, array.Type)); }
/// <summary> /// Helps with the int casting so that both values are of the same type. /// </summary> /// <param name="builder">The builder.</param> /// <param name="value1">The first value.</param> /// <param name="value2">The second value.</param> public static void HelpIntCast(BuilderRef builder, ref StackElement value1, ref StackElement value2) { if (value1.Type != value2.Type) { value2.Value = LLVM.BuildIntCast(builder, value2.Value, value1.Type, "tmpintcast"); value2.Type = value1.Type; value2.ILType = value1.ILType; } }
public void TestORC() { LLVM.InitializeAllTargets(); LLVM.InitializeAllTargetMCs(); LLVM.InitializeAllTargetInfos(); LLVM.InitializeAllAsmPrinters(); // See http://www.doof.me.uk/2017/05/11/using-orc-with-llvms-c-api/ ModuleRef mod = LLVM.ModuleCreateWithName("LLVMSharpIntro"); TypeRef[] param_types = { LLVM.Int32Type(), LLVM.Int32Type() }; TypeRef ret_type = LLVM.FunctionType(LLVM.Int32Type(), param_types, false); ValueRef sum = LLVM.AddFunction(mod, "sum", ret_type); BasicBlockRef entry = LLVM.AppendBasicBlock(sum, "entry"); BuilderRef builder = LLVM.CreateBuilder(); LLVM.PositionBuilderAtEnd(builder, entry); ValueRef tmp = LLVM.BuildAdd(builder, LLVM.GetParam(sum, 0), LLVM.GetParam(sum, 1), "tmp"); LLVM.BuildRet(builder, tmp); MyString the_error = new MyString(); LLVM.VerifyModule(mod, VerifierFailureAction.AbortProcessAction, the_error); //LLVM.DisposeMessage(error); TargetRef t2; string tr2 = LLVM.GetDefaultTargetTriple(); var b = LLVM.GetTargetFromTriple(tr2, out t2, the_error); string triple = ""; string cpu = ""; string features = ""; TargetMachineRef tmr = LLVM.CreateTargetMachine(t2, tr2, cpu, features, CodeGenOptLevel.CodeGenLevelDefault, RelocMode.RelocDefault, CodeModel.CodeModelDefault); OrcJITStackRef ojsr = LLVM.OrcCreateInstance(tmr); MyString ms = new MyString(); LLVM.OrcGetMangledSymbol(ojsr, ms, "sum"); IntPtr ctx = IntPtr.Zero; SharedModuleRef smr = LLVM.OrcMakeSharedModule(mod); OrcErrorCode xx = LLVM.OrcAddLazilyCompiledIR(ojsr, out uint omh, smr, null, ctx); OrcErrorCode p = LLVM.OrcGetSymbolAddress(ojsr, out IntPtr RetAddr, "sum"); Add addMethod = (Add)Marshal.GetDelegateForFunctionPointer(RetAddr, typeof(Add)); int result = addMethod(10, 10); Console.WriteLine("Result of sum is: " + result); if (result != 20) { throw new Exception("Failed."); } LLVM.DumpModule(mod); LLVM.DisposeBuilder(builder); }
/// <summary> /// Emits a Ldc_I8 instruction. /// </summary> /// <param name="context">The context.</param> /// <param name="builder">The builder.</param> public void Emit(Instruction instruction, MethodContext context, BuilderRef builder) { TypeRef type = TypeHelper.Int64; unchecked { ValueRef result = LLVM.ConstInt(type, (ulong)(long)instruction.Operand, true); context.CurrentStack.Push(new StackElement(result, typeof(long).GetTypeReference(), type)); } }
/// <summary> /// Emits an initobj instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="context">The context.</param> /// <param name="builder">The builder.</param> public void Emit(Instruction instruction, MethodContext context, BuilderRef builder) { StackElement valueTypeAddress = context.CurrentStack.Pop(); TypeReference type = (TypeReference)instruction.Operand; TypeRef typeRef = context.Compiler.Lookup.GetTypeRef(type); // We clear this using memset. CastHelper.HelpIntAndPtrCast(builder, ref valueTypeAddress.Value, ref valueTypeAddress.Type, TypeHelper.VoidPtr, "initobjcast"); LLVM.BuildCall(builder, RuntimeHelper.Memset, new ValueRef[] { valueTypeAddress.Value, LLVM.ConstNull(TypeHelper.Int32), LLVM.SizeOf(typeRef) }, string.Empty); }
/// <summary> /// Emits an shr_un instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="context">The context.</param> /// <param name="builder">The builder.</param> public void Emit(Instruction instruction, MethodContext context, BuilderRef builder) { StackElement value2 = context.CurrentStack.Pop(); StackElement value1 = context.CurrentStack.Pop(); CastHelper.HelpIntCast(builder, ref value1, ref value2); ValueRef result = LLVM.BuildLShr(builder, value1.Value, value2.Value, "shrun"); context.CurrentStack.Push(new StackElement(result, value1.ILType, value1.Type)); }
/// <summary> /// Emits a newobj instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="context">The context.</param> /// <param name="builder">The builder.</param> public void Emit(Instruction instruction, MethodContext context, BuilderRef builder) { MethodReference ctor = (MethodReference)instruction.Operand; TypeDefinition objType = ctor.DeclaringType.Resolve(); TypeRef type = TypeHelper.GetTypeRefFromType(ctor.DeclaringType); ValueRef objPtr; bool ptr = (objType.IsClass && !objType.IsValueType); if (ptr) { // This type is a class, therefor we have a specialised "newobj" method. objPtr = LLVM.BuildCall(builder, context.Compiler.Lookup.GetNewobjMethod(ctor.DeclaringType.Resolve()), new ValueRef[0], "newobj"); } else { // Not a class, allocate on stack. objPtr = LLVM.BuildAlloca(builder, type, "newobj"); } // Constructor. ValueRef?ctorFunc = context.Compiler.Lookup.GetFunction(NameHelper.CreateMethodName(ctor)); if (!ctorFunc.HasValue) { throw new Exception("Constructor not found: " + ctor); } // Get .ctor parameters. int paramCount = 1 + ctor.Parameters.Count; ValueRef[] values = new ValueRef[paramCount]; values[0] = objPtr; for (int i = paramCount - 1; i >= 1; i--) { StackElement element = context.CurrentStack.Pop(); values[i] = element.Value; // Cast needed? TypeRef paramType = TypeHelper.GetTypeRefFromType(ctor.Parameters[i - 1].ParameterType); if (element.Type != paramType) { CastHelper.HelpIntAndPtrCast(builder, ref values[i], ref element.Type, paramType, "ctorcallcast"); } } // Call .ctor. LLVM.BuildCall(builder, ctorFunc.Value, values, string.Empty); // Load and push object on stack. ValueRef obj = (ptr) ? objPtr : LLVM.BuildLoad(builder, objPtr, "obj"); context.CurrentStack.Push(new StackElement(obj, ctor.DeclaringType, type)); }
/// <summary> /// Emits a starg instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="context">The context.</param> /// <param name="builder">The builder.</param> public void Emit(Instruction instruction, MethodContext context, BuilderRef builder) { StackElement value = context.CurrentStack.Pop(); ParameterDefinition def = (ParameterDefinition)instruction.Operand; int index = def.Index; ValueRef arg = context.ArgumentValues[index]; CastHelper.HelpIntAndPtrCast(builder, ref value.Value, ref value.Type, TypeHelper.GetTypeRefFromType(context.ArgumentILTypes[index]), "stargcast"); LLVM.BuildStore(builder, value.Value, arg); }
/// <summary> /// Emits a ldelem_ref instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="context">The context.</param> /// <param name="builder">The builder.</param> public void Emit(Instruction instruction, MethodContext context, BuilderRef builder) { StackElement index = context.CurrentStack.Pop(); StackElement array = context.CurrentStack.Pop(); ValueRef ptr = LLVM.BuildGEP(builder, array.Value, new ValueRef[] { index.Value }, "arrayptr"); ValueRef res = LLVM.BuildLoad(builder, ptr, "arrayelem"); TypeRef type = LLVM.TypeOf(res); ArrayType arrayType = (ArrayType)array.ILType; context.CurrentStack.Push(new StackElement(res, arrayType.ElementType, type)); }
/// <summary> /// Emits an instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="context">The context.</param> /// <param name="builder">The builder.</param> public void Emit(Instruction instruction, MethodContext context, BuilderRef builder) { ICodeEmitter emitter = null; if (mEmitters.TryGetValue(instruction.OpCode.Code, out emitter)) { emitter.Emit(instruction, context, builder); } else { throw new NotImplementedException("Instruction with opcode " + instruction.OpCode.Code + " is not implemented"); } }
/// <summary> /// Emits a ldarga instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="context">The context.</param> /// <param name="builder">The builder.</param> public void Emit(Instruction instruction, MethodContext context, BuilderRef builder) { ParameterDefinition def = (ParameterDefinition)instruction.Operand; int index = def.Index; if (def.Method.HasThis) { index++; } ValueRef arg = context.ArgumentValues[index]; context.CurrentStack.Push(new StackElement(arg, context.ArgumentILTypes[index])); }
public unsafe static ValueRef BuildVAArg(BuilderRef arg0, ValueRef List, TypeRef Ty, string Name) { ValueRef ret = new ValueRef(LLVMPINVOKE.BuildVAArg(arg0.Value, List.Value, Ty.Value, Name)); return ret; }
public unsafe static ValueRef BuildCall(BuilderRef arg0, ValueRef Fn, ValueRef[] Args, string Name) { fixed (ValueRef* swig_ptrTo_Args = Args) { ValueRef ret = new ValueRef(LLVMPINVOKE.BuildCall(arg0.Value, Fn.Value, (System.IntPtr)swig_ptrTo_Args, (uint)Args.Length, Name)); return ret; } }
public unsafe static ValueRef BuildSelect(BuilderRef arg0, ValueRef If, ValueRef Then, ValueRef Else, string Name) { ValueRef ret = new ValueRef(LLVMPINVOKE.BuildSelect(arg0.Value, If.Value, Then.Value, Else.Value, Name)); return ret; }
public unsafe static ValueRef BuildAtomicRMW(BuilderRef B, AtomicRMWBinOp op, ValueRef PTR, ValueRef Val, AtomicOrdering ordering, bool singleThread) { ValueRef ret = new ValueRef(LLVMPINVOKE.BuildAtomicRMW(B.Value, (int)op, PTR.Value, Val.Value, (int)ordering, singleThread)); return ret; }
public unsafe static ValueRef BuildNUWNeg(BuilderRef B, ValueRef V, string Name) { ValueRef ret = new ValueRef(LLVMPINVOKE.BuildNUWNeg(B.Value, V.Value, Name)); return ret; }
public unsafe static ValueRef BuildInsertValue(BuilderRef arg0, ValueRef AggVal, ValueRef EltVal, uint Index, string Name) { ValueRef ret = new ValueRef(LLVMPINVOKE.BuildInsertValue(arg0.Value, AggVal.Value, EltVal.Value, Index, Name)); return ret; }
public unsafe static ValueRef BuildPtrDiff(BuilderRef arg0, ValueRef LHS, ValueRef RHS, string Name) { ValueRef ret = new ValueRef(LLVMPINVOKE.BuildPtrDiff(arg0.Value, LHS.Value, RHS.Value, Name)); return ret; }
public unsafe static ValueRef BuildInBoundsGEP(BuilderRef B, ValueRef Pointer, ValueRef[] Indices, string Name) { fixed (ValueRef* swig_ptrTo_Indices = Indices) { ValueRef ret = new ValueRef(LLVMPINVOKE.BuildInBoundsGEP(B.Value, Pointer.Value, (System.IntPtr)swig_ptrTo_Indices, (uint)Indices.Length, Name)); return ret; } }
public unsafe static ValueRef BuildStructGEP(BuilderRef B, ValueRef Pointer, uint Idx, string Name) { ValueRef ret = new ValueRef(LLVMPINVOKE.BuildStructGEP(B.Value, Pointer.Value, Idx, Name)); return ret; }
public unsafe static ValueRef BuildLoad(BuilderRef arg0, ValueRef PointerVal, string Name) { ValueRef ret = new ValueRef(LLVMPINVOKE.BuildLoad(arg0.Value, PointerVal.Value, Name)); return ret; }
public unsafe static ValueRef BuildStore(BuilderRef arg0, ValueRef Val, ValueRef Ptr) { ValueRef ret = new ValueRef(LLVMPINVOKE.BuildStore(arg0.Value, Val.Value, Ptr.Value)); return ret; }
public unsafe static ValueRef BuildFree(BuilderRef arg0, ValueRef PointerVal) { ValueRef ret = new ValueRef(LLVMPINVOKE.BuildFree(arg0.Value, PointerVal.Value)); return ret; }
public unsafe static ValueRef BuildArrayAlloca(BuilderRef arg0, TypeRef Ty, ValueRef Val, string Name) { ValueRef ret = new ValueRef(LLVMPINVOKE.BuildArrayAlloca(arg0.Value, Ty.Value, Val.Value, Name)); return ret; }
public unsafe static ValueRef BuildNot(BuilderRef arg0, ValueRef V, string Name) { ValueRef ret = new ValueRef(LLVMPINVOKE.BuildNot(arg0.Value, V.Value, Name)); return ret; }
public unsafe static ValueRef BuildInsertElement(BuilderRef arg0, ValueRef VecVal, ValueRef EltVal, ValueRef Index, string Name) { ValueRef ret = new ValueRef(LLVMPINVOKE.BuildInsertElement(arg0.Value, VecVal.Value, EltVal.Value, Index.Value, Name)); return ret; }
public unsafe static ValueRef BuildGlobalStringPtr(BuilderRef B, string Str, string Name) { ValueRef ret = new ValueRef(LLVMPINVOKE.BuildGlobalStringPtr(B.Value, Str, Name)); return ret; }
public unsafe static ValueRef BuildShuffleVector(BuilderRef arg0, ValueRef V1, ValueRef V2, ValueRef Mask, string Name) { ValueRef ret = new ValueRef(LLVMPINVOKE.BuildShuffleVector(arg0.Value, V1.Value, V2.Value, Mask.Value, Name)); return ret; }
public unsafe static ValueRef BuildInvoke(BuilderRef arg0, ValueRef Fn, ValueRef[] Args, BasicBlockRef Then, BasicBlockRef Catch, string Name) { fixed (ValueRef* swig_ptrTo_Args = Args) { ValueRef ret = new ValueRef(LLVMPINVOKE.BuildInvoke(arg0.Value, Fn.Value, (System.IntPtr)swig_ptrTo_Args, (uint)Args.Length, Then.Value, Catch.Value, Name)); return ret; } }
public unsafe static ValueRef BuildIsNotNull(BuilderRef arg0, ValueRef Val, string Name) { ValueRef ret = new ValueRef(LLVMPINVOKE.BuildIsNotNull(arg0.Value, Val.Value, Name)); return ret; }
public unsafe static ValueRef BuildResume(BuilderRef B, ValueRef Exn) { ValueRef ret = new ValueRef(LLVMPINVOKE.BuildResume(B.Value, Exn.Value)); return ret; }
public unsafe static ValueRef BuildFence(BuilderRef B, AtomicOrdering ordering, bool singleThread, string Name) { ValueRef ret = new ValueRef(LLVMPINVOKE.BuildFence(B.Value, (int)ordering, singleThread, Name)); return ret; }
public unsafe static ValueRef BuildIndirectBr(BuilderRef B, ValueRef Addr, uint NumDests) { ValueRef ret = new ValueRef(LLVMPINVOKE.BuildIndirectBr(B.Value, Addr.Value, NumDests)); return ret; }
public unsafe static ValueRef BuildUnsignedIntCast(BuilderRef arg0, ValueRef Val, TypeRef DestTy, string Name) { ValueRef ret = new ValueRef(LLVMPINVOKE.BuildUnsignedIntCast(arg0.Value, Val.Value, DestTy.Value, Name)); return ret; }
public unsafe static ValueRef BuildUnreachable(BuilderRef arg0) { ValueRef ret = new ValueRef(LLVMPINVOKE.BuildUnreachable(arg0.Value)); return ret; }
public unsafe static ValueRef BuildCast(BuilderRef B, Opcode Op, ValueRef Val, TypeRef DestTy, string Name) { ValueRef ret = new ValueRef(LLVMPINVOKE.BuildCast(B.Value, (int)Op, Val.Value, DestTy.Value, Name)); return ret; }
public unsafe static ValueRef BuildLandingPad(BuilderRef B, TypeRef Ty, ValueRef PersFn, uint NumClauses, string Name) { ValueRef ret = new ValueRef(LLVMPINVOKE.BuildLandingPad(B.Value, Ty.Value, PersFn.Value, NumClauses, Name)); return ret; }
public unsafe static ValueRef BuildFCmp(BuilderRef arg0, RealPredicate Op, ValueRef LHS, ValueRef RHS, string Name) { ValueRef ret = new ValueRef(LLVMPINVOKE.BuildFCmp(arg0.Value, (int)Op, LHS.Value, RHS.Value, Name)); return ret; }
public unsafe static ValueRef BuildPhi(BuilderRef arg0, TypeRef Ty, string Name) { ValueRef ret = new ValueRef(LLVMPINVOKE.BuildPhi(arg0.Value, Ty.Value, Name)); return ret; }
public unsafe static ValueRef BuildBinOp(BuilderRef B, Opcode Op, ValueRef LHS, ValueRef RHS, string Name) { ValueRef ret = new ValueRef(LLVMPINVOKE.BuildBinOp(B.Value, (int)Op, LHS.Value, RHS.Value, Name)); return ret; }
public unsafe static ValueRef BuildSwitch(BuilderRef arg0, ValueRef V, BasicBlockRef Else, uint NumCases) { ValueRef ret = new ValueRef(LLVMPINVOKE.BuildSwitch(arg0.Value, V.Value, Else.Value, NumCases)); return ret; }