pike.git
/
src
/
operators.c
version
»
Context lines:
10
20
40
80
file
none
3
pike.git/src/operators.c:1:
/* || 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: operators.c,v 1.
190
2004/
05
/
29
18
:
21
:
05
grubba Exp $
+
|| $Id: operators.c,v 1.
191
2004/
08
/
11
14
:
37
:
22
grubba Exp $
*/ #include "global.h" #include <math.h>
-
RCSID("$Id: operators.c,v 1.
190
2004/
05
/
29
18
:
21
:
05
grubba Exp $");
+
RCSID("$Id: operators.c,v 1.
191
2004/
08
/
11
14
:
37
:
22
grubba Exp $");
#include "interpret.h" #include "svalue.h" #include "multiset.h" #include "mapping.h" #include "array.h" #include "stralloc.h" #include "opcodes.h" #include "operators.h" #include "pike_memory.h" #include "pike_error.h"
pike.git/src/operators.c:1142:
*! in Pike 7.0. *! *! @seealso *! @[`-()], @[lfun::`+()], @[lfun::``+()] */ PMOD_EXPORT void f_add(INT32 args) { INT_TYPE e,size; TYPE_FIELD types;
+
tail_recurse:
types=0; for(e=-args;e<0;e++) types|=1<<sp[e].type; switch(types) { default: if(!args) { SIMPLE_TOO_FEW_ARGS_ERROR("`+", 1); }else{ if(types & BIT_OBJECT) { if (args == 1) return; if(sp[-args].type == T_OBJECT && sp[-args].u.object->prog) {
-
+
/* The first argument is an object. */
int i; if(sp[-args].u.object->refs==1 && (i = FIND_LFUN(sp[-args].u.object->prog,LFUN_ADD_EQ)) != -1) { apply_low(sp[-args].u.object, i, args-1); stack_pop_keep_top(); return; } if((i = FIND_LFUN(sp[-args].u.object->prog,LFUN_ADD)) != -1) {
pike.git/src/operators.c:1185:
} } for(e=1;e<args;e++) { int i; if(sp[e-args].type == T_OBJECT && sp[e-args].u.object->prog && (i = FIND_LFUN(sp[e-args].u.object->prog,LFUN_RADD)) != -1) {
-
struct svalue *tmp=
sp+e
-args;
-
check
_
stack
(e);
-
assign
_
svalues
_
no_free
(sp, sp-args, e, -
1
);
-
sp+=
e;
-
apply_low(
tmp
-
>
u.object, i, e);
-
if(
args - e
>
1)
-
{
-
assign_svalue(
tmp
, sp-1);
+
/* There's an object with a lfun::``+() at argument @[e]. */
+
if (e == args-1) {
+
/* The object is the last argument. */
+
struct
object *o = Pike_sp[-1].u.object;
+
ONERROR err;
+
Pike_sp--;
+
SET_ONERROR(err, do_free_object, o);
+
apply_low(o, i, e);
+
CALL_AND_UNSET_ONERROR(err);
+
return;
+
} else {
+
/* Rotate the stack, so that the @[e] first elements come last.
+
*/
+
struct
svalue *tmp
;
+
if (e*2 < args) {
+
tmp
=
xalloc(e*sizeof(struct svalue));
+
memcpy(tmp, Pike_sp
-args
, e*sizeof(struct svalue))
;
+
memmove(Pike
_
sp-args,
(
Pike_sp-args)+e,
+
(args-
e)
*sizeof(struct svalue))
;
+
memcpy(Pike
_
sp-e, tmp, e*sizeof(struct svalue));
+
} else {
+
tmp = xalloc((args-e)*sizeof(struct svalue));
+
memcpy(tmp, (Pike
_
sp-args)+e, (args-e)*sizeof(struct svalue));
+
memmove(Pike
_sp
-e
,
Pike_
sp-args, e
*sizeof(struct svalue));
+
memcpy(Pike_sp-args
,
tmp, (args
-
e
)
*sizeof(struct svalue))
;
+
}
+
free(tmp);
+
/* Now the stack is:
+
*
+
* -args object with lfun::``+()
+
* ...
+
* ... other arguments
+
* ...
+
* -e first argument.
+
* ...
+
* -1 last argument before the object.
+
*/
+
#ifdef PIKE_DEBUG
+
if (Pike_sp[-args].type !
=
T_OBJECT ||
+
!Pike_sp[-args].u.object->prog ||
+
FIND_LFUN(Pike_sp[-args].u.object->prog, LFUN_RADD) != i) {
+
Pike_fatal("`+() Lost track of object.\n")
;
+
}
+
#endif /* PIKE_DEBUG */
+
apply_low(
Pike_sp[
-
args].
u.object, i, e);
+
args -
=
e
;
+
/* Replace the object with the result. */
+
assign_svalue(
Pike_sp-(args+1)
,
Pike_
sp-1);
pop_stack();
-
f_add(args
- e);
-
assign
_
svalue(sp-e-1,sp-1)
;
-
pop_n_elems(e);
-
}else{
-
assign_svalue(sp-args-1,sp-1);
-
pop_n_elems(args);
+
goto
tail
_
recurse
;
}
-
return;
+
} } } } switch(sp[-args].type) { case T_PROGRAM: case T_FUNCTION: SIMPLE_BAD_ARG_ERROR("`+", 1,