aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/interp/ops.c4
-rw-r--r--src/op/CMakeLists.txt2
-rw-r--r--src/op/block.c9
-rw-r--r--src/op/else.c18
-rw-r--r--src/op/if.c43
-rw-r--r--src/op/loop.c10
-rw-r--r--src/routines/start_block.c17
7 files changed, 92 insertions, 11 deletions
diff --git a/src/interp/ops.c b/src/interp/ops.c
index de69126..2bfdff0 100644
--- a/src/interp/ops.c
+++ b/src/interp/ops.c
@@ -18,8 +18,8 @@ static void (*const ops[])(struct nw_interp *) =
nwp_op_nop, /* OP_NOP */
nwp_op_block, /* OP_BLOCK */
nwp_op_loop, /* OP_LOOP */
- NULL, /* OP_IF */
- NULL, /* OP_ELSE */
+ nwp_op_if, /* OP_IF */
+ nwp_op_else, /* OP_ELSE */
NULL,
NULL,
NULL,
diff --git a/src/op/CMakeLists.txt b/src/op/CMakeLists.txt
index 4b4a531..bea3555 100644
--- a/src/op/CMakeLists.txt
+++ b/src/op/CMakeLists.txt
@@ -12,6 +12,7 @@ target_sources(${PROJECT_NAME} PRIVATE
call.c
call_indirect.c
drop.c
+ else.c
end.c
get_local.c
get_global.c
@@ -35,6 +36,7 @@ target_sources(${PROJECT_NAME} PRIVATE
i32_sub.c
i64_const.c
i64_store.c
+ if.c
loop.c
nop.c
return.c
diff --git a/src/op/block.c b/src/op/block.c
index e35a722..78651da 100644
--- a/src/op/block.c
+++ b/src/op/block.c
@@ -8,10 +8,17 @@
*/
#include <nanowasm/nw.h>
+#include <nw/interp.h>
#include <nw/ops.h>
#include <nw/routines.h>
+static enum nw_state resume(struct nw_interp *const i)
+{
+ nwp_interp_resume(i);
+ return NW_AGAIN;
+}
+
void nwp_op_block(struct nw_interp *const i)
{
- nwp_start_block(i);
+ nwp_start_block(i, &i->sm.start_block, resume);
}
diff --git a/src/op/else.c b/src/op/else.c
new file mode 100644
index 0000000..2c1c6b1
--- /dev/null
+++ b/src/op/else.c
@@ -0,0 +1,18 @@
+/*
+ * nanowasm, a tiny WebAssembly/Wasm interpreter
+ * Copyright (C) 2023-2025 Xavier Del Campo Romero
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+#include <nanowasm/nw.h>
+#include <nw/interp.h>
+#include <nw/ops.h>
+#include <nw/routines.h>
+
+void nwp_op_else(struct nw_interp *const i)
+{
+ nwp_break(i, 0);
+}
diff --git a/src/op/if.c b/src/op/if.c
new file mode 100644
index 0000000..2ef9565
--- /dev/null
+++ b/src/op/if.c
@@ -0,0 +1,43 @@
+/*
+ * nanowasm, a tiny WebAssembly/Wasm interpreter
+ * Copyright (C) 2023-2025 Xavier Del Campo Romero
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+#include <nanowasm/nw.h>
+#include <nw/interp.h>
+#include <nw/io.h>
+#include <nw/ops.h>
+#include <nw/routines.h>
+#include <nw/stack.h>
+#include <nw/types.h>
+
+static enum nw_state pop(struct nw_interp *const i)
+{
+ struct nw_i_sm_if *const pif = &i->sm.sm_if;
+ const enum nw_state n = nwp_stack_pop(i, &pif->io);
+
+ if (n)
+ return n;
+ else if (pif->condition)
+ nwp_interp_resume(i);
+ else
+ nwp_break(i, 0);
+
+ return NW_AGAIN;
+}
+
+void nwp_op_if(struct nw_interp *const i)
+{
+ static const struct nw_i_sm_if sm_if;
+ struct nw_i_sm_if *const pif = &i->sm.sm_if;
+ struct nw_sm_io *const io = &pif->io;
+
+ *pif = sm_if;
+ io->buf = &pif->condition;
+ io->n = sizeof pif->condition;
+ nwp_start_block(i, &pif->sb, pop);
+}
diff --git a/src/op/loop.c b/src/op/loop.c
index e129610..cb3137b 100644
--- a/src/op/loop.c
+++ b/src/op/loop.c
@@ -8,9 +8,17 @@
*/
#include <nanowasm/nw.h>
+#include <nw/interp.h>
+#include <nw/ops.h>
#include <nw/routines.h>
+static enum nw_state resume(struct nw_interp *const i)
+{
+ nwp_interp_resume(i);
+ return NW_AGAIN;
+}
+
void nwp_op_loop(struct nw_interp *const i)
{
- nwp_start_block(i);
+ nwp_start_block(i, &i->sm.start_block, resume);
}
diff --git a/src/routines/start_block.c b/src/routines/start_block.c
index 83be44c..fb0b420 100644
--- a/src/routines/start_block.c
+++ b/src/routines/start_block.c
@@ -17,7 +17,7 @@
static enum nw_state get_block_type(struct nw_interp *const i)
{
nw_varint7 type;
- struct nw_i_sm_sb *const sb = &i->sm.start_block;
+ struct nw_i_sm_sb *const sb = i->state;
const struct nw_io_cfg *const cfg = &i->cfg.io;
const enum nw_state n = nwp_varint7(cfg, &sb->leb128, &type, cfg->user);
enum nw_type block_type;
@@ -26,24 +26,27 @@ static enum nw_state get_block_type(struct nw_interp *const i)
return n;
else if (type != 0x40 && nwp_get_type(type, &block_type))
{
- static const char *const exc = "invalid block_type";
+ static const char *const exc = "invalid block type";
i->exception = exc;
-#ifdef NW_LOG
- nwp_log("%s: %#hhx\n", exc, (unsigned char)type);
+#ifdef ENABLE_LOG
+ nwp_log("%s: %#x\n", exc, (unsigned)type);
#endif
return NW_FATAL;
}
i->fr.block_i++;
- nwp_interp_resume(i);
+ i->next = sb->next;
return NW_AGAIN;
}
-void nwp_start_block(struct nw_interp *const i)
+void nwp_start_block(struct nw_interp *const i, struct nw_i_sm_sb *const psb,
+ enum nw_state (*const next)(struct nw_interp *))
{
const struct nw_i_sm_sb sb = {0};
- i->sm.start_block = sb;
+ *psb = sb;
+ psb->next = next;
+ i->state = psb;
i->next = get_block_type;
}