protoverse

A metaverse protocol
git clone git://jb55.com/protoverse
Log | Files | Refs | README | LICENSE

commit 43f8898e2116558ee92cbd5ba23591aa7958f366
parent 06fd9b4cedf3e07af3dd499800dbafad068e50e6
Author: William Casarin <jb55@jb55.com>
Date:   Sun, 22 Nov 2020 11:36:17 -0800

exports

Diffstat:
Msrc/wasm.c | 188++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
Msrc/wasm.h | 25+++++++++++++++++++++++++
2 files changed, 203 insertions(+), 10 deletions(-)

diff --git a/src/wasm.c b/src/wasm.c @@ -123,15 +123,57 @@ static void print_functype(struct functype *ft) printf("\n"); } -static void print_module(struct module *module) +static void print_type_section(struct typesec *typesec) +{ + int i; + printf("%d functypes:\n", typesec->num_functypes); + for (i = 0; i < typesec->num_functypes; i++) { + printf(" "); + print_functype(&typesec->functypes[i]); + } +} + +static void print_func_section(struct funcsec *funcsec) +{ + int i; + printf("%d functions\n", funcsec->num_indices); + printf(" "); + for (i = 0; i < funcsec->num_indices; i++) { + printf("%d ", funcsec->type_indices[i]); + } + printf("\n"); +} + +static const char *exportdesc_name(enum exportdesc desc) +{ + switch (desc) { + case export_func: return "function"; + case export_table: return "table"; + case export_mem: return "memory"; + case export_global: return "global"; + } + + return "unknown"; +} + +static void print_export_section(struct exportsec *exportsec) { int i; - printf("%d functypes:\n", module->type_section.num_functypes); - for (i = 0; i < module->type_section.num_functypes; i++) { - print_functype(&module->type_section.functypes[i]); + printf("%d exports:\n", exportsec->num_exports); + for (i = 0; i < exportsec->num_exports; i++) { + printf(" "); + printf("%s %s\n", exportdesc_name(exportsec->exports[i].desc), + exportsec->exports[i].name); } } +static void print_module(struct module *module) +{ + print_type_section(&module->type_section); + print_func_section(&module->func_section); + print_export_section(&module->export_section); +} + /* I DONT NEED THIS (yet?) */ /* static int leb128_write(struct cursor *write, unsigned int val) @@ -293,6 +335,126 @@ static int parse_func_type(struct wasm_parser *p, struct functype *func) return 1; } +static int parse_name(struct wasm_parser *p, const char **name) +{ + unsigned int bytes; + if (!leb128_read(&p->cur, &bytes)) { + note_error(p, "name len"); + return 0; + } + + if (!pull_data_into_cursor(&p->cur, &p->mem, (unsigned char**)name, + bytes)) { + note_error(p, "name string"); + return 0; + } + + if (!push_byte(&p->mem, 0)) { + note_error(p, "name null byte"); + return 0; + } + + return 1; +} + +static int parse_export_desc(struct wasm_parser *p, enum exportdesc *desc) +{ + unsigned char byte; + + if (!pull_byte(&p->cur, &byte)) { + note_error(p, "export desc byte eof"); + return 0; + } + + switch((enum exportdesc)byte) { + case export_func: + case export_table: + case export_mem: + case export_global: + *desc = (enum exportdesc)byte; + return 1; + } + + note_error(p, "invalid tag: %x", byte); + return 0; +} + +static int parse_export(struct wasm_parser *p, struct wexport *export) +{ + if (!parse_name(p, &export->name)) { + note_error(p, "export name"); + return 0; + } + + if (!parse_export_desc(p, &export->desc)) { + note_error(p, "export desc"); + return 0; + } + + return 1; +} + +static int parse_export_section(struct wasm_parser *p, + struct exportsec *export_section) +{ + struct wexport *exports; + unsigned int elems, i; + + if (!leb128_read(&p->cur, &elems)) { + note_error(p, "export vec len"); + return 0; + } + + exports = cursor_alloc(&p->mem, elems * sizeof(*exports)); + + if (!exports) { + fprintf(stderr, "could not allocate memory for exports section\n"); + return 0; + } + + for (i = 0; i < elems; i++) { + if (!parse_export(p, &exports[i])) { + note_error(p, "export #%d"); + return 0; + } + } + + export_section->num_exports = elems; + export_section->exports = exports; + + return 1; +} + +static int parse_function_section(struct wasm_parser *p, + struct funcsec *funcsec) +{ + unsigned int *indices; + unsigned int i, elems; + + if (!leb128_read(&p->cur, &elems)) { + note_error(p, "typeidx vec len"); + return 0; + } + + indices = cursor_alloc(&p->mem, elems * sizeof(*indices)); + + if (!indices) { + fprintf(stderr, "could not allocate memory for func section\n"); + return 0; + } + + for (i = 0; i < elems; i++) { + if (!leb128_read(&p->cur, &indices[i])) { + note_error(p, "typeidx #%d", i); + return 0; + } + } + + funcsec->type_indices = indices; + funcsec->num_indices = elems; + + return 1; +} /* type section is just a vector of function types */ static int parse_type_section(struct wasm_parser *p, struct typesec *typesec) @@ -329,8 +491,8 @@ static int parse_type_section(struct wasm_parser *p, struct typesec *typesec) return 1; } -static int parse_section_by_tag(struct wasm_parser *p, - enum section_tag tag, unsigned int size) +static int parse_section_by_tag(struct wasm_parser *p, enum section_tag tag, + unsigned int size) { (void)size; switch (tag) { @@ -347,8 +509,11 @@ static int parse_section_by_tag(struct wasm_parser *p, note_error(p, "section_import parse not implemented"); return 0; case section_function: - note_error(p, "section_function parse not implemented"); - return 0; + if (!parse_function_section(p, &p->module.func_section)) { + note_error(p, "function section"); + return 0; + } + return 1; case section_table: note_error(p, "section_table parse not implemented"); return 0; @@ -359,8 +524,11 @@ static int parse_section_by_tag(struct wasm_parser *p, note_error(p, "section_global parse not implemented"); return 0; case section_export: - note_error(p, "section_export parse not implemented"); - return 0; + if (!parse_export_section(p, &p->module.export_section)) { + note_error(p, "export section"); + return 0; + } + return 1; case section_start: note_error(p, "section_start parse not implemented"); return 0; diff --git a/src/wasm.h b/src/wasm.h @@ -19,13 +19,38 @@ struct functype { struct resulttype result; }; +struct funcsec { + unsigned int *type_indices; + int num_indices; +}; + struct typesec { struct functype *functypes; int num_functypes; }; +enum exportdesc { + export_func, + export_table, + export_mem, + export_global, +}; + +struct wexport { + const char *name; + unsigned int index; + enum exportdesc desc; +}; + +struct exportsec { + struct wexport *exports; + int num_exports; +}; + struct module { struct typesec type_section; + struct funcsec func_section; + struct exportsec export_section; }; enum valtype {