pike.git / src / encode.c

version» Context lines:

pike.git/src/encode.c:1:   /*   || This file is part of Pike. For copyright information see COPYRIGHT.   || Pike is distributed under GPL, LGPL and MPL. See the file COPYING   || for more information. - || $Id: encode.c,v 1.173 2004/05/11 11:40:38 grubba Exp $ + || $Id: encode.c,v 1.174 2004/05/11 12:14:12 grubba Exp $   */      #include "global.h"   #include "stralloc.h"   #include "pike_macros.h"   #include "object.h"   #include "constants.h"   #include "interpret.h"   #include "svalue.h"   #include "mapping.h"
pike.git/src/encode.c:25:   #include "fsort.h"   #include "threads.h"   #include "stuff.h"   #include "version.h"   #include "bignum.h"   #include "pikecode.h"   #include "pike_types.h"   #include "opcodes.h"   #include "peep.h"    - RCSID("$Id: encode.c,v 1.173 2004/05/11 11:40:38 grubba Exp $"); + RCSID("$Id: encode.c,v 1.174 2004/05/11 12:14:12 grubba Exp $");      /* #define ENCODE_DEBUG */      /* Use the old encoding method for programs. */   #define OLD_PIKE_ENCODE_PROGRAM      #ifdef ENCODE_DEBUG   /* Pass a nonzero integer as the third arg to encode_value,    * encode_value_canonic and decode_value to activate this debug. */   #define EDB(N,X) do { debug_malloc_touch(data); if (data->debug>=N) {X;} } while (0)
pike.git/src/encode.c:1830:    default: \    Pike_error("Failed to decode string, tag is wrong: %d\n", \    what & TAG_MASK); \    } \   }while(0)      #define decode_number(X,data) do { \    INT32 what, e, num, numh; \    DECODE("decode_number"); \    X=(what & TAG_MASK) | (num<<4); \ -  EDB(5, fprintf(stderr, "%*s ==>%d\n", \ -  data->depth, "", X)); \ +  EDB(5, fprintf(stderr, "%*s ==>%ld\n", \ +  data->depth, "", (long) X)); \    }while(0) \         static void restore_type_stack(struct pike_type **old_stackp)   {   #if 0    fprintf(stderr, "Restoring type-stack: %p => %p\n",    Pike_compiler->type_stackp, old_stackp);   #endif /* 0 */   #ifdef PIKE_DEBUG
pike.git/src/encode.c:2050:    VAR=tmp.u.U; \    SCOUR; \    }else{ \    tmp.type=TYPE; \    tmp.u.U=VAR=ALLOCATE; \    mapping_insert(data->decoded, & data->counter, &tmp); \    /* Since a reference to the object is stored in the mapping, we can \    * safely decrease this reference here. Thus it will be automatically \    * freed if something goes wrong. \    */ \ -  VAR->refs--; \ +  sub_ref(VAR); \    } \    data->counter.u.integer++; \   }while(0)      /* This really needs to disable threads.... */   #define decode_type(X,data) do { \    type_stack_mark(); \    low_decode_type(data); \    (X)=pop_unfinished_type(); \   } while(0)
pike.git/src/encode.c:2073:   {    end_first_pass(0);    compilation_depth = *orig_compilation_depth;   }      static void set_lex_pragmas(INT32 old_pragmas)   {    lex.pragmas = old_pragmas;   }    + static DECLSPEC(noreturn) void decode_error (struct svalue *decoding, +  struct svalue *other, +  char *msg, ...) +  ATTRIBUTE((noreturn,format (printf, 3, 4))); +  + static DECLSPEC(noreturn) void decode_error (struct svalue *decoding, +  struct svalue *other, +  char *msg, ...) + { +  int n = 0; +  char buf[4096]; +  va_list args; +  va_start (args, msg); + #ifdef HAVE_VSNPRINTF +  vsnprintf (buf, sizeof (buf), msg, args); + #else /* !HAVE_VSNPRINTF */ +  VSPRINTF(buf, fmt, args); + #endif /* HAVE_VSNPRINTF */ +  va_end (args); +  +  if (decoding) { +  push_constant_text ("Error while decoding "); n++; +  push_constant_text ("%O"); +  push_svalue (decoding); +  f_sprintf (2); n++; +  push_constant_text (":\n"); n++; +  } +  push_text (buf); n++; +  if (other) { +  push_constant_text ("%O\n"); +  push_svalue (other); +  f_sprintf (2); n++; +  } +  f_add (n); +  +  f_backtrace (0); +  f_aggregate (2); +  +  free_svalue(& throw_value); +  dmalloc_touch_svalue(Pike_sp-1); +  throw_value = *--Pike_sp; +  throw_severity = THROW_ERROR; +  pike_throw(); + } +    static void decode_value2(struct decode_data *data)      #ifdef PIKE_DEBUG   #undef decode_value2   #define decode_value2(X) do { struct svalue *_=Pike_sp; decode_value2_(X); if(Pike_sp!=_+1) Pike_fatal("decode_value2 failed!\n"); } while(0)   #endif         {    INT32 what, e, num, numh;
pike.git/src/encode.c:2263:    SETUP_DECODE_MEMOBJ(T_MAPPING, mapping, m, allocate_mapping(num), ; );       for(e=0;e<num;e++)    {    decode_value2(data);    decode_value2(data);    mapping_insert(m, Pike_sp-2, Pike_sp-1);    pop_n_elems(2);    }    ref_push_mapping(m); - #ifdef ENCODE_DEBUG -  data->depth -= 2; - #endif -  return; +  goto decode_done;    }       case TAG_MULTISET:    {    struct multiset *m;    struct array *a;    if(num<0)    Pike_error("Failed to decode multiset. (multiset size is negative)\n");       /* Heruetical */
pike.git/src/encode.c:2315: Inside #if defined(PIKE_NEW_MULTISETS)
   struct multiset *l = mkmultiset (a);    free_array (a);    /* This special case is handled efficiently by merge_multisets. */    merge_multisets (m, l, PIKE_MERGE_DESTR_A | PIKE_ARRAY_OP_ADD);    free_multiset (l);    }   #else    order_multiset(m);   #endif    ref_push_multiset(m); - #ifdef ENCODE_DEBUG -  data->depth -= 2; - #endif -  return; +  goto decode_done;    }       case TAG_OBJECT:    {    tmp=data->counter;    data->counter.u.integer++;       decode_value2(data);       switch(num)
pike.git/src/encode.c:2409: Inside #if defined(AUTO_BIGNUM)
   * are always available...    */    case 2:    {    check_stack(2);    /* 256 would be better, but then negative numbers    * doesn't work... /Hubbe    */    push_int(36);    convert_stack_top_with_base_to_bignum(); + #if SIZEOF_INT_TYPE > 4 +  reduce_stack_top_bignum(); + #endif    break;    }      #endif    case 3:    pop_stack();    decode_value2(data);    break;       default:
pike.git/src/encode.c:2617:    case T_INT:    p->parent=0;    break;    case T_PROGRAM:    p->parent=Pike_sp[-1].u.program;    break;    case T_FUNCTION:    p->parent=program_from_svalue(Pike_sp-1);    break;    default: -  Pike_error("Program decode failed!\n"); +  decode_error(NULL, Pike_sp - 1, "Program decode failed. Got: ");    }    if(p->parent) {    add_ref(p->parent);    }    pop_stack();       debug_malloc_touch(p);    - #define FOO(X,Y,Z) \ -  decode_number( p->num_##Z, data); + #define FOO(NUMTYPE,TYPE,NAME) \ +  decode_number( p->PIKE_CONCAT(num_,NAME), data);   #include "program_areas.h"          if(data->pass == 1)    {   #define FOO(NUMTYPE,TYPE,NAME) \    size=DO_ALIGN(size, ALIGNOF(TYPE)); \    size+=p->PIKE_CONCAT(num_,NAME)*sizeof(p->NAME[0]);   #include "program_areas.h"   
pike.git/src/encode.c:2681: Inside #if defined(DECODE_PROGRAM)
  #ifdef DECODE_PROGRAM    {    int byteorder = PIKE_BYTEORDER; /* FIXME: Used by bytecode.h */    DECODE_PROGRAM(p);    }   #endif /* DECODE_PROGRAM */    make_program_executable(p);       getdata2(p->linenumbers, p->num_linenumbers);    +  /* Now with the linenumber info in place it gets useful to +  * include the program in error messages. */ +    #ifdef DEBUG_MALLOC    if(p->num_linenumbers && p->linenumbers &&    EXTRACT_UCHAR(p->linenumbers)==127)    {    char *foo = p->linenumbers + 1;    int len = get_small_number(&foo);    int shift = *foo;    char *fname = ++foo;    foo += len << shift;    get_small_number(&foo); /* pc offset */
pike.git/src/encode.c:2704:   #endif          debug_malloc_touch(p);    for(d=0;d<p->num_identifier_index;d++)    {    decode_number(p->identifier_index[d],data);    if(p->identifier_index[d] > p->num_identifier_references)    {    p->identifier_index[d]=0; -  Pike_error("Malformed program in decode.\n"); +  ref_push_program (p); +  decode_error(Pike_sp - 1, NULL, "Malformed program in decode.\n");    }    }       debug_malloc_touch(p);    for(d=0;d<p->num_variable_index;d++)    {    decode_number(p->variable_index[d],data);    if(p->variable_index[d] > p->num_identifiers)    {    p->variable_index[d]=0; -  Pike_error("Malformed program in decode.\n"); +  ref_push_program (p); +  decode_error(Pike_sp - 1, NULL, "Malformed program in decode.\n");    }    }       debug_malloc_touch(p);    for(d=0;d<p->num_identifier_references;d++)    {    decode_number(p->identifier_references[d].inherit_offset,data);    if(p->identifier_references[d].inherit_offset > p->num_inherits)    {    p->identifier_references[d].inherit_offset=0;
pike.git/src/encode.c:2757:      /* p->inherits[0].prog=p;    p->inherits[0].parent_offset=1;   */       if(placeholder && data->pass==1)    {    if(placeholder->prog != null_program)    {    debug_malloc_touch(placeholder); -  Pike_error("Placeholder argument is not a null_program clone!"); +  ref_push_program (p); +  decode_error(Pike_sp - 1, NULL, +  "Placeholder is no longer a __null_program clone.\n");    }else{    free_program(placeholder->prog);    add_ref(placeholder->prog = p);    debug_malloc_touch(placeholder);    }    }       debug_malloc_touch(p);       in=p->num_inherits;
pike.git/src/encode.c:2780:    decode_number(p->inherits[d].inherit_level,data);    decode_number(p->inherits[d].identifier_level,data);    decode_number(p->inherits[d].parent_offset,data);    decode_number(p->inherits[d].parent_identifier,data);    decode_number(p->inherits[d].storage_offset,data);       decode_value2(data);    if(d==0)    {    if(Pike_sp[-1].type != T_PROGRAM || -  Pike_sp[-1].u.program != p) -  Pike_error("Program decode failed!\n"); -  p->refs--; +  Pike_sp[-1].u.program != p) { +  ref_push_program (p); +  decode_error(Pike_sp - 1, Pike_sp - 2, +  "Program decode of self inherit failed. Got: ");    } -  +  sub_ref(p); +  }       if(data->pass > 1)    {    if(p->inherits[d].prog)    {    free_program(p->inherits[d].prog);    p->inherits[d].prog=0;    }       if(p->inherits[d].parent)
pike.git/src/encode.c:2825:    dmalloc_touch_svalue(Pike_sp);    break;       case T_PROGRAM:    EDB(3, fprintf(stderr,"INHERIT%x = prog\n",p->id); );    p->inherits[d].prog=Pike_sp[-1].u.program;    Pike_sp--;    dmalloc_touch_svalue(Pike_sp);    break;    default: -  Pike_error("Failed to decode inheritance.\n"); +  ref_push_program (p); +  decode_error(Pike_sp - 1, Pike_sp - 2, +  "Failed to decode inherited program. Got: ");    }       p->num_inherits=d+1;       getdata3(p->inherits[d].name);       EDB(3, fprintf(stderr,"INHERIT%x < %d: %d id=%d\n",    p->id,d,    p->inherits[d].prog->num_identifiers,    p->inherits[d].prog->id); );
pike.git/src/encode.c:2856:    {    getdata(p->identifiers[d].name);    decode_type(p->identifiers[d].type,data);    decode_number(p->identifiers[d].identifier_flags,data);    decode_number(p->identifiers[d].run_time_type,data);    decode_number(p->identifiers[d].opt_flags,data);    if (!(p->identifiers[d].identifier_flags & IDENTIFIER_C_FUNCTION))    {    decode_number(p->identifiers[d].func.offset,data);    } else { -  Pike_error("Cannot decode functions implemented in C " -  "(identifier='%s').\n", -  p->identifiers[d].name->str); +  ref_push_program (p); +  ref_push_string (p->identifiers[d].name); +  decode_error(Pike_sp - 1, Pike_sp - 2, +  "Cannot decode function implemented in C: ");    }    }          UNSET_ONERROR(err2);    UNSET_ONERROR(err1);       debug_malloc_touch(dat);       debug_malloc_touch(p);
pike.git/src/encode.c:2910: Inside #if defined(PIKE_DEBUG)
   {    int q;    for(q=0;q<p->num_inherits;q++)    if(!p->inherits[q].prog)    Pike_fatal("FOOBAR!@!!!\n");    }   #endif       if(placeholder && data->pass == 1)    { -  if(!p || (placeholder->storage)) +  if(placeholder->storage)    { -  Pike_error("Placeholder already has storage!\n"); +  ref_push_program (p); +  decode_error(Pike_sp - 1, NULL, "Placeholder already has storage!\n");    } else {    placeholder->storage=p->storage_needed ?    (char *)xalloc(p->storage_needed) : -  (char *)0; +  (char *)NULL;    call_c_initializers(placeholder);    }    }       data->pickyness--;       if(placeholder)    {    free_object(placeholder);    UNSET_ONERROR(err4);    }    UNSET_ONERROR(err3);       ref_push_program(p);       if(!(p->flags & PROGRAM_FINISHED) &&    !data->supporter.depends_on)    {    /* Logic for the PROGRAM_FINISHED flag:    * The purpose of this code is to make sure that the PROGRAM_FINISHED -  * flat is not set on the program until all inherited programs also +  * flag is not set on the program until all inherited programs also    * have that flag. -Hubbe    */    for(d=1;d<p->num_inherits;d++)    if(! (p->inherits[d].prog->flags & PROGRAM_FINISHED))    break;       if(d == p->num_inherits)    {    p->flags &=~ PROGRAM_AVOID_CHECK;    p->flags |= PROGRAM_FINISHED;
pike.git/src/encode.c:3035:    l->prog=p;    l->next=data->unfinished_programs;    data->unfinished_programs=l;    }    }      #ifdef _REENTRANT    UNSET_ONERROR(err);    exit_threads_disable(NULL);   #endif - #ifdef ENCODE_DEBUG -  data->depth -= 2; - #endif -  return; +  goto decode_done;    }       case 2:    tmp=data->counter;    data->counter.u.integer++;    decode_value2(data);    decode_value2(data);    if(Pike_sp[-2].type==T_INT)    {    pop_stack();    }else{    f_arrow(2);    }    if(data->pickyness && Pike_sp[-1].type != T_PROGRAM) -  Pike_error("Failed to decode program.\n"); +  decode_error(NULL, Pike_sp - 1, "Failed to decode program. Got: ");    break;       case 3:    tmp=data->counter;    data->counter.u.integer++;    decode_value2(data);    if ((Pike_sp[-1].type == T_INT) &&    (Pike_sp[-1].u.integer < PROG_DYNAMIC_ID_START) &&    (Pike_sp[-1].u.integer > 0)) {    struct program *p = id_to_program(Pike_sp[-1].u.integer);    if (!p) { -  Pike_error("Failed to decode program %d\n", +  Pike_error("Failed to get program from ID %"PRINTPIKEINT"d\n",    Pike_sp[-1].u.integer);    }    pop_stack();    ref_push_program(p);    } else { -  Pike_error("Failed to decode program.\n"); +  decode_error(NULL, Pike_sp - 1, +  "Failed to decode program by ID. Expected integer, got: ");    }    break;    -  case 4: +  case 4: /* New-style encoding. */    {    struct program *p;    ONERROR err;    ONERROR err2;    int orig_compilation_depth;    int byteorder;    int bytecode_method;    int entry_type;    INT16 id_flags;    INT16 p_flags;    INT32 old_pragmas = lex.pragmas; - #define FOO(NUMTYPE,Y,NAME) \ + #define FOO(NUMTYPE,Y,NAME) \    NUMTYPE PIKE_CONCAT(local_num_, NAME) = 0;   #include "program_areas.h"      #ifdef ENCODE_DEBUG    data->depth += 2;   #endif       /* Decode byte-order. */    decode_number(byteorder, data);       EDB(4, -  fprintf(stderr, "%*sByte order:%d\n", +  fprintf(stderr, "%*sbyte order:%d\n",    data->depth, "", byteorder));       if ((byteorder != PIKE_BYTEORDER)   #if (PIKE_BYTEORDER == 1234)    && (byteorder != 4321)   #else   #if (PIKE_BYTEORDER == 4321)    && (byteorder != 1234)   #endif   #endif
pike.git/src/encode.c:3184:    } else if ((Pike_sp[-1].type == T_INT) &&    (!Pike_sp[-1].u.integer)) {    p->parent = NULL;    } else {    Pike_error("Bad type for parent program (%s)\n",    get_name_of_type(Pike_sp[-1].type));    }    Pike_sp--;       /* Decode lengths. */ - #define FOO(X,Y,NAME) decode_number(PIKE_CONCAT(local_num_, NAME), data); + #define FOO(NUMTYPE,TYPE,NAME) \ +  decode_number(PIKE_CONCAT(local_num_, NAME), data);   #include "program_areas.h"       /* Byte-code method */    decode_number(bytecode_method, data);    if (bytecode_method != PIKE_BYTECODE_METHOD) {    Pike_error("Unsupported byte-code method: %d\n", bytecode_method);    }      #ifdef PIKE_USE_MACHINE_CODE    {
pike.git/src/encode.c:3304:    /* Actually the id ref number from the inherited program */    decode_number(ref_no, data);    ref.identifier_offset = p->inherits[ref.inherit_offset].prog->    identifier_references[ref_no].identifier_offset;       /* Expected identifier reference number */    decode_number(no, data);       if (no > p->num_identifier_references) {    EDB (3, dump_program_tables (p, data->depth)); -  Pike_error("Bad identifier reference offset: %d != %d\n", no, +  ref_push_program (p); +  decode_error(Pike_sp - 1, NULL, +  "Bad identifier reference offset: %d != %d\n", no,    Pike_compiler->new_program->    num_identifier_references);    } else if (no == p->num_identifier_references) {    add_to_identifier_references(ref);    }    else {    p->identifier_references[no] = ref;    }    }    break;       case ID_ENTRY_VARIABLE:    {    int no;       /* name */    decode_value2(data);    if (Pike_sp[-1].type != T_STRING) { -  Pike_error("Bad variable name (not a string)\n"); +  ref_push_program (p); +  decode_error(Pike_sp - 1, Pike_sp - 2, +  "Bad variable name (not a string): ");    }       /* type */    decode_value2(data);    if (Pike_sp[-1].type != T_TYPE) { -  Pike_error("Bad variable type (not a type)\n"); +  ref_push_program (p); +  decode_error(Pike_sp - 1, Pike_sp - 2, +  "Bad variable type (not a type): ");    }       /* Expected identifier offset */    decode_number(no, data);       EDB(5,    fprintf(stderr,    "%*sdefine_variable(\"%s\", X, 0x%04x)\n",    data->depth, "",    Pike_sp[-2].u.string->str, id_flags));
pike.git/src/encode.c:3366:    {    union idptr func;    unsigned INT8 func_flags;    unsigned INT16 opt_flags;    int no;    int n;       /* name */    decode_value2(data);    if (Pike_sp[-1].type != T_STRING) { -  Pike_error("Bad function name (not a string)\n"); +  ref_push_program (p); +  decode_error(Pike_sp - 1, Pike_sp - 2, +  "Bad function name (not a string): ");    }       /* type */    decode_value2(data);    if (Pike_sp[-1].type != T_TYPE) { -  Pike_error("Bad function type (not a type)\n"); +  ref_push_program (p); +  decode_error(Pike_sp - 1, Pike_sp - 2, +  "Bad function type (not a type): ");    }       /* func_flags (aka identifier_flags) */    decode_number(func_flags, data);       /* func */    decode_number(func.offset, data);       /* opt_flags */    decode_number(opt_flags, data);
pike.git/src/encode.c:3420:    */    n = define_function(Pike_sp[-2].u.string,    Pike_sp[-1].u.type,    id_flags, func_flags,    &func, opt_flags);    if (no != n &&    (p->identifier_references[no].id_flags != id_flags ||    p->identifier_references[no].identifier_offset !=    p->identifier_references[n].identifier_offset ||    p->identifier_references[no].inherit_offset != 0)) { -  Pike_error("Bad function identifier offset: %d\n", no); +  ref_push_program (p); +  decode_error(Pike_sp - 1, NULL, +  "Bad function identifier offset: %d\n", no);    }       pop_n_elems(2);    }    break;    case ID_ENTRY_CONSTANT:    {    struct identifier id;    struct reference ref;    int no;    int n;       /* name */    decode_value2(data);    if (Pike_sp[-1].type != T_STRING) { -  Pike_error("Bad function name (not a string)\n"); +  ref_push_program (p); +  decode_error(Pike_sp - 1, Pike_sp - 2, +  "Bad constant name (not a string): ");    }    id.name = Pike_sp[-1].u.string;       /* identifier_flags */    id.identifier_flags = IDENTIFIER_CONSTANT;       /* offset */    decode_number(id.func.offset, data);       /* FIXME:    * Verify validity of func.offset    */       /* type */    decode_value2(data);    if (Pike_sp[-1].type != T_TYPE) { -  Pike_error("Bad function type (not a type)\n"); +  ref_push_program (p); +  decode_error(Pike_sp - 1, Pike_sp - 2, +  "Bad constant type (not a type): ");    }    id.type = Pike_sp[-1].u.type;       /* run_time_type */    decode_number(id.run_time_type, data);       /* Expected identifier number. */    decode_number(no, data);       n = isidentifier(id.name);
pike.git/src/encode.c:3498:    *    * identifiers, identifier_references    */       if (n < 0 || (n = override_identifier (&ref, id.name)) < 0) {    n = p->num_identifier_references;    add_to_identifier_references(ref);    }       if (no != n) { -  if (id.name->size_shift) -  Pike_error("Bad constant identifier offset: %d\n", no); -  else -  Pike_error("Bad constant identifier offset %d for %s\n", -  no, id.name->str); +  ref_push_program (p); +  ref_push_string (id.name); +  decode_error(Pike_sp - 2, Pike_sp - 1, +  "Bad function identifier offset " +  "(expected %d, got %d) for ", no, n);    }       add_to_identifiers(id); -  +  dmalloc_touch_svalue(Pike_sp-1); +  dmalloc_touch_svalue(Pike_sp-2);    Pike_sp -= 2;    }    break;    case ID_ENTRY_INHERIT:    {    struct program *prog;    struct object *parent = NULL;    int parent_identifier;    int parent_offset;    struct pike_string *name = NULL;    int no;       decode_number(no, data);    if (no !=    Pike_compiler->new_program->num_identifier_references) { -  Pike_error("Bad inherit identifier offset: %d\n", no); +  ref_push_program (p); +  decode_error(Pike_sp - 1, NULL, +  "Bad inherit identifier offset: %d\n", no);    }       /* name */    decode_value2(data);    if (Pike_sp[-1].type == T_STRING) {    name = Pike_sp[-1].u.string;    } else if ((Pike_sp[-1].type != T_INT) ||    Pike_sp[-1].u.integer) { -  Pike_error("Bad function name (not a string)\n"); +  ref_push_program (p); +  decode_error(Pike_sp - 1, Pike_sp - 2, +  "Bad inherit name (not a string): ");    }       /* prog */    decode_value2(data);    if (Pike_sp[-1].type != T_PROGRAM) { -  Pike_error("Bad inherit: Expected program, got %s\n", -  get_name_of_type(Pike_sp[-1].type)); +  ref_push_program (p); +  decode_error(Pike_sp - 1, Pike_sp - 2, +  "Bad inherit: Expected program, got ");    }    prog = Pike_sp[-1].u.program;       /* parent */    decode_value2(data);    if (Pike_sp[-1].type == T_OBJECT) {    parent = Pike_sp[-1].u.object;    } else if ((Pike_sp[-1].type != T_INT) ||    Pike_sp[-1].u.integer) { -  Pike_error("Bad inherit: Parent isn't an object.\n"); +  ref_push_program (p); +  decode_error(Pike_sp - 1, Pike_sp - 2, +  "Bad inherit: Parent isn't an object: ");    }       /* parent_identifier */    decode_number(parent_identifier, data);       /* parent_offset */    decode_number(parent_offset, data);       /* Expected number of identifier references. */    decode_number(no, data);       if (prog->num_identifier_references != no) { -  Pike_error("Bad number of identifiers in inherit: %d\n", no); +  ref_push_program (p); +  decode_error(Pike_sp - 1, NULL, +  "Bad number of identifiers in inherit: %d != %d\n", +  no, prog->num_identifier_references);    }       EDB(5,    fprintf(stderr,    "%*slow_inherit(..., \"%s\")\n",    data->depth, "",    name?name->str:"NULL"));       /* Alters    *
pike.git/src/encode.c:3612:    if (!(p = end_first_pass(2))) {    Pike_error("Failed to decode program.\n");    }    compilation_depth = orig_compilation_depth;    push_program(p);       /* Restore lex.pragmas. */    CALL_AND_UNSET_ONERROR(err2);       /* Verify... */ - #define FOO(NUMTYPE,Y,NAME) \ -  if (PIKE_CONCAT(local_num_, NAME) != p->PIKE_CONCAT(num_,NAME)) { \ -  Pike_error("Value mismatch for num_" TOSTR(NAME) ": %d != %d\n", \ -  PIKE_CONCAT(local_num_, NAME), \ -  p->PIKE_CONCAT(num_, NAME)); \ + #define FOO(NUMTYPE,TYPE,NAME) \ +  if (PIKE_CONCAT(local_num_, NAME) != p->PIKE_CONCAT(num_,NAME)) { \ +  ref_push_program (p); \ +  decode_error(Pike_sp - 1, NULL, \ +  "Value mismatch for num_" TOSTR(NAME) ": %d != %d\n", \ +  PIKE_CONCAT(local_num_, NAME), \ +  p->PIKE_CONCAT(num_, NAME)); \    }   #include "program_areas.h"       /* Decode the actual constants    *    * This must be done after the program has been ended.    */    for (e=0; e<local_num_constants; e++) {    struct program_constant *constant = p->constants+e;    /* value */    decode_value2(data);    /* name */    decode_value2(data);    if (Pike_sp[-1].type == T_STRING) {    constant->name = Pike_sp[-1].u.string;    } else if ((Pike_sp[-1].type == T_INT) &&    !Pike_sp[-1].u.integer) {    constant->name = NULL;    } else { -  Pike_error("Name of constant is not a string.\n"); +  ref_push_program (p); +  decode_error(Pike_sp - 1, Pike_sp - 2, +  "Name of constant is not a string: ");    }    constant->sval = Pike_sp[-2]; -  +  dmalloc_touch_svalue(Pike_sp-1); +  dmalloc_touch_svalue(Pike_sp-2);    Pike_sp -= 2;    }       data->pickyness--;       /* The program should be consistent now. */    p->flags &= ~PROGRAM_AVOID_CHECK;       EDB(5, fprintf(stderr, "%*sProgram flags: 0x%04x\n",    data->depth, "", p->flags));      #ifdef ENCODE_DEBUG    data->depth -= 2;   #endif -  +  goto decode_done;    } -  break; +        default:    Pike_error("Cannot decode program encoding type %d\n",num);    }    break;       default:    Pike_error("Failed to restore string. (Illegal type)\n");    }    -  + decode_done:    EDB(2,fprintf(stderr, "%*sDecoded to <%d>: ", data->depth, "", tmp.u.integer);    print_svalue(stderr, Pike_sp-1);    fputc('\n', stderr););    mapping_insert(data->decoded, & tmp, Pike_sp-1);   #ifdef ENCODE_DEBUG    data->depth -= 2;   #endif   }      /* Placed after to prevent inlining */