Changeset View
Changeset View
Standalone View
Standalone View
source/blender/makesdna/intern/makesdna.c
| Show First 20 Lines • Show All 158 Lines • ▼ Show 20 Lines | |||||
| static int types_len = 0; | static int types_len = 0; | ||||
| static int structs_len = 0; | static int structs_len = 0; | ||||
| /** At address `names[a]` is string `a`. */ | /** At address `names[a]` is string `a`. */ | ||||
| static char **names; | static char **names; | ||||
| /** At address `types[a]` is string `a`. */ | /** At address `types[a]` is string `a`. */ | ||||
| static char **types; | static char **types; | ||||
| /** At `types_size[a]` is the size of type `a` on this systems bitness (32 or 64). */ | /** At `types_size[a]` is the size of type `a` on this systems bitness (32 or 64). */ | ||||
| static short *types_size_native; | static short *types_size_native; | ||||
| /** Contains align requirements for a struct on 32 bit systems. */ | |||||
| static short *types_align_32; | |||||
| /** Contains align requirements for a struct on 64 bit systems. */ | |||||
| static short *types_align_64; | |||||
| /** Contains sizes as they are calculated on 32 bit systems. */ | /** Contains sizes as they are calculated on 32 bit systems. */ | ||||
| static short *types_size_32; | static short *types_size_32; | ||||
| /** Contains sizes as they are calculated on 64 bit systems. */ | /** Contains sizes as they are calculated on 64 bit systems. */ | ||||
| static short *types_size_64; | static short *types_size_64; | ||||
| /** | /** | ||||
| * At `sp = structs[a]` is the first address of a struct definition: | * At `sp = structs[a]` is the first address of a struct definition: | ||||
| * - `sp[0]` is type number. | * - `sp[0]` is type number. | ||||
| * - `sp[1]` is the length of the element array (next). | * - `sp[1]` is the length of the element array (next). | ||||
| ▲ Show 20 Lines • Show All 194 Lines • ▼ Show 20 Lines | static int add_type(const char *str, int size) | ||||
| /* search through type array */ | /* search through type array */ | ||||
| for (int index = 0; index < types_len; index++) { | for (int index = 0; index < types_len; index++) { | ||||
| if (STREQ(str, types[index])) { | if (STREQ(str, types[index])) { | ||||
| if (size) { | if (size) { | ||||
| types_size_native[index] = size; | types_size_native[index] = size; | ||||
| types_size_32[index] = size; | types_size_32[index] = size; | ||||
| types_size_64[index] = size; | types_size_64[index] = size; | ||||
| types_align_32[index] = size; | |||||
| types_align_64[index] = size; | |||||
| } | } | ||||
| return index; | return index; | ||||
| } | } | ||||
| } | } | ||||
| /* append new type */ | /* append new type */ | ||||
| const int str_size = strlen(str) + 1; | const int str_size = strlen(str) + 1; | ||||
| char *cp = BLI_memarena_alloc(mem_arena, str_size); | char *cp = BLI_memarena_alloc(mem_arena, str_size); | ||||
| memcpy(cp, str, str_size); | memcpy(cp, str, str_size); | ||||
| types[types_len] = cp; | types[types_len] = cp; | ||||
| types_size_native[types_len] = size; | types_size_native[types_len] = size; | ||||
| types_size_32[types_len] = size; | types_size_32[types_len] = size; | ||||
| types_size_64[types_len] = size; | types_size_64[types_len] = size; | ||||
| types_align_32[types_len] = size; | |||||
| types_align_64[types_len] = size; | |||||
| if (types_len >= max_array_len) { | if (types_len >= max_array_len) { | ||||
| printf("too many types\n"); | printf("too many types\n"); | ||||
| return types_len - 1; | return types_len - 1; | ||||
| } | } | ||||
| types_len++; | types_len++; | ||||
| return types_len - 1; | return types_len - 1; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 522 Lines • ▼ Show 20 Lines | for (int a = 0; a < structs_len; a++) { | ||||
| /* when length is not known... */ | /* when length is not known... */ | ||||
| if (types_size_native[structtype] == 0) { | if (types_size_native[structtype] == 0) { | ||||
| const short *sp = structpoin + 2; | const short *sp = structpoin + 2; | ||||
| int size_native = 0; | int size_native = 0; | ||||
| int size_32 = 0; | int size_32 = 0; | ||||
| int size_64 = 0; | int size_64 = 0; | ||||
| bool has_pointer = false; | /* Sizes of the largest field in a struct. */ | ||||
| int max_align_32 = 0; | |||||
| int max_align_64 = 0; | |||||
| /* check all elements in struct */ | /* check all elements in struct */ | ||||
| for (int b = 0; b < structpoin[1]; b++, sp += 2) { | for (int b = 0; b < structpoin[1]; b++, sp += 2) { | ||||
| int type = sp[0]; | int type = sp[0]; | ||||
| const char *cp = names[sp[1]]; | const char *cp = names[sp[1]]; | ||||
| int namelen = (int)strlen(cp); | int namelen = (int)strlen(cp); | ||||
| /* Write size verification to file. */ | /* Write size verification to file. */ | ||||
| Show All 12 Lines | for (int a = 0; a < structs_len; a++) { | ||||
| "verify\");\n", | "verify\");\n", | ||||
| structname, | structname, | ||||
| name_alias ? name_alias : name_static, | name_alias ? name_alias : name_static, | ||||
| size_native); | size_native); | ||||
| } | } | ||||
| /* is it a pointer or function pointer? */ | /* is it a pointer or function pointer? */ | ||||
| if (cp[0] == '*' || cp[1] == '*') { | if (cp[0] == '*' || cp[1] == '*') { | ||||
| has_pointer = 1; | |||||
| /* has the name an extra length? (array) */ | /* has the name an extra length? (array) */ | ||||
| int mul = 1; | int mul = 1; | ||||
| if (cp[namelen - 1] == ']') { | if (cp[namelen - 1] == ']') { | ||||
| mul = DNA_elem_array_size(cp); | mul = DNA_elem_array_size(cp); | ||||
| } | } | ||||
| if (mul == 0) { | if (mul == 0) { | ||||
| fprintf(stderr, | fprintf(stderr, | ||||
| Show All 30 Lines | for (int a = 0; a < structs_len; a++) { | ||||
| types[structtype], | types[structtype], | ||||
| cp); | cp); | ||||
| dna_error = 1; | dna_error = 1; | ||||
| } | } | ||||
| size_native += sizeof(void *) * mul; | size_native += sizeof(void *) * mul; | ||||
| size_32 += 4 * mul; | size_32 += 4 * mul; | ||||
| size_64 += 8 * mul; | size_64 += 8 * mul; | ||||
| max_align_32 = MAX2(max_align_32, 4); | |||||
| max_align_64 = MAX2(max_align_64, 8); | |||||
| } | } | ||||
| else if (cp[0] == '[') { | else if (cp[0] == '[') { | ||||
| /* parsing can cause names "var" and "[3]" | /* parsing can cause names "var" and "[3]" | ||||
| * to be found for "float var [3]" */ | * to be found for "float var [3]" */ | ||||
| fprintf(stderr, | fprintf(stderr, | ||||
| "Parse error in struct, invalid member name: %s %s\n", | "Parse error in struct, invalid member name: %s %s\n", | ||||
| types[structtype], | types[structtype], | ||||
| cp); | cp); | ||||
| Show All 29 Lines | for (int a = 0; a < structs_len; a++) { | ||||
| } | } | ||||
| if (!check_field_alignment(firststruct, structtype, type, size_64, cp, "64 bit")) { | if (!check_field_alignment(firststruct, structtype, type, size_64, cp, "64 bit")) { | ||||
| dna_error = 1; | dna_error = 1; | ||||
| } | } | ||||
| size_native += mul * types_size_native[type]; | size_native += mul * types_size_native[type]; | ||||
| size_32 += mul * types_size_32[type]; | size_32 += mul * types_size_32[type]; | ||||
| size_64 += mul * types_size_64[type]; | size_64 += mul * types_size_64[type]; | ||||
| max_align_32 = MAX2(max_align_32, types_align_32[type]); | |||||
| max_align_64 = MAX2(max_align_64, types_align_64[type]); | |||||
| } | } | ||||
| else { | else { | ||||
| size_native = 0; | size_native = 0; | ||||
| size_32 = 0; | size_32 = 0; | ||||
| size_64 = 0; | size_64 = 0; | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| if (size_native == 0) { | if (size_native == 0) { | ||||
| unknown++; | unknown++; | ||||
| } | } | ||||
| else { | else { | ||||
| types_size_native[structtype] = size_native; | types_size_native[structtype] = size_native; | ||||
| types_size_32[structtype] = size_32; | types_size_32[structtype] = size_32; | ||||
| types_size_64[structtype] = size_64; | types_size_64[structtype] = size_64; | ||||
| /* Two ways to detect if a struct contains a pointer: | types_align_32[structtype] = max_align_32; | ||||
| * has_pointer is set or size_native doesn't match any of 32/64bit lengths. */ | types_align_64[structtype] = max_align_64; | ||||
| if (has_pointer || size_64 != size_native || size_32 != size_native) { | |||||
| if (size_64 % 8) { | /* Santiy check 1: alignment should never be 0. */ | ||||
| BLI_assert(max_align_32); | |||||
| BLI_assert(max_align_64); | |||||
| /* Santiy check 2: alignment should always be equal or smaller than the maximum | |||||
| * size of a build in type which is 8 bytes (ie int64_t or double). */ | |||||
| BLI_assert(max_align_32 <= 8); | |||||
| BLI_assert(max_align_64 <= 8); | |||||
| if (size_32 % max_align_32) { | |||||
| /* There is an one odd case where only the 32 bit struct has alignment issues | |||||
| * and the 64 bit does not, that can only be fixed by adding a padding pointer | |||||
| * to the struct to resolve the problem. */ | |||||
| if ((size_64 % max_align_64 == 0) && (size_32 % max_align_32 == 4)) { | |||||
| fprintf(stderr, | |||||
| "Sizeerror in 32 bit struct: %s (add paddding pointer)\n", | |||||
| types[structtype]); | |||||
| } | |||||
| else { | |||||
| fprintf(stderr, | fprintf(stderr, | ||||
| "Sizeerror 8 in struct: %s (add %d bytes)\n", | "Sizeerror in 32 bit struct: %s (add %d bytes)\n", | ||||
| types[structtype], | types[structtype], | ||||
| size_64 % 8); | max_align_32 - (size_32 % max_align_32)); | ||||
| } | |||||
| dna_error = 1; | dna_error = 1; | ||||
| } | } | ||||
| if (size_64 % max_align_64) { | |||||
| fprintf(stderr, | |||||
| "Sizeerror in 64 bit struct: %s (add %d bytes)\n", | |||||
| types[structtype], | |||||
| max_align_64 - (size_64 % max_align_64)); | |||||
| dna_error = 1; | |||||
| } | } | ||||
| if (size_native % 4 && !ELEM(size_native, 1, 2)) { | if (size_native % 4 && !ELEM(size_native, 1, 2)) { | ||||
| fprintf(stderr, | fprintf(stderr, | ||||
| "Sizeerror 4 in struct: %s (add %d bytes)\n", | "Sizeerror 4 in struct: %s (add %d bytes)\n", | ||||
| types[structtype], | types[structtype], | ||||
| size_native % 4); | size_native % 4); | ||||
| dna_error = 1; | dna_error = 1; | ||||
| ▲ Show 20 Lines • Show All 100 Lines • ▼ Show 20 Lines | static int make_structDNA(const char *base_directory, | ||||
| structdata = MEM_callocN(max_data_size, "structdata"); | structdata = MEM_callocN(max_data_size, "structdata"); | ||||
| /* a maximum of 5000 variables, must be sufficient? */ | /* a maximum of 5000 variables, must be sufficient? */ | ||||
| names = MEM_callocN(sizeof(char *) * max_array_len, "names"); | names = MEM_callocN(sizeof(char *) * max_array_len, "names"); | ||||
| types = MEM_callocN(sizeof(char *) * max_array_len, "types"); | types = MEM_callocN(sizeof(char *) * max_array_len, "types"); | ||||
| types_size_native = MEM_callocN(sizeof(short) * max_array_len, "types_size_native"); | types_size_native = MEM_callocN(sizeof(short) * max_array_len, "types_size_native"); | ||||
| types_size_32 = MEM_callocN(sizeof(short) * max_array_len, "types_size_32"); | types_size_32 = MEM_callocN(sizeof(short) * max_array_len, "types_size_32"); | ||||
| types_size_64 = MEM_callocN(sizeof(short) * max_array_len, "types_size_64"); | types_size_64 = MEM_callocN(sizeof(short) * max_array_len, "types_size_64"); | ||||
| types_align_32 = MEM_callocN(sizeof(short) * max_array_len, "types_size_32"); | |||||
| types_align_64 = MEM_callocN(sizeof(short) * max_array_len, "types_size_64"); | |||||
| structs = MEM_callocN(sizeof(short *) * max_array_len, "structs"); | structs = MEM_callocN(sizeof(short *) * max_array_len, "structs"); | ||||
| /* Build versioning data */ | /* Build versioning data */ | ||||
| DNA_alias_maps(DNA_RENAME_ALIAS_FROM_STATIC, | DNA_alias_maps(DNA_RENAME_ALIAS_FROM_STATIC, | ||||
| &g_version_data.struct_map_alias_from_static, | &g_version_data.struct_map_alias_from_static, | ||||
| &g_version_data.elem_map_alias_from_static); | &g_version_data.elem_map_alias_from_static); | ||||
| DNA_alias_maps(DNA_RENAME_STATIC_FROM_ALIAS, | DNA_alias_maps(DNA_RENAME_STATIC_FROM_ALIAS, | ||||
| &g_version_data.struct_map_static_from_alias, | &g_version_data.struct_map_static_from_alias, | ||||
| ▲ Show 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | if (debugSDNA > 1) { | ||||
| for (a = 0; a < structs_len; a++) { | for (a = 0; a < structs_len; a++) { | ||||
| sp = structs[a]; | sp = structs[a]; | ||||
| printf(" struct %s elems: %d size: %d\n", types[sp[0]], sp[1], types_size_native[sp[0]]); | printf(" struct %s elems: %d size: %d\n", types[sp[0]], sp[1], types_size_native[sp[0]]); | ||||
| num_types = sp[1]; | num_types = sp[1]; | ||||
| sp += 2; | sp += 2; | ||||
| /* ? num_types was elem? */ | /* ? num_types was elem? */ | ||||
| for (b = 0; b < num_types; b++, sp += 2) { | for (b = 0; b < num_types; b++, sp += 2) { | ||||
| printf(" %s %s\n", types[sp[0]], names[sp[1]]); | printf(" %s %s allign32:%d, allign64:%d\n", | ||||
| types[sp[0]], | |||||
| names[sp[1]], | |||||
| types_align_32[sp[0]], | |||||
| types_align_64[sp[0]]); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* file writing */ | /* file writing */ | ||||
| DEBUG_PRINTF(0, "Writing file ... "); | DEBUG_PRINTF(0, "Writing file ... "); | ||||
| ▲ Show 20 Lines • Show All 105 Lines • ▼ Show 20 Lines | static int make_structDNA(const char *base_directory, | ||||
| } | } | ||||
| MEM_freeN(structdata); | MEM_freeN(structdata); | ||||
| MEM_freeN(names); | MEM_freeN(names); | ||||
| MEM_freeN(types); | MEM_freeN(types); | ||||
| MEM_freeN(types_size_native); | MEM_freeN(types_size_native); | ||||
| MEM_freeN(types_size_32); | MEM_freeN(types_size_32); | ||||
| MEM_freeN(types_size_64); | MEM_freeN(types_size_64); | ||||
| MEM_freeN(types_align_32); | |||||
| MEM_freeN(types_align_64); | |||||
| MEM_freeN(structs); | MEM_freeN(structs); | ||||
| BLI_memarena_free(mem_arena); | BLI_memarena_free(mem_arena); | ||||
| BLI_ghash_free(g_version_data.struct_map_alias_from_static, NULL, NULL); | BLI_ghash_free(g_version_data.struct_map_alias_from_static, NULL, NULL); | ||||
| BLI_ghash_free(g_version_data.struct_map_static_from_alias, NULL, NULL); | BLI_ghash_free(g_version_data.struct_map_static_from_alias, NULL, NULL); | ||||
| BLI_ghash_free(g_version_data.elem_map_static_from_alias, MEM_freeN, NULL); | BLI_ghash_free(g_version_data.elem_map_static_from_alias, MEM_freeN, NULL); | ||||
| BLI_ghash_free(g_version_data.elem_map_alias_from_static, MEM_freeN, NULL); | BLI_ghash_free(g_version_data.elem_map_alias_from_static, MEM_freeN, NULL); | ||||
| ▲ Show 20 Lines • Show All 216 Lines • Show Last 20 Lines | |||||