pike.git / src / program.c

version» Context lines:

pike.git/src/program.c:186:    tFuncV(tNone,tZero,tMix), /* "`%", */    tFuncV(tNone,tVoid,tMix), /* "`~", */    tFuncV(tMix,tVoid,tInt), /* "`==", */    tFuncV(tMix,tVoid,tInt), /* "`<", */    tFuncV(tMix,tVoid,tInt), /* "`>", */    tFuncV(tNone,tVoid,tInt), /* "__hash", */    tFuncV(tString,tVoid,tMix), /* "cast", */    tFuncV(tNone,tVoid,tInt), /* "`!", */    tFuncV(tZero,tVoid,tMix), /* "`[]", */    tFuncV(tZero tSetvar(0,tZero),tVoid,tVar(0)), /* "`[]=", */ -  tFuncV(tStr,tVoid,tMix), /* "`->", */ -  tFuncV(tStr tSetvar(0,tZero),tVoid,tVar(0)), /* "`->=", */ -  tFuncV(tNone,tVoid,tInt), /* "_sizeof", */ -  tFuncV(tNone,tVoid,tArray), /* "_indices", */ -  tFuncV(tNone,tVoid,tArray), /* "_values", */ +  tFuncV(tStr tOr(tVoid,tObj) tOr(tVoid,tInt),tVoid,tMix), /* "`->", */ +  tFuncV(tStr tSetvar(0,tZero) tOr(tVoid,tObj) tOr(tVoid,tInt),tVoid,tVar(0)), /* "`->=", */ +  tFuncV(tOr(tVoid,tObj) tOr(tVoid,tInt),tVoid,tInt), /* "_sizeof", */ +  tFuncV(tOr(tVoid,tObj) tOr(tVoid,tInt),tVoid,tArray), /* "_indices", */ +  tFuncV(tOr(tVoid,tObj) tOr(tVoid,tInt),tVoid,tArray), /* "_values", */    tFuncV(tNone,tZero,tMix), /* "`()", */    tFuncV(tZero,tZero,tMix), /* "``+", */    tFuncV(tZero,tVoid,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), /* "``/", */
pike.git/src/program.c:874:    */      /*! @decl mixed lfun::`[]=(zero arg1, zero arg2)    *!    *! Index assignment callback.    *!    *! @seealso    *! @[predef::`[]=()], @[lfun::`->=()]    */    - /*! @decl mixed lfun::`->(string arg) + /*! @decl mixed lfun::`->(string arg, object|void context, int|void access)    *!    *! Arrow index callback.    *!    *! @note    *! It's assumed that this function is side-effect free.    *!    *! @seealso -  *! @[predef::`->()] +  *! @[predef::`->()], @[::`->()]    */    - /*! @decl mixed lfun::`->=(string arg1, zero arg2) + /*! @decl mixed lfun::`->=(string arg, zero value, @ +  *! object|void context, int|void access)    *!    *! Arrow index assignment callback.    *!    *! @seealso -  *! @[predef::`->=()], @[lfun::`[]=()] +  *! @[predef::`->=()], @[::`->=()], @[lfun::`[]=()]    */      /*! @decl int lfun::_sizeof()    *!    *! Size query callback.    *!    *! Called by @[predef::sizeof()] to determine the number of elements    *! in an object. If this function is not present, the number    *! of public symbols in the object will be returned.    *!    *! @returns    *! Expected to return the number of valid indices in the object.    *!    *! @note    *! It's assumed that this function is side-effect free.    *!    *! @seealso    *! @[predef::sizeof()]    */    - /*! @decl array lfun::_indices() + /*! @decl array lfun::_indices(object|void context, int|void access)    *!    *! List indices callback.    *!    *! @returns    *! Expected to return an array with the valid indices in the object.    *!    *! @note    *! It's assumed that this function is side-effect free.    *!    *! @seealso    *! @[predef::indices()], @[lfun::_values()], @[lfun::_types()],    *! @[::_indices()]    */    - /*! @decl array lfun::_values() + /*! @decl array lfun::_values(object|void context, int|void access)    *!    *! List values callback.    *!    *! @returns    *! Expected to return an array with the values corresponding to    *! the indices returned by @[lfun::_indices()].    *!    *! @note    *! It's assumed that this function is side-effect free.    *!
pike.git/src/program.c:1124:    */      /*! @decl mixed lfun::_search(mixed needle, mixed|void start)    *!    *! Search callback.    *!    *! @seealso    *! @[predef::search()]    */    - /*! @decl array lfun::_types() + /*! @decl array lfun::_types(object|void context, int|void access)    *!    *! List types callback.    *!    *! This callback is typically called via @[predef::types()].    *!    *! @returns    *! Expected to return an array with the types corresponding to    *! the indices returned by @[lfun::_indices()].    *!    *! @note
pike.git/src/program.c:1866:    */      /* If the identifier is recognized as one of the magic identifiers,    * like "this", "this_program" or "`->" when preceded by ::, then a    * suitable node is returned, NULL otherwise.    *    * inherit_num is -1 when no specific inherit has been specified; ie    * either when the identifier has no prefix (colon_colon_ref == 0) or    * when the identifier has the prefix :: without any preceding identifier    * (colon_colon_ref == 1). +  * +  * New in Pike 7.9.5 and later: +  * +  * If colon_colon_ref is 1 and the selected inherit defines the +  * `->() lfun, code calling the lfun will be generated as follows: +  * +  * inh::`->(ident, inh::this, 1)    */   struct node_s *program_magic_identifier (struct program_state *state,    int state_depth, int inherit_num,    struct pike_string *ident,    int colon_colon_ref)   {   #if 0    fprintf (stderr, "magic_identifier (state, %d, %d, %s, %d)\n",    state_depth, inherit_num, ident->str, colon_colon_ref);   #endif
pike.git/src/program.c:1916:    } else {    return mkidentifiernode(i);    }    } else {    /* FIXME: Fall back to __INIT? */    }    }    }       if (colon_colon_ref) { +  int i = inherit_num; +     /* These are only recognized when prefixed with the :: operator. */    -  if (inherit_num < 0) inherit_num = 0; +  if (inherit_num < 0) i = 0;    if(ident == lfun_strings[LFUN_ARROW] ||    ident == lfun_strings[LFUN_INDEX]) { -  return mknode(F_MAGIC_INDEX, mknewintnode(inherit_num), +  return mknode(F_MAGIC_INDEX, mknewintnode(i),    mknewintnode(state_depth));    } else if(ident == lfun_strings[LFUN_ASSIGN_ARROW] ||    ident == lfun_strings[LFUN_ASSIGN_INDEX]) { -  return mknode(F_MAGIC_SET_INDEX, mknewintnode(inherit_num), +  return mknode(F_MAGIC_SET_INDEX, mknewintnode(i),    mknewintnode(state_depth));    } else if(ident == lfun_strings[LFUN__INDICES]) { -  return mknode(F_MAGIC_INDICES, mknewintnode(inherit_num), +  return mknode(F_MAGIC_INDICES, mknewintnode(i),    mknewintnode(state_depth));    } else if(ident == lfun_strings[LFUN__VALUES]) { -  return mknode(F_MAGIC_VALUES, mknewintnode(inherit_num), +  return mknode(F_MAGIC_VALUES, mknewintnode(i),    mknewintnode(state_depth));    } else if(ident == lfun_strings[LFUN__TYPES]) { -  return mknode(F_MAGIC_TYPES, mknewintnode(inherit_num), +  return mknode(F_MAGIC_TYPES, mknewintnode(i),    mknewintnode(state_depth));    } -  +  +  if (inherit_num && !TEST_COMPAT(7, 8) && +  (state->new_program->num_inherits > 1)) { +  /* Check if there's an inherited lfun::`->() that we can call. */ +  int id; +  struct program *prog = state->new_program->inherits[i].prog; +  if (((id = FIND_LFUN(prog, LFUN_ARROW)) == -1) && +  (prog == state->new_program)) { +  /* We are allowed to see private symbols in ourselves... */ +  id = really_low_find_shared_string_identifier(lfun_strings[LFUN_ARROW], +  prog, +  SEE_PROTECTED|SEE_PRIVATE); +  } else if ((id != -1) && (prog != state->new_program)) { +  id = really_low_reference_inherited_identifier(state, i, id);    } -  +  if ((id != -1) && (state->compiler_pass == 2)) { +  if (inherit_num < 0) { +  /* Find the closest inherit containing the lfun::`->() +  * that is about to be called. +  * +  * In the single inherit case, this will always +  * result in inherit_num == 1. +  */ +  struct inherit *inherits = state->new_program->inherits; +  inherit_num = PTR_FROM_INT(state->new_program, id)->inherit_offset; +  while (inherits[inherit_num].inherit_level > 1) { +  inherit_num--; +  } +  } +  return mknode(F_APPLY, mkexternalnode(state->new_program, id), +  mknode(F_ARG_LIST, +  mkstrnode(ident), +  mknode(F_ARG_LIST, +  mkthisnode(state->new_program, inherit_num), +  mkintnode(1)))); +  } +  } +  }       return NULL;   }      /* Fixme: allow level=0 to return the current level */   struct program *parent_compilation(int level)   {    struct compilation *c = THIS_COMPILATION;    int n;    struct program_state *p=Pike_compiler->previous;