summaryrefslogtreecommitdiff
path: root/src/bytecode.c
diff options
context:
space:
mode:
authorVibhav Pant <vibhavp@gmail.com>2017-01-15 01:26:04 +0530
committerVibhav Pant <vibhavp@gmail.com>2017-01-15 01:26:04 +0530
commit88549ec38e9bb30e338a9985d0de4e6263b40fb7 (patch)
tree4ee41982939210a6f8a6d74fd539b528805b7b04 /src/bytecode.c
parent877c525f4b98bc785f1bb0b50d70f72d09c80eb2 (diff)
downloademacs-88549ec38e9bb30e338a9985d0de4e6263b40fb7.tar.gz
emacs-88549ec38e9bb30e338a9985d0de4e6263b40fb7.tar.bz2
emacs-88549ec38e9bb30e338a9985d0de4e6263b40fb7.zip
Add new 'switch' byte-code.
'switch' takes two arguments from the stack: the variable to test, and a jump table (implemented as a hash-table with the appropriate :test function). By looking up the value of the variable in the hash table, the interpreter can jump to the label pointed to by the value, if any. This implementation can only be used for `cond' forms of the type `(cond ((test x 'foo) 'bar) ...)`, such that the function `test` and variable `x` is same for all clauses. * lisp/emacs-lisp/bytecomp.el: * Add (byte-compile-cond-valid-obj2-p), (byte-compile-cond-vars), (byte-compile-cond-jump-table-info), (byte-compile-jump-table-add-tag), (byte-compile-cond-jump-table), byte-compile-jump-tables. * Add defcustom `byte-compile-cond-use-jump-table'. * (byte-compile-cond): Use them. * (byte-compile-lapcode): Patch tags present in jump tables, if any. * lisp/emacs-lisp//byte-opt.el: (byte-optimize-lapcode): Add checks to some peephole optimizations to prevent them from messing up any code involving `byte-switch`. * src/bytecode.c: (exec_byte_code): Add bytecode Bswitch.
Diffstat (limited to 'src/bytecode.c')
-rw-r--r--src/bytecode.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/src/bytecode.c b/src/bytecode.c
index a64bc171d14..1695af9cb02 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -267,6 +267,8 @@ DEFINE (Bstack_set, 0262) \
DEFINE (Bstack_set2, 0263) \
DEFINE (BdiscardN, 0266) \
\
+DEFINE (Bswitch, 0267) \
+ \
DEFINE (Bconstant, 0300)
enum byte_code_op
@@ -1411,6 +1413,20 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
DISCARD (op);
NEXT;
+ CASE (Bswitch):
+ {
+ Lisp_Object jmp_table = POP;
+ Lisp_Object v1 = POP;
+ Lisp_Object dest = Fgethash(v1, jmp_table, Qnil);
+ if (!NILP(dest)) {
+ int car = XINT(XCAR(dest));
+ int cdr = XINT(XCDR(dest));
+ op = car + (cdr << 8); /* Simulate FETCH2 */
+ goto op_branch;
+ }
+ }
+ NEXT;
+
CASE_DEFAULT
CASE (Bconstant):
if (BYTE_CODE_SAFE