pike.git / src / program.c

version» Context lines:

pike.git/src/program.c:3186:    i=ID_FROM_INT(Pike_compiler->new_program, id);    free_type(i->type);    i->type=get_type_of_svalue(&tmp);    }       /* Reset annotations so that they can be readded properly. */    for (e = 0; e < p->num_annotations; e++) {    do_free_array(p->annotations[e]);    p->annotations[e] = NULL;    } +  for (e = 0; e < p->num_inherits; e++) { +  struct inherit *inh = p->inherits + e; +  if (inh->inherit_level > 1) continue; +  if (!inh->annotations) continue; +  free_array(inh->annotations); +  inh->annotations = NULL;    } -  +  }    if (pass == COMPILER_PASS_FIRST) {    if(c->compilation_depth >= 1) {    add_ref(p->parent = Pike_compiler->new_program);    debug_malloc_touch (p);    }    }    p->flags &=~ PROGRAM_VIRGIN;    if(idp) *idp=id;       CDFPRINTF("th(%ld) %p low_start_new_program() %s "
pike.git/src/program.c:3389:       i.prog=Pike_compiler->new_program;    i.identifier_level=0;    i.storage_offset=0;    i.inherit_level=0;    i.identifier_ref_offset=0;    i.parent=0;    i.parent_identifier=-1;    i.parent_offset=OBJECT_PARENT;    i.name=0; +  i.annotations = NULL;    add_to_inherits(i);    }       Pike_compiler->init_node=0;    Pike_compiler->num_parse_error=0;       push_compiler_frame(0);    copy_pike_type(Pike_compiler->compiler_frame->current_return_type,    void_type_string);   
pike.git/src/program.c:3510: Inside #if 0
   free_svalue(& p->constants[e].sval);   #if 0    if(p->constants[e].name) free_string(p->constants[e].name);   #endif /* 0 */    }    }       if(p->inherits)    for(e=0; e<p->num_inherits; e++)    { +  if (p->inherits[e].annotations) +  free_array(p->inherits[e].annotations);    if(p->inherits[e].name)    free_string(p->inherits[e].name);    if(e)    {    if(p->inherits[e].prog)    free_program(p->inherits[e].prog);    }    if(p->inherits[e].parent)    free_object(p->inherits[e].parent);    }
pike.git/src/program.c:4225:    dispatch_fun.c_fun = f_dispatch_variant;    return define_function(name, type, id_flags & ~(ID_VARIANT|ID_LOCAL),    IDENTIFIER_C_FUNCTION, &dispatch_fun, 0);   }      /**    * Add a single annotation for a symbol in the current program    * being compiled.    *    * @param id -  * Identifier to annotate, -1 for the current program. +  * Identifier to annotate.    *    * @param val    * Annotation value. Should be an object implementing    * the Pike.Annotation interface.    */   static void add_annotation(int id, struct svalue *val)   { -  id += 1; +     while (Pike_compiler->new_program->num_annotations <= id) {    add_to_annotations(NULL);    }       if (val) {    if (Pike_compiler->new_program->annotations[id]) {    Pike_compiler->new_program->annotations[id] =    append_array(Pike_compiler->new_program->annotations[id], val);    } else {    push_svalue(val);
pike.git/src/program.c:4260:   {    while(annotations) {    node *val_node = CAR(annotations);    annotations = CDR(annotations);    if (val_node->token != F_CONSTANT) continue;    add_annotation(id, &val_node->u.sval);    }   }      /** +  * Add a single annotation for an inherit in the current program +  * being compiled. +  * +  * @param inh +  * Inherit to annotate. +  * +  * @param val +  * Annotation value. Should be an object implementing +  * the Pike.Annotation interface. +  * +  * NOTE: This operation is ONLY valid for inherits at +  * levels 0 and 1! +  * +  */ + static void add_program_annotation(int inh, struct svalue *val) + { +  struct inherit *inherit = Pike_compiler->new_program->inherits + inh; +  if (inherit->inherit_level > 1) { +  Pike_fatal("Attempt to annotate inherit #%d at level %d!\n", +  inh, inherit->inherit_level); +  } +  if (val) { +  if (inherit->annotations) { +  inherit->annotations = append_array(inherit->annotations, val); +  } else { +  push_svalue(val); +  inherit->annotations = aggregate_array(1); +  } +  } + } +  + void compiler_add_program_annotations(int inh, node *annotations) + { +  while(annotations) { +  node *val_node = CAR(annotations); +  annotations = CDR(annotations); +  if (val_node->token != F_CONSTANT) continue; +  add_program_annotation(inh, &val_node->u.sval); +  } + } +  + /**    * End the current compilation pass.    *    * @param finish    * finish-state:    *    * 0: First pass.    * 1: Last pass.    * 2: Called from decode_value().    *    * Note: This function is misnamed, since it's run after all passes.
pike.git/src/program.c:5106:   #endif    CDFPRINTF("th(%ld) %p inherit %p\n",    (long) th_self(), Pike_compiler->new_program, p);       if(!p)    {    yyerror("Illegal program pointer.");    return;    }    -  if (Pike_compiler->compiler_pass == COMPILER_PASS_EXTRA) { +  if (Pike_compiler->compiler_pass != COMPILER_PASS_FIRST) { +  /* NB: Pike_compiler->num_inherits is off by 1! +  * This is probably due to not counting the initial inherit. +  */    struct program *old_p =    Pike_compiler->new_program->    inherits[Pike_compiler->num_inherits+1].prog; -  +  inherit_offset = Pike_compiler->num_inherits + 1;    Pike_compiler->num_inherits += old_p->num_inherits;       if (old_p != p) {    yyerror("Got different program for inherit in second pass "    "(resolver problem).");    } -  +  +  /* Restore annotations (if any) to and from the inherited program. */ +  do { +  struct inherit *src_inh = p->inherits; +  struct inherit *dst_inh = +  Pike_compiler->new_program->inherits + inherit_offset; +  if (!src_inh->annotations) continue; +  +  dst_inh->annotations = copy_array(src_inh->annotations); +  } while(0); +  +  if (Pike_compiler->compiler_pass == COMPILER_PASS_EXTRA) {    return;    } -  if (Pike_compiler->compiler_pass == COMPILER_PASS_LAST) { -  struct program *old_p = -  Pike_compiler->new_program-> -  inherits[Pike_compiler->num_inherits+1].prog; -  Pike_compiler->num_inherits += old_p->num_inherits; +     -  if (old_p != p) { -  yyerror("Got different program for inherit in second pass " -  "(resolver problem)."); -  } +  assert(Pike_compiler->compiler_pass == COMPILER_PASS_LAST);       if (!(p->flags & PROGRAM_FINISHED)) {    /* Require that the inherited program really is finished in pass    * 2. Otherwise we might not have all definitions when we    * fixate our program.    *    * FIXME: Maybe this can be relaxed by registering a dependency    * and delaying compilation here?    */    yyerror ("Cannot inherit program in pass 2 "
pike.git/src/program.c:5247:   #endif    }else{    inherit.parent=parent;    inherit.parent_identifier=parent_identifier;    inherit.parent_offset=INHERIT_PARENT;    }    }else{    inherit.parent_offset=parent_offset;    inherit.parent_identifier=parent_identifier;    } +  +  if (inherit.annotations) { +  inherit.annotations = copy_array(inherit.annotations); +  }    }else{    if(!inherit.parent)    {    if(parent && parent->next != parent && inherit.parent_offset)    {    struct object *par=parent;    int e,pid=parent_identifier;       for(e=1;e<inherit.parent_offset;e++)    {
pike.git/src/program.c:5305:    pid = -1;    par = NULL;    }    }    }       inherit.parent=par;    inherit.parent_offset=INHERIT_PARENT;    }    } +  if (inherit.annotations) { +  add_ref(inherit.annotations);    } -  +  }    if(inherit.parent) add_ref(inherit.parent);       if(name)    {    if(e==0)    {    copy_shared_string(inherit.name,name);    }    else if(inherit.name)    {
pike.git/src/program.c:5489:    low_inherit(p, parent_obj, parent_id, 0, flags, name);   }      void compiler_do_inherit(node *n,    INT32 flags,    struct pike_string *name)   {    struct program *p;    struct identifier *i;    INT32 numid=-1, offset=0; +  int inherit_offset = Pike_compiler->new_program->num_inherits;       if(!n)    {    yyerror("Unable to inherit");    return;    }    -  +  if (Pike_compiler->compiler_pass != COMPILER_PASS_FIRST) { +  /* Note off by one! */ +  inherit_offset = Pike_compiler->num_inherits + 1; +  } +     if ((n->token == F_APPLY) && (CAR(n)->token == F_CONSTANT) &&    (TYPEOF(CAR(n)->u.sval) == T_FUNCTION) &&    (SUBTYPEOF(CAR(n)->u.sval) == FUNCTION_BUILTIN) &&    (CAR(n)->u.sval.u.efun->function == debug_f_aggregate)) {    /* Disambiguate multiple inherit ::-reference. */    node *arg;    while(1) {    while ((arg = CDR(n))) {    n = arg;    if (n->token != F_ARG_LIST) goto found;
pike.git/src/program.c:5597:    yyerror("Inherit identifier is not a constant program");    return;    }    break;       default:    resolv_class(n);    do_inherit(Pike_sp-1, flags, name);    pop_stack();    } +  +  if (Pike_compiler->current_annotations) { +  compiler_add_program_annotations(inherit_offset, +  Pike_compiler->current_annotations); +  free_node(Pike_compiler->current_annotations); +  Pike_compiler->current_annotations = NULL;    } -  + }      int call_handle_inherit(struct pike_string *s)   {    struct compilation *c = THIS_COMPILATION;       CHECK_COMPILER();       ref_push_string(s);    f_string_to_utf8(1);   
pike.git/src/program.c:8700:    for(e = p->num_constants - 1; e >= 0; e--)    gc_mark_svalues(& p->constants[e].sval, 1);       for(e = p->num_inherits - 1; e >= 0; e--)    {    if(p->inherits[e].parent)    gc_mark_object_as_referenced(p->inherits[e].parent);       if(e && p->inherits[e].prog)    gc_mark_program_as_referenced(p->inherits[e].prog); +  +  if (p->inherits[e].annotations) +  gc_mark_array_as_referenced(p->inherits[e].annotations);    }      #if defined (PIKE_DEBUG) || defined (DO_PIKE_CLEANUP)    for (e = p->num_identifiers - 1; e >= 0; e--)    gc_mark_type_as_referenced (p->identifiers[e].type);   #endif       for (e = p->num_annotations-1; e >= 0; e--) {    if (p->annotations[e])    gc_mark_array_as_referenced(p->annotations[e]);
pike.git/src/program.c:8731:    for(e = p->num_constants - 1; e >= 0; e--)    gc_cycle_check_svalues(& p->constants[e].sval, 1);       for(e = p->num_inherits - 1; e >= 0; e--)    {    if(p->inherits[e].parent)    gc_cycle_check_object(p->inherits[e].parent, 0);       if(e && p->inherits[e].prog)    gc_cycle_check_program(p->inherits[e].prog, 0); +  +  if (p->inherits[e].annotations) +  gc_cycle_check_array(p->inherits[e].annotations, 0);    }       for (e = p->num_annotations - 1; e >= 0; e--) {    if (p->annotations[e])    gc_cycle_check_array(p->annotations[e], 0);    }       /* Strong ref follows. It must be last. */    if(p->parent)    gc_cycle_check_program(p->parent, 0);
pike.git/src/program.c:8782:    " as inherited parent object of a program");    }      #ifdef PIKE_DEBUG    if (Pike_in_gc == GC_PASS_LOCATE && p->inherits[e].name)    debug_gc_check (p->inherits[e].name, " as inherit name");   #endif       if(e && p->inherits[e].prog)    debug_gc_check (p->inherits[e].prog, " as inherited program of a program"); +  +  if (p->inherits[e].annotations) +  debug_gc_check(p->inherits[e].annotations, +  " as annotations for an inherit");    }      #if defined (PIKE_DEBUG) || defined (DO_PIKE_CLEANUP)    if (gc_keep_markers || Pike_in_gc == GC_PASS_LOCATE)    {    for(e = p->num_strings - 1; e >= 0; e--)    debug_gc_check (p->strings[e], " in the string storage of a program");    for(e = p->num_identifiers - 1; e >= 0; e--)    debug_gc_check (p->identifiers[e].name,    " as identifier name in a program");
pike.git/src/program.c:8898:    if(p->inherits[e].parent)    {    free_object(p->inherits[e].parent);    p->inherits[e].parent=0;    }    if(e && p->inherits[e].prog)    {    free_program(p->inherits[e].prog);    p->inherits[e].prog=0;    } +  +  if (p->inherits[e].annotations) { +  free_array(p->inherits[e].annotations); +  p->inherits[e].annotations = NULL;    } -  +  }       for (e = 0; e < p->num_annotations; e++) {    do_free_array(p->annotations[e]);    p->annotations[e] = NULL;    }       gc_free_extra_ref(p);    SET_NEXT_AND_FREE(p, free_program);   #ifdef PIKE_DEBUG    if (first) gc_internal_program = next;