X-Git-Url: http://git.chise.org/gitweb/?p=chise%2Fxemacs-chise.git.1;a=blobdiff_plain;f=src%2Fbytecode.c;h=72f5d62a67970432a229ebf6fb9cda63afd6b5b2;hp=b5111d1eb031d1dd4cb2aac6f151dc560691b05e;hb=8b2e8ef2dee7da2f0d4cea712b0fc55902c3cff7;hpb=77dcef404dc78635f6ffa8f71a803d2bc7cc8921 diff --git a/src/bytecode.c b/src/bytecode.c index b5111d1..72f5d62 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -28,7 +28,7 @@ Boston, MA 02111-1307, USA. */ FSF: long ago. -hacked on by jwz@netscape.com 1991-06 +hacked on by jwz@jwz.org 1991-06 o added a compile-time switch to turn on simple sanity checking; o put back the obsolete byte-codes for error-detection; o added a new instruction, unbind_all, which I will use for @@ -56,9 +56,6 @@ by Hallvard: #include "opaque.h" #include "syntax.h" -#include -#include - EXFUN (Ffetch_bytecode, 1); Lisp_Object Qbyte_code, Qcompiled_functionp, Qinvalid_byte_code; @@ -214,24 +211,19 @@ typedef enum Opcode Opcode; typedef unsigned char Opbyte; +static void check_opcode (Opcode opcode); static void invalid_byte_code_error (char *error_message, ...); Lisp_Object * execute_rare_opcode (Lisp_Object *stack_ptr, - CONST Opbyte *program_ptr, + const Opbyte *program_ptr, Opcode opcode); -static Lisp_Object execute_optimized_program (CONST Opbyte *program, +static Lisp_Object execute_optimized_program (const Opbyte *program, int stack_depth, Lisp_Object *constants_data); extern Lisp_Object Qand_rest, Qand_optional; -/* Define ERROR_CHECK_BYTE_CODE to enable some minor sanity checking. - Useful for debugging the byte compiler. */ -#ifdef DEBUG_XEMACS -#define ERROR_CHECK_BYTE_CODE -#endif - /* Define BYTE_CODE_METER to enable generation of a byte-op usage histogram. This isn't defined in FSF Emacs and isn't defined in XEmacs v19. */ /* #define BYTE_CODE_METER */ @@ -242,21 +234,17 @@ extern Lisp_Object Qand_rest, Qand_optional; Lisp_Object Vbyte_code_meter, Qbyte_code_meter; int byte_metering_on; -#define METER_2(code1, code2) \ - XINT (XVECTOR_DATA (XVECTOR_DATA (Vbyte_code_meter)[(code1)])[(code2)]) - -#define METER_1(code) METER_2 (0, (code)) - -#define METER_CODE(last_code, this_code) do { \ - if (byte_metering_on) \ - { \ - if (METER_1 (this_code) != ((1<specpdl_depth); - /* Fmake_byte_code() guaranteed that f->arglist is a valid list - containing only non-constant symbols. */ - LIST_LOOP_3 (symbol, f->arglist, tail) - { - if (EQ (symbol, Qand_rest)) - { - tail = XCDR (tail); - symbol = XCAR (tail); - SPECBIND_FAST_UNSAFE (symbol, Flist (nargs - i, &args[i])); - goto run_code; - } - else if (EQ (symbol, Qand_optional)) - optional = 1; - else if (i == nargs && !optional) - goto wrong_number_of_arguments; - else - SPECBIND_FAST_UNSAFE (symbol, i < nargs ? args[i++] : Qnil); - } + { + /* Fmake_byte_code() guaranteed that f->arglist is a valid list + containing only non-constant symbols. */ + LIST_LOOP_3 (symbol, f->arglist, tail) + { + if (EQ (symbol, Qand_rest)) + { + tail = XCDR (tail); + symbol = XCAR (tail); + SPECBIND_FAST_UNSAFE (symbol, Flist (nargs - i, &args[i])); + goto run_code; + } + else if (EQ (symbol, Qand_optional)) + optional = 1; + else if (i == nargs && !optional) + goto wrong_number_of_arguments; + else + SPECBIND_FAST_UNSAFE (symbol, i < nargs ? args[i++] : Qnil); + } + } if (i < nargs) goto wrong_number_of_arguments; @@ -529,11 +518,19 @@ funcall_compiled_function (Lisp_Object fun, int nargs, Lisp_Object args[]) f->stack_depth, XVECTOR_DATA (f->constants)); - UNBIND_TO_GCPRO_VARIABLES_ONLY (speccount, value); + /* The attempt to optimize this by only unbinding variables failed + because using buffer-local variables as function parameters + leads to specpdl_ptr->func != 0 */ + /* UNBIND_TO_GCPRO_VARIABLES_ONLY (speccount, value); */ + UNBIND_TO_GCPRO (speccount, value); return value; } wrong_number_of_arguments: + /* The actual printed compiled_function object is incomprehensible. + Check the backtrace to see if we can get a more meaningful symbol. */ + if (EQ (fun, indirect_function (*backtrace_list->function, 0))) + fun = *backtrace_list->function; return Fsignal (Qwrong_number_of_arguments, list2 (fun, make_int (nargs))); } @@ -599,12 +596,12 @@ funcall_compiled_function (Lisp_Object fun, int nargs, Lisp_Object args[]) static Lisp_Object -execute_optimized_program (CONST Opbyte *program, +execute_optimized_program (const Opbyte *program, int stack_depth, Lisp_Object *constants_data) { /* This function can GC */ - REGISTER CONST Opbyte *program_ptr = (Opbyte *) program; + REGISTER const Opbyte *program_ptr = (Opbyte *) program; REGISTER Lisp_Object *stack_ptr = alloca_array (Lisp_Object, stack_depth + 1); int speccount = specpdl_depth (); @@ -641,12 +638,13 @@ execute_optimized_program (CONST Opbyte *program, invalid_byte_code_error ("byte code stack overflow"); if (stack_ptr < stack_beg) invalid_byte_code_error ("byte code stack underflow"); + check_opcode (opcode); #endif #ifdef BYTE_CODE_METER prev_opcode = this_opcode; this_opcode = opcode; - METER_CODE (prev_opcode, this_opcode); + meter_code (prev_opcode, this_opcode); #endif switch (opcode) @@ -689,7 +687,7 @@ execute_optimized_program (CONST Opbyte *program, do_varset: { Lisp_Object symbol = constants_data[n]; - struct Lisp_Symbol *symbol_ptr = XSYMBOL (symbol); + Lisp_Symbol *symbol_ptr = XSYMBOL (symbol); Lisp_Object old_value = symbol_ptr->value; Lisp_Object new_value = POP; if (!SYMBOL_VALUE_MAGIC_P (old_value) || UNBOUNDP (old_value)) @@ -710,7 +708,7 @@ execute_optimized_program (CONST Opbyte *program, do_varbind: { Lisp_Object symbol = constants_data[n]; - struct Lisp_Symbol *symbol_ptr = XSYMBOL (symbol); + Lisp_Symbol *symbol_ptr = XSYMBOL (symbol); Lisp_Object old_value = symbol_ptr->value; Lisp_Object new_value = POP; if (!SYMBOL_VALUE_MAGIC_P (old_value) || UNBOUNDP (old_value)) @@ -763,6 +761,7 @@ execute_optimized_program (CONST Opbyte *program, opcode == Bunbind+6 ? READ_UINT_1 : READ_UINT_2)); break; + case Bgoto: JUMP; break; @@ -1000,11 +999,11 @@ execute_optimized_program (CONST Opbyte *program, } case Bsub1: - TOP = INTP (TOP) ? make_int (XINT (TOP) - 1) : Fsub1 (TOP); + TOP = INTP (TOP) ? INT_MINUS1 (TOP) : Fsub1 (TOP); break; case Badd1: - TOP = INTP (TOP) ? make_int (XINT (TOP) + 1) : Fadd1 (TOP); + TOP = INTP (TOP) ? INT_PLUS1 (TOP) : Fadd1 (TOP); break; @@ -1058,7 +1057,7 @@ execute_optimized_program (CONST Opbyte *program, Lisp_Object arg2 = POP; Lisp_Object arg1 = TOP; TOP = INTP (arg1) && INTP (arg2) ? - make_int (XINT (arg1) + XINT (arg2)) : + INT_PLUS (arg1, arg2) : bytecode_arithop (arg1, arg2, opcode); break; } @@ -1068,7 +1067,7 @@ execute_optimized_program (CONST Opbyte *program, Lisp_Object arg2 = POP; Lisp_Object arg1 = TOP; TOP = INTP (arg1) && INTP (arg2) ? - make_int (XINT (arg1) - XINT (arg2)) : + INT_MINUS (arg1, arg2) : bytecode_arithop (arg1, arg2, opcode); break; } @@ -1111,7 +1110,6 @@ execute_optimized_program (CONST Opbyte *program, break; } - case Bset: { Lisp_Object arg = POP; @@ -1224,7 +1222,7 @@ execute_optimized_program (CONST Opbyte *program, Don't make this function static, since then the compiler might inline it. */ Lisp_Object * execute_rare_opcode (Lisp_Object *stack_ptr, - CONST Opbyte *program_ptr, + const Opbyte *program_ptr, Opcode opcode) { switch (opcode) @@ -1478,7 +1476,7 @@ execute_rare_opcode (Lisp_Object *stack_ptr, } default: - abort(); + ABORT(); break; } return stack_ptr; @@ -1494,7 +1492,7 @@ invalid_byte_code_error (char *error_message, ...) sprintf (buf, "%s", error_message); va_start (args, error_message); - obj = emacs_doprnt_string_va ((CONST Bufbyte *) GETTEXT (buf), Qnil, -1, + obj = emacs_doprnt_string_va ((const Bufbyte *) GETTEXT (buf), Qnil, -1, args); va_end (args); @@ -1610,14 +1608,14 @@ optimize_byte_code (/* in */ Lisp_Object instructions, Lisp_Object constants, /* out */ - Opbyte * CONST program, - int * CONST program_length, - int * CONST varbind_count) + Opbyte * const program, + int * const program_length, + int * const varbind_count) { size_t instructions_length = XSTRING_LENGTH (instructions); size_t comfy_size = 2 * instructions_length; - int * CONST icounts = alloca_array (int, comfy_size); + int * const icounts = alloca_array (int, comfy_size); int * icounts_ptr = icounts; /* We maintain a table of jumps in the source code. */ @@ -1626,13 +1624,13 @@ optimize_byte_code (/* in */ int from; int to; }; - struct jump * CONST jumps = alloca_array (struct jump, comfy_size); + struct jump * const jumps = xnew_array (struct jump, comfy_size); struct jump *jumps_ptr = jumps; Opbyte *program_ptr = program; - CONST Bufbyte *ptr = XSTRING_DATA (instructions); - CONST Bufbyte * CONST end = ptr + instructions_length; + const Bufbyte *ptr = XSTRING_DATA (instructions); + const Bufbyte * const end = ptr + instructions_length; *varbind_count = 0; @@ -1861,7 +1859,7 @@ optimize_byte_code (/* in */ break; default: - abort(); + ABORT(); break; } } @@ -1870,6 +1868,7 @@ optimize_byte_code (/* in */ /* *program_ptr++ = 0; */ *program_length = program_ptr - program; + xfree(jumps); } /* Optimize the byte code and store the optimized program, only @@ -1895,10 +1894,10 @@ optimize_compiled_function (Lisp_Object compiled_function) program = alloca_array (Opbyte, 1 + 2 * XSTRING_LENGTH (f->instructions)); optimize_byte_code (f->instructions, f->constants, program, &program_length, &varbind_count); - f->specpdl_depth = XINT (Flength (f->arglist)) + varbind_count; + f->specpdl_depth = (unsigned short) (XINT (Flength (f->arglist)) + + varbind_count); f->instructions = - Fpurecopy (make_opaque (program_length * sizeof (Opbyte), - (CONST void *) program)); + make_opaque (program, program_length * sizeof (Opbyte)); } assert (OPAQUEP (f->instructions)); @@ -1984,15 +1983,15 @@ print_compiled_function (Lisp_Object obj, Lisp_Object printcharfun, static Lisp_Object -mark_compiled_function (Lisp_Object obj, void (*markobj) (Lisp_Object)) +mark_compiled_function (Lisp_Object obj) { Lisp_Compiled_Function *f = XCOMPILED_FUNCTION (obj); - markobj (f->instructions); - markobj (f->arglist); - markobj (f->doc_and_interactive); + mark_object (f->instructions); + mark_object (f->arglist); + mark_object (f->doc_and_interactive); #ifdef COMPILED_FUNCTION_ANNOTATION_HACK - markobj (f->annotated); + mark_object (f->annotated); #endif /* tail-recurse on constants */ return f->constants; @@ -2026,11 +2025,23 @@ compiled_function_hash (Lisp_Object obj, int depth) internal_hash (f->constants, depth + 1)); } +static const struct lrecord_description compiled_function_description[] = { + { XD_LISP_OBJECT, offsetof (Lisp_Compiled_Function, instructions) }, + { XD_LISP_OBJECT, offsetof (Lisp_Compiled_Function, constants) }, + { XD_LISP_OBJECT, offsetof (Lisp_Compiled_Function, arglist) }, + { XD_LISP_OBJECT, offsetof (Lisp_Compiled_Function, doc_and_interactive) }, +#ifdef COMPILED_FUNCTION_ANNOTATION_HACK + { XD_LISP_OBJECT, offsetof (Lisp_Compiled_Function, annotated) }, +#endif + { XD_END } +}; + DEFINE_BASIC_LRECORD_IMPLEMENTATION ("compiled-function", compiled_function, mark_compiled_function, print_compiled_function, 0, compiled_function_equal, compiled_function_hash, + compiled_function_description, Lisp_Compiled_Function); DEFUN ("compiled-function-p", Fcompiled_function_p, 1, 1, 0, /* @@ -2061,13 +2072,13 @@ compiled_function_instructions (Lisp_Compiled_Function *f) /* Invert action performed by optimize_byte_code() */ Lisp_Opaque *opaque = XOPAQUE (f->instructions); - Bufbyte * CONST buffer = + Bufbyte * const buffer = alloca_array (Bufbyte, OPAQUE_SIZE (opaque) * MAX_EMCHAR_LEN); Bufbyte *bp = buffer; - CONST Opbyte * CONST program = (CONST Opbyte *) OPAQUE_DATA (opaque); - CONST Opbyte *program_ptr = program; - CONST Opbyte * CONST program_end = program_ptr + OPAQUE_SIZE (opaque); + const Opbyte * const program = (const Opbyte *) OPAQUE_DATA (opaque); + const Opbyte *program_ptr = program; + const Opbyte * const program_end = program_ptr + OPAQUE_SIZE (opaque); while (program_ptr < program_end) { @@ -2257,7 +2268,7 @@ Return the constants vector of the compiled-function object FUNCTION. } DEFUN ("compiled-function-stack-depth", Fcompiled_function_stack_depth, 1, 1, 0, /* -Return the max stack depth of the compiled-function object FUNCTION. +Return the maximum stack depth of the compiled-function object FUNCTION. */ (function)) { @@ -2336,7 +2347,7 @@ If the byte code for compiled function FUNCTION is lazy-loaded, fetch it now. if (OPAQUEP (f->instructions) || STRINGP (f->instructions)) return function; - if (CONSP (XCOMPILED_FUNCTION (function)->instructions)) + if (CONSP (f->instructions)) { Lisp_Object tem = read_doc_string (f->instructions); if (!CONSP (tem)) @@ -2344,13 +2355,11 @@ If the byte code for compiled function FUNCTION is lazy-loaded, fetch it now. /* v18 or v19 bytecode file. Need to Ebolify. */ if (f->flags.ebolified && VECTORP (XCDR (tem))) ebolify_bytecode_constants (XCDR (tem)); - /* VERY IMPORTANT to purecopy here!!!!! - See load_force_doc_string_unwind. */ - /* f->instructions = Fpurecopy (XCAR (tem)); */ - f->constants = Fpurecopy (XCDR (tem)); + f->instructions = XCAR (tem); + f->constants = XCDR (tem); return function; } - abort (); + ABORT (); return Qnil; /* not reached */ } @@ -2404,8 +2413,9 @@ If STACK-DEPTH is incorrect, Emacs may crash. void syms_of_bytecode (void) { - deferror (&Qinvalid_byte_code, "invalid-byte-code", - "Invalid byte code", Qerror); + INIT_LRECORD_IMPLEMENTATION (compiled_function); + + DEFERROR_STANDARD (Qinvalid_byte_code, Qinvalid_state); defsymbol (&Qbyte_code, "byte-code"); defsymbol (&Qcompiled_functionp, "compiled-function-p");