pike.git / src / program.c

version» Context lines:

pike.git/src/program.c:115:   #include "compilation.h"      struct pike_string *this_program_string, *this_string, *args_string;   static struct pike_string *this_function_string;   static struct pike_string *UNDEFINED_string;      /* Common compiler subsystems */   struct pike_string *parser_system_string;   struct pike_string *type_check_system_string;    + struct pike_string *compat_lfun_destroy_string; +    /* NOTE: There is a corresponding list to this one in    Tools.AutoDoc.PikeObjects       If new lfuns are added it might be beneficial to also add them to    that list.   */   const char *const lfun_names[] = {    "__INIT",    "create", -  "destroy", +  "_destruct",    "`+",    "`-",    "`&",    "`|",    "`^",    "`<<",    "`>>",    "`*",    "`/",    "`%",
pike.git/src/program.c:189:   struct pike_string *lfun_strings[NELEM(lfun_names)];      static struct mapping *lfun_ids;      /* mapping(string:type) */   static struct mapping *lfun_types;      static const char *const raw_lfun_types[] = {    tFuncV(tNone,tVoid,tVoid), /* "__INIT", */    tFuncV(tNone,tZero,tVoid), /* "create", */ -  tFuncV(tOr(tVoid,tInt),tVoid,tVoid), /* "destroy", */ +  tFuncV(tOr(tVoid,tInt),tVoid,tVoid), /* "_destruct", */    tFuncV(tZero,tZero,tMix), /* "`+", */    tFunc(tOr(tVoid,tZero),tMix), /* "`-", */    tFuncV(tNone,tZero,tMix), /* "`&", */    tFuncV(tNone,tZero,tMix), /* "`|", */    tFuncV(tNone,tZero,tMix), /* "`^", */    tFuncV(tZero,tVoid,tMix), /* "`<<", */    tFuncV(tZero,tVoid,tMix), /* "`>>", */    tFuncV(tNone,tZero,tMix), /* "`*", */    tFuncV(tNone,tZero,tMix), /* "`/", */    tFuncV(tNone,tZero,tMix), /* "`%", */
pike.git/src/program.c:258:   /*! @namespace lfun::    *!    *! Callback functions used to overload various builtin functions.    *!    *! The functions can be grouped into a few sets:    *!    *! @ul    *! @item    *! Object initialization and destruction.    *! -  *! @[__INIT()], @[create()], @[destroy()] +  *! @[__INIT()], @[create()], @[_destruct()]    *!    *! @item    *! Unary operator overloading.    *!    *! @[`~()], @[`!()],    *! @[_values()], @[cast()],    *! @[_sizeof()], @[_indices()],    *! @[__hash()]    *!    *! @item
pike.git/src/program.c:364:    *! int foo;    *! int bar;    *! protected void create(int foo)    *! {    *! this::foo = foo;    *! }    *! }    *! @endcode    *!    *! @seealso -  *! @[lfun::__INIT()], @[lfun::destroy()] +  *! @[lfun::__INIT()], @[lfun::_destruct()]    */    - /*! @decl void lfun::destroy (void|int reason) + /*! @decl void lfun::_destruct (void|int reason)    *!    *! Object destruction callback.    *!    *! This function is called right before the object is destructed.    *! That can happen either through a call to @[predef::destruct()],    *! when there are no more references to the object, or when the    *! garbage collector discovers that it's part of a cyclic data    *! structure that has become garbage.    *!    *! @param reason
pike.git/src/program.c:396:    *! Destructed by the garbage collector.    *! @value Object.DESTRUCT_CLEANUP    *! Destructed as part of the cleanup when the pike process    *! exits. Occurs only if Pike has been compiled with the    *! configure option @tt{--with-cleanup-on-exit@}. See note    *! below.    *! @endint    *!    *! @note    *! Objects are normally not destructed when a process exits, so -  *! @expr{destroy@} functions aren't called then. Use @[atexit] to get +  *! @expr{_destruct@} functions aren't called then. Use @[atexit] to get    *! called when the process exits.    *!    *! @note    *! Regarding destruction order during garbage collection:    *!    *! If an object is destructed by the garbage collector, it's part of    *! a reference cycle with other things but with no external -  *! references. If there are other objects with @expr{destroy@} +  *! references. If there are other objects with @expr{_destruct@}    *! functions in the same cycle, it becomes a problem which to call    *! first.    *!    *! E.g. if this object has a variable with another object which    *! (directly or indirectly) points back to this one, you might find    *! that the other object already has been destructed and the variable    *! thus contains zero.    *!    *! The garbage collector tries to minimize such problems by defining    *! an order as far as possible:    *!    *! @ul    *! @item -  *! If an object A contains an @[lfun::destroy] and an object B does +  *! If an object A contains an @[lfun::_destruct] and an object B does    *! not, then A is destructed before B.    *! @item    *! If A references B single way, then A is destructed before B.    *! @item    *! If A and B are in a cycle, and there is a reference somewhere    *! from B to A that is weaker than any reference from A to B, then    *! A is destructed before B.    *! @item    *! If a cycle is resolved according to the rule above by ignoring a    *! weaker reference, and there is another ambiguous cycle that
pike.git/src/program.c:449:    *! destructs a parent object before all children have been    *! destructed.)    *! @endul    *!    *! An example with well defined destruct order due to strong    *! references:    *!    *! @code    *! class Super {    *! class Sub { -  *! protected void destroy() { +  *! protected void _destruct() {    *! if (!Super::this)    *! error ("My parent has been destructed!\n");    *! }    *! }    *! Sub sub = Sub(); -  *! protected void destroy() { +  *! protected void _destruct() {    *! if (!sub)    *! werror ("sub already destructed.\n");    *! }    *! }    *! @endcode    *!    *! The garbage collector ensures that these objects are destructed in    *! an order so that @expr{werror@} in @expr{Super@} is called and not    *! @expr{error@} in @expr{Sub@}.    *!    *! @note -  *! When the garbage collector calls @[lfun::destroy], all accessible -  *! non-objects and objects without @expr{destroy@} functions are -  *! still intact. They are not freed if the @expr{destroy@} function +  *! When the garbage collector calls @[lfun::_destruct], all accessible +  *! non-objects and objects without @expr{_destruct@} functions are +  *! still intact. They are not freed if the @expr{_destruct@} function    *! adds external references to them. However, all objects with -  *! @[lfun::destroy] in the cycle are already scheduled for +  *! @[lfun::_destruct] in the cycle are already scheduled for    *! destruction and will therefore be destroyed even if external    *! references are added to them.    *!    *! @seealso    *! @[lfun::create()], @[predef::destruct()]    */      /*! @decl mixed lfun::`+(zero arg, zero ... rest)    *!    *! Left side addition/concatenation callback.
pike.git/src/program.c:2990:    if (ref->id_flags & ID_HIDDEN) continue;    if (ref->id_flags & ID_VARIANT) continue;    if (ref->inherit_offset != 0) continue;       if ((ref->id_flags & (ID_HIDDEN|ID_PRIVATE|ID_USED)) == ID_PRIVATE) {    yywarning("%S is private but not used anywhere.",    ID_FROM_PTR(p, ref)->name);    }    }    -  /* Set the PROGRAM_LIVE_OBJ flag by looking for destroy() and +  /* Set the PROGRAM_LIVE_OBJ flag by looking for _destruct() and    * inherited PROGRAM_LIVE_OBJ flags. This is done at fixation time    * to allow the user to set and clear that flag while the program is    * being built. */    if (!(p->flags & PROGRAM_LIVE_OBJ)) { -  int e, destroy = p->lfuns[LFUN_DESTROY]; -  if (destroy > -1) { -  struct identifier *id = ID_FROM_INT (p, destroy); +  int e, destruct = p->lfuns[LFUN__DESTRUCT]; +  if (destruct > -1) { +  struct identifier *id = ID_FROM_INT (p, destruct);    if (!IDENTIFIER_IS_PIKE_FUNCTION (id->identifier_flags) ||    id->func.offset != -1) { -  /* Got a destroy function that isn't a prototype. */ +  /* Got a _destruct function that isn't a prototype. */    p->flags |= PROGRAM_LIVE_OBJ;    goto program_live_obj_set;    }    }       for (e = p->num_inherits - 1; e >= 0; e--)    if (p->inherits[e].prog->flags & PROGRAM_LIVE_OBJ) {    p->flags |= PROGRAM_LIVE_OBJ;    break;    }
pike.git/src/program.c:7202: Inside #if defined(PIKE_DEBUG)
   if ((size_t)lfun >= NELEM(lfun_strings)) {    return find_lfun_fatal(p, lfun);    }   #endif    lfun_name = lfun_strings[lfun];       i = really_low_find_shared_string_identifier(lfun_name,    dmalloc_touch(struct program *,    p),    SEE_PROTECTED); -  if (i < 0 || !(p->flags & PROGRAM_FIXED)) return i; +  +  if ((i < 0) && (lfun == LFUN__DESTRUCT)) { +  /* Try the Pike 8.0 compatibility name. */ +  i = really_low_find_shared_string_identifier(compat_lfun_destroy_string, +  dmalloc_touch(struct program *, +  p), +  SEE_PROTECTED); +  if ((i >= 0) && !(p->flags & PROGRAM_FINISHED) && !TEST_COMPAT(8,0)) { +  yywarning("Compat: Substituting destroy() for _destruct()."); +  } +  } +  +  if (i < 0 || !(p->flags & PROGRAM_FIXED)) { +  return i; +  }    id = ID_FROM_INT(p, i);    if (IDENTIFIER_IS_PIKE_FUNCTION(id->identifier_flags) &&    (id->func.offset == -1)) {    /* Function prototype. */    return -1;    }    return i;   }   #ifdef PIKE_DEBUG   PMOD_EXPORT int find_lfun_fatal(struct program *UNUSED(p), enum LFUN lfun)
pike.git/src/program.c:8359:       MAKE_CONST_STRING(this_function_string,"this_function");    MAKE_CONST_STRING(this_program_string,"this_program");    MAKE_CONST_STRING(this_string,"this");    MAKE_CONST_STRING(UNDEFINED_string,"UNDEFINED");    MAKE_CONST_STRING(args_string, "__args__");       MAKE_CONST_STRING(parser_system_string, "parser");    MAKE_CONST_STRING(type_check_system_string, "type_check");    +  MAKE_CONST_STRING(compat_lfun_destroy_string, "destroy"); +     lfun_ids = allocate_mapping(NUM_LFUNS);    lfun_types = allocate_mapping(NUM_LFUNS);    for (i=0; i < NELEM(lfun_names); i++) {    lfun_strings[i] = make_shared_static_string(lfun_names[i], strlen(lfun_names[i]), eightbit);       SET_SVAL(id, T_INT, NUMBER_NUMBER, integer, i);    SET_SVAL(key, T_STRING, 0, string, lfun_strings[i]);    mapping_insert(lfun_ids, &key, &id);       SET_SVAL(val, T_TYPE, 0, type, make_pike_type(raw_lfun_types[i]));