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.167 2004/05/11 10:49:55 grubba Exp $ + || $Id: encode.c,v 1.168 2004/05/11 11:03:00 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.167 2004/05/11 10:49:55 grubba Exp $"); + RCSID("$Id: encode.c,v 1.168 2004/05/11 11:03:00 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:121:    int canonic;    struct object *codec;    struct svalue counter;    struct mapping *encoded;    dynamic_buffer buf;   #ifdef ENCODE_DEBUG    int debug, depth;   #endif   };    - static void encode_value2(struct svalue *val, struct encode_data *data); + static void encode_value2(struct svalue *val, struct encode_data *data, int force_encode);      #define addstr(s, l) low_my_binary_strcat((s), (l), &(data->buf))   #define addchar(t) low_my_putchar((char)(t), &(data->buf))      /* Code a pike string */      #if BYTEORDER == 4321   #define ENCODE_DATA(S) \    addstr( (S)->str, (S)->len << (S)->size_shift );   #else
pike.git/src/encode.c:281:       break;       case PIKE_T_NAME:    {    struct svalue sval;    sval.type = PIKE_T_STRING;    sval.subtype = 0;    sval.u.string = (void *)t->car;    -  encode_value2(&sval, data); +  encode_value2(&sval, data, 0);    }    t=t->cdr;    goto one_more_type;       case T_ASSIGN:    {    ptrdiff_t marker = CAR_TO_INT(t);    if ((marker < 0) || (marker > 9)) {    Pike_fatal("Bad assign marker: %ld\n",    (long)marker);
pike.git/src/encode.c:381:    {    ref_push_program(p);    }else{    push_int(0);    }    } else    push_int( id );    }else{    push_int(0);    } -  encode_value2(Pike_sp-1, data); +  /* If it's a program that should be encoded recursively then we +  * must delay it. Consider: +  * +  * class A {B b;} +  * class B {inherit A;} +  * +  * We can't dump B when the type is encountered inside A, since +  * upon decode B won't have a complete A to inherit then. +  */ +  encode_value2(Pike_sp-1, data, 0);    pop_stack();    break;    }    }   }      static void zap_unfinished_program(struct program *p)   {    int e;    debug_malloc_touch(p);
pike.git/src/encode.c:422:    {    if(p->inherits[e].prog)    {    free_program(p->inherits[e].prog);    p->inherits[e].prog=0;    }    }    }   }    - static void encode_value2(struct svalue *val, struct encode_data *data) + /* force_encode == 0: Maybe dump the thing later, and only a forward +  * reference here (applies to programs only). +  * +  * force_encode == 1: Dump the thing now. +  * +  * force_encode == 2: A forward reference has been encoded to this +  * thing. Now it's time to dump it. */    -  + static void encode_value2(struct svalue *val, struct encode_data *data, int force_encode) +    #ifdef PIKE_DEBUG   #undef encode_value2 - #define encode_value2(X,Y) do { struct svalue *_=Pike_sp; encode_value2_(X,Y); if(Pike_sp!=_) Pike_fatal("encode_value2 failed!\n"); } while(0) + #define encode_value2(X,Y,Z) do { \ +  struct svalue *_=Pike_sp; \ +  struct svalue *X_ = (X); \ +  encode_value2_(X_,Y,Z); \ +  if(Pike_sp != _) { \ +  fprintf(stderr, "Stack error when encoding:\n"); \ +  print_svalue(stderr, X_); \ +  fprintf(stderr, "\n"); \ +  if (X_->type == T_PROGRAM) { \ +  dump_program_tables(X_->u.program, 2); \ +  } \ +  Pike_fatal("encode_value2() failed %p != %p!\n", \ +  Pike_sp, _); \ +  } \ +  } while(0)   #endif      {    static struct svalue dested = {    T_INT, NUMBER_DESTRUCTED,   #ifdef HAVE_UNION_INIT    {0}, /* Only to avoid warnings. */   #endif    };    INT32 i;
pike.git/src/encode.c:657:   #endif    code_entry(TAG_FLOAT,x,data);    code_entry(TAG_FLOAT,y,data);    }    break;    }       case T_ARRAY:    code_entry(TAG_ARRAY, val->u.array->size, data);    for(i=0; i<val->u.array->size; i++) -  encode_value2(ITEM(val->u.array)+i, data); +  encode_value2(ITEM(val->u.array)+i, data, 0);    break;       case T_MAPPING:    check_stack(2);    ref_push_mapping(val->u.mapping);    f_indices(1);       ref_push_mapping(val->u.mapping);    f_values(1);   
pike.git/src/encode.c:688:    }    order = get_switch_order(Pike_sp[-2].u.array);    order_array(Pike_sp[-2].u.array, order);    order_array(Pike_sp[-1].u.array, order);    free((char *) order);    }       code_entry(TAG_MAPPING, Pike_sp[-2].u.array->size,data);    for(i=0; i<Pike_sp[-2].u.array->size; i++)    { -  encode_value2(ITEM(Pike_sp[-2].u.array)+i, data); /* indices */ -  encode_value2(ITEM(Pike_sp[-1].u.array)+i, data); /* values */ +  encode_value2(ITEM(Pike_sp[-2].u.array)+i, data, 0); /* indices */ +  encode_value2(ITEM(Pike_sp[-1].u.array)+i, data, 0); /* values */    }    pop_n_elems(2);    break;       case T_MULTISET: {    struct multiset *l = val->u.multiset;      #ifdef PIKE_NEW_MULTISETS    if (multiset_indval (l) || multiset_get_cmp_less (l)->type != T_INT)    Pike_error ("FIXME: Encoding of multisets with values and/or "
pike.git/src/encode.c:726: Inside #if defined(PIKE_NEW_MULTISETS)
   check_stack(1);   #ifdef PIKE_NEW_MULTISETS    push_array(multiset_indices(l));   #else    push_array(copy_array(l->ind));   #endif    order = get_switch_order(Pike_sp[-1].u.array);    order_array(Pike_sp[-1].u.array, order);    free((char *) order);    for (i = 0; i < Pike_sp[-1].u.array->size; i++) -  encode_value2(ITEM(Pike_sp[-1].u.array)+i, data); +  encode_value2(ITEM(Pike_sp[-1].u.array)+i, data, 0);    pop_stack();    }    else {   #ifdef PIKE_NEW_MULTISETS    struct svalue ind;    union msnode *node = low_multiset_first (l->msd);    for (; node; node = low_multiset_next (node)) -  encode_value2 (low_use_multiset_index (node, ind), data); +  encode_value2 (low_use_multiset_index (node, ind), data, 0);   #else    for(i=0; i<l->ind->size; i++) -  encode_value2(ITEM(l->ind)+i, data); +  encode_value2(ITEM(l->ind)+i, data, 0);   #endif    }   #ifdef PIKE_NEW_MULTISETS    }   #endif    break;    }       case T_OBJECT:    check_stack(1);
pike.git/src/encode.c:763: Inside #if defined(AUTO_BIGNUM)
   if(is_bignum_object(val->u.object))    {    code_entry(TAG_OBJECT, 2, data);    /* 256 would be better, but then negative numbers    * doesn't work... /Hubbe    */    push_int(36);    apply(val->u.object,"digits",1);    if(Pike_sp[-1].type != T_STRING)    Pike_error("Gmp.mpz->digits did not return a string!\n"); -  encode_value2(Pike_sp-1, data); +  encode_value2(Pike_sp-1, data, 0);    pop_stack();    break;    }   #endif       if (data->canonic)    Pike_error("Canonical encoding of objects not supported.\n");    push_svalue(val);    apply(data->codec, "nameof", 1);    EDB(5, fprintf(stderr, "%*s->nameof: ", data->depth, "");
pike.git/src/encode.c:796:       /* We have to remove ourself from the cache */    map_delete(data->encoded, val);       pop_stack();    push_svalue(val);    f_object_program(1);       /* Code the program */    code_entry(TAG_OBJECT, 3,data); -  encode_value2(Pike_sp-1, data); +  encode_value2(Pike_sp-1, data, 1);    pop_stack();       push_svalue(val);       /* If we do not exist in cache, use backwards-    * compatible method, otherwise use newfangled    * style=3. -Hubbe    */    if(!low_mapping_lookup(data->encoded, val))    {
pike.git/src/encode.c:834:    mapping_insert(data->encoded, val, &tmp);    }    break;    }    /* FALL THROUGH */       default:    code_entry(TAG_OBJECT, 0,data);    break;    } -  encode_value2(Pike_sp-1, data); +  encode_value2(Pike_sp-1, data, 0);    pop_stack();    break;       case T_FUNCTION:    /* FIXME: Ought to have special treatment of trampolines. */    if (data->canonic)    Pike_error("Canonical encoding of functions not supported.\n");    check_stack(1);    push_svalue(val);    apply(data->codec,"nameof", 1);
pike.git/src/encode.c:860:    val->u.object->prog)==val->subtype)    {    /* We have to remove ourself from the cache for now */    struct svalue tmp=data->counter;    tmp.u.integer--;    map_delete(data->encoded, val);       code_entry(TAG_FUNCTION, 1, data);    push_svalue(val);    Pike_sp[-1].type=T_OBJECT; -  encode_value2(Pike_sp-1, data); +  encode_value2(Pike_sp-1, data, 0);    ref_push_string(ID_FROM_INT(val->u.object->prog, val->subtype)->name); -  encode_value2(Pike_sp-1, data); +  encode_value2(Pike_sp-1, data, 0);    pop_n_elems(3);       /* Put value back in cache */    mapping_insert(data->encoded, val, &tmp);   #ifdef ENCODE_DEBUG    data->depth -= 2;   #endif    return;    }    }    Pike_error("Encoding of efuns is not supported yet.\n");    }       code_entry(TAG_FUNCTION, 0, data); -  encode_value2(Pike_sp-1, data); +  encode_value2(Pike_sp-1, data, 0);    pop_stack();    break;          case T_PROGRAM:    {    int d;    if (val->u.program->id < PROG_DYNAMIC_ID_START) {    code_entry(TAG_PROGRAM, 3, data);    push_int(val->u.program->id); -  encode_value2(Pike_sp-1, data); +  encode_value2(Pike_sp-1, data, 0);    pop_stack();    break;    }    if (data->canonic)    Pike_error("Canonical encoding of programs not supported.\n");    check_stack(1);    push_svalue(val);    apply(data->codec,"nameof", 1);    if(Pike_sp[-1].type == val->type)    Pike_error("Error in master()->nameof(), same type returned.\n");
pike.git/src/encode.c:913:    {    if(p->parent)    {    /* We have to remove ourself from the cache for now */    struct svalue tmp=data->counter;    tmp.u.integer--;    map_delete(data->encoded, val);       code_entry(TAG_PROGRAM, 2, data);    ref_push_program(p->parent); -  encode_value2(Pike_sp-1,data); +  encode_value2(Pike_sp-1, data, 0);       ref_push_program(p);    f_function_name(1);    if(Pike_sp[-1].type == PIKE_T_INT)    Pike_error("Cannot encode C programs.\n"); -  encode_value2(Pike_sp-1, data); +  encode_value2(Pike_sp-1, data, 0);       pop_n_elems(3);       /* Put value back in cache */    mapping_insert(data->encoded, val, &tmp);   #ifdef ENCODE_DEBUG    data->depth -= 2;   #endif    return;    }
pike.git/src/encode.c:946:    EDB(1,    fprintf(stderr, "%*sencode: encoding program\n",    data->depth, ""));      #ifdef OLD_PIKE_ENCODE_PROGRAM       /* Type 1 -- Old-style encoding. */       code_entry(TAG_PROGRAM, 1, data);    f_version(0); -  encode_value2(Pike_sp-1,data); +  encode_value2(Pike_sp-1,data, 0);    pop_stack();    code_number(p->flags,data);    code_number(p->storage_needed,data);    code_number(p->xstorage,data); /**/    code_number(p->parent_info_storage,data); /**/       code_number(p->alignment_needed,data);    code_number(p->timestamp.tv_sec,data);    code_number(p->timestamp.tv_usec,data);       if(p->parent)    ref_push_program(p->parent);    else    push_int(0); -  encode_value2(Pike_sp-1,data); /**/ +  encode_value2(Pike_sp-1,data, 0); /**/    pop_stack();      #define FOO(X,Y,Z) \    code_number( p->PIKE_CONCAT(num_,Z), data);   #include "program_areas.h"       code_number(PIKE_BYTECODE_METHOD, data);      #ifdef ENCODE_PROGRAM   #ifdef PIKE_DEBUG
pike.git/src/encode.c:1036:    Pike_sp[-1].subtype=p->inherits[d].parent_identifier;    Pike_sp[-1].type=T_FUNCTION;    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); +  encode_value2(Pike_sp-1,data, 1);    pop_stack();       adddata3(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:1068:    "(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); +  encode_value2(& p->constants[d].sval, data, 0);    adddata3(p->constants[d].name);    }      #else /* !OLD_PIKE_ENCODE_PROGRAM */       /* Type 4 -- Portable encoding. */    code_entry(type_to_tag(val->type), 4, data);       /* Byte-order. */    code_number(PIKE_BYTEORDER, data);       /* flags */    code_number(p->flags,data);       /* version */    f_version(0); -  encode_value2(Pike_sp-1, data); +  encode_value2(Pike_sp-1, data, 0);    pop_stack();       /* parent */    if (p->parent) {    ref_push_program(p->parent);    } else {    push_int(0);    } -  encode_value2(Pike_sp-1, data); +  encode_value2(Pike_sp-1, data, 0);    pop_stack();       /* num_* */   #define FOO(X,Y,Z) \    code_number( p->PIKE_CONCAT(num_,Z), data);   #include "program_areas.h"       /* Byte-code method    */    code_number(PIKE_BYTECODE_METHOD, data);
pike.git/src/encode.c:1148:    /* linenumbers */    adddata2(p->linenumbers, p->num_linenumbers);       {    struct svalue str_sval;    str_sval.type = T_STRING;    str_sval.subtype = 0;    /* strings */    for(d=0;d<p->num_strings;d++) {    str_sval.u.string = p->strings[d]; -  encode_value2(&str_sval, data); +  encode_value2(&str_sval, data, 0);    }    }       EDB(5, dump_program_tables(p, data->depth));       /* Dump the identifiers in a portable manner... */    {    int inherit_num = 1;    struct svalue str_sval;    char *id_dumped = (char *) alloca(p->num_identifiers);
pike.git/src/encode.c:1258:       EDB(3,    fprintf(stderr, "%*sencode: encoding constant\n",    data->depth, ""));       code_number(ID_ENTRY_CONSTANT, data);    code_number(ref->id_flags, data);       /* name */    str_sval.u.string = id->name; -  encode_value2(&str_sval, data); +  encode_value2(&str_sval, data, 0);       /* offset */    code_number(id->func.offset, data);       /* type */    ref_push_type_value(id->type); -  encode_value2(Pike_sp-1, data); +  encode_value2(Pike_sp-1, data, 0);    pop_stack();       /* run-time type */    code_number(id->run_time_type, data);    } else if (IDENTIFIER_IS_PIKE_FUNCTION(id->identifier_flags)) {    /* Pike function */       EDB(3,    fprintf(stderr, "%*sencode: encoding function\n",    data->depth, ""));       code_number(ID_ENTRY_FUNCTION, data);    code_number(ref->id_flags, data);       /* name */    str_sval.u.string = id->name; -  encode_value2(&str_sval, data); +  encode_value2(&str_sval, data, 0);       /* type */    ref_push_type_value(id->type); -  encode_value2(Pike_sp-1, data); +  encode_value2(Pike_sp-1, data, 0);    pop_stack();       /* func_flags (aka identifier_flags) */    code_number(id->identifier_flags, data);       /* func */    code_number(id->func.offset, data);       /* opt_flags */    code_number(id->opt_flags, data);
pike.git/src/encode.c:1314:    /* Variable */    EDB(3,    fprintf(stderr, "%*sencode: encoding variable\n",    data->depth, ""));       code_number(ID_ENTRY_VARIABLE, data);    code_number(ref->id_flags, data);       /* name */    str_sval.u.string = id->name; -  encode_value2(&str_sval, data); +  encode_value2(&str_sval, data, 0);       /* type */    ref_push_type_value(id->type); -  encode_value2(Pike_sp-1, data); +  encode_value2(Pike_sp-1, data, 0);    pop_stack();    }    }       /* Identifier reference number */    code_number(d, data);       next_identifier_ref:    ; /* C requires a statement after lables. */   #ifdef ENCODE_DEBUG
pike.git/src/encode.c:1374:       EDB(5,    fprintf(stderr, "%*sinherit_flags: %04x\n",    data->depth, "", inherit_flags_change));       /* Identifier reference level at insertion. */    code_number(d_max, data);       /* name */    str_sval.u.string = inh->name; -  encode_value2(&str_sval, data); +  encode_value2(&str_sval, data, 0);       /* prog */    ref_push_program(inh->prog); -  encode_value2(Pike_sp-1, data); +  encode_value2(Pike_sp-1, data, 1);    pop_stack();       /* parent */    if (inh->parent) {    ref_push_object(inh->parent);    } else {    push_int(0);    } -  encode_value2(Pike_sp-1, data); +  encode_value2(Pike_sp-1, data, 0);    pop_stack();       /* parent_identifier */    code_number(inh->parent_identifier, data);       /* parent_offset */    code_number(inh->parent_offset, data);       /* Number of identifier references. */    code_number(inh->prog->num_identifier_references, data);
pike.git/src/encode.c:1424:    /* Encode the constant values table. */    {    struct svalue str_sval;    str_sval.type = T_STRING;    str_sval.subtype = 0;       /* constants */    for(d=0;d<p->num_constants;d++)    {    /* value */ -  encode_value2(&p->constants[d].sval, data); +  encode_value2(&p->constants[d].sval, data, 0);       /* name */    if (p->constants[d].name) {    str_sval.u.string = p->constants[d].name; -  encode_value2(&str_sval, data); +  encode_value2(&str_sval, data, 0);    } else {    push_int(0); -  encode_value2(Pike_sp-1, data); +  encode_value2(Pike_sp-1, data, 0);    Pike_sp--;    }    }    }   #endif /* OLD_PIKE_ENCODE_PROGRAM */    }else{    code_entry(TAG_PROGRAM, 0, data); -  encode_value2(Pike_sp-1, data); +  encode_value2(Pike_sp-1, data, 0);    }    pop_stack();    break;    }    }      #ifdef ENCODE_DEBUG    data->depth -= 2;   #endif   }
pike.git/src/encode.c:1522:    }else{    data->codec=get_master();    }   #ifdef ENCODE_DEBUG    data->debug = args > 2 ? Pike_sp[2-args].u.integer : 0;    data->depth = -2;   #endif       SET_ONERROR(tmp, free_encode_data, data);    addstr("\266ke0", 4); -  encode_value2(Pike_sp-args, data); +  encode_value2(Pike_sp-args, data, 1);    UNSET_ONERROR(tmp);       free_mapping(data->encoded);       pop_n_elems(args);    push_string(low_free_buf(&data->buf));   }      /*! @decl string encode_value_canonic(mixed value, object|void codec)    *!
pike.git/src/encode.c:1583:    }else{    data->codec=get_master();    }   #ifdef ENCODE_DEBUG    data->debug = args > 2 ? Pike_sp[2-args].u.integer : 0;    data->depth = -2;   #endif       SET_ONERROR(tmp, free_encode_data, data);    addstr("\266ke0", 4); -  encode_value2(Pike_sp-args, data); +  encode_value2(Pike_sp-args, data, 1);    UNSET_ONERROR(tmp);       free_mapping(data->encoded);       pop_n_elems(args);    push_string(low_free_buf(&data->buf));   }         struct unfinished_prog_link