pike.git / src / encode.c

version» Context lines:

pike.git/src/encode.c:18:   #include "pike_error.h"   #include "operators.h"   #include "builtin_functions.h"   #include "module_support.h"   #include "fsort.h"   #include "threads.h"   #include "stuff.h"   #include "version.h"   #include "bignum.h"    - RCSID("$Id: encode.c,v 1.108 2001/07/10 11:57:26 mast Exp $"); + RCSID("$Id: encode.c,v 1.109 2001/07/12 23:14:16 hubbe Exp $");      /* #define ENCODE_DEBUG */      #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(X) do if (data->debug) {X;} while (0) + #define EDB(N,X) do if (data->debug>=N) {X;} while (0)   #else - #define EDB(X) do {} while (0) + #define EDB(N,X) do {} while (0)   #endif      /* The sp macro conflicts with Solaris 2.5.1's <sys/conf.h>. */   #ifdef sp   #undef sp   #define STACKPOINTER_WAS_DEFINED   #endif /* sp */      #ifdef _AIX   #include <net/nh.h>
pike.git/src/encode.c:194:    if (type == T_FLOAT) return TAG_FLOAT;    if (type == T_TYPE) return TAG_TYPE;    return type;   }   static int (*tag_to_type)(int) = type_to_tag;      /* Let's cram those bits... */   static void code_entry(int tag, INT64 num, struct encode_data *data)   {    int t; -  EDB( +  EDB(5,    fprintf(stderr,"%*sencode: code_entry(tag=%d (%s), num=%ld)\n",    data->depth, "", tag,    get_name_of_type(tag_to_type(tag)),    (long)num) );    if(num<0)    {    tag |= TAG_NEG;    num = ~num;    }   
pike.git/src/encode.c:541:    data->depth += 2;   #endif       if((val->type == T_OBJECT ||    (val->type==T_FUNCTION && val->subtype!=FUNCTION_BUILTIN)) &&    !val->u.object->prog)    val = &dested;       if((tmp=low_mapping_lookup(data->encoded, val)))    { -  EDB(fprintf(stderr, "%*sEncoding TAG_AGAIN to <%d>\n", +  EDB(1,fprintf(stderr, "%*sEncoding TAG_AGAIN from <%d>\n",    data->depth, "", tmp->u.integer));    code_entry(TAG_AGAIN, tmp->u.integer, data);   #ifdef ENCODE_DEBUG    data->depth -= 2;   #endif    return;    }else if (val->type != T_TYPE) { -  EDB(fprintf(stderr, "%*sEncoding to <%d>: ", +  EDB(1,fprintf(stderr, "%*sEncoding to <%d>: ",    data->depth, "", data->counter.u.integer); -  +  if(data->debug == 1) +  { +  fprintf(stderr,"TAG%d",val->type); +  }else{    print_svalue(stderr, val); -  +  +  }    fputc('\n', stderr););    mapping_insert(data->encoded, val, &data->counter);    data->counter.u.integer++;    }          switch(val->type)    {    case T_INT:    /* FIXME:
pike.git/src/encode.c:581:    break;       case T_TYPE:    /* NOTE: Types are added to the encoded mapping AFTER they have    * been encoded, to simplify decoding.    */    if (data->canonic)    Pike_error("Canonical encoding of the type type not supported.\n");    code_entry(TAG_TYPE, 0, data); /* Type encoding #0 */    encode_type(val->u.type, data); -  EDB(fprintf(stderr, "%*sEncoded type to <%d>: ", +  EDB(2,fprintf(stderr, "%*sEncoded type to <%d>: ",    data->depth, "", data->counter.u.integer);    print_svalue(stderr, val);    fputc('\n', stderr););    mapping_insert(data->encoded, val, &data->counter);    data->counter.u.integer++;    break;       case T_FLOAT:    {    if(val->u.float_number==0.0)
pike.git/src/encode.c:604:    code_entry(TAG_FLOAT,0,data);    }else{    INT64 x;    int y;    double tmp;       tmp = FREXP((double)val->u.float_number, &y);    x = DO_NOT_WARN((INT64)((((INT64)1)<<(sizeof(INT64)*8 - 2))*tmp));    y -= sizeof(INT64)*8 - 2;    -  EDB(fprintf(stderr, +  EDB(2,fprintf(stderr,    "Encoding float... tmp: %10g, x: 0x%016llx, y: %d\n",    tmp, x, y));      #if 0    if (x && !(x & 0xffffffffUL)) {   #endif /* 0 */    x >>= 32;    y += 32;    -  EDB(fprintf(stderr, +  EDB(2,fprintf(stderr,    "Reducing float... x: 0x%08llx, y: %d\n",    x, y));   #if 0    }   #endif /* 0 */   #if 0    while(x && y && !(x&1))    {    x>>=1;    y++;
pike.git/src/encode.c:735:    apply(data->codec, "nameof", 1);    switch(Pike_sp[-1].type)    {    case T_INT:    if(Pike_sp[-1].subtype == NUMBER_UNDEFINED)    {    pop_stack();    push_svalue(val);    f_object_program(1);    -  code_entry(type_to_tag(val->type), 1,data); +  /* FIXME: +  * If we want to be more backwards compatible, then +  * we could follow the following steps: +  * 1) do a code_entry(TAG_OBJECT, 1, data); +  * 2) remove ourselves from the cache +  * 3) code the program +  * 4) if val is present in the cache, goto 7 +  * 5) call encode_object +  * 6) break; +  * (This is the hard part...) +  * 7) change code_entry in (1) to code_entry(TAG_OBJECT,3 data) +  * 8) push_svalue(val) +  * 9) break; +  * +  * -Hubbe +  */ +  +  if(low_mapping_lookup(data->encoded, Pike_sp-1)) +  { +  code_entry(TAG_OBJECT, 1,data);    encode_value2(Pike_sp-1, data);    pop_stack();       push_svalue(val);    apply(data->codec,"encode_object",1); -  +  }else{ +  /* We have to remove ourself from the cache permanently */ +  map_delete(data->encoded, val); +  +  /* Code the program */ +  code_entry(TAG_OBJECT, 3,data); +  encode_value2(Pike_sp-1, data); +  pop_stack(); +  +  /* Code the object */ +  push_svalue(val); +  }    break;    }    /* FALL THROUGH */       default: -  code_entry(type_to_tag(val->type), 0,data); +  code_entry(TAG_OBJECT, 0,data);    break;    }    encode_value2(Pike_sp-1, data);    pop_stack();    break;       case T_FUNCTION:    if (data->canonic)    Pike_error("Canonical encoding of functions not supported.\n");    check_stack(1);
pike.git/src/encode.c:888:    code_number(p->identifier_index[d],data);       for(d=0;d<p->num_variable_index;d++)    code_number(p->variable_index[d],data);       for(d=0;d<p->num_identifier_references;d++)    {    code_number(p->identifier_references[d].inherit_offset,data);    code_number(p->identifier_references[d].identifier_offset,data);    code_number(p->identifier_references[d].id_flags,data); -  EDB(fprintf(stderr,"IDREF%x > %d: { %d, %d, %d }\n", +  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););    }       for(d=0;d<p->num_strings;d++) adddata(p->strings[d]);       for(d=0;d<p->num_inherits;d++)    {
pike.git/src/encode.c:910:    code_number(p->inherits[d].identifier_level,data);    code_number(p->inherits[d].parent_offset,data);    code_number(p->inherits[d].parent_identifier,data);    code_number(p->inherits[d].storage_offset,data);       if(p->inherits[d].parent)    {    ref_push_object(p->inherits[d].parent);    Pike_sp[-1].subtype=p->inherits[d].parent_identifier;    Pike_sp[-1].type=T_FUNCTION; -  EDB(fprintf(stderr,"INHERIT%x coded as func { %p, %d }\n", +  EDB(3,fprintf(stderr,"INHERIT%x coded as func { %p, %d }\n",    p->id, p->inherits[d].parent, p->inherits[d].parent_identifier););    }else if(p->inherits[d].prog){    ref_push_program(p->inherits[d].prog);    }else{    Pike_error("Failed to encode inherit #%d\n", d);    push_int(0);    }    encode_value2(Pike_sp-1,data);    pop_stack();       adddata3(p->inherits[d].name);    -  EDB(fprintf(stderr,"INHERIT%x > %d: %d id=%d\n", +  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););    }       for(d=0;d<p->num_identifiers;d++)    {    adddata(p->identifiers[d].name);    encode_type(p->identifiers[d].type, data);    code_number(p->identifiers[d].identifier_flags,data);
pike.git/src/encode.c:945:    code_number(p->identifiers[d].opt_flags,data);    if (!(p->identifiers[d].identifier_flags & IDENTIFIER_C_FUNCTION)) {    code_number(p->identifiers[d].func.offset,data);    } else {    Pike_error("Cannot encode functions implemented in C "    "(identifier='%s').\n",    p->identifiers[d].name->str);    }    }    +  for(d=0;d<NUM_LFUNS;d++) +  code_number(p->lfuns[d], data); +     for(d=0;d<p->num_constants;d++)    {    encode_value2(& p->constants[d].sval, data);    adddata3(p->constants[d].name);    } -  -  for(d=0;d<NUM_LFUNS;d++) -  code_number(p->lfuns[d], data); +     }else{    code_entry(type_to_tag(val->type), 0,data);    encode_value2(Pike_sp-1, data);    }    pop_stack();    break;    }    }      #ifdef ENCODE_DEBUG
pike.git/src/encode.c:1108:    push_string(low_free_buf(&data->buf));   }         struct unfinished_prog_link   {    struct unfinished_prog_link *next;    struct program *prog;   };    + struct unfinished_obj_link + { +  struct unfinished_prog_link *next; +  struct object *o; + }; +    struct decode_data   {    unsigned char *data;    ptrdiff_t len;    ptrdiff_t ptr;    struct mapping *decoded;    struct unfinished_prog_link *unfinished_programs; -  +  struct unfinished_obj_link *unfinished_objects;    struct svalue counter;    struct object *codec;    int pickyness;    struct pike_string *raw;    struct decode_data *next;   #ifdef ENCODE_DEBUG    int debug, depth;   #endif   };   
pike.git/src/encode.c:1154:   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 { \ -  EDB( \ +  EDB(5, \    fprintf(stderr,"%*sdecode(%s) at %d: ", \    data->depth,"",(Z),__LINE__)); \    what=GETC(); \    e=what>>SIZE_SHIFT; \    numh=0; \    if(what & TAG_SMALL) { \    num=e; \    } else { \    INT32 numl; \    num=0; \
pike.git/src/encode.c:1178:    } \    while(e-->=0) num=(num<<8) + (GETC()+1); \    numl = num + MAX_SMALL - 1; \    if (numl < num) numh++; \    num = numl; \    } \    if(what & TAG_NEG) { \    num = ~num; \    numh = ~numh; \    } \ -  EDB( \ +  EDB(5, \    fprintf(stderr,"type=%d (%s), num=%ld\n", \    (what & TAG_MASK), \    get_name_of_type(tag_to_type(what & TAG_MASK)), \    (long)num) ); \   } while (0)            #define decode_entry(X,Y,Z) \    do { \
pike.git/src/encode.c:1522:   {    INT32 what, e, num, numh;    struct svalue tmp, *tmp2;      #ifdef ENCODE_DEBUG    data->depth += 2;   #endif       DECODE("decode_value2");    + #ifdef ENCODE_DEBUG +  if(data->debug) +  { +  if((what & TAG_MASK ) == TAG_AGAIN) +  fprintf(stderr, "%*sDecoding TAG_AGAIN from <%d>\n", +  data->depth, "", num); +  +  else +  if(data->debug < 2) +  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_AGAIN:    tmp.type=T_INT;    tmp.subtype=0;    tmp.u.integer=num;    if((tmp2=low_mapping_lookup(data->decoded, &tmp)))    {
pike.git/src/encode.c:1563:    data->counter.u.integer++;    get_string_data(str, num, data);    push_string(str);    break;    }       case TAG_FLOAT:    {    double res;    -  EDB(fprintf(stderr, "Decoding float... numh:0x%08x, num:0x%08x\n", +  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(fprintf(stderr, "Mantissa: %10g\n", res)); +  EDB(2,fprintf(stderr, "Mantissa: %10g\n", res));       tmp = data->counter;    data->counter.u.integer++;       DECODE("float");    -  EDB(fprintf(stderr, "Exponent: %d\n", num)); +  EDB(2,fprintf(stderr, "Exponent: %d\n", num));       push_float(LDEXP(res, num));    break;    }       case TAG_TYPE:    {    struct pike_type *t;       decode_type(t, data);
pike.git/src/encode.c:1607:    struct array *a;    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");       tmp.type=T_ARRAY;    tmp.u.array=a=allocate_array(num); -  EDB(fprintf(stderr, "%*sDecoding array of size %d to <%d>\n", +  EDB(2,fprintf(stderr, "%*sDecoding array of size %d to <%d>\n",    data->depth, "", num, data->counter.u.integer));    mapping_insert(data->decoded, & data->counter, &tmp);    data->counter.u.integer++;       /* Since a reference to the array is stored in the mapping, we can    * safely decrease this reference here. Thus it will be automatically    * freed if something goes wrong.    */    a->refs--;   
pike.git/src/encode.c:1645:    if(num<0)    Pike_error("Failed to decode string. (mapping size is negative)\n");       /* Heruetical */    if(data->ptr + num > data->len)    Pike_error("Failed to decode mapping. (not enough data)\n");       m=allocate_mapping(num);    tmp.type=T_MAPPING;    tmp.u.mapping=m; -  EDB(fprintf(stderr, "%*sDecoding mapping of size %d to <%d>\n", +  EDB(2,fprintf(stderr, "%*sDecoding mapping of size %d to <%d>\n",    data->depth, "", num, data->counter.u.integer));    mapping_insert(data->decoded, & data->counter, &tmp);    data->counter.u.integer++;    m->refs--;       for(e=0;e<num;e++)    {    decode_value2(data);    decode_value2(data);    mapping_insert(m, Pike_sp-2, Pike_sp-1);
pike.git/src/encode.c:1681:       /* 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...*/    a = low_allocate_array(num, 0);    m = allocate_multiset(a);    tmp.type = T_MULTISET;    tmp.u.multiset = m; -  EDB(fprintf(stderr, "%*sDecoding multiset of size %d to <%d>\n", +  EDB(2,fprintf(stderr, "%*sDecoding multiset of size %d to <%d>\n",    data->depth, "", num, data->counter.u.integer));    mapping_insert(data->decoded, & data->counter, &tmp);    data->counter.u.integer++;    debug_malloc_touch(m);       for(e=0;e<num;e++)    {    decode_value2(data);    a->item[e] = sp[-1];    sp--;
pike.git/src/encode.c:1703:    }    array_fix_type_field(a);    order_multiset(m);    push_multiset(m);   #ifdef ENCODE_DEBUG    data->depth -= 2;   #endif    return;    }    -  +     case TAG_OBJECT: -  +  {    tmp=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(IS_ZERO(Pike_sp-1))    { -  EDB(fprintf(stderr, "%*sDecoded a failed object to <%d>: ", +  EDB(1,fprintf(stderr, "%*sDecoded a failed object to <%d>: ",    data->depth, "", tmp.u.integer);    print_svalue(stderr, Pike_sp-1);    fputc('\n', stderr);); -  mapping_insert(data->decoded, &tmp, Pike_sp-1); +     decode_value2(data);    pop_stack();    }else{ -  f_call_function(1); -  EDB(fprintf(stderr, "%*sDecoded an object to <%d>: ", +  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); +  debug_malloc_touch(o); +  pop_stack(); +  push_object(o); +  +  if(o->prog) +  { +  if(o->prog->flags & PROGRAM_FINISHED) +  { +  apply_lfun(o, LFUN___INIT, 0); +  pop_stack(); +  }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, "", tmp.u.integer);    print_svalue(stderr, Pike_sp-1);    fputc('\n', stderr);); -  mapping_insert(data->decoded, &tmp, Pike_sp-1); -  push_svalue(Pike_sp-1); +  +  ref_push_object(o);    decode_value2(data);    if(!data->codec)    Pike_error("Failed to decode (no codec)\n");    apply(data->codec,"decode_object",2);    pop_stack();    } -  if(data->pickyness && Pike_sp[-1].type != T_OBJECT) -  Pike_error("Failed to decode object.\n"); - #ifdef ENCODE_DEBUG -  data->depth -= 2; - #endif -  return; +     -  +  break; +    #ifdef AUTO_BIGNUM    /* It is possible that we should do this even without    * AUTO_BIGNUM /Hubbe    * However, that requires that some of the bignum functions    * 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();    break;    }      #endif -  +  case 3: +  pop_stack(); +  decode_value2(data); +  break;       default:    Pike_error("Object coding not compatible.\n");    break;    } -  if(data->pickyness && Pike_sp[-1].type != T_OBJECT) -  Pike_error("Failed to decode (got type %d; expected object).\n", -  Pike_sp[-1].type); +  if(Pike_sp[-1].type != T_OBJECT) +  if(data->pickyness) +  Pike_error("Failed to decode object.\n"); +  + #ifdef ENCODE_DEBUG +  data->depth -= 2; + #endif    break; -  +  }       case TAG_FUNCTION:    tmp=data->counter;    data->counter.u.integer++;    decode_value2(data);       switch(num)    {    case 0:    if(data->codec)
pike.git/src/encode.c:1881: Inside #if defined(_REENTRANT)
   low_init_threads_disable();    SET_ONERROR(err, do_enable_threads, 0);   #endif       p=low_allocate_program();    SET_ONERROR(err3, zap_unfinished_program, p);       debug_malloc_touch(p);    tmp.type=T_PROGRAM;    tmp.u.program=p; -  EDB(fprintf(stderr, "%*sDecoding a program to <%d>: ", +  EDB(2,fprintf(stderr, "%*sDecoding a program to <%d>: ",    data->depth, "", data->counter.u.integer);    print_svalue(stderr, &tmp);    fputc('\n', stderr););    mapping_insert(data->decoded, & data->counter, &tmp);    data->counter.u.integer++;    p->refs--;       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);       debug_malloc_touch(p);    decode_number(p->flags,data); -  p->flags &= ~(PROGRAM_FINISHED | PROGRAM_OPTIMIZED); +  p->flags &= ~(PROGRAM_FINISHED | PROGRAM_OPTIMIZED | +  PROGRAM_FIXED | PROGRAM_PASS_1_DONE);    p->flags |= PROGRAM_AVOID_CHECK;    decode_number(p->storage_needed,data);    decode_number(p->xstorage,data);    decode_number(p->parent_info_storage,data);    decode_number(p->alignment_needed,data);    decode_number(p->timestamp.tv_sec,data);    decode_number(p->timestamp.tv_usec,data);       debug_malloc_touch(p);    decode_value2(data);
pike.git/src/encode.c:2011:    {    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");    }    decode_number(p->identifier_references[d].identifier_offset,data);    decode_number(p->identifier_references[d].id_flags,data);    -  EDB(fprintf(stderr,"IDREF%x < %d: { %d, %d, %d }\n", +  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]);   
pike.git/src/encode.c:2056:    Pike_error("Program decode failed!\n");    p->refs--;    }       switch(Pike_sp[-1].type)    {    case T_FUNCTION:    if(Pike_sp[-1].subtype == FUNCTION_BUILTIN)    Pike_error("Failed to decode parent.\n");    -  EDB( fprintf(stderr,"INHERIT%x = func { %p, %d} \n",p->id,Pike_sp[-1].u.object, Pike_sp[-1].subtype); ); +  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");    add_ref(p->inherits[d].prog);    p->inherits[d].parent=Pike_sp[-1].u.object;    Pike_sp--;    dmalloc_touch_svalue(Pike_sp);    break;       case T_PROGRAM: -  EDB( fprintf(stderr,"INHERIT%x = prog\n",p->id); ); +  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");    }       getdata3(p->inherits[d].name);    -  EDB( fprintf(stderr,"INHERIT%x < %d: %d id=%d\n", +  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); );    }       debug_malloc_touch(dat);          SET_ONERROR(err1, restore_type_stack, Pike_compiler->type_stackp);    SET_ONERROR(err2, restore_type_mark, Pike_compiler->pike_type_mark_stackp);
pike.git/src/encode.c:2117:    }    }          UNSET_ONERROR(err2);    UNSET_ONERROR(err1);       debug_malloc_touch(dat);       debug_malloc_touch(p); -  for(d=0;d<p->num_constants;d++) -  { -  decode_value2(data); -  p->constants[d].sval=*--Pike_sp; -  dmalloc_touch_svalue(Pike_sp); -  getdata3(p->constants[d].name); -  } -  data->pickyness--; -  -  debug_malloc_touch(dat); -  -  debug_malloc_touch(p); +     for(d=0;d<NUM_LFUNS;d++)    decode_number(p->lfuns[d],data);       debug_malloc_touch(dat);       debug_malloc_touch(p);    {    struct program *new_program_save=Pike_compiler->new_program;    Pike_compiler->new_program=p;    fsort((void *)p->identifier_index,    p->num_identifier_index,    sizeof(unsigned short),(fsortfun)program_function_index_compare);    Pike_compiler->new_program=new_program_save;    } -  +  +  debug_malloc_touch(dat); +  debug_malloc_touch(p); +  p->flags |= PROGRAM_PASS_1_DONE | PROGRAM_FIXED; +  for(d=0;d<p->num_constants;d++) +  { +  decode_value2(data); +  p->constants[d].sval=*--Pike_sp; +  dmalloc_touch_svalue(Pike_sp); +  getdata3(p->constants[d].name); +  } +  data->pickyness--; +  +     UNSET_ONERROR(err3);       ref_push_program(p);       /* 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    * 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)    { -  int done=0; -  struct unfinished_prog_link *l, **ptr; +     p->flags &=~ PROGRAM_AVOID_CHECK;    p->flags |= PROGRAM_FINISHED;    -  +  /* Go through the linked list of unfinished programs +  * to see what programs are now finished. +  */ +  { +  struct unfinished_prog_link *l, **ptr; +    #ifdef PIKE_DEBUG    check_program(p);   #endif /* PIKE_DEBUG */       /* It is possible that we need to restart loop    * in some cases... /Hubbe    */    for(ptr= &data->unfinished_programs ; (l=*ptr);)    {    struct program *pp=l->prog;
pike.git/src/encode.c:2192: Inside #if defined(PIKE_DEBUG)
  #ifdef PIKE_DEBUG    check_program(pp);   #endif /* PIKE_DEBUG */       *ptr = l->next;    free((char *)l);    }else{    ptr=&l->next;    }    } +  } +  +  /* Go through the linked list of unfinished objects +  * to see what objects are now finished. +  */ +  { +  struct unfinished_obj_link *l, **ptr; +  for(ptr= &data->unfinished_objects ; (l=*ptr);) +  { +  struct object *o=l->o; +  if(o->prog) +  { +  if(o->prog->flags & PROGRAM_FINISHED) +  { +  apply_lfun(o, LFUN___INIT, 0); +  pop_stack();    }else{ -  +  ptr=&l->next; +  continue; +  } +  } +  *ptr = l->next; +  free((char *)l); +  } +  } +  +  +  }else{    struct unfinished_prog_link *l;    l=ALLOC_STRUCT(unfinished_prog_link);    l->prog=p;    l->next=data->unfinished_programs;    data->unfinished_programs=l;    }      #ifdef _REENTRANT    UNSET_ONERROR(err);    exit_threads_disable(NULL);
pike.git/src/encode.c:2253:       default:    Pike_error("Cannot decode program encoding type %d\n",num);    }    break;       default:    Pike_error("Failed to restore string. (Illegal type)\n");    }    -  EDB(fprintf(stderr, "%*sDecoded to <%d>: ", data->depth, "", tmp.u.integer); +  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   }         static struct decode_data *current_decode = NULL;      static void free_decode_data(struct decode_data *data)   {    free_mapping(data->decoded);    while(data->unfinished_programs)    {    struct unfinished_prog_link *tmp=data->unfinished_programs;    data->unfinished_programs=tmp->next;    free((char *)tmp);    } -  +  +  while(data->unfinished_objects) +  { +  struct unfinished_obj_link *tmp=data->unfinished_objects; +  data->unfinished_objects=tmp->next; +  free((char *)tmp); +  }    if (current_decode == data) {    current_decode = data->next;    } else {    struct decode_data *d;    for (d = current_decode; d; d=d->next) {    if (d->next == data) {    d->next = d->next->next;    break;    }    }
pike.git/src/encode.c:2331:       data=&d;    data->counter.type=T_INT;    data->counter.u.integer=COUNTER_START;    data->data=(unsigned char *)tmp->str;    data->len=tmp->len;    data->ptr=0;    data->codec=codec;    data->pickyness=0;    data->unfinished_programs=0; +  data->unfinished_objects=0;    data->raw = tmp;    data->next = current_decode;   #ifdef ENCODE_DEBUG    data->debug = debug;    data->depth = -2;   #endif       if (tmp->size_shift) return 0;    if(data->len < 5) return 0;    if(GETC() != 182 ||
pike.git/src/encode.c:2355:       data->decoded=allocate_mapping(128);       current_decode = data;       SET_ONERROR(err, free_decode_data, data);    decode_value2(data);      #ifdef PIKE_DEBUG    if(data->unfinished_programs) -  fatal("We have unfinished programs left in decode()! We may need a double loop!\n"); +  fatal("We have unfinished programs left in decode()!\n"); +  if(data->unfinished_objects) +  fatal("We have unfinished objects left in decode()!\n");   #endif    CALL_AND_UNSET_ONERROR(err);    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");