aboutsummaryrefslogtreecommitdiff
path: root/tools/parse_module.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/parse_module.c')
-rw-r--r--tools/parse_module.c172
1 files changed, 91 insertions, 81 deletions
diff --git a/tools/parse_module.c b/tools/parse_module.c
index 155fc9c..75329f8 100644
--- a/tools/parse_module.c
+++ b/tools/parse_module.c
@@ -68,6 +68,19 @@ int leb_u32(FILE *handle, uint32_t *result)
return 0;
}
+void deinitialize_resulttype(struct resulttype *type)
+{
+ type->count = 0;
+ free(type->types);
+ type->types = NULL;
+}
+
+void deinitialize_functype(struct functype *type)
+{
+ deinitialize_resulttype(&type->args);
+ deinitialize_resulttype(&type->results);
+}
+
void free_module(struct module *module)
{
size_t i;
@@ -76,7 +89,7 @@ void free_module(struct module *module)
return;
for (i = 0; i < module->functypes_count; i++)
- free(module->functypes[i].arguments);
+ deinitialize_functype(module->functypes + i);
free(module->functypes);
@@ -113,37 +126,30 @@ static inline int safe_mul(size_t *factor1, uint32_t factor2)
return 0;
}
-int parse_type_section(FILE *handle, struct module *module)
+int parse_resulttype(FILE *handle, struct resulttype *type)
{
- uint32_t types_count;
int readval;
- size_t malloc_size;
- struct functype *types = NULL;
- uint32_t types_parsed = 0;
- uint32_t args_count;
- char *args;
uint32_t i;
- if (leb_u32(handle, &types_count)) {
+ if (leb_u32(handle, &type->count)) {
PRERR(MSG_BAD_NUM);
goto fail;
}
- malloc_size = sizeof(struct functype);
+ if (type->count) {
+ type->types = malloc(type->count);
- if (safe_mul(&malloc_size, types_count)) {
- PRERR(MSG_BAD_SIZE);
- goto fail;
+ if (!type->types) {
+ PRERR(MSG_ALLOC_FAIL(type->count));
+ goto fail;
+ }
+ } else {
+ type->types = NULL;
}
- types = malloc(malloc_size);
-
- if (!types) {
- PRERR(MSG_ALLOC_FAIL(malloc_size));
- goto fail;
- }
+ i = type->count;
- while (types_parsed < types_count) {
+ while (i--) {
readval = fgetc(handle);
if (readval == EOF) {
@@ -151,77 +157,78 @@ int parse_type_section(FILE *handle, struct module *module)
goto fail;
}
- if (readval != 0x60) {
- PRERR(MSG_BAD("functype starting byte (0x60)",
- readval));
+ if (!is_valid_valtype(readval)) {
+ PRERR(MSG_BAD("value type encoding", readval));
goto fail;
}
- if (leb_u32(handle, &args_count)) {
- PRERR(MSG_BAD_NUM);
- goto fail;
- }
+ type->types[i] = readval;
+ }
- if (args_count) {
- args = malloc(args_count);
+ return 0;
- if (!args) {
- PRERR(MSG_ALLOC_FAIL(args_count));
- goto fail;
- }
- } else {
- args = NULL;
- }
+fail:
+ deinitialize_resulttype(type);
- types[types_parsed].arguments_count = args_count;
- types[types_parsed].arguments = args;
- /* Increment here, so that jump to fail: frees the args */
- types_parsed++;
+ return -1;
+}
- for (i = 0; i < args_count; i++) {
- readval = fgetc(handle);
+int parse_functype(FILE *handle, struct functype *type)
+{
+ int readval;
- if (readval == EOF) {
- PRERR(MSG_EOF);
- goto fail;
- }
+ readval = fgetc(handle);
- if (!is_valid_valtype(readval)) {
- PRERR(MSG_BAD("value type encoding", readval));
- goto fail;
- }
+ if (readval == EOF) {
+ PRERR(MSG_EOF);
+ return -1;
+ }
- args[i] = readval;
- }
+ if (readval != 0x60) {
+ PRERR(MSG_BAD("functype starting byte (0x60)", readval));
+ return -1;
+ }
- readval = fgetc(handle);
+ if (parse_resulttype(handle, &type->args) ||
+ parse_resulttype(handle, &type->results)) {
+ deinitialize_functype(type);
+ return -1;
+ }
- if (readval == EOF) {
- PRERR(MSG_EOF);
- goto fail;
- }
+ return 0;
+}
- if (readval == 0x00) {
- types[types_parsed - 1].result = 0;
- } else if (readval == 0x01) {
+int parse_type_section(FILE *handle, struct module *module)
+{
+ uint32_t types_count;
+ size_t malloc_size;
+ struct functype *types = NULL;
+ uint32_t types_parsed = 0;
- readval = fgetc(handle);
+ if (leb_u32(handle, &types_count)) {
+ PRERR(MSG_BAD_NUM);
+ goto fail;
+ }
- if (readval == EOF) {
- PRERR(MSG_EOF);
- goto fail;
- }
+ malloc_size = sizeof(struct functype);
- if (!is_valid_valtype(readval)) {
- PRERR(MSG_BAD("value type encoding", readval));
- goto fail;
- }
+ if (safe_mul(&malloc_size, types_count)) {
+ PRERR(MSG_BAD_SIZE);
+ goto fail;
+ }
- types[types_parsed - 1].result = readval;
- } else {
- PRERR(MSG_BAD("return values count", readval));
+ types = malloc(malloc_size);
+
+ if (!types) {
+ PRERR(MSG_ALLOC_FAIL(malloc_size));
+ goto fail;
+ }
+
+ while (types_parsed < types_count) {
+ if (parse_functype(handle, types + types_parsed))
goto fail;
- }
+
+ types_parsed++;
}
module->functypes_count = types_count;
@@ -233,10 +240,8 @@ fail:
PRERR("Couldn't parse function types section\n");
if (types) {
- while (types_parsed) {
- free(types[types_parsed - 1].arguments);
- types_parsed--;
- }
+ while (types_parsed--)
+ deinitialize_functype(types + types_parsed);
free(types);
}
@@ -282,7 +287,12 @@ int parse_function_section(FILE *handle, struct module *module)
goto fail;
}
- funcs[i].type = module->functypes + i;
+ if (module->functypes[type_idx].results.count > 1) {
+ PRERR("Function returning more than one value\n");
+ goto fail;
+ }
+
+ funcs[i].type = module->functypes + type_idx;
funcs[i].translated_body = NULL;
}
@@ -444,7 +454,6 @@ static int parse_function_code(FILE *handle, struct function *function,
uint32_t locals_blocks;
uint32_t locals_count = 0;
char *locals = NULL, *tmp;
- char *body = NULL;
uint32_t i;
uint32_t locals_in_block;
@@ -459,7 +468,8 @@ static int parse_function_code(FILE *handle, struct function *function,
goto fail;
}
- if (locals_count + (uint64_t) locals_in_block > UINT32_MAX) {
+ if (locals_count + (uint64_t) locals_in_block +
+ (uint64_t) function->type->args.count > UINT32_MAX) {
PRERR("Too many locals\n");
goto fail;
}
@@ -505,7 +515,6 @@ static int parse_function_code(FILE *handle, struct function *function,
fail:
free(locals);
- free(body);
return -1;
}
@@ -565,6 +574,7 @@ fail:
free(module->functions[functions_parsed - 1].locals);
free_expr(module->functions[functions_parsed - 1]
.translated_body);
+ module->functions[functions_parsed - 1].translated_body = NULL;
functions_parsed--;
}