Exemplo n.º 1
0
static void dl_load_txt_build_default_data( dl_ctx_t ctx, dl_txt_read_ctx* read_state, unsigned int member_index )
{
	if( ctx->member_descs[member_index].default_value_offset == 0xFFFFFFFF )
		return;

	// TODO: check that this is not outside the buffers
	dl_type_desc*   def_type   = dl_alloc_type( ctx, dl_internal_hash_string( "a_type_here" ) );
	dl_member_desc* def_member = dl_alloc_member( ctx );

	dl_member_desc* member = &ctx->member_descs[member_index];

	uint32_t def_start = member->default_value_offset;
	uint32_t def_len   = member->default_value_size;

	char def_buffer[2048]; // TODO: no hardcode =/

	// TODO: check that typename do not exist in the ctx!

	size_t name_start = ctx->typedata_strings_size;
	dl_txt_read_substr temp = { "a_type_here", 11 };
	def_type->name = dl_alloc_string( ctx, &temp );
	def_type->size[DL_PTR_SIZE_HOST]      = member->size[DL_PTR_SIZE_HOST];
	def_type->alignment[DL_PTR_SIZE_HOST] = member->alignment[DL_PTR_SIZE_HOST];
	def_type->member_count = 1;

	memcpy( def_member, member, sizeof( dl_member_desc ) );
	def_member->offset[0] = 0;
	def_member->offset[1] = 0;

	dl_internal_str_format( def_buffer, sizeof(def_buffer), "{\"a_type_here\":{\"%s\":%.*s}}", dl_internal_member_name( ctx, member ), (int)def_len, read_state->start + def_start );

	size_t prod_bytes;
	dl_error_t err;
	err = dl_txt_pack( ctx, def_buffer, 0x0, 0, &prod_bytes );
	if( err != DL_ERROR_OK )
		dl_txt_read_failed( ctx, read_state, DL_ERROR_INVALID_DEFAULT_VALUE, "failed to pack default-value for member \"%s\" with error \"%s\"",
															dl_internal_member_name( ctx, member ),
															dl_error_to_string( err ) );

	uint8_t* pack_buffer = (uint8_t*)dl_alloc( &ctx->alloc, prod_bytes );

	dl_txt_pack( ctx, def_buffer, pack_buffer, prod_bytes, 0x0 );

	// TODO: convert packed instance to typelib endian/ptrsize here!

	size_t inst_size = prod_bytes - sizeof( dl_data_header );

	ctx->default_data = (uint8_t*)dl_realloc( &ctx->alloc, ctx->default_data, ctx->default_data_size + inst_size, ctx->default_data_size );
	memcpy( ctx->default_data + ctx->default_data_size, pack_buffer + sizeof( dl_data_header ), inst_size );

	dl_free( &ctx->alloc, pack_buffer );

	member->default_value_offset = (uint32_t)ctx->default_data_size;
	member->default_value_size   = (uint32_t)inst_size;
	ctx->default_data_size += inst_size;

	--ctx->type_count;
	--ctx->member_count;
	ctx->typedata_strings_size = name_start;
}
Exemplo n.º 2
0
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];
}
Exemplo n.º 3
0
static void dl_txt_unpack_member( dl_ctx_t dl_ctx, dl_txt_unpack_ctx* unpack_ctx, dl_binary_writer* writer, const dl_member_desc* member, const uint8_t* member_data )
{
	dl_txt_unpack_write_indent( writer, unpack_ctx );
	dl_txt_unpack_write_string( writer, dl_internal_member_name( dl_ctx, member ) );
	dl_binary_writer_write( writer, " : ", 3 );

	switch( member->AtomType() )
	{
		case DL_TYPE_ATOM_POD:
		{
			switch( member->StorageType() )
			{
				case DL_TYPE_STORAGE_INT8:        dl_txt_unpack_int8  ( writer, *(int8_t* )member_data ); break;
				case DL_TYPE_STORAGE_INT16:       dl_txt_unpack_int16 ( writer, *(int16_t*)member_data ); break;
				case DL_TYPE_STORAGE_INT32:       dl_txt_unpack_int32 ( writer, *(int32_t*)member_data ); break;
				case DL_TYPE_STORAGE_INT64:       dl_txt_unpack_int64 ( writer, *(int64_t*)member_data ); break;
				case DL_TYPE_STORAGE_UINT8:       dl_txt_unpack_uint8 ( writer, *(uint8_t* )member_data ); break;
				case DL_TYPE_STORAGE_UINT16:      dl_txt_unpack_uint16( writer, *(uint16_t*)member_data ); break;
				case DL_TYPE_STORAGE_UINT32:      dl_txt_unpack_uint32( writer, *(uint32_t*)member_data ); break;
				case DL_TYPE_STORAGE_UINT64:      dl_txt_unpack_uint64( writer, *(uint64_t*)member_data ); break;
				case DL_TYPE_STORAGE_FP32:        dl_txt_unpack_fp32  ( writer, *(float*)member_data ); break;
				case DL_TYPE_STORAGE_FP64:        dl_txt_unpack_fp64  ( writer, *(double*)member_data ); break;
				case DL_TYPE_STORAGE_ENUM_INT8:   dl_txt_unpack_enum  ( dl_ctx, writer, dl_internal_find_enum( dl_ctx, member->type_id ), (uint64_t)*( int8_t*)  member_data ); break;
				case DL_TYPE_STORAGE_ENUM_UINT8:  dl_txt_unpack_enum  ( dl_ctx, writer, dl_internal_find_enum( dl_ctx, member->type_id ), (uint64_t)*(uint8_t*)  member_data ); break;
				case DL_TYPE_STORAGE_ENUM_INT16:  dl_txt_unpack_enum  ( dl_ctx, writer, dl_internal_find_enum( dl_ctx, member->type_id ), (uint64_t)*( int16_t*) member_data ); break;
				case DL_TYPE_STORAGE_ENUM_UINT16: dl_txt_unpack_enum  ( dl_ctx, writer, dl_internal_find_enum( dl_ctx, member->type_id ), (uint64_t)*(uint16_t*) member_data ); break;
				case DL_TYPE_STORAGE_ENUM_INT32:  dl_txt_unpack_enum  ( dl_ctx, writer, dl_internal_find_enum( dl_ctx, member->type_id ), (uint64_t)*( int32_t*) member_data ); break;
				case DL_TYPE_STORAGE_ENUM_UINT32: dl_txt_unpack_enum  ( dl_ctx, writer, dl_internal_find_enum( dl_ctx, member->type_id ), (uint64_t)*(uint32_t*) member_data ); break;
				case DL_TYPE_STORAGE_ENUM_INT64:  dl_txt_unpack_enum  ( dl_ctx, writer, dl_internal_find_enum( dl_ctx, member->type_id ), (uint64_t)*( int64_t*) member_data ); break;
				case DL_TYPE_STORAGE_ENUM_UINT64: dl_txt_unpack_enum  ( dl_ctx, writer, dl_internal_find_enum( dl_ctx, member->type_id ), (uint64_t)*(uint64_t*) member_data ); break;
				case DL_TYPE_STORAGE_STR:         dl_txt_unpack_write_string_or_null( writer, unpack_ctx, *(uintptr_t*)member_data ); break;
				case DL_TYPE_STORAGE_PTR:
				{
					dl_txt_unpack_ptr( writer, *(uintptr_t*)member_data );
					unpack_ctx->has_ptrs = true;
				}
				break;
				case DL_TYPE_STORAGE_STRUCT: dl_txt_unpack_struct( dl_ctx, unpack_ctx, writer, dl_internal_find_type( dl_ctx, member->type_id ), member_data ); break;
				default:
					DL_ASSERT(false);
			}
		}
		break;
		case DL_TYPE_ATOM_ARRAY:
		{
			uintptr_t offset = *(uintptr_t*)member_data;
			uint32_t  count  = *(uint32_t*)(member_data + sizeof(uintptr_t));
			if( offset == (uintptr_t)-1 )
				dl_binary_writer_write( writer, "[]", 2 );
			else
				dl_txt_unpack_array( dl_ctx, unpack_ctx, writer, member->StorageType(), &unpack_ctx->packed_instance[offset], count, member->type_id );
		}
		break;
		case DL_TYPE_ATOM_INLINE_ARRAY:
			dl_txt_unpack_array( dl_ctx, unpack_ctx, writer, member->StorageType(), member_data, member->inline_array_cnt(), member->type_id );
		break;
		case DL_TYPE_ATOM_BITFIELD:
		{
			uint64_t write_me  = 0;
			uint32_t bf_bits   = member->bitfield_bits();
			uint32_t bf_offset = dl_bf_offset( DL_ENDIAN_HOST, member->size[DL_PTR_SIZE_HOST], member->bitfield_offset(), bf_bits );

			switch( member->size[DL_PTR_SIZE_HOST] )
			{
				case 1: write_me = DL_EXTRACT_BITS( uint64_t( *(uint8_t*)member_data), uint64_t(bf_offset), uint64_t(bf_bits) ); break;
				case 2: write_me = DL_EXTRACT_BITS( uint64_t(*(uint16_t*)member_data), uint64_t(bf_offset), uint64_t(bf_bits) ); break;
				case 4: write_me = DL_EXTRACT_BITS( uint64_t(*(uint32_t*)member_data), uint64_t(bf_offset), uint64_t(bf_bits) ); break;
				case 8: write_me = DL_EXTRACT_BITS( uint64_t(*(uint64_t*)member_data), uint64_t(bf_offset), uint64_t(bf_bits) ); break;
				default:
					DL_ASSERT(false && "This should not happen!");
					break;
			}
			dl_txt_unpack_uint64( writer, write_me );
		}
		break;
		default:
			DL_ASSERT( false );
	}
}
Exemplo n.º 4
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;
}