pike.git / src / encode.c

version» Context lines:

pike.git/src/encode.c:67:      #include <math.h>      #ifdef PIKE_DEBUG   #define encode_value2 encode_value2_   #define decode_value2 decode_value2_   #endif         /* Tags used by encode value. -  * Currently they only differ from the PIKE_T variants by -  * TAG_FLOAT == PIKE_T_TYPE == 7 +  * +  * Currently they differ from the old PIKE_T variants by +  * TAG_FLOAT == OLD_PIKE_T_TYPE == 7    * and -  * TAG_TYPE == PIKE_T_FLOAT == 9 +  * TAG_TYPE == OLD_PIKE_T_FLOAT == 9 +  * +  * The old PIKE_T variants in turn differ from the current for values +  * less than 16 (aka MAX_TYPE) by bit 3 (mask 0x0008 (aka MIN_REF_TYPE)) +  * being inverted. +  *    * These are NOT to be renumbered unless the file-format version is changed!    */   /* Current encoding: ¬∂ke0    *    * +---+-+-+-------+ -  * |s z|s|n|t y p e| +  * |s z|s|n| t a g |    * +---+-+-+-------+    * sz size/small int    * s small int indicator    * n negative (or rather inverted) -  * type TAG_type +  * tag TAG_type (4 bits)    */   #define TAG_ARRAY 0   #define TAG_MAPPING 1   #define TAG_MULTISET 2   #define TAG_OBJECT 3   #define TAG_FUNCTION 4   #define TAG_PROGRAM 5   #define TAG_STRING 6   #define TAG_FLOAT 7   #define TAG_INT 8
pike.git/src/encode.c:228:    } \   }while(0)      #define adddata2(s,l) addstr((char *)(s),(l) * sizeof((s)[0]));      /* NOTE: Fix when type encodings change. */   static int type_to_tag(int type)   {    if (type == T_FLOAT) return TAG_FLOAT;    if (type == T_TYPE) return TAG_TYPE; +  if (type <= MAX_TYPE) return type ^ MIN_REF_TYPE;    return type;   } - static int (*tag_to_type)(int) = type_to_tag; + static int tag_to_type(int tag) + { +  if (tag == TAG_FLOAT) return T_FLOAT; +  if (tag == TAG_TYPE) return T_TYPE; +  if (tag <= MAX_TYPE) return tag ^ MIN_REF_TYPE; +  return tag; + }      /* Let's cram those bits... */   static void code_entry(int tag, INT64 num, struct encode_data *data)   {    int t;    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) );
pike.git/src/encode.c:306:   #endif      /* NOTE: Take care to encode it exactly as the corresponing    * type string would have been encoded (cf T_FUNCTION, T_MANY,    * T_STRING, PIKE_T_NSTRING).    */   static void encode_type(struct pike_type *t, struct encode_data *data)   {    one_more_type:    if (t->type == T_MANY) { -  addchar(T_FUNCTION); +  addchar(T_FUNCTION ^ MIN_REF_TYPE);    addchar(T_MANY);    } else if (t->type == T_STRING) {    if (t->car == int_type_string) { -  addchar(T_STRING); +  addchar(T_STRING ^ MIN_REF_TYPE);    } else {    /* Narrow string */    addchar(PIKE_T_NSTRING);    encode_type(t->car, data);    }    return; -  +  } else if (t->type <= MAX_TYPE) { +  addchar(t->type ^ MIN_REF_TYPE);    } else {    addchar(t->type);    }    switch(t->type) {    default:    Pike_fatal("error in type tree: %d.\n", t->type);    /*NOTREACHED*/       break;   
pike.git/src/encode.c:594:    /* NOTE: Doesn't encode NUMBER_UNDEFINED et al. */    /* But that's a feature; NUMBER_UNDEFINED is an inherently    * transient value. It would lose its usefulness otherwise.    * /mast */      #if SIZEOF_INT_TYPE > 4    {    INT_TYPE i=val->u.integer;    if (i != (INT32)i)    { - #ifdef AUTO_BIGNUM +     /* Reuse the id. */    data->counter.u.integer--;    /* Make sure we don't find ourselves again below... */    map_delete(data->encoded, val);       /* Encode as a bignum */    push_int(i);    convert_stack_top_to_bignum();    encode_value2(Pike_sp-1,data, 0);    pop_stack();       /* Restore the entry we removed above. */    mapping_insert(data->encoded, val, &entry_id); - #else -  Pike_error ("Cannot encode integers with more than 32 bits " -  "without bignum support.\n"); - #endif +     goto encode_done;    }    else    code_entry(TAG_INT, i,data);    }   #else    code_entry(TAG_INT, val->u.integer,data);   #endif    break;   
pike.git/src/encode.c:873:    for (; node; node = low_multiset_next (node))    encode_value2 (low_use_multiset_index (node, ind), data, 0);    }    }    break;    }       case T_OBJECT:    check_stack(1);    - #ifdef AUTO_BIGNUM +     /* This could be implemented a lot more generic,    * but that will have to wait until next time. /Hubbe    */    if(is_bignum_object(val->u.object))    {    code_entry(TAG_OBJECT, 2, data);    /* 256 would be better, but then negative numbers    * won't work... /Hubbe    */    push_int(36);    apply(val->u.object,"digits",1);    if(TYPEOF(Pike_sp[-1]) != T_STRING)    Pike_error("Gmp.mpz->digits did not return a string!\n");    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(encoder_codec (data), "nameof", 1);    EDB(5, fprintf(stderr, "%*s->nameof: ", data->depth, "");    print_svalue(stderr, Pike_sp-1);    fputc('\n', stderr););    switch(TYPEOF(Pike_sp[-1]))    {
pike.git/src/encode.c:1060:    /* We have to remove ourselves from the cache for now */    struct svalue tmp = entry_id;    map_delete(data->encoded, val);       code_entry(TAG_PROGRAM, 2, data);    ref_push_program(p->parent);    encode_value2(Pike_sp-1, data, 0);       ref_push_program(p);    f_function_name(1); + #if 0    if(TYPEOF(Pike_sp[-1]) == PIKE_T_INT)    Pike_error("Cannot encode C programs.\n"); -  + #endif    encode_value2(Pike_sp-1, data, 0);       pop_n_elems(2);       /* Put value back in cache */    mapping_insert(data->encoded, val, &tmp);    goto encode_done;    }    if( p->event_handler )    Pike_error("Cannot encode programs with event handlers.\n"); -  + #if 0    Pike_error("Cannot encode C programs.\n"); -  + #endif    }      #ifdef OLD_PIKE_ENCODE_PROGRAM       EDB(1,    fprintf(stderr, "%*sencode: encoding program in old style\n",    data->depth, ""));       /* Type 1 -- Old-style encoding. */   
pike.git/src/encode.c:1392:    EDB (4, fprintf (stderr, "%*sencode: inherit_num: %d, d_max: %d\n",    data->depth, "", inherit_num, d_max););       /* Fix locally defined identifiers. */    for (; d < d_max; d++) {    struct reference *ref = p->identifier_references + d;    struct inherit *inh = INHERIT_FROM_PTR(p, ref);    struct identifier *id = ID_FROM_PTR(p, ref);       /* Skip identifiers that haven't been overloaded. */ -  if (ref->id_flags & ID_INHERITED) continue; +  if (ref->id_flags & ID_INHERITED) { +  if ((ref->id_flags & (ID_VARIANT|ID_HIDDEN)) == ID_VARIANT) { +  /* Find the dispatcher. */ +  int i = really_low_find_shared_string_identifier(id->name, p, +  SEE_PROTECTED|SEE_PRIVATE); +  /* NB: We use the id_dumped flag for the +  * dispatcher to mark whether we have +  * dumped the first variant of this +  * name in this program. +  */ +  if ((i >= 0) && !is_variant_dispatcher(p, i) && +  !PTR_FROM_INT(p, i)->inherit_offset) { +  /* Overloaded in this program. +  * +  * Make sure later variants don't clear this one. +  */ +  id_dumped[PTR_FROM_INT(p, i)->identifier_offset] = 1; +  } +  } +  continue; +  }       /* Skip getter/setter variables; they get pulled in    * by their respective functions.    */    if (!IDENTIFIER_IS_ALIAS(id->identifier_flags) &&    IDENTIFIER_IS_VARIABLE(id->identifier_flags) &&    (id->run_time_type == PIKE_T_GET_SET))    continue;       EDB(3,
pike.git/src/encode.c:1507:    }    if (symbol) {    int i = really_low_find_shared_string_identifier(symbol, p,    SEE_PROTECTED|SEE_PRIVATE);    if (i >= 0) {    /* Found the symbol. */    gs_flags = PTR_FROM_INT(p, i)->id_flags;    }    free_string(symbol);    } +  } else if (ref->id_flags & ID_VARIANT) { +  /* Find the dispatcher. */ +  int i = really_low_find_shared_string_identifier(id->name, p, +  SEE_PROTECTED|SEE_PRIVATE); +  /* NB: We use the id_dumped flag for the +  * dispatcher to mark whether we have +  * dumped the first variant of this +  * name in this program. +  */ +  if ((i < 0) || !is_variant_dispatcher(p, i)) { +  Pike_error("Failed to find dispatcher for inherited " +  "variant function: %S\n", id->name);    } -  +  if (PTR_FROM_INT(p, i)->inherit_offset) { +  Pike_error("Dispatcher for variant function %S " +  "is inherited.\n", id->name); +  } +  gs_flags = ref->id_flags & PTR_FROM_INT(p, i)->id_flags; +  if (id_dumped[PTR_FROM_INT(p, i)->identifier_offset]) { +  gs_flags |= ID_VARIANT; +  } else { +  /* First variant. */ +  id_dumped[PTR_FROM_INT(p, i)->identifier_offset] = 1; +  } +  }       if (IDENTIFIER_IS_ALIAS(id->identifier_flags)) {    if ((!id->func.ext_ref.depth) &&    IDENTIFIER_IS_VARIABLE(id->identifier_flags)) {    struct identifier *other =    ID_FROM_INT(p, id->func.ext_ref.id);    if (other->name == id->name) {    /* Let define_variable() handle the decoding. */    EDB(3, fprintf(stderr,    "%*sencode: encoding aliased variable\n",
pike.git/src/encode.c:1640:    }   #else /* !PIKE_PORTABLE_BYTECODE */    code_number(id->func.offset, data);   #endif /* PIKE_PORTABLE_BYTECODE */       /* opt_flags */    code_number(id->opt_flags, data);    break;       case IDENTIFIER_C_FUNCTION: +  if (is_variant_dispatcher(p, d)) { +  /* This is handled by end_first_pass() et all. */ +  /* NB: This can be reached even though id_dumped +  * for it gets set by the variant functions, +  * if it is overriding an old definition. +  * +  * We thus need to make sure id_dumped stays cleared. +  */ +  id_dumped[ref->identifier_offset] = 0; +  continue; +  }    /* Not supported. */    Pike_error("Cannot encode functions implemented in C "    "(identifier=\"%S\").\n",    id->name);    break;       case IDENTIFIER_VARIABLE:    if (d < d_min) {    EDB(3,    fprintf(stderr, "%*sencode: Skipping overloaded variable \"%s\"\n",
pike.git/src/encode.c:1684:    pop_stack();       /* filename */    code_number(id->filename_strno, data);       /* linenumber */    code_number(id->linenumber, data);       break;    -  default:; +    #ifdef PIKE_DEBUG -  +  default:    Pike_fatal ("Unknown identifier type: 0x%04x for symbol \"%s\".\n",    id->identifier_flags & IDENTIFIER_TYPE_MASK,    id->name->str);   #endif    }    }       /* Identifier reference number */    code_number(d, data);   
pike.git/src/encode.c:2316:    /* FIXME: Probably ought to use the tag encodings too. */       int tmp;    ONERROR err1;    ONERROR err2;       SET_ONERROR(err1, restore_type_stack, Pike_compiler->type_stackp);    SET_ONERROR(err2, restore_type_mark, Pike_compiler->pike_type_mark_stackp);       tmp = GETC(); +  if (tmp <= MAX_TYPE) tmp ^= MIN_REF_TYPE;    switch(tmp)    {    default:    decode_error(data, NULL, "Error in type string (%d).\n", tmp);    /*NOTREACHED*/    break;       case T_ASSIGN:    tmp = GETC();    if ((tmp < '0') || (tmp > '9')) {
pike.git/src/encode.c:2531:    } \   }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 (void *ignored) + static void cleanup_new_program_decode (void *UNUSED(ignored))   {    debug_malloc_touch(Pike_compiler->new_program);    debug_malloc_touch(Pike_compiler->new_program->parent);    /* The program is consistent enough to be freed... */    Pike_compiler->new_program->flags &= ~PROGRAM_AVOID_CHECK;    end_first_pass(0);   }      static void restore_current_file(void *save_current_file)   {
pike.git/src/encode.c:2997:    } else {    free_array(Pike_sp->u.array);    }    apply_low(o, fun, args);    }    pop_stack();    }       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();   #if SIZEOF_INT_TYPE > 4    reduce_stack_top_bignum();   #endif    break;    }    - #endif +     case 3:    pop_stack();    decode_value2(data);    break;       case 4:    /* Subtyped object. */    if ((TYPEOF(Pike_sp[-1]) != T_OBJECT) || SUBTYPEOF(Pike_sp[-1]) ||    !Pike_sp[-1].u.object->prog) {    decode_error(data, NULL, "Expected plain object. Got: %O\n",
pike.git/src/encode.c:3747:    /* Note: We steal the references from l. */    push_object(o);    *(Pike_sp++) = l->decode_arg;       *ptr = l->next;    free((char *)l);       /* Let the codec do it's job... */    apply_low(decoder_codec (data), decode_fun, 2);    if ((TYPEOF(Pike_sp[-1]) == T_ARRAY) && +  o->prog &&    ((fun = FIND_LFUN(o->prog, LFUN_CREATE)) != -1)) {    /* Call lfun::create(@args). */    INT32 args;    Pike_sp--;    args = Pike_sp->u.array->size;    if (args) {    /* Note: Eats reference to the array. */    push_array_items(Pike_sp->u.array);    } else {    free_array(Pike_sp->u.array);
pike.git/src/encode.c:4611:       if (prog->num_identifier_references != no) {    ref_push_program (p);    decode_error(data, Pike_sp - 1, "Bad number of identifiers "    "in inherit (%d != %d).\n",    no, prog->num_identifier_references);    }       EDB(5,    fprintf(stderr, -  "%*slow_inherit(..., \"%s\")\n", +  "%*slower_inherit(..., \"%s\")\n",    data->depth, "",    name?name->str:"NULL"));       /* Alters    *    * storage, inherits and identifier_references    */ -  low_inherit(prog, parent, parent_identifier, +  lower_inherit(prog, parent, parent_identifier,    parent_offset + 42, id_flags, name);       pop_n_elems(3);    }    break;    default:    decode_error(data, NULL, "Unsupported id entry type: %d\n",    entry_type);    }    decode_number(entry_type, data);
pike.git/src/encode.c:4841:    UNSETJMP(rec);    return 0;    }   }            static struct decode_data *current_decode = NULL;      static void free_decode_data (struct decode_data *data, int delay, -  int free_after_error) +  int DEBUGUSED(free_after_error))   {   #ifdef PIKE_DEBUG    int e;    struct keypair *k;   #endif       debug_malloc_touch(data);       if (current_decode == data) {    current_decode = data->next;