Пример #1
0
        public void OutputCodeForDelegateCtorInit(LLVMBuilderRef builder, LLVMValueRef helperFunc,
                                                  MethodDesc constructor,
                                                  LLVMValueRef fatFunction)
        {
            StackEntry[] argValues   = new StackEntry [constructor.Signature.Length + 1]; // for delegate this
            var          shadowStack = helperFunc.GetParam(0);

            argValues[0] = new LoadExpressionEntry(StackValueKind.ObjRef, "this", shadowStack, GetWellKnownType(WellKnownType.Object));
            for (var i = 0; i < constructor.Signature.Length; i++)
            {
                if (i == 1)
                {
                    argValues[i + 1] = new ExpressionEntry(StackValueKind.Int32, "arg" + (i + 1),
                                                           builder.BuildIntToPtr(fatFunction, LLVMTypeRef.CreatePointer(LLVMTypeRef.Int8, 0), "toPtr"),
                                                           GetWellKnownType(WellKnownType.IntPtr));
                }
                else
                {
                    var argRef = LoadVarAddress(i + 1, LocalVarKind.Argument, out TypeDesc type);
                    var ptrPtr = builder.BuildPointerCast(argRef,
                                                          LLVMTypeRef.CreatePointer(LLVMTypeRef.CreatePointer(LLVMTypeRef.Int8, 0), 0), "ptrPtr");
                    var loadArg = builder.BuildLoad(ptrPtr, "arg" + (i + 1));
                    argValues[i + 1] = new ExpressionEntry(GetStackValueKind(constructor.Signature[i]), "arg" + i + 1, loadArg,
                                                           constructor.Signature[i]);
                }
            }
            HandleCall(constructor, constructor.Signature, constructor, argValues, null);
        }
Пример #2
0
        private void ImportReturn()
        {
            if (_method.Signature.ReturnType != GetWellKnownType(WellKnownType.Void))
            {
                StackEntry  retVal    = _stack.Pop();
                LLVMTypeRef valueType = GetLLVMTypeForTypeDesc(_method.Signature.ReturnType);

                ImportStoreHelper(retVal.LLVMValue, valueType, LLVM.GetNextParam(LLVM.GetFirstParam(_llvmFunction)), 0);
            }

            LLVM.BuildRetVoid(_builder);
        }
Пример #3
0
        /// <summary>
        /// Generate a cast in case the stack type of source is not identical or compatible with destination type.
        /// </summary>
        /// <param name="destType">Type of destination</param>
        /// <param name="srcEntry">Source entry from stack</param>
        private void AppendCastIfNecessary(TypeDesc destType, StackEntry srcEntry)
        {
            ConstantEntry constant = srcEntry as ConstantEntry;

            if ((constant != null) && (constant.IsCastNecessary(destType)) || !destType.IsValueType || destType != srcEntry.Type)
            {
                throw new NotImplementedException();

                /*
                 * Append("(");
                 * Append(GetSignatureTypeNameAndAddReference(destType));
                 * Append(")");*/
            }
        }
Пример #4
0
        private void ImportConvert(WellKnownType wellKnownType, bool checkOverflow, bool unsigned)
        {
            StackEntry value          = _stack.Pop();
            StackEntry convertedValue = value.Duplicate();

            //conv.u for a pointer should change to a int8*
            if (wellKnownType == WellKnownType.UIntPtr)
            {
                if (value.Kind == StackValueKind.Int32)
                {
                    convertedValue.LLVMValue = LLVM.BuildIntToPtr(_builder, value.LLVMValue, LLVM.PointerType(LLVM.Int8Type(), 0), "conv.u");
                }
            }

            _stack.Push(convertedValue);
        }
        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);
        }
Пример #6
0
        private void ImportLoadIndirect(TypeDesc type)
        {
            StackEntry  pointer     = _stack.Pop();
            LLVMTypeRef loadType    = GetLLVMTypeForTypeDesc(type);
            LLVMTypeRef pointerType = LLVM.PointerType(loadType, 0);

            LLVMValueRef typedPointer;

            if (LLVM.GetTypeKind(LLVM.TypeOf(pointer.LLVMValue)) != LLVMTypeKind.LLVMPointerTypeKind)
            {
                typedPointer = LLVM.BuildIntToPtr(_builder, pointer.LLVMValue, pointerType, "ldindintptrcast");
            }
            else
            {
                typedPointer = LLVM.BuildPointerCast(_builder, pointer.LLVMValue, pointerType, "ldindptrcast");
            }

            LLVMValueRef load = LLVM.BuildLoad(_builder, typedPointer, "ldind");

            PushExpression(GetStackValueKind(type), "ldlind", load, type);
        }
Пример #7
0
        private void ImportBinaryOperation(ILOpcode opcode)
        {
            StackEntry op1 = _stack.Pop();
            StackEntry op2 = _stack.Pop();

            // StackValueKind is carefully ordered to make this work (assuming the IL is valid)
            StackValueKind kind;
            TypeDesc       type;

            if (op1.Kind > op2.Kind)
            {
                kind = op1.Kind;
                type = op1.Type;
            }
            else
            {
                kind = op2.Kind;
                type = op2.Type;
            }

            // The one exception from the above rule
            if ((kind == StackValueKind.ByRef) &&
                (opcode == ILOpcode.sub || opcode == ILOpcode.sub_ovf || opcode == ILOpcode.sub_ovf_un))
            {
                kind = StackValueKind.NativeInt;
                type = null;
            }

            LLVMValueRef result;

            switch (opcode)
            {
            case ILOpcode.add:
                // TODO: converting these to ints should also happen for sub and some other operations
                LLVMValueRef left  = op1.LLVMValue;
                LLVMValueRef right = op2.LLVMValue;

                if (kind == StackValueKind.NativeInt || kind == StackValueKind.ObjRef || kind == StackValueKind.ByRef)
                {
                    if (LLVM.GetTypeKind(LLVM.TypeOf(left)) == LLVMTypeKind.LLVMPointerTypeKind)
                    {
                        left = LLVM.BuildPtrToInt(_builder, left, LLVM.Int32Type(), "lptrasint");
                    }
                    if (LLVM.GetTypeKind(LLVM.TypeOf(right)) == LLVMTypeKind.LLVMPointerTypeKind)
                    {
                        right = LLVM.BuildPtrToInt(_builder, right, LLVM.Int32Type(), "rptrasint");
                    }
                }
                result = LLVM.BuildAdd(_builder, left, right, "add");
                break;

            case ILOpcode.sub:
                result = LLVM.BuildSub(_builder, op1.LLVMValue, op2.LLVMValue, "sub");
                break;

            case ILOpcode.mul:
                result = LLVM.BuildMul(_builder, op1.LLVMValue, op2.LLVMValue, "mul");
                break;

            case ILOpcode.div:
                result = LLVM.BuildSDiv(_builder, op1.LLVMValue, op2.LLVMValue, "sdiv");
                break;

            case ILOpcode.div_un:
                result = LLVM.BuildUDiv(_builder, op1.LLVMValue, op2.LLVMValue, "udiv");
                break;

            case ILOpcode.rem:
                result = LLVM.BuildSRem(_builder, op1.LLVMValue, op2.LLVMValue, "srem");
                break;

            case ILOpcode.rem_un:
                result = LLVM.BuildURem(_builder, op1.LLVMValue, op2.LLVMValue, "urem");
                break;

            case ILOpcode.and:
                result = LLVM.BuildAnd(_builder, op1.LLVMValue, op2.LLVMValue, "and");
                break;

            case ILOpcode.or:
                result = LLVM.BuildOr(_builder, op1.LLVMValue, op2.LLVMValue, "or");
                break;

            case ILOpcode.xor:
                result = LLVM.BuildXor(_builder, op1.LLVMValue, op2.LLVMValue, "xor");
                break;

            // TODO: Overflow checks
            case ILOpcode.add_ovf:
            case ILOpcode.add_ovf_un:
                result = LLVM.BuildAdd(_builder, op1.LLVMValue, op2.LLVMValue, "add");
                break;

            case ILOpcode.sub_ovf:
            case ILOpcode.sub_ovf_un:
                result = LLVM.BuildSub(_builder, op1.LLVMValue, op2.LLVMValue, "sub");
                break;

            case ILOpcode.mul_ovf:
            case ILOpcode.mul_ovf_un:
                result = LLVM.BuildMul(_builder, op1.LLVMValue, op2.LLVMValue, "mul");
                break;

            default:
                throw new InvalidOperationException();     // Should be unreachable
            }

            PushExpression(kind, "", result, type);
        }
Пример #8
0
 public static string Name(this StackEntry entry)
 {
     return((entry as ExpressionEntry)?.Name);
 }
        private void ImportBinaryOperation(ILOpcode opcode)
        {
            StackEntry op1 = _stack.Pop();
            StackEntry op2 = _stack.Pop();

            // StackValueKind is carefully ordered to make this work (assuming the IL is valid)
            StackValueKind kind;
            TypeDesc       type;

            if (op1.Kind > op2.Kind)
            {
                kind = op1.Kind;
                type = op1.Type;
            }
            else
            {
                kind = op2.Kind;
                type = op2.Type;
            }

            // The one exception from the above rule
            if ((kind == StackValueKind.ByRef) &&
                (opcode == ILOpcode.sub || opcode == ILOpcode.sub_ovf || opcode == ILOpcode.sub_ovf_un))
            {
                kind = StackValueKind.NativeInt;
                type = null;
            }

            LLVMValueRef result;

            switch (opcode)
            {
            case ILOpcode.add:
                result = LLVM.BuildAdd(_builder, op1.LLVMValue, op2.LLVMValue, "add");
                break;

            case ILOpcode.sub:
                result = LLVM.BuildSub(_builder, op1.LLVMValue, op2.LLVMValue, "sub");
                break;

            case ILOpcode.mul:
                result = LLVM.BuildMul(_builder, op1.LLVMValue, op2.LLVMValue, "mul");
                break;

            case ILOpcode.div:
                result = LLVM.BuildSDiv(_builder, op1.LLVMValue, op2.LLVMValue, "sdiv");
                break;

            case ILOpcode.div_un:
                result = LLVM.BuildUDiv(_builder, op1.LLVMValue, op2.LLVMValue, "udiv");
                break;

            case ILOpcode.rem:
                result = LLVM.BuildSRem(_builder, op1.LLVMValue, op2.LLVMValue, "srem");
                break;

            case ILOpcode.rem_un:
                result = LLVM.BuildURem(_builder, op1.LLVMValue, op2.LLVMValue, "urem");
                break;

            case ILOpcode.and:
                result = LLVM.BuildAnd(_builder, op1.LLVMValue, op2.LLVMValue, "and");
                break;

            case ILOpcode.or:
                result = LLVM.BuildOr(_builder, op1.LLVMValue, op2.LLVMValue, "or");
                break;

            case ILOpcode.xor:
                result = LLVM.BuildXor(_builder, op1.LLVMValue, op2.LLVMValue, "xor");
                break;

            // TODO: Overflow checks
            case ILOpcode.add_ovf:
            case ILOpcode.add_ovf_un:
                result = LLVM.BuildAdd(_builder, op1.LLVMValue, op2.LLVMValue, "add");
                break;

            case ILOpcode.sub_ovf:
            case ILOpcode.sub_ovf_un:
                result = LLVM.BuildSub(_builder, op1.LLVMValue, op2.LLVMValue, "sub");
                break;

            case ILOpcode.mul_ovf:
            case ILOpcode.mul_ovf_un:
                result = LLVM.BuildMul(_builder, op1.LLVMValue, op2.LLVMValue, "mul");
                break;

            default:
                throw new InvalidOperationException();     // Should be unreachable
            }

            PushExpression(kind, "", result, type);
        }