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.230 2005/05/31 12:00:07 grubba Exp $ + || $Id: encode.c,v 1.231 2005/05/31 16:22:59 mast 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:1822:   };      struct unfinished_obj_link   {    struct unfinished_obj_link *next;    struct object *o;   };      struct decode_data   { +  struct pike_string *data_str;    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;    int pass;    struct pike_string *raw;    struct decode_data *next;   #ifdef PIKE_THREADS    struct thread_state *thread_state; -  +  struct object *thread_obj;   #endif   #ifdef ENCODE_DEBUG    int debug, depth;   #endif -  + #if TWO_PASS_DECODE_WORKS +  /* The delay stuff can trig a second pass through the decoder, +  * but it doesn't seem to really handle that. /mast */    struct Supporter supporter; -  + #endif   };      static void decode_value2(struct decode_data *data);      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++ ];   }
pike.git/src/encode.c:2809:    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 TWO_PASS_DECODE_WORKS    if(! data->supporter.prog)    data->supporter.prog = p; -  + #endif       debug_malloc_touch(p);    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.git/src/encode.c:3227:       if(placeholder)    {    free_object(placeholder);    UNSET_ONERROR(err4);    }    UNSET_ONERROR(err3);       ref_push_program(p);    -  if(!(p->flags & PROGRAM_FINISHED) && -  !data->supporter.depends_on) +  if(!(p->flags & PROGRAM_FINISHED) + #if TWO_PASS_DECODE_WORKS +  && !data->supporter.depends_on + #endif +  )    {    /* Logic for the PROGRAM_FINISHED flag:    * The purpose of this code is to make sure that the PROGRAM_FINISHED    * 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;   
pike.git/src/encode.c:3476:    * __pragma_save_parent__.    */    lex.pragmas = (old_pragmas & ~ID_SAVE_PARENT)|ID_DONT_SAVE_PARENT;    SET_ONERROR(err2, set_lex_pragmas, (ptrdiff_t) old_pragmas);       /* Start the new program. */    orig_compilation_depth = compilation_depth;    compilation_depth = -1;    low_start_new_program(p, 1, NULL, 0, NULL);    p = Pike_compiler->new_program; + #if TWO_PASS_DECODE_WORKS +  if(! data->supporter.prog) +  data->supporter.prog = p; + #endif       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);   
pike.git/src/encode.c:4223:    call_pike_initializers(placeholder,0);    UNSETJMP(rec);    return 0;    }   }            static struct decode_data *current_decode = NULL;    - static void free_decode_data(struct decode_data *data) + static void free_decode_data (struct decode_data *data, int delay, +  int free_after_error)   { -  int delay; + #ifdef PIKE_DEBUG +  int e; +  struct keypair *k; + #endif       debug_malloc_touch(data);       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;    }    } - #ifdef PIKE_DEBUG -  if (!d) { -  Pike_fatal("Decode data fell off the stack!\n"); +     } - #endif /* PIKE_DEBUG */ -  } +     -  -  delay=unlink_current_supporter(&data->supporter); -  call_dependants(& data->supporter, 1); -  +     if(delay)    {    debug_malloc_touch(data);    /* We have been delayed */    return;    }    -  free_mapping(data->decoded); -  +    #ifdef PIKE_DEBUG -  +  if (!free_after_error) { +  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); +  } +  }    if(data->unfinished_programs)    Pike_fatal("We have unfinished programs left in decode()!\n");    if(data->unfinished_objects)    Pike_fatal("We have unfinished objects left in decode()!\n"); -  +  }   #endif    -  +  free_string (data->data_str); +  free_object (data->codec); +  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);    } -  +    #ifdef PIKE_THREADS    data->thread_state = NULL; -  +  free_object (data->thread_obj);   #endif       free( (char *) data);   }      static void low_do_decode (struct decode_data *data)   { -  decode_value2(current_decode = data); +  current_decode = data;    -  +  decode_value2(data); +     while (data->ptr < data->len) {    decode_value2 (data);    pop_stack();    }   }    -  + #if TWO_PASS_DECODE_WORKS   /* Run pass2 */   int re_decode(struct decode_data *data, int ignored)   { -  ONERROR err; -  SET_ONERROR(err, free_decode_data, data); +  JMP_BUF recovery; +  struct svalue orig_thrown; +  move_svalue (&orig_thrown, &throw_value); +  throw_value.type = T_INT; +  +  if (SETJMP (recovery)) { +  UNSETJMP (recovery); +  call_handle_error(); +  move_svalue (&throw_value, &orig_thrown); +  free_decode_data (data, 0, 1); +  return 0; +  } +  +  else {    data->next = current_decode;    low_do_decode (data); -  CALL_AND_UNSET_ONERROR(err); +  UNSETJMP (recovery); +  move_svalue (&throw_value, &orig_thrown); +  free_decode_data (data, 0, 0);    return 1;    } -  + } + #endif    -  + static void error_free_decode_data (struct decode_data *data) + { +  int delay; +  debug_malloc_touch (data); + #if TWO_PASS_DECODE_WORKS +  delay=unlink_current_supporter(&data->supporter); +  call_dependants(& data->supporter, 1); + #else +  delay = 0; + #endif +  free_decode_data (data, delay, 1); + } +    static INT32 my_decode(struct pike_string *tmp,    struct object *codec   #ifdef ENCODE_DEBUG    , int debug   #endif    )   {    struct decode_data *data; -  int e; -  struct keypair *k; +     ONERROR err;       /* 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_state == Pike_interpreter.thread_state   #endif    ) {    struct svalue *res;
pike.git/src/encode.c:4347:    }    /* Possible recursion detected. */    /* return 0; */    }    }       data=ALLOC_STRUCT(decode_data);    data->counter.type=T_INT;    data->counter.subtype=NUMBER_NUMBER;    data->counter.u.integer=COUNTER_START; +  data->data_str = tmp;    data->data=(unsigned char *)tmp->str;    data->len=tmp->len;    data->ptr=0;    data->codec=codec;    data->pickyness=0;    data->pass=1;    data->unfinished_programs=0;    data->unfinished_objects=0;    data->raw = tmp;    data->next = current_decode;   #ifdef PIKE_THREADS    data->thread_state = Pike_interpreter.thread_state; -  +  data->thread_obj = Pike_interpreter.thread_state->thread_obj;   #endif   #ifdef ENCODE_DEBUG    data->debug = debug;    data->depth = -2;   #endif       if (tmp->size_shift ||    data->len < 5 ||    GETC() != 182 ||    GETC() != 'k' ||    GETC() != 'e' ||    GETC() != '0')    {    free( (char *) data);    return 0;    }       data->decoded=allocate_mapping(128);    -  SET_ONERROR(err, free_decode_data, data); +  add_ref (data->data_str); +  add_ref (data->codec); +  add_ref (data->thread_obj); +  SET_ONERROR(err, error_free_decode_data, data);    -  + #if TWO_PASS_DECODE_WORKS    init_supporter(& data->supporter,    (supporter_callback *) re_decode,    (void *)data); -  + #endif       low_do_decode (data);    - #ifdef PIKE_DEBUG -  NEW_MAPPING_LOOP (data->decoded->data) { -  if (k->val.type == T_PROGRAM && -  !(k->val.u.program->flags & PROGRAM_FINISHED)) { -  decode_error (Pike_sp-1, &k->val, -  "Got unfinished program <k:%"PRINTPIKEINT"d> " -  "after decode: ", -  k->ind.u.integer); -  } -  } +  UNSET_ONERROR(err); +  +  { +  int delay; + #if TWO_PASS_DECODE_WORKS +  delay=unlink_current_supporter(&data->supporter); +  call_dependants(& data->supporter, 1); + #else +  delay = 0;   #endif -  +  free_decode_data (data, delay, 0); +  }    -  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");    else (*l)--;    (*v)++;