comparison src/bytecode.c @ 442:abe6d1db359e r21-2-36

Import from CVS: tag r21-2-36
author cvs
date Mon, 13 Aug 2007 11:35:02 +0200
parents 8de8e3f6228a
children 576fb035e263
comparison
equal deleted inserted replaced
441:72a7cfa4a488 442:abe6d1db359e
53 #include "backtrace.h" 53 #include "backtrace.h"
54 #include "buffer.h" 54 #include "buffer.h"
55 #include "bytecode.h" 55 #include "bytecode.h"
56 #include "opaque.h" 56 #include "opaque.h"
57 #include "syntax.h" 57 #include "syntax.h"
58
59 #include <limits.h>
60 58
61 EXFUN (Ffetch_bytecode, 1); 59 EXFUN (Ffetch_bytecode, 1);
62 60
63 Lisp_Object Qbyte_code, Qcompiled_functionp, Qinvalid_byte_code; 61 Lisp_Object Qbyte_code, Qcompiled_functionp, Qinvalid_byte_code;
64 62
214 212
215 213
216 static void invalid_byte_code_error (char *error_message, ...); 214 static void invalid_byte_code_error (char *error_message, ...);
217 215
218 Lisp_Object * execute_rare_opcode (Lisp_Object *stack_ptr, 216 Lisp_Object * execute_rare_opcode (Lisp_Object *stack_ptr,
219 CONST Opbyte *program_ptr, 217 const Opbyte *program_ptr,
220 Opcode opcode); 218 Opcode opcode);
221 219
222 static Lisp_Object execute_optimized_program (CONST Opbyte *program, 220 static Lisp_Object execute_optimized_program (const Opbyte *program,
223 int stack_depth, 221 int stack_depth,
224 Lisp_Object *constants_data); 222 Lisp_Object *constants_data);
225 223
226 extern Lisp_Object Qand_rest, Qand_optional; 224 extern Lisp_Object Qand_rest, Qand_optional;
227 225
471 in ARGS, and return the result of evaluation. */ 469 in ARGS, and return the result of evaluation. */
472 Lisp_Object 470 Lisp_Object
473 funcall_compiled_function (Lisp_Object fun, int nargs, Lisp_Object args[]) 471 funcall_compiled_function (Lisp_Object fun, int nargs, Lisp_Object args[])
474 { 472 {
475 /* This function can GC */ 473 /* This function can GC */
476 Lisp_Object symbol, tail;
477 int speccount = specpdl_depth(); 474 int speccount = specpdl_depth();
478 REGISTER int i = 0; 475 REGISTER int i = 0;
479 Lisp_Compiled_Function *f = XCOMPILED_FUNCTION (fun); 476 Lisp_Compiled_Function *f = XCOMPILED_FUNCTION (fun);
480 int optional = 0; 477 int optional = 0;
481 478
486 /* optimize_compiled_function() guaranteed that f->specpdl_depth is 483 /* optimize_compiled_function() guaranteed that f->specpdl_depth is
487 the required space on the specbinding stack for binding the args 484 the required space on the specbinding stack for binding the args
488 and local variables of fun. So just reserve it once. */ 485 and local variables of fun. So just reserve it once. */
489 SPECPDL_RESERVE (f->specpdl_depth); 486 SPECPDL_RESERVE (f->specpdl_depth);
490 487
491 /* Fmake_byte_code() guaranteed that f->arglist is a valid list 488 {
492 containing only non-constant symbols. */ 489 /* Fmake_byte_code() guaranteed that f->arglist is a valid list
493 LIST_LOOP_3 (symbol, f->arglist, tail) 490 containing only non-constant symbols. */
494 { 491 LIST_LOOP_3 (symbol, f->arglist, tail)
495 if (EQ (symbol, Qand_rest)) 492 {
496 { 493 if (EQ (symbol, Qand_rest))
497 tail = XCDR (tail); 494 {
498 symbol = XCAR (tail); 495 tail = XCDR (tail);
499 SPECBIND_FAST_UNSAFE (symbol, Flist (nargs - i, &args[i])); 496 symbol = XCAR (tail);
500 goto run_code; 497 SPECBIND_FAST_UNSAFE (symbol, Flist (nargs - i, &args[i]));
501 } 498 goto run_code;
502 else if (EQ (symbol, Qand_optional)) 499 }
503 optional = 1; 500 else if (EQ (symbol, Qand_optional))
504 else if (i == nargs && !optional) 501 optional = 1;
505 goto wrong_number_of_arguments; 502 else if (i == nargs && !optional)
506 else 503 goto wrong_number_of_arguments;
507 SPECBIND_FAST_UNSAFE (symbol, i < nargs ? args[i++] : Qnil); 504 else
508 } 505 SPECBIND_FAST_UNSAFE (symbol, i < nargs ? args[i++] : Qnil);
506 }
507 }
509 508
510 if (i < nargs) 509 if (i < nargs)
511 goto wrong_number_of_arguments; 510 goto wrong_number_of_arguments;
512 511
513 run_code: 512 run_code:
594 Don't change the constructs unless you are willing to do 593 Don't change the constructs unless you are willing to do
595 real benchmarking and profiling work -- martin */ 594 real benchmarking and profiling work -- martin */
596 595
597 596
598 static Lisp_Object 597 static Lisp_Object
599 execute_optimized_program (CONST Opbyte *program, 598 execute_optimized_program (const Opbyte *program,
600 int stack_depth, 599 int stack_depth,
601 Lisp_Object *constants_data) 600 Lisp_Object *constants_data)
602 { 601 {
603 /* This function can GC */ 602 /* This function can GC */
604 REGISTER CONST Opbyte *program_ptr = (Opbyte *) program; 603 REGISTER const Opbyte *program_ptr = (Opbyte *) program;
605 REGISTER Lisp_Object *stack_ptr 604 REGISTER Lisp_Object *stack_ptr
606 = alloca_array (Lisp_Object, stack_depth + 1); 605 = alloca_array (Lisp_Object, stack_depth + 1);
607 int speccount = specpdl_depth (); 606 int speccount = specpdl_depth ();
608 struct gcpro gcpro1; 607 struct gcpro gcpro1;
609 608
1219 rarely executed code, to minimize cache misses. 1218 rarely executed code, to minimize cache misses.
1220 1219
1221 Don't make this function static, since then the compiler might inline it. */ 1220 Don't make this function static, since then the compiler might inline it. */
1222 Lisp_Object * 1221 Lisp_Object *
1223 execute_rare_opcode (Lisp_Object *stack_ptr, 1222 execute_rare_opcode (Lisp_Object *stack_ptr,
1224 CONST Opbyte *program_ptr, 1223 const Opbyte *program_ptr,
1225 Opcode opcode) 1224 Opcode opcode)
1226 { 1225 {
1227 switch (opcode) 1226 switch (opcode)
1228 { 1227 {
1229 1228
1489 va_list args; 1488 va_list args;
1490 char *buf = alloca_array (char, strlen (error_message) + 128); 1489 char *buf = alloca_array (char, strlen (error_message) + 128);
1491 1490
1492 sprintf (buf, "%s", error_message); 1491 sprintf (buf, "%s", error_message);
1493 va_start (args, error_message); 1492 va_start (args, error_message);
1494 obj = emacs_doprnt_string_va ((CONST Bufbyte *) GETTEXT (buf), Qnil, -1, 1493 obj = emacs_doprnt_string_va ((const Bufbyte *) GETTEXT (buf), Qnil, -1,
1495 args); 1494 args);
1496 va_end (args); 1495 va_end (args);
1497 1496
1498 signal_error (Qinvalid_byte_code, list1 (obj)); 1497 signal_error (Qinvalid_byte_code, list1 (obj));
1499 } 1498 }
1605 static void 1604 static void
1606 optimize_byte_code (/* in */ 1605 optimize_byte_code (/* in */
1607 Lisp_Object instructions, 1606 Lisp_Object instructions,
1608 Lisp_Object constants, 1607 Lisp_Object constants,
1609 /* out */ 1608 /* out */
1610 Opbyte * CONST program, 1609 Opbyte * const program,
1611 int * CONST program_length, 1610 int * const program_length,
1612 int * CONST varbind_count) 1611 int * const varbind_count)
1613 { 1612 {
1614 size_t instructions_length = XSTRING_LENGTH (instructions); 1613 size_t instructions_length = XSTRING_LENGTH (instructions);
1615 size_t comfy_size = 2 * instructions_length; 1614 size_t comfy_size = 2 * instructions_length;
1616 1615
1617 int * CONST icounts = alloca_array (int, comfy_size); 1616 int * const icounts = alloca_array (int, comfy_size);
1618 int * icounts_ptr = icounts; 1617 int * icounts_ptr = icounts;
1619 1618
1620 /* We maintain a table of jumps in the source code. */ 1619 /* We maintain a table of jumps in the source code. */
1621 struct jump 1620 struct jump
1622 { 1621 {
1623 int from; 1622 int from;
1624 int to; 1623 int to;
1625 }; 1624 };
1626 struct jump * CONST jumps = alloca_array (struct jump, comfy_size); 1625 struct jump * const jumps = alloca_array (struct jump, comfy_size);
1627 struct jump *jumps_ptr = jumps; 1626 struct jump *jumps_ptr = jumps;
1628 1627
1629 Opbyte *program_ptr = program; 1628 Opbyte *program_ptr = program;
1630 1629
1631 CONST Bufbyte *ptr = XSTRING_DATA (instructions); 1630 const Bufbyte *ptr = XSTRING_DATA (instructions);
1632 CONST Bufbyte * CONST end = ptr + instructions_length; 1631 const Bufbyte * const end = ptr + instructions_length;
1633 1632
1634 *varbind_count = 0; 1633 *varbind_count = 0;
1635 1634
1636 while (ptr < end) 1635 while (ptr < end)
1637 { 1636 {
2067 2066
2068 { 2067 {
2069 /* Invert action performed by optimize_byte_code() */ 2068 /* Invert action performed by optimize_byte_code() */
2070 Lisp_Opaque *opaque = XOPAQUE (f->instructions); 2069 Lisp_Opaque *opaque = XOPAQUE (f->instructions);
2071 2070
2072 Bufbyte * CONST buffer = 2071 Bufbyte * const buffer =
2073 alloca_array (Bufbyte, OPAQUE_SIZE (opaque) * MAX_EMCHAR_LEN); 2072 alloca_array (Bufbyte, OPAQUE_SIZE (opaque) * MAX_EMCHAR_LEN);
2074 Bufbyte *bp = buffer; 2073 Bufbyte *bp = buffer;
2075 2074
2076 CONST Opbyte * CONST program = (CONST Opbyte *) OPAQUE_DATA (opaque); 2075 const Opbyte * const program = (const Opbyte *) OPAQUE_DATA (opaque);
2077 CONST Opbyte *program_ptr = program; 2076 const Opbyte *program_ptr = program;
2078 CONST Opbyte * CONST program_end = program_ptr + OPAQUE_SIZE (opaque); 2077 const Opbyte * const program_end = program_ptr + OPAQUE_SIZE (opaque);
2079 2078
2080 while (program_ptr < program_end) 2079 while (program_ptr < program_end)
2081 { 2080 {
2082 Opcode opcode = (Opcode) READ_UINT_1; 2081 Opcode opcode = (Opcode) READ_UINT_1;
2083 bp += set_charptr_emchar (bp, opcode); 2082 bp += set_charptr_emchar (bp, opcode);
2408 2407
2409 2408
2410 void 2409 void
2411 syms_of_bytecode (void) 2410 syms_of_bytecode (void)
2412 { 2411 {
2413 deferror (&Qinvalid_byte_code, "invalid-byte-code", 2412 INIT_LRECORD_IMPLEMENTATION (compiled_function);
2414 "Invalid byte code", Qerror); 2413
2414 DEFERROR_STANDARD (Qinvalid_byte_code, Qinvalid_state);
2415 defsymbol (&Qbyte_code, "byte-code"); 2415 defsymbol (&Qbyte_code, "byte-code");
2416 defsymbol (&Qcompiled_functionp, "compiled-function-p"); 2416 defsymbol (&Qcompiled_functionp, "compiled-function-p");
2417 2417
2418 DEFSUBR (Fbyte_code); 2418 DEFSUBR (Fbyte_code);
2419 DEFSUBR (Ffetch_bytecode); 2419 DEFSUBR (Ffetch_bytecode);