pike.git/src/docode.c:451:
/* Emit code for a function call to the identifier reference #id,
* with the arguments specified by args.
*/
static int do_lfun_call(int id, node *args)
{
struct compilation *c = THIS_COMPILATION;
struct reference *ref =
Pike_compiler->new_program->identifier_references + id;
- emit0(F_MARK);
+ if((Pike_compiler->compiler_frame->current_function_number >= 0) &&
+ ((id == Pike_compiler->compiler_frame->current_function_number) ||
+ ((!ref->inherit_offset) &&
+ (ref->identifier_offset ==
+ Pike_compiler->new_program->
+ identifier_references[Pike_compiler->compiler_frame->
+ current_function_number].identifier_offset))) &&
+ !(Pike_compiler->new_program->
+ identifiers[ref->identifier_offset].identifier_flags &
+ (IDENTIFIER_VARARGS|IDENTIFIER_SCOPE_USED)) &&
+ !(Pike_compiler->compiler_frame->lexical_scope & SCOPE_SCOPE_USED))
+ {
PUSH_CLEANUP_FRAME(do_pop_mark, 0);
-
+ emit0(F_MARK);
do_docode(args,0);
/* Test description:
*
* * Test if we have a valid current function.
*
* * Quick check if id is the current function.
*
* * Check if id is an alternate reference to the current function.
*
* * Check that the function isn't varargs or contains scoped functions.
*
* * Check that the current function doesn't contain scoped functions.
*/
- if((Pike_compiler->compiler_frame->current_function_number >= 0) &&
- ((id == Pike_compiler->compiler_frame->current_function_number) ||
- ((!ref->inherit_offset) &&
- (ref->identifier_offset ==
- Pike_compiler->new_program->
- identifier_references[Pike_compiler->compiler_frame->
- current_function_number].identifier_offset))) &&
- !(Pike_compiler->new_program->
- identifiers[ref->identifier_offset].identifier_flags &
- (IDENTIFIER_VARARGS|IDENTIFIER_SCOPE_USED)) &&
- !(Pike_compiler->compiler_frame->lexical_scope & SCOPE_SCOPE_USED))
+ if(Pike_compiler->compiler_frame->is_inline || (ref->id_flags & (ID_INLINE|ID_PRIVATE)))
{
- if(Pike_compiler->compiler_frame->is_inline || (ref->id_flags & ID_INLINE))
- {
+
/* Identifier is declared inline/local
* or in inlining pass.
*/
- if ((ref->id_flags & ID_INLINE) &&
+ if ((ref->id_flags & (ID_INLINE|ID_PRIVATE)) &&
(!Pike_compiler->compiler_frame->is_inline)) {
/* Explicit local:: reference in first pass.
*
* RECUR directly to label 0.
*
* Note that we in this case don't know if we are overloaded or
* not, and thus can't RECUR to the recur_label.
*/
do_jump(F_RECUR, 0);
} else {
Pike_compiler->compiler_frame->recur_label =
do_jump(F_RECUR, Pike_compiler->compiler_frame->recur_label);
}
} else {
/* Recur if not overloaded. */
emit1(F_COND_RECUR,id);
Pike_compiler->compiler_frame->recur_label =
do_jump(F_POINTER, Pike_compiler->compiler_frame->recur_label);
}
- } else {
- emit1(F_CALL_LFUN, id);
+ POP_AND_DONT_CLEANUP;
+ return 1;
}
-
+ else {
+ #ifdef USE_APPLY_N
+ int nargs = count_args(args);
+ if( nargs == -1 )
+ {
+ #endif
+ PUSH_CLEANUP_FRAME(do_pop_mark, 0);
+ emit0(F_MARK);
+ do_docode(args,0);
+ emit1(F_CALL_LFUN, id);
POP_AND_DONT_CLEANUP;
return 1;
-
+ #ifdef USE_APPLY_N
}
-
+ else
+ {
+ do_docode(args,0);
+ emit2(F_CALL_LFUN_N, id, nargs);
+ }
+ #endif
+ }
+ return 1;
+ }
/*
* FIXME: this can be optimized, but is not really used
* enough to be worth it yet.
*/
static void emit_apply_builtin(char *func)
{
INT32 tmp1;
struct compilation *c = THIS_COMPILATION;
struct pike_string *n1=make_shared_string(func);
pike.git/src/docode.c:949:
} else if (n->u.integer.b == IDREF_MAGIC_THIS) {
emit1(F_THIS_OBJECT, 0);
} else if(IDENTIFIER_IS_FUNCTION(id->identifier_flags) &&
id->identifier_flags & IDENTIFIER_HAS_BODY)
{
/* Only use this opcode when it's certain that the result
* can't zero, i.e. when we know the function isn't just a
* prototype. */
emit1(F_LFUN, n->u.integer.b);
} else if (IDENTIFIER_IS_CONSTANT(id->identifier_flags) &&
- (ref->id_flags & ID_INLINE) && !ref->inherit_offset &&
+ (ref->id_flags & (ID_INLINE|ID_PRIVATE)) && !ref->inherit_offset &&
(id->func.const_info.offset >= 0)) {
/* An inline, local or final constant identifier.
* No need for vtable traversal during runtime.
*/
struct svalue *s = &state->new_program->
constants[id->func.const_info.offset].sval;
if (TYPEOF(*s) == T_PROGRAM &&
s->u.program->flags & PROGRAM_USES_PARENT) {
/* Program using parent. Convert to an LFUN. */
emit1(F_LFUN, n->u.integer.b);
pike.git/src/docode.c:1377: Inside #if defined(PIKE_DEBUG)
get_name_of_type(id->run_time_type),
id->run_time_type);
}
#endif /* PIKE_DEBUG */
f = id->func.gs_info.setter;
if (f == -1) {
yywarning("Variable %S lacks a setter.", id->name);
} else if (!level) {
f += inh->identifier_level;
if (flags & DO_POP) {
+ #ifndef USE_APPLY_N
emit0(F_MARK);
-
+ #endif
code_expression(CAR(n), 0, "RHS");
} else {
code_expression(CAR(n), 0, "RHS");
-
+ #ifndef USE_APPLY_N
emit0(F_MARK);
-
+ #endif
emit0(F_DUP);
}
-
+ #ifdef USE_APPLY_N
+ emit2(F_CALL_LFUN_N, f, 1);
+ #else
emit1(F_CALL_LFUN, f);
-
+ #endif
emit0(F_POP_VALUE);
return !(flags & DO_POP);
}
}
}
/* FALL_THROUGH */
case F_EXTERNAL:
/* Check that it is in this context */
if(Pike_compiler ->new_program->id == CDR(n)->u.integer.a)
{