private static void EmitFixedArrayAsNativeArrayIL(ILState state) { // char name[64] -> NativeArray<byte> name // float co[3] -> NativeArray<float> position var il = state.Generator; var field = state.FieldInfo; // Extract type N from `NativeArray<N>` var type = field.FieldType.GetGenericArguments()[0]; var arrayEntity = state.RNA.FindEntityForType(type); var constantArraySize = state.Field.Count; // local.x = Factory.CreateNativeArray<N>(rna, ctype, count, ptr + offset); il.Emit(OpCodes.Ldloca_S, state.Local); // RNA responsible for conversion il.Emit(OpCodes.Ldarg_1); // The entity type to convert il.Emit(OpCodes.Ldstr, arrayEntity?.CType ?? ""); // Number of elements in the array il.Emit(OpCodes.Ldc_I4, constantArraySize); // Pointer stored at offset to convert il.Emit(OpCodes.Ldarg_0); // Load source pointer onto stack il.Emit(OpCodes.Ldc_I4, state.Field.Offset); // Push read field offset onto stack il.Emit(OpCodes.Add); // Add offset to pointer il.Emit(OpCodes.Call, typeof(NativeArrayConverter).GetMethod("Create").MakeGenericMethod(type)); il.Emit(OpCodes.Stfld, field); // Store retval in local field }
public void GenerateIL(ILState state) { // char name[64]; -> string name; var il = state.Generator; var field = state.FieldInfo; throw new NotImplementedException(); }
private static void EmitPointerAsNativeArrayIL(ILState state) { // char* name -> NativeArray<byte> name // MVert* verts -> NativeArray<Vertex> vertices var il = state.Generator; var field = state.FieldInfo; // Extract type N from `NativeArray<N>` var type = field.FieldType.GetGenericArguments()[0]; var arrayEntity = state.RNA.FindEntityForType(type); var arraySizeLocal = il.DeclareLocal(typeof(int)); if (!string.IsNullOrEmpty(state.DNAInfo.SizeField)) { var sizeField = state.Entity.Fields[state.DNAInfo.SizeField]; // Sanity check - ensure it's int-like. if (sizeField.CType != "int") { // TODO: Friendly errors // TODO: Might have uints? If so, we need a different opcode to load and local type. throw new Exception("Expected int SizeField"); } // Add opcodes to extract the element count from another field in the struct. // arraySizeLocal = *(int*)(ptr + sizeFieldOffset) il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldc_I4, sizeField.Offset); il.Emit(OpCodes.Add); il.Emit(OpCodes.Ldind_I4); il.Emit(OpCodes.Stloc, arraySizeLocal); } // local.x = Factory.CreateNativeArray<N>(rna, ctype, count, ptr + offset); il.Emit(OpCodes.Ldloca_S, state.Local); // RNA responsible for conversion il.Emit(OpCodes.Ldarg_1); // The entity type to convert il.Emit(OpCodes.Ldstr, arrayEntity?.CType ?? ""); // Number of elements in the array il.Emit(OpCodes.Ldloc, arraySizeLocal); // Pointer stored at offset to convert il.Emit(OpCodes.Ldarg_0); // Load source pointer onto stack il.Emit(OpCodes.Ldc_I4, state.Field.Offset); // Push read field offset onto stack il.Emit(OpCodes.Add); // Add offset to pointer il.Emit(OpCodes.Ldind_I8); // Replace value as a pointer to the start of the array and push back il.Emit(OpCodes.Call, typeof(NativeArrayConverter).GetMethod("Create").MakeGenericMethod(type)); il.Emit(OpCodes.Stfld, field); // Store retval in local field }
public void GenerateIL(ILState state) { if (state.Field.Type == EntityType.Array) { EmitFixedArrayAsNativeArrayIL(state); } else if (state.Field.Type == EntityType.Pointer) { EmitPointerAsNativeArrayIL(state); } else { throw new Exception( $"Cannot represent a primitive/struct [{state.Field.CType}] as NativeArray" ); } }
public void GenerateIL(ILState state) { if (state.Field.Type != EntityType.Pointer) { throw new Exception( $"Cannot represent a [{state.Field.CType}] as NativePointer" ); } // Mesh* mesh -> NativePointer<Mesh> mesh; var il = state.Generator; var field = state.FieldInfo; // Extract type N from `NativeArray<N>` var type = field.FieldType.GetGenericArguments()[0]; var arrayEntity = state.RNA.FindEntityForType(type); if (arrayEntity == null) { throw new Exception( $"Type {type} needs to be [DNA] for use with NativePointer" ); } // local.x = NativePointerConversion.Create<N>(rna, ctype, ptr + offset); il.Emit(OpCodes.Ldloca_S, state.Local); // RNA responsible for conversion il.Emit(OpCodes.Ldarg_1); // The entity type to convert il.Emit(OpCodes.Ldstr, arrayEntity.CType); // Indirect pointer stored at offset to convert il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldc_I4, state.Field.Offset); il.Emit(OpCodes.Add); il.Emit(OpCodes.Ldind_I8); il.Emit(OpCodes.Call, typeof(NativePointerConverter).GetMethod("Create").MakeGenericMethod(type)); il.Emit(OpCodes.Stfld, field); }
public void GenerateIL(ILState state) { throw new NotImplementedException(); }