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.
204
2005/
04
/
08
16
:
59
:
18
grubba Exp $
+
|| $Id: operators.c,v 1.
205
2005/
09
/
15
12
:
30
:
46
grubba Exp $
*/ #include "global.h" #include <math.h> #include "interpret.h" #include "svalue.h" #include "multiset.h" #include "mapping.h" #include "array.h" #include "stralloc.h"
pike.git/src/operators.c:1075:
bad_arg_error(lfun_names[OP], sp-args, args, 1, "object", sp-args, \ "Called in destructed object.\n"); \ if((i = FIND_LFUN(o_->prog->inherits[sp[-args].subtype].prog, \ OP)) == -1) \ bad_arg_error(lfun_names[OP], sp-args, args, 1, "object", sp-args, \ "Operator not in object.\n"); \ apply_low(o_, i, args-1); \ stack_pop_keep_top(); \ } while (0)
+
/* Helper function for calling ``-operators.
+
*
+
* Assumes o is at Pike_sp[e - args].
+
*
+
* i is the resolved lfun to call.
+
*
+
* Returns the number of remaining elements on the stack.
+
*/
+
PMOD_EXPORT INT32 low_rop(struct object *o, int i, INT32 e, INT32 args)
+
{
+
if (e == args-1) {
+
/* The object is the last argument. */
+
ONERROR err;
+
Pike_sp--;
+
SET_ONERROR(err, do_free_object, o);
+
apply_low(o, i, e);
+
CALL_AND_UNSET_ONERROR(err);
+
return args - e;
+
} 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 the 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 != o ||
+
!o->prog) {
+
Pike_fatal("low_rop() Lost track of object.\n");
+
}
+
#endif /* PIKE_DEBUG */
+
apply_low(o, i, e);
+
args -= e;
+
/* Replace the object with the result. */
+
assign_svalue(Pike_sp-(args+1), Pike_sp-1);
+
pop_stack();
+
return args;
+
}
+
}
+
/*! @decl mixed `+(mixed arg) *! @decl mixed `+(object arg, mixed ... more) *! @decl int `+(int arg, int ... more) *! @decl float `+(float|int arg, float|int ... more) *! @decl string `+(string|float|int arg, string|float|int ... more) *! @decl array `+(array arg, array ... more) *! @decl mapping `+(mapping arg, mapping ... more) *! @decl multiset `+(multiset arg, multiset ... more) *! *! Addition/concatenation.
pike.git/src/operators.c:1205:
} for(e=1;e<args;e++) { if(sp[e-args].type == T_OBJECT && (p = (o = sp[e-args].u.object)->prog) && (i = FIND_LFUN(p->inherits[sp[e-args].subtype].prog, LFUN_RADD)) != -1) { /* There's an object with a lfun::``+() at argument @[e]. */
-
if (
e
=
=
args-1) {
-
/* The object is the last argument. */
-
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 != o ||
-
!o-
>
prog)
{
-
Pike_fatal("`+() Lost track of object.\n");
-
}
-
#endif /* PIKE_DEBUG */
-
apply_low(o, i, e);
-
args -= e;
-
/* Replace the object with the result. */
-
assign_svalue(Pike_sp-(args+1), Pike_sp-
1)
;
-
pop_stack();
+
if (
(args
=
low
_
rop
(o, i, e, args)) > 1)
goto tail_recurse; } } } }
-
}
+
switch(sp[-args].type) { case T_PROGRAM: case T_FUNCTION: SIMPLE_BAD_ARG_ERROR("`+", 1, "string|object|int|float|array|mapping|multiset"); } bad_arg_error("`+", sp-args, args, 1, "string|object|int|float|array|mapping|multiset", sp-args,