pike.git/src/program.c:86:
*
* Further measurements seems to indicate that this cache can slow
* things down a bit if the hit/miss rate is not fairly high.
* For normal applications, the hitrate is most likely well over 90%,
* but that should be verified.
* - Holistiska Centralbyrån (Hubbe)
*/
/* Define the size of the cache that is used for method lookup. */
/* A value of zero disables this cache */
- #define FIND_FUNCTION_HASHSIZE 15013
+ #define FIND_FUNCTION_HASHSIZE 16384
/* Programs with less methods will not use the cache for method lookups.. */
#define FIND_FUNCTION_HASH_TRESHOLD 9
#define DECLARE
#include "compilation.h"
struct pike_string *this_program_string;
static struct pike_string *this_string, *this_function_string;
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;
pike.git/src/program.c:5587:
PMOD_EXPORT int add_integer_constant(const char *name,
INT_ARG_TYPE i,
INT32 flags)
{
struct svalue tmp;
SET_SVAL(tmp, T_INT, NUMBER_NUMBER, integer, i);
return simple_add_constant(name, &tmp, flags);
}
+ PMOD_EXPORT int low_add_integer_constant(struct pike_string *name,
+ INT_ARG_TYPE i,
+ INT32 flags)
+ {
+ struct svalue tmp;
+ SET_SVAL(tmp, T_INT, NUMBER_NUMBER, integer, i);
+ return add_constant(name, &tmp, flags);
+ }
+
PMOD_EXPORT int quick_add_integer_constant(const char *name,
int name_length,
INT_ARG_TYPE i,
INT32 flags)
{
- struct svalue tmp;
- struct pike_string *id;
+
INT32 ret;
-
- SET_SVAL(tmp, T_INT, NUMBER_NUMBER, integer, i);
- id=make_shared_binary_string(name,name_length);
- ret=add_constant(id, &tmp, flags);
- free_string(id);
+ struct pike_string *n = make_shared_binary_string(name, name_length);
+ ret=low_add_integer_constant(n, i, flags);
+ free_string(n);
return ret;
}
PMOD_EXPORT int add_float_constant(const char *name,
FLOAT_ARG_TYPE f,
INT32 flags)
{
struct svalue tmp;
SET_SVAL(tmp, T_FLOAT, 0, float_number, (FLOAT_TYPE)f);
return simple_add_constant(name, &tmp, flags);
pike.git/src/program.c:6377: Inside #if defined(FIND_FUNCTION_HASHSIZE)
#ifdef FIND_FUNCTION_HASHSIZE
if(prog -> flags & PROGRAM_FIXED
#if FIND_FUNCTION_HASH_TRESHOLD - 0
&& prog->num_identifier_index >= FIND_FUNCTION_HASH_TRESHOLD
#endif
)
{
size_t hashval;
hashval = my_hash_string(name);
hashval += prog->id;
- hashval %= FIND_FUNCTION_HASHSIZE;
+ hashval &= (FIND_FUNCTION_HASHSIZE-1);
if(is_same_string(cache[hashval].name,name) &&
cache[hashval].id==prog->id)
return cache[hashval].fun;
if(cache[hashval].name) free_string(cache[hashval].name);
copy_shared_string(cache[hashval].name,name);
cache[hashval].id=prog->id;
return cache[hashval].fun=low_find_shared_string_identifier(name,prog);
}
#endif /* FIND_FUNCTION_HASHSIZE */