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; }
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)); }
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)); }
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; }
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); }
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)); }
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)); }
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)); }
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); }
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); }
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(); }
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)); }
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)); }
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); }