Beispiel #1
0
        private ValueRef[] BuildStaticFieldIndices(Field field)
        {
            var indices = new[]
            {
                LLVM.ConstInt(int32LLVM, 0, false),                                         // Pointer indirection
                LLVM.ConstInt(int32LLVM, (int)RuntimeTypeInfoFields.StaticFields, false),   // Access static fields
                LLVM.ConstInt(int32LLVM, (ulong)field.StructIndex, false),                  // Access specific static field
            };

            return indices;
        }
Beispiel #2
0
        private void EmitLdsfld(FunctionStack stack, Field field, InstructionFlags instructionFlags)
        {
            var runtimeTypeInfoGlobal = GetClass(field.DeclaringType).GeneratedEETypeRuntimeLLVM;

            // Get static field GEP indices
            var indices = BuildStaticFieldIndices(field);

            // Find static field address in runtime type info
            var staticFieldAddress = LLVM.BuildInBoundsGEP(builder, runtimeTypeInfoGlobal, indices, string.Empty);

            // Load value from field and create "fake" local
            var value = LoadValue(field.Type.StackType, staticFieldAddress, instructionFlags);

            // Convert from local to stack value
            value = ConvertFromLocalToStack(field.Type, value);

            // Add value to stack
            stack.Add(new StackValue(field.Type.StackType, field.Type, value));
        }
Beispiel #3
0
        private void EmitLdsflda(FunctionStack stack, Field field)
        {
            var runtimeTypeInfoGlobal = GetClass(field.DeclaringType).GeneratedEETypeRuntimeLLVM;

            var refType = GetType(field.Type.TypeReferenceCecil.MakeByReferenceType(), TypeState.Opaque);

            // Get static field GEP indices
            var indices = BuildStaticFieldIndices(field);

            // Find static field address in runtime type info
            var staticFieldAddress = LLVM.BuildInBoundsGEP(builder, runtimeTypeInfoGlobal, indices, string.Empty);

            // Add value to stack
            stack.Add(new StackValue(StackValueType.Reference, refType, staticFieldAddress));
        }
Beispiel #4
0
        private ValueRef ComputeFieldAddress(BuilderRef builder, Field field, StackValueType objectStackType, ValueRef objectValue, ref InstructionFlags instructionFlags)
        {
            objectValue = ConvertReferenceToExpectedType(builder, objectStackType, objectValue, field.DeclaringType);
            Type type = field.DeclaringType;

            // Build indices for GEP
            var indices = new List<ValueRef>(3);

            if (objectStackType == StackValueType.Reference || objectStackType == StackValueType.Object || objectStackType == StackValueType.Value || objectStackType == StackValueType.NativeInt)
            {
                // First pointer indirection
                indices.Add(LLVM.ConstInt(int32LLVM, 0, false));
            }

            bool isCustomLayout = IsCustomLayout(type.TypeDefinitionCecil);

            if (objectStackType == StackValueType.Object)
            {
                // Access data
                indices.Add(LLVM.ConstInt(int32LLVM, (int)ObjectFields.Data, false));

                if (!isCustomLayout)
                {
                    // For now, go through hierarchy and check that type match
                    // Other options:
                    // - cast
                    // - store class depth (and just do a substraction)
                    int depth = 0;
                    var @class = GetClass(type);
                    while (@class != null)
                    {
                        if (@class.Type == field.DeclaringType)
                            break;

                        @class = @class.BaseType;
                        depth++;
                    }

                    if (@class == null)
                        throw new InvalidOperationException(string.Format("Could not find field {0} in hierarchy of {1}", field.FieldDefinition, type.TypeReferenceCecil));

                    // Apply GEP indices to find right object (parent is always stored in first element)
                    for (int i = 0; i < depth; ++i)
                        indices.Add(LLVM.ConstInt(int32LLVM, 0, false));
                }
            }

            // Access the appropriate field
            indices.Add(LLVM.ConstInt(int32LLVM, (uint)field.StructIndex, false));

            // Find field address using GEP
            var fieldAddress = LLVM.BuildInBoundsGEP(builder, objectValue, indices.ToArray(), string.Empty);

            // Cast to real field type (if stored in a custom layout array)
            if (isCustomLayout)
            {
                fieldAddress = LLVM.BuildPointerCast(builder, fieldAddress, LLVM.PointerType(field.Type.DefaultTypeLLVM, 0), string.Empty);

                // Check if non aligned
                if (field.StructIndex % 4 != 0)
                    instructionFlags = InstructionFlags.Unaligned;
            }

            return fieldAddress;
        }
Beispiel #5
0
        private void EmitStsfld(FunctionStack stack, Field field, InstructionFlags instructionFlags)
        {
            var value = stack.Pop();

            var runtimeTypeInfoGlobal = GetClass(field.DeclaringType).GeneratedEETypeRuntimeLLVM;

            // Get static field GEP indices
            var indices = BuildStaticFieldIndices(field);

            // Find static field address in runtime type info
            var fieldAddress = LLVM.BuildInBoundsGEP(builder, runtimeTypeInfoGlobal, indices, string.Empty);

            // Convert stack value to appropriate type
            var fieldValue = ConvertFromStackToLocal(field.Type, value);

            // Store value in static field
            StoreValue(field.Type.StackType, fieldValue, fieldAddress, instructionFlags);
        }
Beispiel #6
0
        private void EmitLdfld(FunctionStack stack, Field field, InstructionFlags instructionFlags)
        {
            var @object = stack.Pop();

            // Compute field address
            var fieldAddress = ComputeFieldAddress(builder, field, @object.StackType, @object.Value, ref instructionFlags);

            // Load value from field and create "fake" local
            var value = LoadValue(field.Type.StackType, fieldAddress, instructionFlags);

            // Convert from local to stack value
            value = ConvertFromLocalToStack(field.Type, value);

            // Add value to stack
            stack.Add(new StackValue(field.Type.StackType, field.Type, value));
        }
Beispiel #7
0
        private void EmitLdflda(FunctionStack stack, Field field)
        {
            var @object = stack.Pop();

            var refType = GetType(field.Type.TypeReferenceCecil.MakeByReferenceType(), TypeState.Opaque);

            // Compute field address
            var instructionFlags = InstructionFlags.None;
            var fieldAddress = ComputeFieldAddress(builder, field, @object.StackType, @object.Value, ref instructionFlags);

            // Add value to stack
            stack.Add(new StackValue(StackValueType.Reference, refType, fieldAddress));
        }
Beispiel #8
0
        private void EmitLdsflda(List<StackValue> stack, Field field)
        {
            var runtimeTypeInfoGlobal = field.DeclaringClass.GeneratedRuntimeTypeInfoGlobal;

            var refType = GetType(field.Type.TypeReference.MakeByReferenceType());

            // Get static field GEP indices
            var indices = BuildStaticFieldIndices(field);

            // Find static field address in runtime type info
            var staticFieldAddress = LLVM.BuildInBoundsGEP(builder, runtimeTypeInfoGlobal, indices, string.Empty);

            // Add value to stack
            stack.Add(new StackValue(StackValueType.Reference, refType, staticFieldAddress));
        }
Beispiel #9
0
        private void EmitStfld(FunctionStack stack, Field field, InstructionFlags instructionFlags)
        {
            var value = stack.Pop();
            var @object = stack.Pop();

            // Compute field address
            var fieldAddress = ComputeFieldAddress(builder, field, @object.StackType, @object.Value, ref instructionFlags);

            // Convert stack value to appropriate type
            var fieldValue = ConvertFromStackToLocal(field.Type, value);

            // Store value in field
            StoreValue(field.Type.StackType, fieldValue, fieldAddress, instructionFlags);
        }
Beispiel #10
0
        private void EmitStsfld(List<StackValue> stack, Field field, InstructionFlags instructionFlags)
        {
            var value = stack.Pop();

            var runtimeTypeInfoGlobal = field.DeclaringClass.GeneratedRuntimeTypeInfoGlobal;

            // Get static field GEP indices
            var indices = BuildStaticFieldIndices(field);

            // Find static field address in runtime type info
            var staticFieldAddress = LLVM.BuildInBoundsGEP(builder, runtimeTypeInfoGlobal, indices, string.Empty);

            // Convert stack value to appropriate type
            var fieldValue = ConvertFromStackToLocal(field.Type, value);

            // Store value in static field
            var storeInst = LLVM.BuildStore(builder, fieldValue, staticFieldAddress);

            // Set instruction flags
            SetInstructionFlags(storeInst, instructionFlags);
        }
Beispiel #11
0
        private ValueRef[] BuildFieldIndices(Field field, StackValueType stackValueType, Type type)
        {
            // Build indices for GEP
            var indices = new List<ValueRef>(3);

            if (stackValueType == StackValueType.Reference || stackValueType == StackValueType.Object || stackValueType == StackValueType.NativeInt)
            {
                // First pointer indirection
                indices.Add(LLVM.ConstInt(int32Type, 0, false));
            }

            if (stackValueType == StackValueType.Object)
            {
                // Access data
                indices.Add(LLVM.ConstInt(int32Type, (int)ObjectFields.Data, false));

                // For now, go through hierarchy and check that type match
                // Other options:
                // - cast
                // - store class depth (and just do a substraction)
                int depth = 0;
                var @class = GetClass(type);
                while (@class != null)
                {
                    if (@class == field.DeclaringClass)
                        break;

                    @class = @class.BaseType;
                    depth++;
                }

                if (@class == null)
                    throw new InvalidOperationException(string.Format("Could not find field {0} in hierarchy of {1}", field.FieldDefinition, type.TypeReference));

                // Apply GEP indices to find right object (parent is always stored in first element)
                for (int i = 0; i < depth; ++i)
                    indices.Add(LLVM.ConstInt(int32Type, 0, false));
            }

            // Access the appropriate field
            indices.Add(LLVM.ConstInt(int32Type, (uint)field.StructIndex, false));
            return indices.ToArray();
        }
Beispiel #12
0
        private void EmitLdflda(List<StackValue> stack, Field field)
        {
            var @object = stack.Pop();

            var refType = GetType(field.Type.TypeReference.MakeByReferenceType());

            // Build indices for GEP
            var indices = BuildFieldIndices(field, @object.StackType, @object.Type);

            // Find field address using GEP
            var fieldAddress = LLVM.BuildInBoundsGEP(builder, @object.Value, indices, string.Empty);

            // Add value to stack
            stack.Add(new StackValue(StackValueType.Reference, refType, fieldAddress));
        }
Beispiel #13
0
        private void EmitLdfld(List<StackValue> stack, Field field, InstructionFlags instructionFlags)
        {
            var @object = stack.Pop();

            ValueRef value;
            if (@object.StackType == StackValueType.Value)
            {
                value = LLVM.BuildExtractValue(builder, @object.Value, (uint)field.StructIndex, string.Empty);
            }
            else
            {
                var objectValue = ConvertReferenceToExpectedType(@object, field.DeclaringClass.Type);

                // Build indices for GEP
                var indices = BuildFieldIndices(field, @object.StackType, field.DeclaringClass.Type);

                // Find field address using GEP
                var fieldAddress = LLVM.BuildInBoundsGEP(builder, objectValue, indices, string.Empty);

                // Load value from field and create "fake" local
                value = LLVM.BuildLoad(builder, fieldAddress, string.Empty);

                // Set instruction flags
                SetInstructionFlags(value, instructionFlags);
            }

            // Convert from local to stack value
            value = ConvertFromLocalToStack(field.Type, value);

            // Add value to stack
            stack.Add(new StackValue(field.Type.StackType, field.Type, value));
        }
Beispiel #14
0
        private void EmitStfld(List<StackValue> stack, Field field, InstructionFlags instructionFlags)
        {
            var value = stack.Pop();
            var @object = stack.Pop();

            var objectValue = ConvertReferenceToExpectedType(@object, field.DeclaringClass.Type);

            // Build indices for GEP
            var indices = BuildFieldIndices(field, @object.StackType, field.DeclaringClass.Type);

            // Find field address using GEP
            var fieldAddress = LLVM.BuildInBoundsGEP(builder, objectValue, indices, string.Empty);

            // Convert stack value to appropriate type
            var fieldValue = ConvertFromStackToLocal(field.Type, value);

            // Store value in field
            var storeInst = LLVM.BuildStore(builder, fieldValue, fieldAddress);

            // Set instruction flags
            SetInstructionFlags(storeInst, instructionFlags);
        }