pike.git / src / operators.c

version» Context lines:

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,