Mercurial > hg > xemacs-beta
diff src/bytecode.c @ 412:697ef44129c6 r21-2-14
Import from CVS: tag r21-2-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:20:41 +0200 |
parents | de805c49cfc1 |
children | da8ed4261e83 |
line wrap: on
line diff
--- a/src/bytecode.c Mon Aug 13 11:19:22 2007 +0200 +++ b/src/bytecode.c Mon Aug 13 11:20:41 2007 +0200 @@ -28,7 +28,7 @@ FSF: long ago. -hacked on by jwz@jwz.org 1991-06 +hacked on by jwz@netscape.com 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,6 +56,9 @@ #include "opaque.h" #include "syntax.h" +#include <stddef.h> +#include <limits.h> + EXFUN (Ffetch_bytecode, 1); Lisp_Object Qbyte_code, Qcompiled_functionp, Qinvalid_byte_code; @@ -214,15 +217,21 @@ 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 */ @@ -233,17 +242,21 @@ Lisp_Object Vbyte_code_meter, Qbyte_code_meter; int byte_metering_on; -static void -meter_code (Opcode prev_opcode, Opcode this_opcode) -{ - if (byte_metering_on) - { - Lisp_Object *p = XVECTOR_DATA (XVECTOR_DATA (Vbyte_code_meter)[this_opcode]); - p[0] = INT_PLUS1 (p[0]); - if (prev_opcode) - p[prev_opcode] = INT_PLUS1 (p[prev_opcode]); - } -} +#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<<VALBITS)-1)) \ + METER_1 (this_code)++; \ + if (last_code \ + && METER_2 (last_code, this_code) != ((1<<VALBITS)-1)) \ + METER_2 (last_code, this_code)++; \ + } \ +} while (0) #endif /* BYTE_CODE_METER */ @@ -253,12 +266,12 @@ { retry: - if (INTP (obj)) return make_int (- XINT (obj)); #ifdef LISP_FLOAT_TYPE if (FLOATP (obj)) return make_float (- XFLOAT_DATA (obj)); #endif if (CHARP (obj)) return make_int (- ((int) XCHAR (obj))); if (MARKERP (obj)) return make_int (- ((int) marker_position (obj))); + if (INTP (obj)) return make_int (- XINT (obj)); obj = wrong_type_argument (Qnumber_char_or_marker_p, obj); goto retry; @@ -292,7 +305,7 @@ #ifdef LISP_FLOAT_TYPE { - EMACS_INT ival1, ival2; + int ival1, ival2; if (INTP (obj1)) ival1 = XINT (obj1); else if (CHARP (obj1)) ival1 = XCHAR (obj1); @@ -336,7 +349,7 @@ } #else /* !LISP_FLOAT_TYPE */ { - EMACS_INT ival1, ival2; + int ival1, ival2; if (INTP (obj1)) ival1 = XINT (obj1); else if (CHARP (obj1)) ival1 = XCHAR (obj1); @@ -365,7 +378,7 @@ bytecode_arithop (Lisp_Object obj1, Lisp_Object obj2, Opcode opcode) { #ifdef LISP_FLOAT_TYPE - EMACS_INT ival1, ival2; + int ival1, ival2; int float_p; retry: @@ -427,7 +440,7 @@ return make_float (dval1); } #else /* !LISP_FLOAT_TYPE */ - EMACS_INT ival1, ival2; + int ival1, ival2; retry: @@ -525,10 +538,6 @@ } 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))); } @@ -594,12 +603,12 @@ 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,7 +650,7 @@ #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) @@ -684,7 +693,7 @@ do_varset: { Lisp_Object symbol = constants_data[n]; - Lisp_Symbol *symbol_ptr = XSYMBOL (symbol); + struct 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)) @@ -705,7 +714,7 @@ do_varbind: { Lisp_Object symbol = constants_data[n]; - Lisp_Symbol *symbol_ptr = XSYMBOL (symbol); + struct 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)) @@ -758,7 +767,6 @@ opcode == Bunbind+6 ? READ_UINT_1 : READ_UINT_2)); break; - case Bgoto: JUMP; break; @@ -996,11 +1004,11 @@ } case Bsub1: - TOP = INTP (TOP) ? INT_MINUS1 (TOP) : Fsub1 (TOP); + TOP = INTP (TOP) ? make_int (XINT (TOP) - 1) : Fsub1 (TOP); break; case Badd1: - TOP = INTP (TOP) ? INT_PLUS1 (TOP) : Fadd1 (TOP); + TOP = INTP (TOP) ? make_int (XINT (TOP) + 1) : Fadd1 (TOP); break; @@ -1054,7 +1062,7 @@ Lisp_Object arg2 = POP; Lisp_Object arg1 = TOP; TOP = INTP (arg1) && INTP (arg2) ? - INT_PLUS (arg1, arg2) : + make_int (XINT (arg1) + XINT (arg2)) : bytecode_arithop (arg1, arg2, opcode); break; } @@ -1064,7 +1072,7 @@ Lisp_Object arg2 = POP; Lisp_Object arg1 = TOP; TOP = INTP (arg1) && INTP (arg2) ? - INT_MINUS (arg1, arg2) : + make_int (XINT (arg1) - XINT (arg2)) : bytecode_arithop (arg1, arg2, opcode); break; } @@ -1107,6 +1115,7 @@ break; } + case Bset: { Lisp_Object arg = POP; @@ -1219,7 +1228,7 @@ 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) @@ -1489,7 +1498,7 @@ 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); @@ -1605,14 +1614,14 @@ 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. */ @@ -1621,13 +1630,13 @@ int from; int to; }; - struct jump * const jumps = alloca_array (struct jump, comfy_size); + struct jump * CONST jumps = alloca_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; @@ -1892,7 +1901,8 @@ program, &program_length, &varbind_count); f->specpdl_depth = XINT (Flength (f->arglist)) + varbind_count; f->instructions = - make_opaque (program, program_length * sizeof (Opbyte)); + Fpurecopy (make_opaque (program_length * sizeof (Opbyte), + (CONST void *) program)); } assert (OPAQUEP (f->instructions)); @@ -1978,15 +1988,15 @@ static Lisp_Object -mark_compiled_function (Lisp_Object obj) +mark_compiled_function (Lisp_Object obj, void (*markobj) (Lisp_Object)) { Lisp_Compiled_Function *f = XCOMPILED_FUNCTION (obj); - mark_object (f->instructions); - mark_object (f->arglist); - mark_object (f->doc_and_interactive); + markobj (f->instructions); + markobj (f->arglist); + markobj (f->doc_and_interactive); #ifdef COMPILED_FUNCTION_ANNOTATION_HACK - mark_object (f->annotated); + markobj (f->annotated); #endif /* tail-recurse on constants */ return f->constants; @@ -2020,23 +2030,11 @@ 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, /* @@ -2067,13 +2065,13 @@ /* 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) { @@ -2350,8 +2348,10 @@ /* v18 or v19 bytecode file. Need to Ebolify. */ if (f->flags.ebolified && VECTORP (XCDR (tem))) ebolify_bytecode_constants (XCDR (tem)); - f->instructions = XCAR (tem); - f->constants = XCDR (tem); + /* VERY IMPORTANT to purecopy here!!!!! + See load_force_doc_string_unwind. */ + f->instructions = Fpurecopy (XCAR (tem)); + f->constants = Fpurecopy (XCDR (tem)); return function; } abort (); @@ -2408,8 +2408,6 @@ void syms_of_bytecode (void) { - INIT_LRECORD_IMPLEMENTATION (compiled_function); - deferror (&Qinvalid_byte_code, "invalid-byte-code", "Invalid byte code", Qerror); defsymbol (&Qbyte_code, "byte-code");