예제 #1
0
        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
        }
예제 #2
0
        public void GenerateIL(ILState state)
        {
            // char name[64]; -> string name;
            var il    = state.Generator;
            var field = state.FieldInfo;

            throw new NotImplementedException();
        }
예제 #3
0
        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
        }
예제 #4
0
 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"
                   );
     }
 }
예제 #5
0
        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);
        }
예제 #6
0
 public void GenerateIL(ILState state)
 {
     throw new NotImplementedException();
 }