summaryrefslogtreecommitdiff
path: root/src/runtime/c/pgf
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime/c/pgf')
-rw-r--r--src/runtime/c/pgf/data.h3
-rw-r--r--src/runtime/c/pgf/jit.c22
2 files changed, 24 insertions, 1 deletions
diff --git a/src/runtime/c/pgf/data.h b/src/runtime/c/pgf/data.h
index 8c9b577d9..b1e0a2b35 100644
--- a/src/runtime/c/pgf/data.h
+++ b/src/runtime/c/pgf/data.h
@@ -119,7 +119,8 @@ typedef enum {
PGF_INSTR_PUSH = 9,
PGF_INSTR_EVAL = 10,
PGF_INSTR_RET = 13,
- PGF_INSTR_FAIL = 15
+ PGF_INSTR_DROP = 15,
+ PGF_INSTR_FAIL = 16
} PgfInstruction;
struct PgfPGF {
diff --git a/src/runtime/c/pgf/jit.c b/src/runtime/c/pgf/jit.c
index 0470b7f9f..09fdf3bc6 100644
--- a/src/runtime/c/pgf/jit.c
+++ b/src/runtime/c/pgf/jit.c
@@ -1093,6 +1093,28 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr,
jit_bare_ret(a*sizeof(PgfClosure*));
break;
}
+ case PGF_INSTR_DROP: {
+ size_t n = pgf_read_int(rdr);
+ size_t target = pgf_read_int(rdr);
+
+#ifdef PGF_JIT_DEBUG
+ gu_printf(out, err, "DROP %d %03d\n", n, target);
+#endif
+
+ if (n > 0)
+ jit_addi_p(JIT_SP, JIT_SP, n*sizeof(PgfClosure*));
+
+ jit_insn *jump =
+ jit_jmpi(jit_forward());
+
+ PgfSegmentPatch label_patch;
+ label_patch.segment = target;
+ label_patch.ref = jump;
+ label_patch.is_abs = false;
+ gu_buf_push(rdr->jit_state->segment_patches, PgfSegmentPatch, label_patch);
+
+ break;
+ }
case PGF_INSTR_FAIL:
#ifdef PGF_JIT_DEBUG
gu_printf(out, err, "FAIL\n");