diff options
| author | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2024-05-22 14:04:36 +0200 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2024-06-12 13:38:05 +0200 |
| commit | 4f9a2c7a2d8464b04cc08075a7762c6d457090df (patch) | |
| tree | ae8fe229a3a5ba60d08b74299d0c1850685bda86 /src/section | |
| parent | f25b015e5b668028c34974bbb22faa4105c26690 (diff) | |
| download | nanowasm-sync-4f9a2c7a2d8464b04cc08075a7762c6d457090df.tar.gz | |
WIP
Diffstat (limited to 'src/section')
| -rw-r--r-- | src/section/code.c | 211 | ||||
| -rw-r--r-- | src/section/common.c | 88 | ||||
| -rw-r--r-- | src/section/function.c | 5 | ||||
| -rw-r--r-- | src/section/global.c | 103 | ||||
| -rw-r--r-- | src/section/type.c | 10 |
5 files changed, 101 insertions, 316 deletions
diff --git a/src/section/code.c b/src/section/code.c index da45047..3d62143 100644 --- a/src/section/code.c +++ b/src/section/code.c @@ -66,146 +66,35 @@ static int check_body(FILE *const f, const unsigned long n) return 0; } -#if 0 - -static int push_locals(struct nw_interp *const i, - const struct nw_frame *const f) +static int push_i32(struct nw_interp *const i) { - const enum value_type t = f->local_type; - const size_t typesz = get_type_size(t); - const unsigned long n = f->n_locals; - - if (mul_overflow(typesz, f->n_locals)) - { - LOG("%s: local variables size mul overflow", __func__); - i->exception = "mul overfllow"; - return -1; - } - - const size_t totalsz = typesz * n, max = i->cfg.stack.n; + const int32_t value = 0; - if (totalsz > max || i->stack_i > max - totalsz) - { - LOG("%s: cannot allocate locals\n", __func__); - i->exception = "stack overflow"; - return 1; - } - - init_locals(t, n, interp_stackptr(i)); - i->stack_i += totalsz; - return 0; + return interp_stack_push(i, &value, sizeof value); } -static int push_block(struct nw_interp *const i) +static int push_i64(struct nw_interp *const i) { - const long pc = ftell(i->f); - - if (pc < 0) - { - LOG("%s: ftell(3): %s\n", __func__, strerror(errno)); - return -1; - } - - const struct nw_block b = - { - .pc = pc - }; - - if (interp_stack_push(i, &b, sizeof b)) - { - LOG("%s: interp_stack_push failed\n", __func__); - return -1; - } + const int64_t value = 0; - struct nw_block *const p = (struct nw_block *)interp_stackptr(i) - 1; - - if (i->fp->block) - { - for (struct nw_block *b = i->fp->block; b; b = b->next) - if (!b->next) - { - b->next = p; - break; - } - } - else - i->fp->block = p; - - return 0; + return interp_stack_push(i, &value, sizeof value); } -static int loop_push_blocks(struct nw_interp *const i) +static int push_f32(struct nw_interp *const i) { - for (;;) - { - uint8_t op; - - if (!fread(&op, sizeof op, 1, i->f)) - { - LOG("%s: fread(3) failed, feof=%d, ferror=%d\n", __func__, - feof(i->f), ferror(i->f)); - i->exception = "I/O error"; - return -1; - } - else if (op >= sizeof ops / sizeof *ops) - { - LOG("%s: invalid opcode %#" PRIx8 "\n", __func__, op); - i->exception = "invalid opcode"; - return -1; - } - else if (interp_check_opcode(op, i->f)) - { - LOG("%s: interp_check_opcode failed\n", __func__); - return -1; - } + const float value = 0; - switch (op) - { - case OP_END: - return 0; - - case OP_BLOCK: - if (push_block(i)) - { - LOG("%s: push_block failed\n", __func__); - return -1; - } - - break; - - default: - break; - } - } + return interp_stack_push(i, &value, sizeof value); } -static int push_blocks(struct nw_interp *const i, - const struct nw_frame *const fr) +static int push_f64(struct nw_interp *const i) { - FILE *const f = i->f; - const long orig = ftell(f); - - if (orig < 0) - { - LOG("%s: ftell(3): %s\n", __func__, strerror(errno)); - return -1; - } - else if (loop_push_blocks(i)) - { - LOG("%s: loop_push_blocks failed\n", __func__); - return -1; - } - else if (fseek(f, orig, SEEK_SET)) - { - LOG("%s: fseek(3): %s\n", __func__, strerror(errno)); - return -1; - } + const double value = 0; - return 0; + return interp_stack_push(i, &value, sizeof value); } -#endif -static int push_local_count(struct nw_frame *const f, const varuint32 count, +static int push_locals(struct nw_interp *const in, const varuint32 count, const varint7 type) { enum value_type vtype; @@ -216,12 +105,26 @@ static int push_local_count(struct nw_frame *const f, const varuint32 count, return -1; } - f->n_locals = count; - f->local_type = vtype; + static int (*const f[])(struct nw_interp *) = + { + [VALUE_TYPE_I32] = push_i32, + [VALUE_TYPE_I64] = push_i64, + [VALUE_TYPE_F32] = push_f32, + [VALUE_TYPE_F64] = push_f64 + }; + + for (varuint32 i = 0; i < count; i++) + if (f[vtype](in)) + { + LOG("%s: local variable push failed, type=%s, index=%lu\n", + __func__, value_type_tostr(vtype), (unsigned long)i); + return -1; + } + return 0; } -static int check_local(FILE *const f, struct nw_frame *const fr) +static int check_local_group(FILE *const f, struct nw_interp *const i) { varuint32 count; varint7 type; @@ -236,16 +139,16 @@ static int check_local(FILE *const f, struct nw_frame *const fr) LOG("%s: varint7_read failed\n", __func__); return -1; } - else if (fr && push_local_count(fr, count, type)) + else if (i && push_locals(i, count, type)) { - LOG("%s: push_local_count failed\n", __func__); + LOG("%s: push_locals failed\n", __func__); return -1; } return 0; } -static int check_locals(FILE *const f, struct nw_frame *const fr) +static int run(FILE *const f, struct nw_interp *const in) { varuint32 local_count; @@ -256,7 +159,7 @@ static int check_locals(FILE *const f, struct nw_frame *const fr) } for (varuint32 i = 0; i < local_count; i++) - if (check_local(f, fr)) + if (check_local_group(f, in)) { LOG("%s: check_local failed\n", __func__); return -1; @@ -265,6 +168,23 @@ static int check_locals(FILE *const f, struct nw_frame *const fr) return 0; } +static int push_frame(struct nw_interp *const i, + const struct nw_frame *const src) +{ + struct nw_frame *const dst = interp_stackptr(i); + + if (interp_stack_push(i, src, sizeof (*src))) + { + LOG("%s: interp_stack_push failed\n", __func__); + return -1; + } + else if (i->fp) + i->fp->next = dst; + + i->fp = dst; + return 0; +} + static int check_function_body(FILE *const f, long *const out) { varuint32 body_size; @@ -282,9 +202,9 @@ static int check_function_body(FILE *const f, long *const out) LOG("%s: ftell(3) start: %s\n", __func__, strerror(errno)); return -1; } - else if (check_locals(f, NULL)) + else if (run(f, NULL)) { - LOG("%s: check_locals failed\n", __func__); + LOG("%s: check_local_groups failed\n", __func__); return -1; } @@ -313,8 +233,7 @@ static int check_function_body(FILE *const f, long *const out) return 0; } -static int run(FILE *const f, const varuint32 idx, - struct section_code *const out) +static int run(FILE *const f, const varuint32 idx, struct nw_interp *const in) { varuint32 count; @@ -323,11 +242,6 @@ static int run(FILE *const f, const varuint32 idx, LOG("%s: varuint32_read failed\n", __func__); return -1; } - else if (count > ULONG_MAX - 1) - { - fprintf(stderr, "%s: count overflow\n", __func__); - return -1; - } for (varuint32 i = 0; i < count; i++) { @@ -366,7 +280,7 @@ int section_code_check(const struct section *const s, struct nw_mod *const m, LOG("%s: ftell(3): %s\n", __func__, strerror(errno)); return -1; } - else if (run(f, 0, NULL)) + else if (run(f, NULL)) { LOG("%s: run failed\n", __func__); return -1; @@ -412,18 +326,7 @@ int section_code(const struct section *const s, const struct nw_mod *const m, return run(s->f, idx, out); } -int section_code_push(FILE *const f, const long pc, struct nw_frame *const fr) +int section_code_push(FILE *const f, struct nw_interp *const i) { - if (fseek(f, pc, SEEK_SET)) - { - LOG("%s: fseek(3): %s\n", __func__, strerror(errno)); - return -1; - } - else if (check_locals(f, fr)) - { - LOG("%s: check_local failed\n", __func__); - return -1; - } - - return 0; + return run(f, i); } diff --git a/src/section/common.c b/src/section/common.c index b768470..84ed191 100644 --- a/src/section/common.c +++ b/src/section/common.c @@ -60,91 +60,3 @@ int check_resizable_limits(FILE *const f, struct resizable_limits *const r) r->sz = initial * page_size; return 0; } - -size_t get_type_size(const enum value_type type) -{ - static const size_t list[] = - { - [VALUE_TYPE_I32] = sizeof (int32_t), - [VALUE_TYPE_I64] = sizeof (int64_t), - [VALUE_TYPE_F32] = sizeof (float), - [VALUE_TYPE_F64] = sizeof (double) - }; - - return list[type]; -} - -enum -{ - I32 = 0x7f, - I64 = 0x7e, - F32 = 0x7d, - F64 = 0x7c, - ANYFUNC = 0x70, - FUNC = 0x60, - BLOCK_TYPE = 0x40 -}; - -int get_value_type(const varint7 type, enum value_type *const vtype) -{ - static const struct size - { - varint7 type; - enum value_type vtype; - } sizes[] = - { - {.type = I32, .vtype = VALUE_TYPE_I32}, - {.type = I64, .vtype = VALUE_TYPE_I64}, - {.type = F32, .vtype = VALUE_TYPE_F32}, - {.type = F64, .vtype = VALUE_TYPE_F64}, - /* TODO: check this. */ - {.type = ANYFUNC, .vtype = VALUE_TYPE_I32}, - /* TODO: check this. */ - {.type = FUNC, .vtype = VALUE_TYPE_I32}, - /* TODO: check this. */ - {.type = BLOCK_TYPE, .vtype = VALUE_TYPE_I32} - }; - - for (size_t i = 0; i < sizeof sizes / sizeof *sizes; i++) - { - const struct size *const s = &sizes[i]; - - if (type == s->type) - { - *vtype = s->vtype; - return 0; - } - } - - LOG("%s: unknown type %#hhx\n", __func__, (char)type); - return -1; -} - -static int32_t swap_i32(const int32_t in) -{ - const int8_t *const p = (const int8_t *)∈ - - return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); -} - -int32_t htoni32(const int32_t in) -{ - return swap_i32(in); -} - -int32_t ntohi32(const int32_t in) -{ - return swap_i32(in); -} - -const char *value_type_tostr(const enum value_type v) -{ - static const char *const s[] = - { -#define X(x) [x] = #x, - VALUE_TYPES -#undef X - }; - - return s[v]; -} diff --git a/src/section/function.c b/src/section/function.c index 3ffed36..0395b24 100644 --- a/src/section/function.c +++ b/src/section/function.c @@ -28,11 +28,6 @@ static int run(FILE *const f, const varuint32 idx, LOG("%s: varuint32_read count failed\n", __func__); return -1; } - else if (count > ULONG_MAX - 1) - { - fprintf(stderr, "%s: count overflow\n", __func__); - return -1; - } for (varuint32 i = 0; i < count; i++) { diff --git a/src/section/global.c b/src/section/global.c index eff2e0b..4f3a2ee 100644 --- a/src/section/global.c +++ b/src/section/global.c @@ -30,66 +30,44 @@ struct global_type } value; }; -static int get_i32(const struct nw_interp *const i, - union global_value *const value) +static int get_global(struct nw_interp *const i, void *const dst, + const size_t n) { - if (i->stack_i != sizeof value->i32) + if (i->stack_i != n) { LOG("%s: expected %zu used stack bytes, got %zu\n", - __func__, i->stack_i, sizeof value->i32); + __func__, i->stack_i, n); + i->exception = "unexpected stack consumption"; return -1; } - value->i32 = *(const int32_t *)i->cfg.stack.buf; - return 0; + return interp_global_pop(i, dst, n); } -static int get_i64(const struct nw_interp *const i, - union global_value *const value) +static int get_i32(struct nw_interp *const i, union global_value *const value) { - if (i->stack_i != sizeof value->i64) - { - LOG("%s: expected %zu used stack bytes, got %zu\n", - __func__, i->stack_i, sizeof value->i64); - return -1; - } - - value->i64 = *(const int64_t *)i->cfg.stack.buf; - return 0; + return get_global(i, &value->i32, sizeof value->i32); } -static int get_f32(const struct nw_interp *const i, - union global_value *const value) +static int get_i64(struct nw_interp *const i, union global_value *const value) { - if (i->stack_i != sizeof value->f32) - { - LOG("%s: expected %zu used stack bytes, got %zu\n", - __func__, i->stack_i, sizeof value->f32); - return -1; - } - - value->f32 = *(const float *)i->cfg.stack.buf; - return 0; + return get_global(i, &value->i64, sizeof value->i64); } -static int get_f64(const struct nw_interp *const i, - union global_value *const value) +static int get_f32(struct nw_interp *const i, union global_value *const value) { - if (i->stack_i != sizeof value->f64) - { - LOG("%s: expected %zu used stack bytes, got %zu\n", - __func__, i->stack_i, sizeof value->f64); - return -1; - } + return get_global(i, &value->f32, sizeof value->f32); +} - value->f64 = *(const double *)i->cfg.stack.buf; - return 0; +static int get_f64(struct nw_interp *const i, union global_value *const value) +{ + return get_global(i, &value->f64, sizeof value->f64); } -static int get_value(const struct nw_interp *const i, - const enum value_type type, union global_value *const value) +static int get_value(struct nw_interp *const i, const enum value_type type, + union global_value *const value) { - static int (*const get[])(const struct nw_interp *, union global_value *) = + static int (*const get[])(struct nw_interp *, union global_value *) = { [VALUE_TYPE_I32] = get_i32, [VALUE_TYPE_I64] = get_i64, @@ -163,29 +141,33 @@ static int check_global_type(FILE *const f, struct global_type *const g) static int set_i32(struct nw_interp *const i, void *const dst, const struct global_type *const g) { - *(int32_t *)dst = g->value.i32; - return 0; + const int32_t value = g->value.i32; + + return interp_global_push(i, &value, sizeof value); } static int set_i64(struct nw_interp *const i, void *const dst, const struct global_type *const g) { - *(int64_t *)dst = g->value.i64; - return 0; + const int64_t value = g->value.i64; + + return interp_global_push(i, &value, sizeof value); } static int set_f32(struct nw_interp *const i, void *const dst, const struct global_type *const g) { - *(float *)dst = g->value.f32; - return 0; + const float value = g->value.f32; + + return interp_global_push(i, &value, sizeof value); } static int set_f64(struct nw_interp *const i, void *const dst, const struct global_type *const g) { - *(double *)dst = g->value.f64; - return 0; + const double value = g->value.f64; + + return interp_global_push(i, &value, sizeof value); } static int add_global(struct nw_interp *const i, @@ -197,24 +179,14 @@ static int add_global(struct nw_interp *const i, .type = g->type }; - const size_t sz = sizeof f + get_type_size(g->type), - max = i->cfg.global.n; + struct nw_gframe *const dst = interp_globalptr(i);; - if (max < sz || i->global_i > max - sz) + if (interp_global_push(i, &f, sizeof f)) { - LOG("%s: global memory overflow\n", __func__); - i->exception = "global memory overflow"; + LOG("%s: interp_global_push failed\n", __func__); return -1; } - void *const buf = (char *)i->cfg.global.buf + i->global_i; - struct nw_gframe *const dst = buf; - - if (i->gfp) - i->gfp->next = dst; - - *dst = f; - static int (*const set[])(struct nw_interp *, void *, const struct global_type *) = { @@ -226,11 +198,14 @@ static int add_global(struct nw_interp *const i, if (set[g->type](i, dst + 1, g)) { - LOG("%s: set failed with type %d\n", __func__, g->type); + LOG("%s: set failed with type %s\n", __func__, + value_type_tostr(g->type)); return -1; } - i->global_i += sz; + if (i->gfp) + i->gfp->next = dst; + i->gfp = dst; return 0; } diff --git a/src/section/type.c b/src/section/type.c index 0bf7a06..f7bc712 100644 --- a/src/section/type.c +++ b/src/section/type.c @@ -80,7 +80,7 @@ static int check_func_type(FILE *const f, struct retval *const r) } static int run(FILE *const f, const unsigned long len, const varuint32 idx, - struct nw_frame *const fr) + struct retval *const out) { const long start = ftell(f); varuint32 count; @@ -105,9 +105,9 @@ static int run(FILE *const f, const unsigned long len, const varuint32 idx, LOG("%s: check_func_type failed\n", __func__); return -1; } - else if (fr && i == idx) + else if (out && i == idx) { - fr->retval = r; + *out = r; return 0; } } @@ -161,7 +161,7 @@ int section_type_check(const struct section *const s, struct nw_mod *const m, } int section_type_push(FILE *const f, const struct nw_mod *const m, - const varuint32 idx, struct nw_frame *const fr) + const varuint32 idx, struct retval *const out) { const long offset = m->sections.type; @@ -176,5 +176,5 @@ int section_type_push(FILE *const f, const struct nw_mod *const m, return -1; } - return run(f, 0, idx, fr); + return run(f, 0, idx, out); } |
