2008-01-29
2008-01-29 20:01:48 by Henrik Grubbström (Grubba) <grubba@grubba.org>
-
5f28056eff4765b0e6b06ba3f6af5a2476ffd54b
(52 lines)
(+47/-5)
[
Show
| Annotate
]
Branch: 7.9
Added opcodes F_LTOSVAL_CALL_BUILTIN_AND_ASSIGN{,_POP}.
Rev: src/interpret_functions.h:1.198
2:
|| This file is part of Pike. For copyright information see COPYRIGHT.
|| Pike is distributed under GPL, LGPL and MPL. See the file COPYING
|| for more information.
- || $Id: interpret_functions.h,v 1.197 2008/01/26 22:34:20 mast Exp $
+ || $Id: interpret_functions.h,v 1.198 2008/01/29 20:01:48 grubba Exp $
*/
/*
2247: Inside #if defined(PIKE_DEBUG)
#undef DO_CALL_BUILTIN
#ifdef PIKE_DEBUG
#define DO_CALL_BUILTIN(ARGS) do { \
- int args=(ARGS); \
- struct svalue *expected_stack=Pike_sp-args; \
+ int args_=(ARGS); \
+ struct svalue *expected_stack=Pike_sp-args_; \
LOCAL_VAR(struct svalue *s); \
s = &Pike_fp->context.prog->constants[arg1].sval; \
if(Pike_interpreter.trace_level) \
2259:
my_strcat ("[widestring function name]"); \
else \
my_strcat (s->u.efun->name->str); \
- do_trace_call(args, &save_buf); \
+ do_trace_call(args_, &save_buf); \
} \
- (*(s->u.efun->function))(args); \
+ (*(s->u.efun->function))(args_); \
s->u.efun->runs++; \
if(Pike_sp != expected_stack + !s->u.efun->may_return_void) \
{ \
2335:
pop_stack();
});
+ OPCODE1_TAIL(F_LTOSVAL_CALL_BUILTIN_AND_ASSIGN_POP,
+ "ltosval, call builtin, assign & pop", I_UPDATE_ALL, {
+ OPCODE1(F_LTOSVAL_CALL_BUILTIN_AND_ASSIGN, "ltosval, call builtin & assign",
+ I_UPDATE_ALL, {
+ INT32 args = DO_NOT_WARN((INT32)(Pike_sp - *--Pike_mark_sp));
+ ONERROR uwp;
+
+ /* FIXME: Assert that args > 0 */
+
+ free_svalue(Pike_sp-args);
+ lvalue_to_svalue_no_free(Pike_sp-args, Pike_sp-args-2);
+ /* This is so that foo = efun(foo,...) (and similar things) will be faster.
+ * It's done by freeing the old reference to foo after it has been
+ * pushed on the stack. That way foo can have only 1 reference if we
+ * are lucky, and then the low array/multiset/mapping manipulation
+ * routines can be destructive if they like.
+ */
+ if( (1 << Pike_sp[-args].type) &
+ (BIT_ARRAY | BIT_MULTISET | BIT_MAPPING | BIT_STRING) )
+ {
+ LOCAL_VAR(struct svalue tmp);
+ tmp.type = PIKE_T_INT;
+ tmp.subtype = NUMBER_NUMBER;
+ tmp.u.integer = 0;
+ assign_lvalue(Pike_sp-args-2, &tmp);
+ }
+ /* NOTE: Pike_sp-args-2 is the lvalue, Pike_sp-args is the original value.
+ * If an error gets thrown, the original value will thus be restored.
+ * If the efun succeeds, Pike_sp-args will hold the result.
+ */
+ SET_ONERROR(uwp, o_assign_lvalue, Pike_sp-args-2);
+ DO_CALL_BUILTIN(args);
+ CALL_AND_UNSET_ONERROR(uwp);
+ free_svalue(Pike_sp-3);
+ free_svalue(Pike_sp-2);
+ move_svalue(Pike_sp - 3, Pike_sp - 1);
+ Pike_sp-=2;
+ });
+ pop_stack();
+ });
+
#ifndef ENTRY_PROLOGUE_SIZE
#define ENTRY_PROLOGUE_SIZE 0
#endif /* !ENTRY_PROLOGUE_SIZE */