示例#1
0
static dl_error_t dl_internal_load_type_library_defaults(dl_ctx_t dl_ctx, unsigned int first_new_type, const uint8* default_data, unsigned int default_data_size)
{
	if( default_data_size == 0 ) return DL_ERROR_OK;

	if( dl_ctx->default_data != 0x0 )
		return DL_ERROR_OUT_OF_DEFAULT_VALUE_SLOTS;

	dl_ctx->default_data = (uint8*)dl_ctx->alloc_func( default_data_size * 2, sizeof(void*), dl_ctx->alloc_ctx ); // TODO: times 2 here need to be fixed!

	uint8* dst = dl_ctx->default_data;

	// ptr-patch and convert to native
	for( unsigned int type_index = first_new_type; type_index < dl_ctx->type_count; ++type_index )
	{
		union
		{
			const uint8*   data_ptr;
			const SDLType* type_ptr;
		} ptr_conv;
		ptr_conv.data_ptr = dl_ctx->type_info_data + dl_ctx->type_lookup[type_index].offset;

		for( unsigned int member_index = 0; member_index < ptr_conv.type_ptr->member_count; ++member_index )
		{
			SDLMember* member = (SDLMember*)ptr_conv.type_ptr->members + member_index;
			if( member->default_value_offset == DL_UINT32_MAX )
				continue;

			dst                          = dl_internal_align_up( dst, member->alignment[DL_PTR_SIZE_HOST] );
			uint8* src                   = (uint8*)default_data + member->default_value_offset;
			pint base_offset             = pint( dst ) - pint( dl_ctx->default_data );
			member->default_value_offset = uint32( base_offset );

			dl_one_member_type dummy( member );
			size_t needed_size;

			union
			{
				dl_one_member_type* one_mem_ptr;
				SDLType*        type_ptr;
			} conv;
			conv.one_mem_ptr = &dummy;

			dl_internal_convert_no_header( dl_ctx,
										   src, (unsigned char*)default_data,
										   dst, 1337, // need to check this size ;) Should be the remainder of space in m_pDefaultInstances.
										   &needed_size,
										   DL_ENDIAN_LITTLE,  DL_ENDIAN_HOST,
										   DL_PTR_SIZE_32BIT, DL_PTR_SIZE_HOST,
										   conv.type_ptr, base_offset );

			SPatchedInstances patch_instances;
			dl_internal_patch_loaded_ptrs( dl_ctx, &patch_instances, dst, conv.type_ptr, dl_ctx->default_data, false );

			dst += needed_size;
		}
	}

	return DL_ERROR_OK;
}
示例#2
0
void dl_internal_patch_struct_array( dl_ctx_t            ctx,
									 const dl_type_desc* type,
									 uint8_t*            array_data,
									 uint32_t            count,
									 uintptr_t           patch_distance,
									 uintptr_t           base_address,
									 dl_patched_ptrs*    patched_ptrs )
{
	uint32_t size = dl_internal_align_up( type->size[DL_PTR_SIZE_HOST], type->alignment[DL_PTR_SIZE_HOST] );
	for( uint32_t index = 0; index < count; ++index )
	{
		uint8_t* struct_data = array_data + index * size;
		dl_internal_patch_struct( ctx, type, struct_data, base_address, patch_distance, patched_ptrs );
	}
}
static void dl_load_txt_calc_type_size_and_align( dl_ctx_t ctx, dl_txt_read_ctx* read_state, dl_type_desc* type )
{
	// ... is the type already processed ...
	if( type->size[0] > 0 )
		return;

	dl_load_txt_fixup_bitfield_members( ctx, type );

	uint32_t size[2]  = { 0, 0 };
	uint32_t align[2] = { type->alignment[DL_PTR_SIZE_32BIT], type->alignment[DL_PTR_SIZE_64BIT] };

	unsigned int mem_start = type->member_start;
	unsigned int mem_end   = type->member_start + type->member_count;

	dl_member_desc* bitfield_group_start = 0x0;

	for( unsigned int member_index = mem_start; member_index < mem_end; ++member_index )
	{
		dl_member_desc* member = ctx->member_descs + member_index;

		// If a member is marked as a struct it could also have been an enum that we didn't know about parse-time, patch it in that case.
		if( member->StorageType() == DL_TYPE_STORAGE_STRUCT )
		{
			if( const dl_enum_desc* edesc = dl_internal_find_enum( ctx, member->type_id ) )
				member->set_storage( edesc->storage );
		}

		dl_type_atom_t    atom    = member->AtomType();
		dl_type_storage_t storage = member->StorageType();

		switch( atom )
		{
			case DL_TYPE_ATOM_POD:
			case DL_TYPE_ATOM_INLINE_ARRAY:
			{
				if( atom == DL_TYPE_ATOM_INLINE_ARRAY )
				{
					if( member->inline_array_cnt() == 0 )
					{
						const char* enum_value_name = 0x0;
						uint32_t enum_value_name_len = 0;
						if( sizeof(void*) == 8 )
						{
							enum_value_name = (const char*)( ( (uint64_t)member->size[0] ) | (uint64_t)member->size[1] << 32 );
							enum_value_name_len = member->alignment[0];
						}
						else
						{
							enum_value_name = (const char*)(uint64_t)member->size[0];
							enum_value_name_len = member->alignment[0];
						}

						uint64_t val;
						if( !dl_internal_find_enum_value_from_name( ctx, enum_value_name, (size_t)enum_value_name_len, &val ) )
							dl_txt_read_failed( ctx, read_state, DL_ERROR_TXT_INVALID_ENUM_VALUE, "%s.%s is an inline array with size %.*s, but that enum value does not exist.",
												dl_internal_type_name( ctx, type ),
												dl_internal_member_name( ctx, member ),
												(int)enum_value_name_len,
												enum_value_name );

						member->set_inline_array_cnt( (uint32_t)val );
					}
				}

				if( storage == DL_TYPE_STORAGE_STRUCT )
				{
					const dl_type_desc* sub_type = dl_internal_find_type( ctx, member->type_id );
					if( sub_type == 0x0 )
						continue;

					dl_load_txt_calc_type_size_and_align( ctx, read_state, (dl_type_desc*)sub_type );
					member->copy_size( sub_type->size );
					member->copy_align( sub_type->alignment );
				}
				else
					dl_set_member_size_and_align_from_builtin( storage, member );

				if( atom == DL_TYPE_ATOM_INLINE_ARRAY )
				{
					member->size[DL_PTR_SIZE_32BIT] *= member->inline_array_cnt();
					member->size[DL_PTR_SIZE_64BIT] *= member->inline_array_cnt();
				}

				bitfield_group_start = 0x0;
			}
			break;
			case DL_TYPE_ATOM_ARRAY:
			{
				member->set_size( 8, 16 );
				member->set_align( 4, 8 );
			}
			break;
			case DL_TYPE_ATOM_BITFIELD:
			{
				if( bitfield_group_start )
				{
					member->offset[DL_PTR_SIZE_32BIT] = bitfield_group_start->offset[DL_PTR_SIZE_32BIT];
					member->offset[DL_PTR_SIZE_64BIT] = bitfield_group_start->offset[DL_PTR_SIZE_64BIT];
					continue;
				}
				bitfield_group_start = member;
			}
			break;
			default:
				bitfield_group_start = 0x0;
		}

		if( type->flags & DL_TYPE_FLAG_IS_UNION )
		{
			member->set_offset( 0, 0 );
			size[DL_PTR_SIZE_32BIT] = member->size[DL_PTR_SIZE_32BIT] > size[DL_PTR_SIZE_32BIT] ? member->size[DL_PTR_SIZE_32BIT] : size[DL_PTR_SIZE_32BIT];
			size[DL_PTR_SIZE_64BIT] = member->size[DL_PTR_SIZE_64BIT] > size[DL_PTR_SIZE_64BIT] ? member->size[DL_PTR_SIZE_64BIT] : size[DL_PTR_SIZE_64BIT];
		}
		else
		{
			member->offset[DL_PTR_SIZE_32BIT] = dl_internal_align_up( size[DL_PTR_SIZE_32BIT], member->alignment[DL_PTR_SIZE_32BIT] );
			member->offset[DL_PTR_SIZE_64BIT] = dl_internal_align_up( size[DL_PTR_SIZE_64BIT], member->alignment[DL_PTR_SIZE_64BIT] );
			size[DL_PTR_SIZE_32BIT] = member->offset[DL_PTR_SIZE_32BIT] + member->size[DL_PTR_SIZE_32BIT];
			size[DL_PTR_SIZE_64BIT] = member->offset[DL_PTR_SIZE_64BIT] + member->size[DL_PTR_SIZE_64BIT];
		}

		align[DL_PTR_SIZE_32BIT] = member->alignment[DL_PTR_SIZE_32BIT] > align[DL_PTR_SIZE_32BIT] ? member->alignment[DL_PTR_SIZE_32BIT] : align[DL_PTR_SIZE_32BIT];
		align[DL_PTR_SIZE_64BIT] = member->alignment[DL_PTR_SIZE_64BIT] > align[DL_PTR_SIZE_64BIT] ? member->alignment[DL_PTR_SIZE_64BIT] : align[DL_PTR_SIZE_64BIT];
	}

	if( type->flags & DL_TYPE_FLAG_IS_UNION )
	{
		// ... add size for the union type flag ...
		size[DL_PTR_SIZE_32BIT] = dl_internal_align_up( size[DL_PTR_SIZE_32BIT], align[DL_PTR_SIZE_32BIT] ) + (uint32_t)sizeof(uint32_t);
		size[DL_PTR_SIZE_64BIT] = dl_internal_align_up( size[DL_PTR_SIZE_64BIT], align[DL_PTR_SIZE_64BIT] ) + (uint32_t)sizeof(uint32_t);
	}

	type->size[DL_PTR_SIZE_32BIT] = dl_internal_align_up( size[DL_PTR_SIZE_32BIT], align[DL_PTR_SIZE_32BIT] );
	type->size[DL_PTR_SIZE_64BIT] = dl_internal_align_up( size[DL_PTR_SIZE_64BIT], align[DL_PTR_SIZE_64BIT] );
	type->alignment[DL_PTR_SIZE_32BIT] = align[DL_PTR_SIZE_32BIT];
	type->alignment[DL_PTR_SIZE_64BIT] = align[DL_PTR_SIZE_64BIT];
}
示例#4
0
static dl_error_t dl_internal_store_member( dl_ctx_t dl_ctx, const SDLMember* member, uint8* instance, CDLBinStoreContext* store_ctx )
{
	dl_type_t atom_type    = dl_type_t(member->type & DL_TYPE_ATOM_MASK);
	dl_type_t storage_type = dl_type_t(member->type & DL_TYPE_STORAGE_MASK);

	switch ( atom_type )
	{
		case DL_TYPE_ATOM_POD:
		{
			switch( storage_type )
			{
				case DL_TYPE_STORAGE_STRUCT:
				{
					const SDLType* sub_type = dl_internal_find_type( dl_ctx, member->type_id );
					if( sub_type == 0x0 )
					{
						dl_log_error( dl_ctx, "Could not find subtype for member %s", member->name );
						return DL_ERROR_TYPE_NOT_FOUND;
					}
					dl_internal_instance_store( dl_ctx, sub_type, instance, store_ctx );
				}
				break;
				case DL_TYPE_STORAGE_STR:
					dl_internal_store_string( instance, store_ctx );
					break;
				case DL_TYPE_STORAGE_PTR:
				{
					uint8* data = *(uint8**)instance;
					pint offset = store_ctx->FindWrittenPtr( data );

					if( data == 0x0 ) // Null-pointer, store pint(-1) to signal to patching!
					{
						DL_ASSERT(offset == pint(-1) && "This pointer should not have been found among the written ptrs!");
						// keep the -1 in Offset and store it to ptr.
					}
					else if( offset == pint(-1) ) // has not been written yet!
					{
						pint pos = dl_binary_writer_tell( &store_ctx->writer );
						dl_binary_writer_seek_end( &store_ctx->writer );

						const SDLType* sub_type = dl_internal_find_type( dl_ctx, member->type_id );
						pint size = dl_internal_align_up( sub_type->size[DL_PTR_SIZE_HOST], sub_type->alignment[DL_PTR_SIZE_HOST] );
						dl_binary_writer_align( &store_ctx->writer, sub_type->alignment[DL_PTR_SIZE_HOST] );

						offset = dl_binary_writer_tell( &store_ctx->writer );

						// write data!
						dl_binary_writer_reserve( &store_ctx->writer, size ); // reserve space for ptr so subdata is placed correctly

						store_ctx->AddWrittenPtr(data, offset);

						dl_internal_instance_store(dl_ctx, sub_type, data, store_ctx);

						dl_binary_writer_seek_set( &store_ctx->writer, pos );
					}

					dl_binary_writer_write( &store_ctx->writer, &offset, sizeof(pint) );
				}
				break;
				default: // default is a standard pod-type
					DL_ASSERT( member->IsSimplePod() || storage_type == DL_TYPE_STORAGE_ENUM );
					dl_binary_writer_write( &store_ctx->writer, instance, member->size[DL_PTR_SIZE_HOST] );
					break;
			}
		}
		return DL_ERROR_OK;

		case DL_TYPE_ATOM_INLINE_ARRAY:
		{
			switch( storage_type )
			{
				case DL_TYPE_STORAGE_STRUCT:
					dl_binary_writer_write( &store_ctx->writer, instance, member->size[DL_PTR_SIZE_HOST] ); // TODO: I Guess that this is a bug! Will it fix ptrs well?
					break;
				case DL_TYPE_STORAGE_STR:
				{
					uint32 count = member->size[DL_PTR_SIZE_HOST] / sizeof(char*);

					for( uint32 elem = 0; elem < count; ++elem )
						dl_internal_store_string( instance + (elem * sizeof(char*)), store_ctx );
				}
				break;
				default: // default is a standard pod-type
					DL_ASSERT( member->IsSimplePod() || storage_type == DL_TYPE_STORAGE_ENUM );
					dl_binary_writer_write( &store_ctx->writer, instance, member->size[DL_PTR_SIZE_HOST] );
					break;
			}
		}
		return DL_ERROR_OK;

		case DL_TYPE_ATOM_ARRAY:
		{
			pint size = 0;
			const SDLType* sub_type = 0x0;

			uint8* data_ptr = instance;
			uint32 count    = *(uint32*)( data_ptr + sizeof(void*) );

			pint offset = 0;

			if( count == 0 )
				offset = DL_NULL_PTR_OFFSET[ DL_PTR_SIZE_HOST ];
			else
			{
				pint pos = dl_binary_writer_tell( &store_ctx->writer );
				dl_binary_writer_seek_end( &store_ctx->writer );

				switch(storage_type)
				{
					case DL_TYPE_STORAGE_STRUCT:
						sub_type = dl_internal_find_type( dl_ctx, member->type_id );
						size = dl_internal_align_up( sub_type->size[DL_PTR_SIZE_HOST], sub_type->alignment[DL_PTR_SIZE_HOST] );
						dl_binary_writer_align( &store_ctx->writer, sub_type->alignment[DL_PTR_SIZE_HOST] );
						break;
					case DL_TYPE_STORAGE_STR:
						size = sizeof(void*);
						dl_binary_writer_align( &store_ctx->writer, size );
						break;
					default:
						size = DLPodSize( member->type );
						dl_binary_writer_align( &store_ctx->writer, size );
				}

				offset = dl_binary_writer_tell( &store_ctx->writer );

				// write data!
				dl_binary_writer_reserve( &store_ctx->writer, count * size ); // reserve space for array so subdata is placed correctly

				uint8* data = *(uint8**)data_ptr;

				switch(storage_type)
				{
					case DL_TYPE_STORAGE_STRUCT:
						for ( unsigned int elem = 0; elem < count; ++elem )
							dl_internal_instance_store( dl_ctx, sub_type, data + (elem * size), store_ctx );
						break;
					case DL_TYPE_STORAGE_STR:
						for ( unsigned int elem = 0; elem < count; ++elem )
							dl_internal_store_string( data + (elem * size), store_ctx );
						break;
					default:
						for ( unsigned int elem = 0; elem < count; ++elem )
							dl_binary_writer_write( &store_ctx->writer, data + (elem * size), size ); break;
				}

				dl_binary_writer_seek_set( &store_ctx->writer, pos );
			}

			// make room for ptr
			dl_binary_writer_write( &store_ctx->writer, &offset, sizeof(pint) );

			// write count
			dl_binary_writer_write( &store_ctx->writer, &count, sizeof(uint32) );
		}
		return DL_ERROR_OK;

		case DL_TYPE_ATOM_BITFIELD:
			dl_binary_writer_write( &store_ctx->writer, instance, member->size[DL_PTR_SIZE_HOST] );
		break;

		default:
			DL_ASSERT(false && "Invalid ATOM-type!");
			break;
	}

	return DL_ERROR_OK;
}
示例#5
0
static dl_error_t dl_internal_patch_loaded_ptrs( dl_ctx_t           dl_ctx,
												 SPatchedInstances* patched_instances,
												 const uint8*       instance,
												 const SDLType*     type,
												 const uint8*       base_data,
												 bool               is_member_struct )
{
	// TODO: Optimize this please, linear search might not be the best if many subinstances is in file!
	if( !is_member_struct )
	{
		if(patched_instances->IsPatched(instance))
			return DL_ERROR_OK;

		patched_instances->m_lpPatched.Add(instance);
	}

	for( uint32 member_index = 0; member_index < type->member_count; ++member_index )
	{
		const SDLMember* member      = type->members + member_index;
		const uint8*     member_data = instance + member->offset[DL_PTR_SIZE_HOST];

		dl_type_t atom_type    = member->AtomType();
		dl_type_t storage_type = member->StorageType();

		switch( atom_type )
		{
			case DL_TYPE_ATOM_POD:
			{
				switch( storage_type )
				{
					case DL_TYPE_STORAGE_STR:
						dl_internal_patch_ptr( member_data, base_data );
						break;
					case DL_TYPE_STORAGE_STRUCT:
						dl_internal_patch_loaded_ptrs( dl_ctx,
													   patched_instances,
													   member_data,
													   dl_internal_find_type( dl_ctx, member->type_id ),
													   base_data,
													   true );
					break;
					case DL_TYPE_STORAGE_PTR:
					{
						uint8** ptr = (uint8**)member_data;
						dl_internal_patch_ptr(member_data, base_data);

						if(*ptr != 0x0)
							dl_internal_patch_loaded_ptrs( dl_ctx,
														   patched_instances,
														   *ptr,
														   dl_internal_find_type( dl_ctx, member->type_id ),
														   base_data,
														   false );
					}
					break;
					default:
						// ignore
						break;
				}
			}
			break;
			case DL_TYPE_ATOM_ARRAY:
			{
				if( storage_type == DL_TYPE_STORAGE_STR || storage_type == DL_TYPE_STORAGE_STRUCT )
				{
					dl_internal_patch_ptr( member_data, base_data );
					const uint8* array_data = *(const uint8**)member_data;

					pint count = *(uint32*)( member_data + sizeof(void*) );

					if( count > 0 )
					{
						if(storage_type == DL_TYPE_STORAGE_STRUCT)
						{
							// patch sub-ptrs!
							const SDLType* sub_type = dl_internal_find_type( dl_ctx, member->type_id );
							pint size = dl_internal_align_up( sub_type->size[DL_PTR_SIZE_HOST], sub_type->alignment[DL_PTR_SIZE_HOST] );

							for( pint elem_offset = 0; elem_offset < count * size; elem_offset += size )
								dl_internal_patch_loaded_ptrs( dl_ctx, patched_instances, array_data + elem_offset, sub_type, base_data, true );
						}
						else
						{
							for( pint elem_offset = 0; elem_offset < count * sizeof(char*); elem_offset += sizeof(char*) )
								dl_internal_patch_ptr( array_data + elem_offset, base_data );
						}
					}
				}
				else // pod
					dl_internal_patch_ptr( member_data, base_data );
			}
			break;

			case DL_TYPE_ATOM_INLINE_ARRAY:
			{
				if( storage_type == DL_TYPE_STORAGE_STR )
				{
					for( pint elem_offset = 0; elem_offset < member->size[DL_PTR_SIZE_HOST]; elem_offset += sizeof(char*) )
						dl_internal_patch_ptr( member_data + elem_offset, base_data );
				}
			}
			break;

			case DL_TYPE_ATOM_BITFIELD:
			// ignore
			break;

		default:
			DL_ASSERT(false && "Unknown atom type");
			break;
		}
	}
	return DL_ERROR_OK;
}
示例#6
0
static dl_error_t dl_internal_store_member( dl_ctx_t dl_ctx, const dl_member_desc* member, uint8_t* instance, CDLBinStoreContext* store_ctx )
{
	dl_type_t atom_type    = dl_type_t(member->type & DL_TYPE_ATOM_MASK);
	dl_type_t storage_type = dl_type_t(member->type & DL_TYPE_STORAGE_MASK);

	switch ( atom_type )
	{
		case DL_TYPE_ATOM_POD:
		{
			switch( storage_type )
			{
				case DL_TYPE_STORAGE_STRUCT:
				{
					const dl_type_desc* sub_type = dl_internal_find_type( dl_ctx, member->type_id );
					if( sub_type == 0x0 )
					{
						dl_log_error( dl_ctx, "Could not find subtype for member %s", dl_internal_member_name( dl_ctx, member ) );
						return DL_ERROR_TYPE_NOT_FOUND;
					}
					dl_internal_instance_store( dl_ctx, sub_type, instance, store_ctx );
				}
				break;
				case DL_TYPE_STORAGE_STR:
					dl_internal_store_string( instance, store_ctx );
					break;
				case DL_TYPE_STORAGE_PTR:
				{
					uint8_t* data = *(uint8_t**)instance;
					uintptr_t offset = store_ctx->FindWrittenPtr( data );

					if( data == 0x0 ) // Null-pointer, store pint(-1) to signal to patching!
					{
						DL_ASSERT(offset == (uintptr_t)-1 && "This pointer should not have been found among the written ptrs!");
						// keep the -1 in Offset and store it to ptr.
					}
					else if( offset == (uintptr_t)-1 ) // has not been written yet!
					{
						uintptr_t pos = dl_binary_writer_tell( &store_ctx->writer );
						dl_binary_writer_seek_end( &store_ctx->writer );

						const dl_type_desc* sub_type = dl_internal_find_type( dl_ctx, member->type_id );
						uintptr_t size = dl_internal_align_up( sub_type->size[DL_PTR_SIZE_HOST], sub_type->alignment[DL_PTR_SIZE_HOST] );
						dl_binary_writer_align( &store_ctx->writer, sub_type->alignment[DL_PTR_SIZE_HOST] );

						offset = dl_binary_writer_tell( &store_ctx->writer );

						// write data!
						dl_binary_writer_reserve( &store_ctx->writer, size ); // reserve space for ptr so subdata is placed correctly

						store_ctx->AddWrittenPtr(data, offset);

						dl_internal_instance_store(dl_ctx, sub_type, data, store_ctx);

						dl_binary_writer_seek_set( &store_ctx->writer, pos );
					}

					dl_binary_writer_write( &store_ctx->writer, &offset, sizeof(uintptr_t) );
				}
				break;
				default: // default is a standard pod-type
					DL_ASSERT( member->IsSimplePod() || storage_type == DL_TYPE_STORAGE_ENUM );
					dl_binary_writer_write( &store_ctx->writer, instance, member->size[DL_PTR_SIZE_HOST] );
					break;
			}
		}
		return DL_ERROR_OK;

		case DL_TYPE_ATOM_INLINE_ARRAY:
		{
			const dl_type_desc* sub_type = 0x0;
			uint32_t count = member->inline_array_cnt();
			if( storage_type == DL_TYPE_STORAGE_STRUCT )
			{
				sub_type = dl_internal_find_type(dl_ctx, member->type_id);
				if (sub_type == 0x0)
				{
					dl_log_error(dl_ctx, "Could not find subtype for member %s", dl_internal_member_name(dl_ctx, member));
					return DL_ERROR_TYPE_NOT_FOUND;
				}
			}
			else if( storage_type != DL_TYPE_STORAGE_STR )
				count = member->size[DL_PTR_SIZE_HOST];

			dl_internal_store_array( dl_ctx, storage_type, sub_type, instance, count, 1, store_ctx );
		}
		return DL_ERROR_OK;

		case DL_TYPE_ATOM_ARRAY:
		{
			uintptr_t size = 0;
			const dl_type_desc* sub_type = 0x0;

			uint8_t* data_ptr = instance;
			uint32_t count    = *(uint32_t*)( data_ptr + sizeof(void*) );

			uintptr_t offset = 0;

			if( count == 0 )
				offset = DL_NULL_PTR_OFFSET[ DL_PTR_SIZE_HOST ];
			else
			{
				uintptr_t pos = dl_binary_writer_tell( &store_ctx->writer );
				dl_binary_writer_seek_end( &store_ctx->writer );

				switch(storage_type)
				{
					case DL_TYPE_STORAGE_STRUCT:
						sub_type = dl_internal_find_type( dl_ctx, member->type_id );
						size = dl_internal_align_up( sub_type->size[DL_PTR_SIZE_HOST], sub_type->alignment[DL_PTR_SIZE_HOST] );
						dl_binary_writer_align( &store_ctx->writer, sub_type->alignment[DL_PTR_SIZE_HOST] );
						break;
					case DL_TYPE_STORAGE_STR:
						size = sizeof(void*);
						dl_binary_writer_align( &store_ctx->writer, size );
						break;
					default:
						size = dl_pod_size( member->type );
						dl_binary_writer_align( &store_ctx->writer, size );
				}

				offset = dl_binary_writer_tell( &store_ctx->writer );

				// write data!
				dl_binary_writer_reserve( &store_ctx->writer, count * size ); // reserve space for array so subdata is placed correctly

				uint8_t* data = *(uint8_t**)data_ptr;

				dl_internal_store_array( dl_ctx, storage_type, sub_type, data, count, size, store_ctx );
				dl_binary_writer_seek_set( &store_ctx->writer, pos );
			}

			// make room for ptr
			dl_binary_writer_write( &store_ctx->writer, &offset, sizeof(uintptr_t) );

			// write count
			dl_binary_writer_write( &store_ctx->writer, &count, sizeof(uint32_t) );
		}
		return DL_ERROR_OK;

		case DL_TYPE_ATOM_BITFIELD:
			dl_binary_writer_write( &store_ctx->writer, instance, member->size[DL_PTR_SIZE_HOST] );
		break;

		default:
			DL_ASSERT(false && "Invalid ATOM-type!");
			break;
	}

	return DL_ERROR_OK;
}