pike.git / src / encode.c

version» Context lines:

pike.git/src/encode.c:2460:    struct mapping *decoded;    struct unfinished_prog_link *unfinished_programs;    struct unfinished_obj_link *unfinished_objects;    struct unfinished_obj_link *unfinished_placeholders;    struct svalue counter;    struct object *codec;    int explicit_codec;    int pickyness;    int pass;    int delay_counter; +  int support_delay_counter; +  struct compilation *support_compilation;    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;    ptrdiff_t debug_ptr;    struct string_builder *debug_buf;
pike.git/src/encode.c:2876:    } \   }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 *UNUSED(ignored)) + static void cleanup_new_program_decode (void *compilation)   { -  +  struct compilation *c = compilation;    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; -  +  unlink_current_supporter(& c->supporter);    end_first_pass(0);   }      static void restore_current_file(void *save_current_file)   {    struct compilation *c = THIS_COMPILATION;    free_string(c->lex.current_file);    c->lex.current_file = save_current_file;   }   
pike.git/src/encode.c:2999:    EMIT_BYTECODE(STR0, EMIT_BYTECODE2);    break;   #undef SIGNED_CHAR   #undef EMIT_BYTECODE   #undef EMIT_BYTECODE2    }    UNSET_ONERROR(err);    return assemble(1);   }    + static void low_do_decode (struct decode_data *data); + static void free_decode_data (struct decode_data *data, int delay, +  int DEBUGUSED(free_after_error)); +  + static int call_delayed_decode(struct Supporter *s, int finish) + { +  JMP_BUF recovery; +  struct decode_data *data = s->data; +  struct compilation *cc = (struct compilation *)s; +  volatile int ok = 0; +  +  if (!data) +  return 0; +  +  debug_malloc_touch(cc); +  debug_malloc_touch(cc->p); +  +  if (finish) { + #ifdef ENCODE_DEBUG +  struct string_builder buf; + #endif +  struct svalue *osp = Pike_sp; +  struct compilation *prevcc = data->support_compilation; +  data->support_compilation = cc; +  SET_SVAL(data->counter, T_INT, NUMBER_NUMBER, integer, COUNTER_START); +  data->ptr=4; /* Skip 182 'k' 'e' '0' */ + #ifdef ENCODE_DEBUG +  data->debug_ptr = 0; +  if (data->debug && !data->debug_buf) { +  data->debug_buf = &buf; +  init_string_builder(data->debug_buf, 0); +  } +  data->depth = -2; + #endif +  +  if (SETJMP(recovery)) { +  push_svalue (&throw_value); +  SAFE_APPLY_MASTER ("describe_error", 1); +  pop_stack(); +  UNSETJMP(recovery); +  free_svalue(&throw_value); +  mark_free_svalue (&throw_value); +  } else { +  int e; +  struct keypair *k; +  +  while(data->unfinished_programs) +  { +  struct unfinished_prog_link *tmp=data->unfinished_programs; +  data->unfinished_programs=tmp->next; +  free(tmp); +  } +  +  while(data->unfinished_objects) +  { +  struct unfinished_obj_link *tmp=data->unfinished_objects; +  data->unfinished_objects=tmp->next; +  free_svalue(&tmp->decode_arg); +  free_object(tmp->o); +  free(tmp); +  } +  +  while(data->unfinished_placeholders) +  { +  struct unfinished_obj_link *tmp=data->unfinished_placeholders; +  data->unfinished_placeholders=tmp->next; +  free_object(tmp->o); +  free(tmp); +  } +  +  data->pass=1; +  +  low_do_decode (data); +  +  UNSETJMP(recovery); +  ok = 1; +  } + #ifdef ENCODE_DEBUG +  if (data->debug_buf == &buf) { +  write_and_reset_string_builder(2, data->debug_buf); +  free_string_builder(data->debug_buf); +  data->debug_buf = NULL; +  } + #endif +  data->support_compilation = prevcc; +  pop_n_elems(Pike_sp-osp); +  } +  +  if(cc->p) { +  free_program(cc->p); /* later */ +  cc->p = NULL; +  } +  + #ifdef PIKE_DEBUG +  verify_supporters(); + #endif +  +  return ok; + } +  + static void exit_delayed_decode(struct Supporter *s) + { +  if (s->data != NULL) { +  struct decode_data *data = s->data; +  --data->support_delay_counter; +  free_decode_data(data, 0, 0); +  } + } +    static void decode_value2(struct decode_data *data)      #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;
pike.git/src/encode.c:3714:    decode_error (data, NULL, "Didn't get program embryo "    "for delay encoded program <%O>: %O\n",    &entry_id, delayed_enc_val);    }    /* 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;    debug_malloc_touch(p);    } -  else +  else if (data->support_compilation) { +  struct svalue *val = low_mapping_lookup (data->decoded, &entry_id); +  if (val == NULL)    p = NULL; -  +  else { +  if (TYPEOF(*val) != T_PROGRAM || +  (val->u.program->flags & +  (PROGRAM_OPTIMIZED | PROGRAM_FIXED | +  PROGRAM_FINISHED | PROGRAM_PASS_1_DONE)) != +  PROGRAM_PASS_1_DONE) { +  decode_error (data, NULL, "Didn't get pass 1 program " +  "for supporter delay encoded program <%O>: %O\n", +  &entry_id, val); +  } +  p = val->u.program; +  if (p != data->support_compilation->supporter.prog) +  p = NULL; +  else { +  debug_malloc_touch(p); +  /* low_start_new_program will restore the program to +  a pristine state as long as p->program is NULL, +  so free it here */ +  if (p->program) { + #ifdef PIKE_USE_MACHINE_CODE +  mexec_free(p->program); + #else +  free(p->program); + #endif +  p->program = NULL; +  p->num_program = 0; +  } +  } +  } +  } else +  p = NULL;       enter_compiler(NULL, 0);       c = THIS_COMPILATION;       /* We don't want to be affected by #pragma save_parent or    * __pragma_save_parent__.    */    old_pragmas = c->lex.pragmas;    c->lex.pragmas = (old_pragmas & ~ID_SAVE_PARENT)|ID_DONT_SAVE_PARENT;
pike.git/src/encode.c:3737:    c->lex.pragmas |= ID_NO_DEPRECATION_WARNINGS;       /* Start the new program. */    low_start_new_program(p, COMPILER_PASS_FIRST, NULL, 0, NULL);    p = Pike_compiler->new_program;    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, NULL); +  init_supporter(& c->supporter, +  (supporter_callback *) call_delayed_decode, NULL); +  c->supporter.exit_fun = exit_delayed_decode; +  c->supporter.prog = p; +  SET_ONERROR(err, cleanup_new_program_decode, c);    -  +  if (data->support_compilation && +  data->support_compilation->supporter.prog == p && +  data->support_compilation->placeholder != NULL) +  add_ref(c->placeholder = data->support_compilation->placeholder); +  else    {    int fun = find_identifier("__register_new_program",    decoder_codec (data)->prog);       if (fun >= 0) {    ref_push_program(p);    apply_low(data->codec, fun, 1);       /* Returned a placeholder */    if(TYPEOF(Pike_sp[-1]) == T_OBJECT)
pike.git/src/encode.c:4520:    });       /* Restore c->lex. */    CALL_AND_UNSET_ONERROR(err2);    c->lex.current_line = save_current_line;      #ifdef ENCODE_DEBUG    data->depth-=2;   #endif    +  int delay = unlink_current_supporter(& c->supporter);    UNSET_ONERROR(err);    -  +  if (delay) { +  data->support_delay_counter++; +  c->supporter.data = data; +  } +     /* De-kludge to get end_first_pass() to free the program. */    Pike_compiler->num_parse_error--;       p->flags |= PROGRAM_PASS_1_DONE;       /* Fixate & optimize    *    * lfuns and identifier_index    */    ref_push_program (p); -  if (!(p = end_first_pass(2))) { +  if (!(p = end_first_pass(delay? 0 : 2)) || +  !call_dependants(&c->supporter, !!p)) {    decode_error(data, Pike_sp - 1, "Failed to decode program.\n");    }    pop_stack();    push_program(p);    -  if (c->placeholder) { +  if (c->placeholder && !delay) {    push_object(placeholder = c->placeholder);    c->placeholder = NULL;    }       exit_compiler();       EDB(5, dump_program_tables(p, data->depth));   #ifdef PIKE_DEBUG    check_program (p);   #endif
pike.git/src/encode.c:4566:   #define FOO(NUMTYPE,TYPE,ARGTYPE,NAME) \    if (PIKE_CONCAT(local_num_, NAME) != p->PIKE_CONCAT(num_,NAME)) { \    ref_push_program (p); \    decode_error(data, Pike_sp - 1, \    "Value mismatch for num_" TOSTR(NAME) ": " \    "%zd != %zd (bytecode method: %d)\n", \    (size_t) PIKE_CONCAT(local_num_, NAME), \    (size_t) p->PIKE_CONCAT(num_, NAME), \    bytecode_method); \    } +  if (!delay) {   #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 ((TYPEOF(constant->sval) != T_INT) ||    (SUBTYPEOF(constant->sval) != NUMBER_UNDEFINED)) {    /* Already initialized. */
pike.git/src/encode.c:4701:    } else {    struct decode_data *d;    for (d = current_decode; d; d=d->next) {    if (d->next == data) {    d->next = d->next->next;    break;    }    }    }    -  if(delay) +  if(delay || data->support_delay_counter)    {    debug_malloc_touch(data);    /* We have been delayed */    return;    }      #ifdef PIKE_DEBUG    if (!free_after_error) {    if(data->unfinished_programs)    Pike_fatal("We have unfinished programs left in decode()!\n");
pike.git/src/encode.c:4754: Inside #if defined(PIKE_THREADS)
     #ifdef PIKE_THREADS    data->thread_state = NULL;    free_object (data->thread_obj);   #endif      #ifdef PIKE_DEBUG    if (!free_after_error) {    NEW_MAPPING_LOOP (data->decoded->data) {    if (TYPEOF(k->val) == T_PROGRAM && -  !(k->val.u.program->flags & PROGRAM_FINISHED)) { +  !(k->val.u.program->flags & PROGRAM_PASS_1_DONE)) {    ONERROR err;    /* Move some references to the stack so that they    * will be freed when decode_error() throws, but    * still be available to decode_error().    */    push_string(data->data_str);    push_mapping(data->decoded);    SET_ONERROR(err, free, data);       decode_error (data, NULL,
pike.git/src/encode.c:4797:   }      static void error_free_decode_data (struct decode_data *data)   {    int delay;    debug_malloc_touch (data);    delay = 0;    free_decode_data (data, delay, 1);   }    + #ifdef ENCODE_DEBUG + static void error_debug_free_decode_data (struct decode_data *data) + { +  write_and_reset_string_builder(2, data->debug_buf); +  free_string_builder(data->debug_buf); +  data->debug_buf = NULL; +  error_free_decode_data (data); + } + #endif +    static INT32 my_decode(struct pike_string *tmp,    struct object *codec   #ifdef ENCODE_DEBUG    , int debug, struct string_builder *debug_buf   #endif    )   {    struct decode_data *data;    ONERROR err;   #ifdef ENCODE_DEBUG
pike.git/src/encode.c:4844:    data->len=tmp->len;    data->ptr=0;    data->codec=codec;    data->explicit_codec = codec ? 1 : 0;    data->pickyness=0;    data->pass=1;    data->unfinished_programs=0;    data->unfinished_objects=0;    data->unfinished_placeholders = NULL;    data->delay_counter = 0; +  data->support_delay_counter = 0; +  data->support_compilation = NULL;    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->debug_buf = debug_buf;    data->debug_ptr = 0;
pike.git/src/encode.c:4890:    data->debug_ptr = data->ptr;    });       data->decoded=allocate_mapping(128);       add_ref (data->data_str);    if (data->codec) add_ref (data->codec);   #ifdef PIKE_THREADS    add_ref (data->thread_obj);   #endif + #ifdef ENCODE_DEBUG +  if (debug_buf == &buf) +  SET_ONERROR(err, error_debug_free_decode_data, data); +  else + #endif    SET_ONERROR(err, error_free_decode_data, data);       low_do_decode (data);       UNSET_ONERROR(err);       EDB(1, {    DECODE_FLUSH();    });      #ifdef ENCODE_DEBUG    if (debug_buf == &buf) {    write_and_reset_string_builder(2, debug_buf);    free_string_builder(debug_buf); -  +  data->debug_buf = NULL;    }   #endif       {    int delay;    delay = 0;    free_decode_data (data, delay, 0);    }       return 1;