summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--share/txr/stdlib/asm.tl2
-rw-r--r--vm.c17
-rw-r--r--vmop.h61
3 files changed, 48 insertions, 32 deletions
diff --git a/share/txr/stdlib/asm.tl b/share/txr/stdlib/asm.tl
index c6a7efc9..4871dd4f 100644
--- a/share/txr/stdlib/asm.tl
+++ b/share/txr/stdlib/asm.tl
@@ -268,6 +268,8 @@
(:method dis (me asm lev size)
^(,me.symbol ,lev ,size)))
+(defopcode-derived op-sframe sframe auto op-frame)
+
(defopcode-derived op-dframe dframe auto op-frame)
(defopcode op-end end auto
diff --git a/vm.c b/vm.c
index 128b8f29..7759500c 100644
--- a/vm.c
+++ b/vm.c
@@ -262,7 +262,7 @@ INLINE void vm_set(struct vm_env *dspl, unsigned ref, val newval)
mut(env->vec);
}
-static void vm_frame(struct vm *vm, vm_word_t insn)
+static void vm_do_frame(struct vm *vm, vm_word_t insn, int capturable)
{
int lev = vm_insn_extra(insn);
int size = vm_insn_operand(insn);
@@ -272,11 +272,21 @@ static void vm_frame(struct vm *vm, vm_word_t insn)
vm->lev = lev;
vm->dspl[lev].mem = coerce(val *, zalloca(size * sizeof (val *)));
- vm->dspl[lev].vec = num_fast(size);
+ vm->dspl[lev].vec = (capturable ? num_fast(size) : 0);
vm_execute(vm);
vm->lev = lev - 1;
}
+static void vm_frame(struct vm *vm, vm_word_t insn)
+{
+ vm_do_frame(vm, insn, 1);
+}
+
+static void vm_sframe(struct vm *vm, vm_word_t insn)
+{
+ vm_do_frame(vm, insn, 0);
+}
+
static void vm_dframe(struct vm *vm, vm_word_t insn)
{
val saved_dyn_env = dyn_env;
@@ -610,6 +620,9 @@ static val vm_execute(struct vm *vm)
case FRAME:
vm_frame(vm, insn);
break;
+ case SFRAME:
+ vm_sframe(vm, insn);
+ break;
case DFRAME:
vm_dframe(vm, insn);
break;
diff --git a/vmop.h b/vmop.h
index 6f4d518a..6783b25d 100644
--- a/vmop.h
+++ b/vmop.h
@@ -28,34 +28,35 @@
typedef enum vm_op {
NOOP = 0,
FRAME = 1,
- DFRAME = 2,
- END = 3,
- FIN = 4,
- CALL = 5,
- APPLY = 6,
- MOVRS = 7,
- MOVSR = 8,
- MOVRR = 9,
- MOVRSI = 10,
- MOVSMI = 11,
- MOVRBI = 12,
- JMP = 13,
- IF = 14,
- UWPROT = 15,
- BLOCK = 16,
- RETSR = 17,
- RETRS = 18,
- RETRR = 19,
- CATCH = 20,
- HANDLE = 21,
- GETV = 22,
- GETF = 23,
- GETL1 = 24,
- GETVB = 25,
- GETFB = 26,
- GETL1B = 27,
- SETV = 28,
- SETL1 = 29,
- BINDV = 30,
- CLOSE = 31,
+ SFRAME = 2,
+ DFRAME = 3,
+ END = 4,
+ FIN = 5,
+ CALL = 6,
+ APPLY = 7,
+ MOVRS = 8,
+ MOVSR = 9,
+ MOVRR = 10,
+ MOVRSI = 11,
+ MOVSMI = 12,
+ MOVRBI = 13,
+ JMP = 14,
+ IF = 15,
+ UWPROT = 16,
+ BLOCK = 17,
+ RETSR = 18,
+ RETRS = 19,
+ RETRR = 20,
+ CATCH = 21,
+ HANDLE = 22,
+ GETV = 23,
+ GETF = 24,
+ GETL1 = 25,
+ GETVB = 26,
+ GETFB = 27,
+ GETL1B = 28,
+ SETV = 29,
+ SETL1 = 30,
+ BINDV = 31,
+ CLOSE = 32,
} vm_op_t;