aboutsummaryrefslogtreecommitdiffstats
path: root/src/bytecode.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bytecode.c')
-rw-r--r--src/bytecode.c128
1 files changed, 122 insertions, 6 deletions
diff --git a/src/bytecode.c b/src/bytecode.c
index c53c5acdbb3..fec855c0b83 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -87,9 +87,11 @@ int byte_metering_on;
87 87
88 88
89Lisp_Object Qbytecode; 89Lisp_Object Qbytecode;
90extern Lisp_Object Qand_optional, Qand_rest;
90 91
91/* Byte codes: */ 92/* Byte codes: */
92 93
94#define Bstack_ref 0
93#define Bvarref 010 95#define Bvarref 010
94#define Bvarset 020 96#define Bvarset 020
95#define Bvarbind 030 97#define Bvarbind 030
@@ -229,6 +231,13 @@ Lisp_Object Qbytecode;
229#define BconcatN 0260 231#define BconcatN 0260
230#define BinsertN 0261 232#define BinsertN 0261
231 233
234/* Bstack_ref is code 0. */
235#define Bstack_set 0262
236#define Bstack_set2 0263
237#define Bvec_ref 0264
238#define Bvec_set 0265
239#define BdiscardN 0266
240
232#define Bconstant 0300 241#define Bconstant 0300
233#define CONSTANTLIM 0100 242#define CONSTANTLIM 0100
234 243
@@ -397,14 +406,41 @@ unmark_byte_stack ()
397 } while (0) 406 } while (0)
398 407
399 408
400DEFUN ("byte-code", Fbyte_code, Sbyte_code, 3, 3, 0, 409DEFUN ("byte-code", Fbyte_code, Sbyte_code, 3, MANY, 0,
401 doc: /* Function used internally in byte-compiled code. 410 doc: /* Function used internally in byte-compiled code.
402The first argument, BYTESTR, is a string of byte code; 411The first argument, BYTESTR, is a string of byte code;
403the second, VECTOR, a vector of constants; 412the second, VECTOR, a vector of constants;
404the third, MAXDEPTH, the maximum stack depth used in this function. 413the third, MAXDEPTH, the maximum stack depth used in this function.
405If the third argument is incorrect, Emacs may crash. */) 414If the third argument is incorrect, Emacs may crash.
406 (bytestr, vector, maxdepth) 415
407 Lisp_Object bytestr, vector, maxdepth; 416If ARGS-TEMPLATE is specified, it is an argument list specification,
417according to which any remaining arguments are pushed on the stack
418before executing BYTESTR.
419
420usage: (byte-code BYTESTR VECTOR MAXDEP &optional ARGS-TEMPLATE &rest ARGS) */)
421 (nargs, args)
422 int nargs;
423 Lisp_Object *args;
424{
425 Lisp_Object args_tmpl = nargs >= 4 ? args[3] : Qnil;
426 int pnargs = nargs >= 4 ? nargs - 4 : 0;
427 Lisp_Object *pargs = nargs >= 4 ? args + 4 : 0;
428 return exec_byte_code (args[0], args[1], args[2], args_tmpl, pnargs, pargs);
429}
430
431/* Execute the byte-code in BYTESTR. VECTOR is the constant vector, and
432 MAXDEPTH is the maximum stack depth used (if MAXDEPTH is incorrect,
433 emacs may crash!). If ARGS_TEMPLATE is non-nil, it should be a lisp
434 argument list (including &rest, &optional, etc.), and ARGS, of size
435 NARGS, should be a vector of the actual arguments. The arguments in
436 ARGS are pushed on the stack according to ARGS_TEMPLATE before
437 executing BYTESTR. */
438
439Lisp_Object
440exec_byte_code (bytestr, vector, maxdepth, args_template, nargs, args)
441 Lisp_Object bytestr, vector, maxdepth, args_template;
442 int nargs;
443 Lisp_Object *args;
408{ 444{
409 int count = SPECPDL_INDEX (); 445 int count = SPECPDL_INDEX ();
410#ifdef BYTE_CODE_METER 446#ifdef BYTE_CODE_METER
@@ -462,6 +498,37 @@ If the third argument is incorrect, Emacs may crash. */)
462 stacke = stack.bottom - 1 + XFASTINT (maxdepth); 498 stacke = stack.bottom - 1 + XFASTINT (maxdepth);
463#endif 499#endif
464 500
501 if (! NILP (args_template))
502 /* We should push some arguments on the stack. */
503 {
504 Lisp_Object at;
505 int pushed = 0, optional = 0;
506
507 for (at = args_template; CONSP (at); at = XCDR (at))
508 if (EQ (XCAR (at), Qand_optional))
509 optional = 1;
510 else if (EQ (XCAR (at), Qand_rest))
511 {
512 PUSH (Flist (nargs, args));
513 pushed = nargs;
514 at = Qnil;
515 break;
516 }
517 else if (pushed < nargs)
518 {
519 PUSH (*args++);
520 pushed++;
521 }
522 else if (optional)
523 PUSH (Qnil);
524 else
525 break;
526
527 if (pushed != nargs || !NILP (at))
528 Fsignal (Qwrong_number_of_arguments,
529 Fcons (args_template, Fcons (make_number (nargs), Qnil)));
530 }
531
465 while (1) 532 while (1)
466 { 533 {
467#ifdef BYTE_CODE_SAFE 534#ifdef BYTE_CODE_SAFE
@@ -1641,8 +1708,57 @@ If the third argument is incorrect, Emacs may crash. */)
1641 break; 1708 break;
1642#endif 1709#endif
1643 1710
1644 case 0: 1711 /* Handy byte-codes for lexical binding. */
1645 abort (); 1712 case Bstack_ref:
1713 case Bstack_ref+1:
1714 case Bstack_ref+2:
1715 case Bstack_ref+3:
1716 case Bstack_ref+4:
1717 case Bstack_ref+5:
1718 PUSH (stack.bottom[op - Bstack_ref]);
1719 break;
1720 case Bstack_ref+6:
1721 PUSH (stack.bottom[FETCH]);
1722 break;
1723 case Bstack_ref+7:
1724 PUSH (stack.bottom[FETCH2]);
1725 break;
1726 case Bstack_set:
1727 stack.bottom[FETCH] = POP;
1728 break;
1729 case Bstack_set2:
1730 stack.bottom[FETCH2] = POP;
1731 break;
1732 case Bvec_ref:
1733 case Bvec_set:
1734 /* These byte-codes used mostly for variable references to
1735 lexically bound variables that are in an environment vector
1736 instead of on the byte-interpreter stack (generally those
1737 variables which might be shared with a closure). */
1738 {
1739 int index = FETCH;
1740 Lisp_Object vec = POP;
1741
1742 if (! VECTORP (vec))
1743 wrong_type_argument (Qvectorp, vec);
1744 else if (index < 0 || index >= XVECTOR (vec)->size)
1745 args_out_of_range (vec, index);
1746
1747 if (op == Bvec_ref)
1748 PUSH (XVECTOR (vec)->contents[index]);
1749 else
1750 XVECTOR (vec)->contents[index] = POP;
1751 }
1752 break;
1753 case BdiscardN:
1754 op = FETCH;
1755 if (op & 0x80)
1756 {
1757 op &= 0x7F;
1758 top[-op] = TOP;
1759 }
1760 DISCARD (op);
1761 break;
1646 1762
1647 case 255: 1763 case 255:
1648 default: 1764 default: