public void Dispose()
        {
            if (Inputs.IsCreated)
            {
                Inputs.Dispose();
            }

            if (Outputs.IsCreated)
            {
                Outputs.Dispose();
            }

            if (OutputBufferOffsets.IsCreated)
            {
                OutputBufferOffsets.Dispose();
            }
        }
        GenerateDataPortDeclarations(Type definitionType, Type kernelPortType)
        {
            // Offset from the start of the field of the data port to the pointer. A bit of a hack.
            const int k_PtrOffset = 0;

            var inputs              = new BlitList <InputDeclaration>(0);
            var outputs             = new BlitList <OutputDeclaration>(0);
            var outputBufferOffsets = new BlitList <BufferOffset>(0);

            try
            {
                var kernelPortValue = definitionType.GetField("s_KernelPorts", BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null);

                foreach (var potentialPortFieldInfo in kernelPortType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static))
                {
                    ValidateFieldOnKernelPort(potentialPortFieldInfo);

                    var portType = potentialPortFieldInfo.FieldType;

                    if (!portType.IsConstructedGenericType)
                    {
                        throw new InvalidNodeDefinitionException($"Simulation port definition contains disallowed field {portType}.");
                    }

                    // Acquire the assigned port number of this port declaration
                    var assignedPortNumberField = portType.GetField("Port", BindingFlags.Instance | BindingFlags.NonPublic);

                    var genericPortType = portType.GetGenericTypeDefinition();

                    var genericsForDeclaration = portType.GetGenericArguments();

                    bool isPortArray = genericPortType == typeof(PortArray <>);
                    if (isPortArray)
                    {
                        // Extract the specifics of the port type inside the port array.
                        portType = genericsForDeclaration[0];
                        if (!portType.IsConstructedGenericType)
                        {
                            throw new InvalidNodeDefinitionException($"Simulation port definition contains disallowed field {portType}.");
                        }
                        genericPortType        = portType.GetGenericTypeDefinition();
                        genericsForDeclaration = portType.GetGenericArguments();
                    }

                    if (genericsForDeclaration.Length < 2)
                    {
                        throw new InvalidNodeDefinitionException($"Simulation port definition contains disallowed type {portType}.");
                    }

                    var dataType = genericsForDeclaration[1];

                    ValidateDataPortType(potentialPortFieldInfo, dataType);

                    var offsetOfWholePortDeclaration = UnsafeUtility.GetFieldOffset(potentialPortFieldInfo);

                    var portValue = potentialPortFieldInfo.GetValue(kernelPortValue);

                    if (genericPortType == typeof(DataInput <,>))
                    {
                        if (UnsafeUtility.SizeOf(dataType) > k_MaxInputSize)
                        {
                            throw new InvalidNodeDefinitionException($"Node input data structure types cannot have a sizeof larger than {k_MaxInputSize}");
                        }

                        inputs.Add(
                            new InputDeclaration(
                                new SimpleType(dataType),
                                offsetOfWholePortDeclaration + k_PtrOffset,
                                (InputPortID)assignedPortNumberField.GetValue(portValue),
                                isPortArray
                                )
                            );
                    }
                    else if (genericPortType == typeof(DataOutput <,>))
                    {
                        SimpleType type;

                        if (IsBufferDefinition(dataType))
                        {
                            // Compute the simple type of an element inside a buffer if possible
                            type = new SimpleType(dataType.GetGenericArguments()[0]);
                            outputBufferOffsets.Add(new BufferOffset(offsetOfWholePortDeclaration));
                        }
                        else
                        {
                            // otherwise the entire value (breaks for aggregates)
                            type = new SimpleType(dataType);

                            foreach (var field in WalkTypeInstanceFields(dataType, BindingFlags.Public, IsBufferDefinition))
                            {
                                outputBufferOffsets.Add(new BufferOffset(offsetOfWholePortDeclaration + UnsafeUtility.GetFieldOffset(field)));
                            }
                        }

                        outputs.Add(
                            new OutputDeclaration(
                                type,
                                offsetOfWholePortDeclaration + k_PtrOffset,
                                (OutputPortID)assignedPortNumberField.GetValue(portValue)
                                )
                            );
                    }
                    else
                    {
                        throw new InvalidNodeDefinitionException($"Kernel port definition {kernelPortType} contains other types of fields than DataInput<> and DataOutput<> ({portType})");
                    }
                }
            }
            catch
            {
                inputs.Dispose();
                outputs.Dispose();
                outputBufferOffsets.Dispose();
                throw;
            }
            return(inputs, outputs, outputBufferOffsets);
        }
 public void Dispose()
 {
     Inputs.Dispose();
     Outputs.Dispose();
     JITPorts.Dispose();
 }