Branch: Tag:

2012-04-29

2012-04-29 20:53:39 by Henrik Grubbström (Grubba) <grubba@grubba.org>

Compiler: First try at resolving inherited symbols via inherited lfun::`->().

193:    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), /* "``-", */
881:    *! @[predef::`[]=()], @[lfun::`->=()]    */    - /*! @decl mixed lfun::`->(string arg) + /*! @decl mixed lfun::`->(string arg, object|void context, int|void access)    *!    *! Arrow index callback.    *!
889:    *! 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()
918:    *! @[predef::sizeof()]    */    - /*! @decl array lfun::_indices() + /*! @decl array lfun::_indices(object|void context, int|void access)    *!    *! List indices callback.    *!
933:    *! @[::_indices()]    */    - /*! @decl array lfun::_values() + /*! @decl array lfun::_values(object|void context, int|void access)    *!    *! List values callback.    *!
1131:    *! @[predef::search()]    */    - /*! @decl array lfun::_types() + /*! @decl array lfun::_types(object|void context, int|void access)    *!    *! List types callback.    *!
1873:    * 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,
1923:    }       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;   }