pike.git/
src/
program.c
Branch:
Tag:
Non-build tags
All tags
No tags
2012-04-29
2012-04-29 20:53:39 by Henrik Grubbström (Grubba) <grubba@grubba.org>
4bd520d531def3d06cde67b99b9e7dc0ae5deac8 (
84
lines) (+
66
/-
18
)
[
Show
|
Annotate
]
Branch:
7.9
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; }