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.176 2004/05/11 13:19:06 grubba Exp $ + || $Id: encode.c,v 1.177 2004/05/11 14:07:28 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.176 2004/05/11 13:19:06 grubba Exp $"); + RCSID("$Id: encode.c,v 1.177 2004/05/11 14:07:28 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:1688:    struct object *thread_id;   #endif   #ifdef ENCODE_DEBUG    int debug, depth;   #endif    struct Supporter supporter;   };      static void decode_value2(struct decode_data *data);    - static void fallback_codec(void) - { -  size_t x; -  push_constant_text("."); -  f_divide(2); -  f_reverse(1); -  Pike_sp--; -  x=Pike_sp->u.array->size; -  push_array_items(Pike_sp->u.array); -  ref_push_mapping(get_builtin_constants()); -  while(x--) -  { -  stack_swap(); -  f_arrow(2); -  } - } -  +    static int my_extract_char(struct decode_data *data)   {    if(data->ptr >= data->len)    Pike_error("Format error, not enough data in string.\n");    return data->data [ data->ptr++ ];   }      #define GETC() my_extract_char(data)      #define DECODE(Z) do { \
pike.git/src/encode.c:2053:    }else{ \    tmp.type=TYPE; \    tmp.u.U=VAR=ALLOCATE; \    mapping_insert(data->decoded, & entry_id, &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. \    */ \    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)      static void cleanup_new_program_decode (int *orig_compilation_depth)
pike.git/src/encode.c:2130: Inside #if defined(PIKE_DEBUG)
     #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;    struct svalue entry_id, *tmp2; +  struct svalue *delayed_enc_val;      #ifdef ENCODE_DEBUG    data->depth += 2;   #endif       DECODE("decode_value2");      #ifdef ENCODE_DEBUG    if(data->debug)    {
pike.git/src/encode.c:2156: Inside #if defined(ENCODE_DEBUG)
   fprintf(stderr, "%*sDecoding to <%d>: TAG%d (%d)\n",    data->depth, "", data->counter.u.integer ,    what & TAG_MASK, num);    }   #endif       check_stack(1);       switch(what & TAG_MASK)    { +  case TAG_DELAYED: +  EDB (2, fprintf(stderr, "%*sDecoding delay encoded from <%d>\n", +  data->depth, "", num);); +  entry_id.type = T_INT; +  entry_id.subtype = 0; +  entry_id.u.integer = num; +  if (!(delayed_enc_val = low_mapping_lookup (data->decoded, &entry_id))) +  Pike_error ("Failed to find previous record of delay encoded entry <%d>.\n", +  num); +  DECODE ("decode_value2"); +  break; +     case TAG_AGAIN: -  +  EDB (1, fprintf(stderr, "%*sDecoding TAG_AGAIN from <%d>\n", +  data->depth, "", num););    entry_id.type=T_INT;    entry_id.subtype=0;    entry_id.u.integer=num;    if((tmp2=low_mapping_lookup(data->decoded, &entry_id)))    {    push_svalue(tmp2);    }else{    Pike_error("Failed to decode TAG_AGAIN entry <%d>.\n", num);    }    goto decode_done;    -  case TAG_INT: -  entry_id.type = T_INT; -  entry_id=data->counter; +  default: +  entry_id = data->counter;    data->counter.u.integer++; -  +  /* Fall through. */ +  +  case TAG_TYPE: +  EDB (2, fprintf(stderr, "%*sDecoding to <%d>: TAG%d (%d)\n", +  data->depth, "", entry_id.u.integer , +  what & TAG_MASK, num);); +  /* Types are added to the encoded mapping AFTER they have been +  * encoded. */ +  delayed_enc_val = NULL; +  break; +  } +  +  check_stack(1); +  +  switch(what & TAG_MASK) +  { +  case TAG_INT:    push_int(num);    break;       case TAG_STRING:    {    struct pike_string *str;    entry_id.type = T_INT;    entry_id=data->counter;    data->counter.u.integer++;    get_string_data(str, num, data);
pike.git/src/encode.c:2197:    {    double res;       EDB(2,fprintf(stderr, "Decoding float... numh:0x%08x, num:0x%08x\n",    numh, num));       res = LDEXP((double)numh, 32) + (double)(unsigned INT32)num;       EDB(2,fprintf(stderr, "Mantissa: %10g\n", res));    -  entry_id = data->counter; -  data->counter.u.integer++; -  +     DECODE("float");       EDB(2,fprintf(stderr, "Exponent: %d\n", num));       if(!res)    {    DECLARE_INF    DECLARE_NAN       switch(num)
pike.git/src/encode.c:2247:    }       case TAG_TYPE:    {    struct pike_type *t;       decode_type(t, data);    check_type_string(t);    push_type_value(t);    -  entry_id.type = T_INT; +     entry_id = data->counter;    data->counter.u.integer++;    }    break;       case TAG_ARRAY:    {    struct array *a; -  +  TYPE_FIELD types;    if(num < 0)    Pike_error("Failed to decode array. (array size is negative)\n");       /* Heruetical */    if(data->ptr + num > data->len)    Pike_error("Failed to decode array. (not enough data)\n");       EDB(2,fprintf(stderr, "%*sDecoding array of size %d to <%d>\n", -  data->depth, "", num, data->counter.u.integer)); +  data->depth, "", num, entry_id.u.integer));       SETUP_DECODE_MEMOBJ(T_ARRAY, array, a, allocate_array(num),    free_svalues(ITEM(a), a->size, a->type_field));    -  +  types = 0;    for(e=0;e<num;e++)    {    decode_value2(data); -  ITEM(a)[e]=Pike_sp[-1]; -  Pike_sp--; -  dmalloc_touch_svalue(Pike_sp); +  stack_pop_to_no_free (ITEM(a) + e); +  types |= 1 << ITEM(a)[e].type;    } -  +  a->type_field = types;    ref_push_array(a); - #ifdef ENCODE_DEBUG -  data->depth -= 2; - #endif -  return; +  goto decode_done;    }       case TAG_MAPPING:    {    struct mapping *m;    if(num<0)    Pike_error("Failed to decode mapping. (mapping size is negative)\n");       /* Heruetical */    if(data->ptr + num > data->len)    Pike_error("Failed to decode mapping. (not enough data)\n");       EDB(2,fprintf(stderr, "%*sDecoding mapping of size %d to <%d>\n", -  data->depth, "", num, data->counter.u.integer)); +  data->depth, "", num, entry_id.u.integer));       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);    goto decode_done;    }       case TAG_MULTISET:    {    struct multiset *m;    struct array *a; -  +  TYPE_FIELD types;    if(num<0)    Pike_error("Failed to decode multiset. (multiset size is negative)\n");       /* Heruetical */    if(data->ptr + num > data->len)    Pike_error("Failed to decode multiset. (not enough data)\n");       /* NOTE: This code knows stuff about the implementation of multisets...*/       EDB(2,fprintf(stderr, "%*sDecoding multiset of size %d to <%d>\n", -  data->depth, "", num, data->counter.u.integer)); +  data->depth, "", num, entry_id.u.integer));   #ifdef PIKE_NEW_MULTISETS    SETUP_DECODE_MEMOBJ (T_MULTISET, multiset, m,    allocate_multiset (0, 0, NULL), ;);    /* FIXME: This array could be avoided by building the multiset directly. */    a = low_allocate_array (num, 0);   #else    SETUP_DECODE_MEMOBJ(T_MULTISET, multiset, m,    allocate_multiset(low_allocate_array(num, 0)), ;);    a=m->ind;   #endif    -  +  types = 0;    for(e=0;e<num;e++)    {    decode_value2(data); -  assign_svalue(a->item+e , Pike_sp-1); -  pop_stack(); -  dmalloc_touch_svalue(Pike_sp); +  stack_pop_to_no_free (ITEM(a) + e); +  types |= 1 << ITEM(a)[e].type;    } -  +  a->type_field = types;    array_fix_type_field(a);   #ifdef 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);    goto decode_done;    }       case TAG_OBJECT:    { -  entry_id=data->counter; -  data->counter.u.integer++; -  +     decode_value2(data);       switch(num)    {    case 0: -  if(data->codec) -  { +     apply(data->codec,"objectof", 1); -  }else{ -  fallback_codec(); -  } +     break;       case 1: -  if(UNSAFE_IS_ZERO(Pike_sp-1)) +     { -  +  int fun; +  /* decode_value_clone_object does not call __INIT, so +  * we want to do that ourselves... +  */ +  struct object *o=decode_value_clone_object(Pike_sp-1); +  +  if (!o) { +  if (data->pickyness) +  decode_error (NULL, Pike_sp - 1, +  "Failed to decode program for object. Got: ");    EDB(1,fprintf(stderr, "%*sDecoded a failed object to <%d>: ",    data->depth, "", entry_id.u.integer);    print_svalue(stderr, Pike_sp-1);    fputc('\n', stderr););    decode_value2(data); -  pop_stack(); -  }else{ -  int fun; -  struct object *o; -  /* decode_value_clone_object does not call __INIT, so -  * we want to do that ourselves... -  */ -  o=decode_value_clone_object(Pike_sp-1); +  pop_n_elems(2); +  push_undefined(); +  break; +  } +     debug_malloc_touch(o);    pop_stack();    push_object(o);       if(o->prog)    {    if(o->prog->flags & PROGRAM_FINISHED)    { -  apply_lfun(o, LFUN___INIT, 0); +  int lfun = FIND_LFUN(o->prog, LFUN___INIT); +  if (lfun >= 0) { +  apply_low(o, lfun, 0);    pop_stack(); -  +  }    /* FIXME: Should call LFUN_CREATE here in <= 7.2    * compatibility mode. */    }else{    struct unfinished_obj_link *ol=ALLOC_STRUCT(unfinished_obj_link);    ol->o=o;    ol->next=data->unfinished_objects;    data->unfinished_objects=ol;    }    }       EDB(2,fprintf(stderr, "%*sDecoded an object to <%d>: ",    data->depth, "", entry_id.u.integer);    print_svalue(stderr, Pike_sp-1);    fputc('\n', stderr););       ref_push_object(o);    decode_value2(data);    if(!data->codec) -  Pike_error("Failed to decode object (no codec)\n"); +  decode_error(Pike_sp - 1, NULL, +  "Cannot decode object without codec.\n");       fun = find_identifier("decode_object", data->codec->prog);    if (fun < 0) -  Pike_error("Cannot decode objects without a " +  decode_error(Pike_sp - 1, NULL, +  "Cannot decode objects without a "    "\"decode_object\" function in the codec.\n");    apply_low(data->codec,fun,2);    pop_stack();    }       break;      #ifdef AUTO_BIGNUM    /* It is possible that we should do this even without    * AUTO_BIGNUM /Hubbe
pike.git/src/encode.c:2462:   #endif    case 3:    pop_stack();    decode_value2(data);    break;       default:    Pike_error("Object coding not compatible.\n");    break;    } -  if(Pike_sp[-1].type != T_OBJECT) -  if(data->pickyness) -  Pike_error("Failed to decode object.\n"); +     -  +  if(Pike_sp[-1].type != T_OBJECT && data->pickyness) +  decode_error(NULL, Pike_sp - 1, "Failed to decode object. Got: "); +     break;    }       case TAG_FUNCTION: -  entry_id=data->counter; -  data->counter.u.integer++; +     decode_value2(data);       switch(num)    {    case 0: -  if(data->codec) -  { +     apply(data->codec,"functionof", 1); -  }else{ -  fallback_codec(); -  } +     break;       case 1: {    struct program *p; -  +  if(Pike_sp[-1].type != T_OBJECT && data->pickyness) +  decode_error(NULL, Pike_sp - 1, +  "Failed to decode function object. Got: "); +     decode_value2(data); -  +  if(Pike_sp[-1].type != T_STRING && data->pickyness) +  decode_error(NULL, Pike_sp - 1, +  "Failed to decode function identifier. Got: "); +     if (Pike_sp[-2].type == T_OBJECT &&    Pike_sp[-1].type == T_STRING &&    (p = Pike_sp[-2].u.object->prog)) {    int f = find_shared_string_identifier(Pike_sp[-1].u.string, p);    if (f >= 0) {    struct svalue func;    low_object_index_no_free(&func, Pike_sp[-2].u.object, f);   #ifdef PIKE_SECURITY    /* FIXME: Check access to the function. */   #endif    pop_n_elems(2);    *Pike_sp++ = func; -  +  dmalloc_touch_svalue(Pike_sp-1);    break;    } -  +  else if (data->pickyness) { +  if (Pike_sp[-1].u.string->size_shift) +  decode_error(NULL, Pike_sp - 2, "Couldn't find identifier in "); +  else +  decode_error(NULL, Pike_sp - 2, "Couldn't find identifier %s in ", +  Pike_sp[-1].u.string->str);    } -  +  }    pop_stack();    break;    }       default:    Pike_error("Function coding not compatible.\n");    break;    } -  if(data->pickyness && Pike_sp[-1].type != T_FUNCTION) -  Pike_error("Failed to decode function.\n"); +  +  if(Pike_sp[-1].type != T_FUNCTION && data->pickyness) +  decode_error(NULL, Pike_sp - 1, "Failed to decode function. Got: "); +     break;          case TAG_PROGRAM:    EDB(3,    fprintf(stderr, "%*s TAG_PROGRAM(%d)\n",    data->depth, "", num));    switch(num)    {    case 0:    { -  struct svalue *prog_code; +     struct program *p;    -  entry_id=data->counter; -  data->counter.u.integer++; +     decode_value2(data); -  -  /* Keep the value so that we can make a good error-message. */ -  prog_code = Pike_sp-1; -  stack_dup(); -  -  if(data->codec) -  { +     apply(data->codec,"programof", 1); -  }else{ -  fallback_codec(); -  } +        p = program_from_svalue(Pike_sp-1);       if (!p) {    if(data->pickyness) { -  if ((prog_code->type == T_STRING) && -  (prog_code->u.string->len < 128) && -  (!prog_code->u.string->size_shift)) { -  Pike_error("Failed to decode program \"%s\".\n", -  prog_code->u.string->str); +  decode_error(NULL, Pike_sp - 1, +  "Failed to decode program. Got: ");    } -  Pike_error("Failed to decode program.\n"); -  } -  pop_n_elems(2); +  pop_stack();    push_undefined();    break;    } -  /* Remove the extra entry from the stack. */ -  ref_push_program(p); -  stack_pop_n_elems_keep_top(2); +  +  add_ref(p); +  pop_stack(); +  push_program(p);    break;    }    -  case 1: +  case 1: /* Old-style encoding. */    {    int d, in;    size_t size=0;    char *dat=0;    struct program *p;    struct object *placeholder=0;    ONERROR err1, err2, err3, err4;      #ifdef _REENTRANT    ONERROR err;    low_init_threads_disable();    SET_ONERROR(err, do_enable_threads, 0);   #endif    -  + #if 0 + #ifndef OLD_PIKE_ENCODE_PROGRAM +  fprintf (stderr, "Warning: Using old-style encoding\n"); + #endif /* !OLD_PIKE_ENCODE_PROGRAM */ + #endif /* 0 */ +     EDB(2,fprintf(stderr, "%*sDecoding a program to <%d>: ", -  data->depth, "", data->counter.u.integer); +  data->depth, "", entry_id.u.integer);    print_svalue(stderr, &entry_id);    fputc('\n', stderr););       SETUP_DECODE_MEMOBJ(T_PROGRAM, program, p, low_allocate_program(),;);       SET_ONERROR(err3, zap_unfinished_program, p);       if(data->pass == 1)    {    if(! data->supporter.prog)    data->supporter.prog = p;       debug_malloc_touch(p); -  if(data->codec) -  { +     ref_push_program(p);    apply(data->codec, "__register_new_program", 1);       /* return a placeholder */    if(Pike_sp[-1].type == T_OBJECT)    {    placeholder=Pike_sp[-1].u.object;    if(placeholder->prog != null_program)    Pike_error("Placeholder object is not a null_program clone!\n");    Pike_sp--; -  }else{ +  } +  else if (Pike_sp[-1].type != T_INT || +  Pike_sp[-1].u.integer) +  Pike_error ("Expected placeholder object or zero " +  "from __register_new_program.\n"); +  else {    pop_stack();    }    } -  } +        if(placeholder)    SET_ONERROR(err4, zap_placeholder, placeholder);       decode_value2(data);    f_version(0);    if(!is_eq(Pike_sp-1,Pike_sp-2))    Pike_error("Cannot decode programs encoded with other pike version.\n");    pop_n_elems(2);    -  +  data->pickyness++; +     debug_malloc_touch(p);    decode_number(p->flags,data);       if(data->pass == 1)    {    p->flags &= ~(PROGRAM_FINISHED | PROGRAM_OPTIMIZED |    PROGRAM_FIXED | PROGRAM_PASS_1_DONE);    p->flags |= PROGRAM_AVOID_CHECK;    }    decode_number(p->storage_needed,data);
pike.git/src/encode.c:2771:    }    }       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_error("Malformed program in decode.\n"); +  ref_push_program (p); +  decode_error(Pike_sp - 1, NULL, "Malformed program in decode.\n");    }    decode_number(p->identifier_references[d].identifier_offset,data);    decode_number(p->identifier_references[d].id_flags,data);       EDB(3,fprintf(stderr,"IDREF%x < %d: { %d, %d, %d }\n",    p->id,d,    p->identifier_references[d].inherit_offset,    p->identifier_references[d].identifier_offset,    p->identifier_references[d].id_flags); );    }       debug_malloc_touch(p);    for(d=0;d<p->num_strings;d++)    getdata(p->strings[d]);       debug_malloc_touch(p);    debug_malloc_touch(dat);    -  data->pickyness++; -  -  +    /* 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);    ref_push_program (p);
pike.git/src/encode.c:2852:       if(p->inherits[d].parent)    {    free_object(p->inherits[d].parent);    p->inherits[d].parent=0;    }    }       switch(Pike_sp[-1].type)    { -  case T_FUNCTION: -  if(Pike_sp[-1].subtype == FUNCTION_BUILTIN) -  Pike_error("Failed to decode parent.\n"); +  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;    -  +  case T_FUNCTION: +  if(Pike_sp[-1].subtype != FUNCTION_BUILTIN) {    EDB(3, fprintf(stderr,"INHERIT%x = func { %p, %d} \n",p->id,Pike_sp[-1].u.object, Pike_sp[-1].subtype); );       p->inherits[d].parent_identifier=Pike_sp[-1].subtype;    p->inherits[d].prog=program_from_svalue(Pike_sp-1); -  if(!p->inherits[d].prog) -  Pike_error("Failed to decode parent.\n"); +  if(!p->inherits[d].prog) { +  ref_push_program (p); +  decode_error(Pike_sp - 1, Pike_sp - 2, +  "Failed to decode inherited program. Got: "); +  }    add_ref(p->inherits[d].prog);    p->inherits[d].parent=Pike_sp[-1].u.object;    Pike_sp--;    dmalloc_touch_svalue(Pike_sp);    break; -  +  } +  /* Fall through */    -  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:    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);   
pike.git/src/encode.c:2946:       p->flags |= PROGRAM_PASS_1_DONE | PROGRAM_FIXED;    for(d=0;d<p->num_constants;d++)    {    decode_value2(data);    if(data->pass > 1)    {    assign_svalue(& p->constants[d].sval , Pike_sp -1 );    pop_stack();    }else{ +  dmalloc_touch_svalue(Pike_sp-1);    p->constants[d].sval=*--Pike_sp;    }    dmalloc_touch_svalue(Pike_sp);    getdata3(p->constants[d].name);    }      #ifdef PIKE_DEBUG    {    int q;    for(q=0;q<p->num_inherits;q++)
pike.git/src/encode.c:3093:    }      #ifdef _REENTRANT    UNSET_ONERROR(err);    exit_threads_disable(NULL);   #endif    goto decode_done;    }       case 2: -  entry_id=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) +  if(Pike_sp[-1].type != T_PROGRAM && data->pickyness)    decode_error(NULL, Pike_sp - 1, "Failed to decode program. Got: ");    break;       case 3:    entry_id=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)) {
pike.git/src/encode.c:3208:    Pike_error("Unsupported byte-order. Native:%d Encoded:%d\n",    PIKE_BYTEORDER, byteorder);    }       /* Decode flags. */    decode_number(p_flags,data);    p_flags &= ~(PROGRAM_FINISHED | PROGRAM_OPTIMIZED |    PROGRAM_FIXED | PROGRAM_PASS_1_DONE);    p_flags |= PROGRAM_AVOID_CHECK;    +  if (delayed_enc_val) { +  EDB(2,fprintf(stderr, "%*sdecoding a delay encoded program: ", +  data->depth, ""); +  print_svalue(stderr, delayed_enc_val); +  fputc('\n', stderr);); +  if (delayed_enc_val->type != T_PROGRAM || +  delayed_enc_val->u.program->flags != PROGRAM_VIRGIN) { +  decode_error (NULL, delayed_enc_val, +  "Didn't get program embryo " +  "for delay encoded program <%"PRINTPIKEINT"d>: ", +  entry_id.u.integer); +  } +  /* No new ref here; low_start_new_program will add one for +  * Pike_compiler->new_program and we want ride on that one +  * just like when it's created there. */ +  p = delayed_enc_val->u.program; +  } +  else +  p = NULL; +     /* We don't want to be affected by #pragma save_parent or    * __pragma_save_parent__.    */    lex.pragmas = (old_pragmas & ~ID_SAVE_PARENT)|ID_DONT_SAVE_PARENT;    SET_ONERROR(err2, set_lex_pragmas, old_pragmas);       /* Start the new program. */    orig_compilation_depth = compilation_depth;    compilation_depth = -1; -  low_start_new_program(NULL, 1, NULL, 0, NULL); +  low_start_new_program(p, 1, NULL, 0, NULL);    p = Pike_compiler->new_program;    -  /* We don't want to be affected by #pragma save_parent or -  * __pragma_save_parent__. -  */ -  lex.pragmas = (old_pragmas & ~ID_SAVE_PARENT)|ID_DONT_SAVE_PARENT; -  +     p->flags = p_flags;       /* Kludge to get end_first_pass() to free the program. */    Pike_compiler->num_parse_error++;       SET_ONERROR(err, cleanup_new_program_decode, &orig_compilation_depth);       debug_malloc_touch(p);    -  { +  if (!delayed_enc_val) {    struct svalue prog;    prog.type=T_PROGRAM;    prog.u.program=p;    EDB(2,fprintf(stderr, "%*sDecoding a program to <%d>: ",    data->depth, "", entry_id.u.integer);    print_svalue(stderr, &prog);    fputc('\n', stderr););    mapping_insert(data->decoded, &entry_id, &prog);    }   
pike.git/src/encode.c:3773:    data->depth-=2;   #endif       UNSET_ONERROR(err);       /* De-kludge to get end_first_pass() to free the program. */    Pike_compiler->num_parse_error--;       p->flags |= PROGRAM_PASS_1_DONE;    -  EDB(5, dump_program_tables(p, data->depth)); -  +     /* Fixate & optimize    *    * lfuns and identifier_index    */    if (!(p = end_first_pass(2))) { -  Pike_error("Failed to decode program.\n"); +  decode_error(Pike_sp - 1, NULL, "Failed to decode program.\n");    } -  +  pop_stack();    compilation_depth = orig_compilation_depth;    push_program(p);       /* Restore lex.pragmas. */    CALL_AND_UNSET_ONERROR(err2);    -  +  EDB(5, dump_program_tables(p, data->depth)); + #ifdef PIKE_DEBUG +  check_program (p); + #endif +     /* Verify... */   #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; -  +  if ((constant->sval.type != T_INT) || +  (constant->sval.subtype != NUMBER_UNDEFINED)) { +  /* Already initialized. */ +  continue; +  }    /* 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.git/src/encode.c:3939:    free((char *)tmp);    }       while(data->unfinished_objects)    {    struct unfinished_obj_link *tmp=data->unfinished_objects;    data->unfinished_objects=tmp->next;    free((char *)tmp);    }   #ifdef PIKE_THREADS -  free_object(data->thread_id); +  data->thread_id = NULL;   #endif       free( (char *) data);   }    - /* Run pass2 */ - int re_decode(struct decode_data *data, int ignored) + static void low_do_decode (struct decode_data *data)   { -  +  int e; +  struct keypair *k;    ONERROR err;    SET_ONERROR(err, free_decode_data, data); -  data->next = current_decode; +     current_decode = data;       decode_value2(data);    -  UNSET_ONERROR(err); +  while (data->ptr < data->len) { +  decode_value2 (data); +  pop_stack(); +  }    -  + #ifdef PIKE_DEBUG +  NEW_MAPPING_LOOP (data->decoded->data) { +  if (k->val.type == T_PROGRAM && +  !(k->val.u.program->flags & PROGRAM_FINISHED)) { +  decode_error (NULL, &k->val, +  "Got unfinished program <%"PRINTPIKEINT"d> after decode: ", +  k->ind.u.integer); +  } +  } + #endif +  +  UNSET_ONERROR(err);    free_decode_data(data); -  + } +  + /* Run pass2 */ + int re_decode(struct decode_data *data, int ignored) + { +  data->next = current_decode; +  low_do_decode (data);    return 1;   }      static INT32 my_decode(struct pike_string *tmp,    struct object *codec   #ifdef ENCODE_DEBUG    , int debug   #endif    )   { -  ONERROR err; +     struct decode_data *data;       /* Attempt to avoid infinite recursion on circular structures. */    for (data = current_decode; data; data=data->next) {    if (data->raw == tmp && data->codec == codec   #ifdef PIKE_THREADS    && data->thread_id == Pike_interpreter.thread_id   #endif    ) {    struct svalue *res;
pike.git/src/encode.c:4027:    data->len < 5 ||    GETC() != 182 ||    GETC() != 'k' ||    GETC() != 'e' ||    GETC() != '0')    {    free( (char *) data);    return 0;    }    - #ifdef PIKE_THREADS -  add_ref(Pike_interpreter.thread_id); - #endif -  +     data->decoded=allocate_mapping(128);    -  current_decode = data; -  -  SET_ONERROR(err, free_decode_data, data); -  +     init_supporter(& data->supporter,    (supporter_callback *) re_decode,    (void *)data);       decode_value2(data);    -  CALL_AND_UNSET_ONERROR(err); +  low_do_decode (data); +     return 1;   }      /* Compatibilidy decoder */      static unsigned char extract_char(char **v, ptrdiff_t *l)   {    if(!*l) Pike_error("Format error, not enough place for char.\n");    else (*l)--;    (*v)++;
pike.git/src/encode.c:4180:    *!    *! @seealso    *! @[encode_value()], @[encode_value_canonic()]    */   void f_decode_value(INT32 args)   {    struct pike_string *s;    struct object *codec;      #ifdef ENCODE_DEBUG -  int debug; +  int debug = 0;   #endif /* ENCODE_DEBUG */       check_all_args("decode_value", args, -  BIT_STRING, BIT_VOID | BIT_OBJECT | BIT_INT, +  BIT_STRING, +  BIT_VOID | BIT_OBJECT | BIT_ZERO,   #ifdef ENCODE_DEBUG    /* This argument is only an internal debug helper.    * It's intentionally not part of the function    * prototype, to keep the argument position free for    * other uses in the future. */    BIT_VOID | BIT_INT,   #endif    0);      #ifdef ENCODE_DEBUG    debug = args > 2 ? Pike_sp[2-args].u.integer : 0;   #endif /* ENCODE_DEBUG */       s = Pike_sp[-args].u.string; -  if(args<2) -  { -  codec=get_master(); +  +  switch (args) { +  default: + #ifdef ENCODE_DEBUG +  debug = Pike_sp[2-args].u.integer; +  /* Fall through. */ +  case 2: + #endif +  if (Pike_sp[1-args].type == T_OBJECT) { +  codec = Pike_sp[1-args].u.object; +  break;    } -  else if(Pike_sp[1-args].type == T_OBJECT) -  { -  codec=Pike_sp[1-args].u.object; +  /* Fall through. */ +  case 1: +  codec = get_master(); +  if (!codec) { +  /* Use a dummy if there's no master around yet, to avoid checks. */ +  push_object (clone_object (null_program, 0)); +  args++; +  codec = Pike_sp[-1].u.object;    } -  else -  { -  codec=0; +     }       if(!my_decode(s, codec   #ifdef ENCODE_DEBUG    , debug   #endif    ))    {    char *v=s->str;    ptrdiff_t l=s->len;    rec_restore_value(&v, &l);    }    assign_svalue(Pike_sp-args-1, Pike_sp-1);    pop_n_elems(args);   }