Exemple #1
0
        /// <summary>
        /// Loads the value of a field specified by the given metadata token.
        /// </summary>
        /// <param name="field">The field.</param>
        private void LoadField(FieldInfo field)
        {
            var value = CurrentBlock.Pop();
            var name  = string.Empty;

            if (value.ValueType.IsTreatedAsPtr())
            {
                var address = LoadFieldAddress(field, value);
                CurrentBlock.Push(field.FieldType, BuildLoad(Builder, address, name));
            }
            else
            {
                // It is a value object
                do
                {
                    var mappedType = Unit.GetObjectType(value.ValueType);
                    if (mappedType.TryResolveOffset(field, out int offset))
                    {
                        value = new Value(field.FieldType, BuildExtractValue(Builder, value.LLVMValue, offset, name));
                        break;
                    }
                    var baseType = value.ValueType.BaseType;
                    if (baseType == null)
                    {
                        throw new InvalidOperationException();
                    }
                    value = new Value(baseType, BuildExtractValue(Builder, value.LLVMValue, 0, name));
                }while (value.ValueType.BaseType != null);
                CurrentBlock.Push(value);
            }
        }
Exemple #2
0
        /// <summary>
        /// Loads the length of an array.
        /// </summary>
        private void LoadArrayLength()
        {
            var array = CurrentBlock.Pop();

            Debug.Assert(array.ValueType.IsArray);
            CurrentBlock.Push(typeof(int), BuildExtractValue(Builder, array.LLVMValue, 1, "ldlen"));
        }
Exemple #3
0
        /// <summary>
        /// Realizes a new-array instruction.
        /// </summary>
        /// <param name="elementType">The element type of the array.</param>
        private void MakeNewArray(Type elementType)
        {
            var stackValue  = CurrentBlock.Pop();
            var arrayLength = stackValue.LLVMValue;

            if (!IsConstant(arrayLength))
            {
                throw CompilationContext.GetNotSupportedException(ErrorMessages.NotSupportedArrayCreation);
            }

            // Allocate the element data first in a local alloca
            var llvmElementType  = Unit.GetType(elementType);
            var arrayLengthValue = (int)ConstIntGetZExtValue(arrayLength);

            var llvmAllocaArrayType = ArrayType(llvmElementType, arrayLengthValue);
            var arrayData           = CreateTempAlloca(llvmAllocaArrayType);

            BuildStore(Builder, ConstNull(llvmAllocaArrayType), arrayData);

            // Array<T> = (T*, int32)
            var arrayType         = elementType.MakeArrayType();
            var llvmArrayType     = Unit.GetType(arrayType);
            var initialArrayValue = GetUndef(llvmArrayType);
            // Setup T*: (T*, undef)
            var basePtr          = BuildPointerCast(Builder, arrayData, PointerType(llvmElementType), string.Empty);
            var arrayWithPointer = BuildInsertValue(Builder, initialArrayValue, basePtr, 0, string.Empty);
            // Setup length: (T*, int32)
            var array = BuildInsertValue(Builder, arrayWithPointer, arrayLength, 1, string.Empty);

            // Push the final array value
            CurrentBlock.Push(arrayType, array);
        }
Exemple #4
0
        /// <summary>
        /// Loads a value of the given type from an unsafe memory address.
        /// </summary>
        /// <param name="type">The type of the value to load.</param>
        private void LoadIndirect(Type type)
        {
            var address = CurrentBlock.Pop(type.MakePointerType());
            var load    = BuildLoad(Builder, address.LLVMValue, "ldind");

            CurrentBlock.Push(type, load);
        }
Exemple #5
0
        /// <summary>
        /// Stores a value to an unsafe address.
        /// </summary>
        /// <param name="type">The type of the value to store.</param>
        private void StoreIndirect(Type type)
        {
            var value   = CurrentBlock.Pop(type);
            var address = CurrentBlock.Pop(type.MakePointerType());

            BuildStore(Builder, value.LLVMValue, address.LLVMValue);
        }
Exemple #6
0
        /// <summary>
        /// Realizes an indirect load instruction.
        /// </summary>
        /// <param name="type">The target type.</param>
        private void MakeLoadObject(Type type)
        {
            var address = CurrentBlock.Pop();

            address = CreateConversion(address, type.MakePointerType());
            CurrentBlock.Push(type, BuildLoad(Builder, address.LLVMValue, string.Empty));
        }
Exemple #7
0
        /// <summary>
        /// Stores a value to a field.
        /// </summary>
        /// <param name="field">The field.</param>
        private void StoreField(FieldInfo field)
        {
            var value        = CurrentBlock.Pop(field.FieldType);
            var fieldValue   = CurrentBlock.Pop();
            var fieldAddress = LoadFieldAddress(field, fieldValue);

            BuildStore(Builder, value.LLVMValue, fieldAddress);
        }
Exemple #8
0
        /// <summary>
        /// Realizes an indirect store instruction.
        /// </summary>
        /// <param name="type">The target type.</param>
        private void MakeStoreObject(Type type)
        {
            var value   = CurrentBlock.Pop(type);
            var address = CurrentBlock.Pop();

            address = CreateConversion(address, type.MakePointerType());
            BuildStore(Builder, value.LLVMValue, address.LLVMValue);
        }
Exemple #9
0
        /// <summary>
        /// Stores a value to a static field.
        /// </summary>
        /// <param name="field">The field.</param>
        private void StoreStaticField(FieldInfo field)
        {
            VerifyStaticFieldStore(CompilationContext, Unit.Flags, field);

            // Consume the current value from the stack but do not emit a global store,
            // since we dont have any valid target address.
            // TODO: Stores to static fields could be automatically propagated to the .Net
            // runtime after kernel invocation. However, this remains as a future feature.
            CurrentBlock.Pop();
        }
Exemple #10
0
        /// <summary>
        /// Realizes an un-boxing operation that unboxes a previously boxed value.
        /// </summary>
        /// <param name="type">The target type.</param>
        private void MakeUnbox(Type type)
        {
            var value = CurrentBlock.Pop();

            if (!value.ValueType.IsPointer || !type.IsValueType)
            {
                throw CompilationContext.GetInvalidILCodeException();
            }
            throw CompilationContext.GetNotSupportedException(ErrorMessages.NotSupportedUnboxing);
        }
Exemple #11
0
        /// <summary>
        /// Loads the address of an array element.
        /// </summary>
        private void LoadArrayElementAddress()
        {
            var idx   = CurrentBlock.PopInt();
            var array = CurrentBlock.Pop();

            Debug.Assert(array.ValueType.IsArray);
            var addr = ComputeArrayAddress(array.LLVMValue, idx.LLVMValue);

            CurrentBlock.Push(array.ValueType.GetElementType().MakePointerType(), addr);
        }
Exemple #12
0
        /// <summary>
        /// Loads an array element.
        /// </summary>
        /// <param name="type">The type of element to load.</param>
        private void LoadArrayElement(Type type)
        {
            var idx   = CurrentBlock.PopInt();
            var array = CurrentBlock.Pop();

            Debug.Assert(array.ValueType.IsArray);
            var addr  = ComputeArrayAddress(array.LLVMValue, idx.LLVMValue);
            var value = BuildLoad(Builder, addr, string.Empty);

            CurrentBlock.Push(CreateConversion(new Value(array.ValueType.GetElementType(), value), type));
        }
Exemple #13
0
        /// <summary>
        /// Stores an array element of the specified type.
        /// </summary>
        /// <param name="type">The target type.</param>
        private void StoreArrayElement(Type type)
        {
            var value = CurrentBlock.Pop(type);
            var idx   = CurrentBlock.PopInt();
            var array = CurrentBlock.Pop();

            Debug.Assert(array.ValueType.IsArray);
            var addr = ComputeArrayAddress(array.LLVMValue, idx.LLVMValue);

            BuildStore(Builder, value.LLVMValue, addr);
        }
Exemple #14
0
 /// <summary>
 /// Realizes a return instruction.
 /// </summary>
 private void MakeReturn()
 {
     if (Method.IsVoid)
     {
         BuildRetVoid(Builder);
     }
     else
     {
         var returnValue = CurrentBlock.Pop(Method.ReturnType);
         BuildRet(Builder, returnValue.LLVMValue);
     }
 }
Exemple #15
0
        /// <summary>
        /// Realizes a managed-object initialization.
        /// </summary>
        /// <param name="type">The target type.</param>
        private void MakeInitObject(Type type)
        {
            if (type == null)
            {
                throw CompilationContext.GetInvalidILCodeException();
            }

            var address = CurrentBlock.Pop();

            var llvmType = Unit.GetType(type);

            BuildStore(Builder, ConstNull(llvmType), address.LLVMValue);
        }
Exemple #16
0
        /// <summary>
        /// Realizes a numeric-neg instruction.
        /// </summary>
        private void MakeNumericNeg()
        {
            var value = CurrentBlock.Pop();
            var name  = string.Empty;

            if (value.ValueType.IsFloat())
            {
                CurrentBlock.Push(value.ValueType, BuildFNeg(Builder, value.LLVMValue, name));
            }
            else
            {
                CurrentBlock.Push(value.ValueType, BuildNeg(Builder, value.LLVMValue, name));
            }
        }
Exemple #17
0
        /// <summary>
        /// Stores a value to the argument with index idx.
        /// </summary>
        /// <param name="var">The variable reference.</param>
        private void StoreVariable(VariableRef var)
        {
            Debug.Assert(var.RefType == VariableRefType.Argument || var.RefType == VariableRefType.Local);
            var variableType = variableTypes[var];
            var value        = CurrentBlock.Pop(variableType);

            if (variables.TryGetValue(var, out Value nonSSAValue))
            {
                BuildStore(Builder, value.LLVMValue, nonSSAValue.LLVMValue);
            }
            else
            {
                CurrentBlock.SetValue(var, value);
            }
        }
Exemple #18
0
        /// <summary>
        /// Realizes a local stackalloc instruction.
        /// </summary>
        private void MakeLocalAlloc()
        {
            var size        = CurrentBlock.Pop();
            var arrayLength = size.LLVMValue;

            if (!IsConstant(arrayLength))
            {
                throw CompilationContext.GetNotSupportedException(
                          ErrorMessages.NotSupportedUnsafeAllocation);
            }
            // Allocate the element data first in a local alloca
            var llvmElementType = LLVMContext.Int8Type;
            var arrayData       = BuildArrayAlloca(Builder, llvmElementType, arrayLength, "localloc");

            CurrentBlock.Push(typeof(byte).MakePointerType(), arrayData);
        }
Exemple #19
0
        /// <summary>
        /// Realizes a numeric-not instruction.
        /// </summary>
        private void MakeNumericNot()
        {
            var value = CurrentBlock.Pop();

            CurrentBlock.Push(value.ValueType, BuildNot(Builder, value.LLVMValue, string.Empty));
        }
Exemple #20
0
        /// <summary>
        /// Realizes a cast operation that casts a given class to another type.
        /// </summary>
        /// <param name="targetType">The target type.</param>
        private void MakeCastClass(Type targetType)
        {
            var value = CurrentBlock.Pop();

            CurrentBlock.Push(CreateCastClass(value, targetType));
        }
Exemple #21
0
        /// <summary>
        /// Realizes a convert instruction.
        /// </summary>
        /// <param name="targetType">The target type.</param>
        /// <param name="forceUnsigned">True, if the comparison should be forced to be unsigned.</param>
        private void MakeConvert(Type targetType, bool forceUnsigned = false)
        {
            var value = CurrentBlock.Pop();

            CurrentBlock.Push(CreateConversion(value, targetType, forceUnsigned));
        }
Exemple #22
0
        /// <summary>
        /// Loads the address of a field specified by the given metadata token.
        /// </summary>
        /// <param name="field">The field.</param>
        private void LoadFieldAddress(FieldInfo field)
        {
            var value = CurrentBlock.Pop();

            CurrentBlock.Push(field.FieldType.MakePointerType(), LoadFieldAddress(field, value));
        }