aboutsummaryrefslogtreecommitdiff
path: root/src/section
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi.dcr@tutanota.com>2024-05-22 14:04:36 +0200
committerXavier Del Campo Romero <xavi.dcr@tutanota.com>2024-06-12 13:38:05 +0200
commit4f9a2c7a2d8464b04cc08075a7762c6d457090df (patch)
treeae8fe229a3a5ba60d08b74299d0c1850685bda86 /src/section
parentf25b015e5b668028c34974bbb22faa4105c26690 (diff)
downloadnanowasm-sync-4f9a2c7a2d8464b04cc08075a7762c6d457090df.tar.gz
WIP
Diffstat (limited to 'src/section')
-rw-r--r--src/section/code.c211
-rw-r--r--src/section/common.c88
-rw-r--r--src/section/function.c5
-rw-r--r--src/section/global.c103
-rw-r--r--src/section/type.c10
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 *)&in;
-
- 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);
}