pike.git
/
src
/
operators.c
version
»
Context lines:
10
20
40
80
file
none
3
pike.git/src/operators.c:30:
#include "cyclic.h" #include "pike_compiler.h" #define sp Pike_sp #define OP_DIVISION_BY_ZERO_ERROR(FUNC) \ math_error(FUNC, sp-2, 2, 0, "Division by zero.\n") #define OP_MODULO_BY_ZERO_ERROR(FUNC) \ math_error(FUNC, sp-2, 2, 0, "Modulo by zero.\n")
-
/* The destructive multiset merge code is broken.
-
* l->msd gets -1 refs.
-
*
-
* Disable it for now.
-
* /grubba 2008-07-08
-
*/
-
#undef PIKE_MERGE_DESTR_A
-
#define PIKE_MERGE_DESTR_A 0
-
+
/* This calculation should always give some margin based on the size. */ /* It utilizes that log10(256) ~= 2.4 < 5/2. */ /* One extra char for the sign and one for the \0 terminator. */ #define MAX_INT_SPRINTF_LEN (2 + (SIZEOF_INT_TYPE * 5 + 1) / 2) /* Enough to hold a Pike float or int in textform */ #define MAX_NUM_BUF (MAXIMUM(MAX_INT_SPRINTF_LEN,MAX_FLOAT_SPRINTF_LEN))
-
+
static int has_lfun( enum LFUN lfun, int arg );
+
static int call_lfun(enum LFUN left, enum LFUN right);
+
static int call_lhs_lfun( enum LFUN lfun, int arg );
+
static int float_promote(void);
-
+
void index_no_free(struct svalue *to,struct svalue *what,struct svalue *ind) { switch(TYPEOF(*what)) { case T_ARRAY: simple_array_index_no_free(to,what->u.array,ind); break; case T_MAPPING: mapping_index_no_free(to,what->u.mapping,ind);
pike.git/src/operators.c:210:
PMOD_EXPORT void o_cast_to_int(void) { switch(TYPEOF(sp[-1])) { case T_OBJECT: if(!sp[-1].u.object->prog) { /* Casting a destructed object should be like casting a zero. */ pop_stack(); push_int (0); }
-
-
else
{
+
else
{
-
struct object *o =
sp[-1].u.object
;
-
struct program *p = o
->prog
->inherits[SUBTYPEOF(sp[-1])].prog;
-
int f
=
FIND
_
LFUN(p,
LFUN_CAST
)
;
-
if(f == -1)
-
Pike_error("No cast method in object.\n")
;
+
if(
sp[-1].u.object->prog =
=
bignum
_
program
)
+
return;
+
ref_push_string(literal_int_string);
-
apply
_
low
(
o,
f,
1
);
-
stack_pop_keep_top();
-
}
+
if(!call_lhs_lfun(LFUN_CAST,2))
+
Pike
_
error
(
"No
cast
method in object <2>.\n"
);
+
stack_pop_keep_top();
/*
pop
object.
*/
if(TYPEOF(sp[-1]) != PIKE_T_INT) {
-
if(TYPEOF(sp[-1]) == T_OBJECT
&& sp[-1].u.object->prog
)
+
if(TYPEOF(sp[-1]) == T_OBJECT)
{ struct object *o = sp[-1].u.object;
-
int f = FIND_LFUN
(o->prog
->inherits[SUBTYPEOF(sp[-1])].prog,
-
LFUN__IS_TYPE)
;
-
if(
f !=
-
1
)
+
if(
o->prog
==
bignum_program
)
+
return
;
+
else
if(
o->prog
)
{
-
+
int f = 0;
ref_push_string(literal_int_string);
-
apply
_
low
(
o,
f
,
1
)
;
-
f=!UNSAFE_IS_ZERO(sp-1);
+
if( call
_
lhs_lfun
(
LFUN__IS_TYPE
,
2)
)
+
f
=
!UNSAFE_IS_ZERO(sp-1);
pop_stack(); if(f) return; } } Pike_error("Cast failed, wanted int, got %s\n", get_name_of_type(TYPEOF(sp[-1]))); } else if(SUBTYPEOF(sp[-1]) == NUMBER_UNDEFINED) Pike_error("Cannot cast this object to int.\n"); }
-
+
break; case T_FLOAT: { FLOAT_TYPE f = sp[-1].u.float_number; if ( PIKE_ISINF(f) || PIKE_ISNAN(f) ) Pike_error("Can't cast infinites or NaN to int.\n");
-
+
/* should perhaps convert to Int.Inf now that we have them? */
if (UNLIKELY(f > MAX_INT_TYPE || f < MIN_INT_TYPE)) { convert_stack_top_to_bignum(); } else { SET_SVAL(sp[-1], T_INT, NUMBER_NUMBER, integer, f); } break; } case T_STRING:
pike.git/src/operators.c:298:
struct pike_string *s; switch(TYPEOF(sp[-1])) { case T_OBJECT: if(!sp[-1].u.object->prog) { /* Casting a destructed object should be like casting a zero. */ pop_stack(); push_constant_text("0"); } else {
-
{
-
struct object *o = sp[-1].u.object;
-
int f = FIND_LFUN(o->prog->inherits[SUBTYPEOF(sp[-1])].prog, LFUN_CAST);
-
if(f == -1)
-
Pike_error("No cast method in object.\n");
+
ref_push_string(literal_string_string);
-
apply
_
low
(
o,
f,
1
);
+
if(!call_lhs_lfun(LFUN_CAST,2))
+
Pike
_
error
(
"No
cast
method in object.\n"
);
stack_pop_keep_top();
-
}
-
+
if(TYPEOF(sp[-1]) != PIKE_T_STRING) { if(TYPEOF(sp[-1])==PIKE_T_INT && SUBTYPEOF(sp[-1])==NUMBER_UNDEFINED) Pike_error("Cannot cast this object to string.\n"); if(TYPEOF(sp[-1]) == T_OBJECT && sp[-1].u.object->prog) {
-
struct object *o = sp[-1].u.object;
-
int f = FIND_LFUN(o->prog->inherits[SUBTYPEOF(sp[-1])].prog,
-
LFUN__IS_TYPE);
-
if( f != -1)
-
{
+
ref_push_string(literal_string_string);
-
apply
_
low
(
o,
f
,
1
)
;
-
f=
!UNSAFE_IS_ZERO(sp-1);
+
if(
call
_
lhs_lfun
(
LFUN__IS_TYPE
,
2
)
)
+
if(
!UNSAFE_IS_ZERO(sp-1)
)
+
return
;
pop_stack();
-
if(f) return;
+
}
-
}
+
Pike_error("Cast failed, wanted string, got %s\n", get_name_of_type(TYPEOF(sp[-1]))); } } return; case T_ARRAY: { int i, alen; struct array *a = sp[-1].u.array;
pike.git/src/operators.c:1134:
*! Returns @expr{1@} if the test is successful, @expr{0@} *! otherwise. *! *! @seealso *! @[`==()] */ PMOD_EXPORT void f_ne(INT32 args) { f_eq(args);
-
o
_
not()
;
+
/* f
_
eq and friends always returns 1 or 0. */
+
Pike_sp[-1].u.integer = !Pike_sp[-1].u.integer
;
} /*! @decl int(0..1) `==(mixed arg1, mixed arg2, mixed ... extras) *! *! Equality test. *! *! Every expression with the @expr{==@} operator becomes a call to *! this function, i.e. @expr{a==b@} is the same as *! @expr{predef::`==(a,b)@}. *!
pike.git/src/operators.c:1270:
*! otherwise. *! *! @note *! For total orders, e.g. integers, this is the inverse of @[`<()]. *! *! @seealso *! @[`<=()], @[`>()], @[`<()] */ COMPARISON(f_ge,"`>=",is_ge)
+
#ifdef OPTIMIZE_ADD
+
static void add_strings(INT32 args)
+
{
+
struct pike_string *r;
+
PCHARP buf;
+
ptrdiff_t tmp;
+
int max_shift=0;
+
ptrdiff_t size=0,e;
+
int num=0;
-
#define
CALL_OPERATOR(OP,
args)
do
{
\
-
struct object *o_ =
sp[
-args
].u.
object; \
-
int i; \
-
if(!o_
->
prog)
\
-
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[SUBTYPEOF(
sp[
-args
]
)]
.
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)
+
for
(
e=-
args
;e<0;e++
)
+
{
+
if(
sp[
e
].u.
string
->
len
!=
0)
num++;
+
size
+=
sp
[
e
]
.u.string
-
>len
;
+
if(sp[
e
].
u.string->size_shift
>
max_shift
)
+
max
_
shift=sp
[
e
].
u.string
-
>size
_
shift
;
+
}
-
/*
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
(
num
==
1
)
{
-
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))
;
+
/*
Only
one
string
has
length
(or
none!).
Return
it
. */
+
for(e=
-
args
;e
<0
;
e++
)
+
{
+
if(
sp
[e].
u.string->len
)
+
{
+
if
( e
!=
-args )
+
{
+
r
=
sp
[
e
].u.string
;
+
sp[e].u.string
= sp
[
-args
].u.string
;
+
sp
[
-args
].u.string
=
r
;
}
-
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 (TYPEOF(Pike_sp[-args]) != 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
_
n_elems(args-1);
+
return;
+
}
+
+
tmp=sp[-args].u.string->len;
+
r=new
_
realloc_shared_string
(
sp[-args].u.string
,
size,max_shift);
+
mark_free_svalue (sp - args);
+
buf=MKPCHARP_STR_OFF(r
,
tmp);
+
for(
e
=-args+1;e<0;e++
)
+
{
+
if( sp[e].u.string->len )
+
{
+
update_flags_for_add( r, sp[e].u.string )
;
+
pike_string_cpy(buf,sp[e].u.string);
+
INC_PCHARP(buf,sp[e].u.string
-
>len);
+
free_string(sp[
e
].u.string)
;
+
}
+
}
+
Pike_sp -= args-1;
+
SET_SVAL(sp[-1], T_STRING, 0, string, low_end_shared_string(r));
+
}
+
#endif
+
+
static int pair_add()
+
{
+
+
if(TYPEOF(sp[-1]) == PIKE_T_OBJECT ||
+
TYPEOF(sp[-2]) == PIKE_T_OBJECT)
+
{
+
if(TYPEOF(sp[-2]) == PIKE_T_OBJECT &&
+
/*
Note:
pairwise
add always has an extra reference! */
+
sp[-2].u.
object
->refs
==
2
&&
+
call_lhs_lfun(LFUN_ADD_EQ,2))
+
return 1; /* optimized version of +
. */
+
if(call
_
lfun
(
LFUN
_
ADD, LFUN_RADD))
+
return 1; /* standard editon */
+
}
+
+
+
if (TYPEOF(
sp
[
-
2]) != TYPEOF
(
sp[-1]
)
)
+
{
+
if(IS
_
UNDEFINED(
sp-
2
)
)
+
{
+
stack_swap()
;
pop_stack();
-
return
args
;
+
return
1
;
}
-
+
+
if(IS_UNDEFINED(sp-1))
+
{
+
pop_stack();
+
return 1;
}
-
/*
Sift
down
large
(absolute)
values
on
the
heap.
*/
-
static
void
float
_
heap
_
sift
_
down
(
struct
svalue
*svalues,
int
root,
int
nelems
)
+
/*
string
+
X
&&
X
+
string
->
string
*/
+
if( TYPEOF(Pike
_
sp[-2]) == PIKE
_
T
_
STRING )
+
o_cast_to_string
(
);
+
else
if(
TYPEOF(Pike_sp[-1]
)
== PIKE_T_STRING )
{
-
FLOAT_ARG_TYPE
val
=
svalues[root].u.float
_
number
;
-
FLOAT
_
ARG
_
TYPE abs
_
val
=
fabs
(
val
);
-
int
child;
+
stack
_
swap()
;
+
o
_
cast
_
to
_
string();
+
stack_swap
();
+
}
-
while
((
child
=
((root<<1)
+1
)
)
<
nelems)
{
-
int
swap
=
root;
-
FLOAT_ARG_TYPE
s_abs_val;
-
if
((s_abs_val
=
fabs(svalues
[
child
].u.float_number
))
< abs_val) {
-
swap
=
child
;
-
}
else
{
-
s
_
abs_val
=
abs
_
val
;
+
if
(
TYPEOF
(
Pike_sp[-2])
=
=
PIKE_T_FLOAT
)
+
{
+
if( TYPEOF(Pike_sp[-1])
=
=
PIKE_T_INT )
+
{
+
Pike_sp
[
-1
].u.float_number
=
Pike
_
sp[-1].u.integer
;
+
TYPEOF(Pike
_
sp[-1])
=
PIKE
_
T_FLOAT
;
}
-
child++;
-
if ((child < nelems) &&
-
(fabs(svalues[child].u.float_number) < s_abs_val)) {
-
swap = child;
+
}
-
if (
swap
==
root
)
break;
-
svalues
[
root
] =
svalues
[
swap
];
-
root
=
swap
;
+
+
if
(
TYPEOF
(
Pike_sp[-1])
==
PIKE_T_FLOAT
)
+
{
+
if( TYPEOF(Pike_sp
[
-2
]
)
=
=
PIKE_T_INT )
+
{
+
Pike_sp
[
-2
]
.u.float_number = Pike_sp[-2].u.integer
;
+
TYPEOF(Pike_sp[-2])
=
PIKE_T_FLOAT
;
}
-
svalues[root].u.float_number = val;
+
}
-
+
if (TYPEOF(sp[-2]) != TYPEOF(sp[-1]))
+
return 0;
+
}
+
+
/* types now identical. */
+
switch(TYPEOF(sp[-1]))
+
{
+
/*
+
Note: these cases mainly tend to happen when there is an object
+
in the argument list. otherwise pairwise addition is not done
+
using this code.
+
*/
+
case PIKE_T_INT:
+
{
+
INT_TYPE res;
+
if (DO_INT_TYPE_ADD_OVERFLOW(sp[-2].u.integer, sp[-1].u.integer, &res))
+
{
+
convert_svalue_to_bignum(sp-2);
+
call_lfun(LFUN_ADD,LFUN_RADD);
+
return 1;
+
}
+
sp[-2].u.integer = res;
+
sp--;
+
}
+
return 1;
+
case PIKE_T_FLOAT:
+
sp[-2].u.float_number += sp[-1].u.float_number;
+
sp--;
+
return 1;
+
case PIKE_T_STRING:
+
Pike_sp[-2].u.string = add_and_free_shared_strings(Pike_sp[-2].u.string,
+
Pike_sp[-1].u.string);
+
Pike_sp--;
+
return 1;
+
+
case PIKE_T_ARRAY:
+
push_array( add_arrays(sp-2,2) );
+
stack_swap(); pop_stack();
+
stack_swap(); pop_stack();
+
return 1;
+
case PIKE_T_MAPPING:
+
push_mapping( add_mappings(sp-2,2) );
+
stack_swap(); pop_stack();
+
stack_swap(); pop_stack();
+
return 1;
+
case PIKE_T_MULTISET:
+
push_multiset( add_multisets(sp-2,2) );
+
stack_swap(); pop_stack();
+
stack_swap(); pop_stack();
+
return 1;
+
case PIKE_T_OBJECT:
+
return call_lfun(LFUN_ADD,LFUN_RADD);
+
}
+
return 0;
+
}
+
+
/*! @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:1449:
*! In Pike 7.0 and earlier the addition order was unspecified. *! *! The treatment of @[UNDEFINED] was new *! in Pike 7.0. *! *! @seealso *! @[`-()], @[lfun::`+()], @[lfun::``+()] */ PMOD_EXPORT void f_add(INT32 args) {
-
INT_TYPE e,size;
-
TYPE
_
FIELD
types
;
+
if(!args)
+
SIMPLE
_
WRONG_NUM_ARGS_ERROR("`+",
1)
;
-
tail_recurse:
-
if
(args
==
1) return;
+
if(args==1)
+
return;
-
types=0;
+
{
+
struct svalue *s=sp-args;
+
int e;
+
TYPE_FIELD
types
=
0;
+
for(e=-args;e<0;e++) types |= 1<<TYPEOF(sp[e]); switch(types) { default:
-
if(!args)
-
{
-
SIMPLE
_
WRONG_NUM_ARGS_ERROR("`+", 1);
-
}else{
-
if(types & BIT
_
OBJECT)
-
{
-
struct object *o;
-
struct program *p;
-
int i;
-
-
if(TYPEOF(sp[-args]) == T_OBJECT && sp[-args].u.object->prog)
-
{
-
/* The first argument is an object. */
-
o = sp[-args].u.object;
-
p = o->prog->inherits[SUBTYPEOF(sp[-args])].prog;
-
if(o->refs==1 &&
-
(i = FIND_LFUN(p, LFUN_ADD_EQ)) != -1)
-
{
-
apply_low(o, i, args-1);
-
stack_pop_keep_top();
-
return;
-
}
-
if((i = FIND_LFUN(p, LFUN_ADD)) != -1)
-
{
-
apply_low(o, i, args-1);
-
free_
svalue(
sp-2
);
-
sp[-2]=sp[-1];
-
sp--;
-
dmalloc_touch_svalue(sp);
-
return;
-
}
-
}
-
+
pairwise
_
add:
+
push
_svalue(
s
);
for(e=1;e<args;e++) {
-
if(TYPEOF(sp[e-args]) == T
_
OBJECT &&
-
(
p = (o = sp[e-args].u.object
)
->prog) &&
-
(
i = FIND
_
LFUN
(
p->inherits[SUBTYPEOF(sp[e-args]
)
].prog,
-
LFUN_RADD
)
) != -1)
+
push
_
svalue
(
s+e
)
;
+
if
(
!pair
_
add
())
{
-
/*
There'
s
an
object
with
a
lfun::``+()
at
argument
@[e].
*/
-
if
((args
=
low
_
rop
(
o
,
i,
e,
args))
>
1)
{
-
goto
tail
_
recurse
;
+
Pike_error("Addition
on unsupported types: %
s
+
%s\nm",
+
get
_
name_of_type
(
TYPEOF(sp[-1]))
,
+
get
_
name_of_type(TYPEOF(*s)))
;
}
-
return;
+
}
-
}
-
}
-
}
-
-
switch(TYPEOF(sp[-args]))
-
{
-
case T
_
PROGRAM:
-
case T_FUNCTION:
-
SIMPLE_ARG_TYPE_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,
-
"Incompatible types\n"
);
-
return;
/*
compiler
hint
*/
-
+
assign_svalue
(
s,
sp-1);
+
pop
_
n
_
elems
(sp-
s-
1
);
+
return
;
+
#ifdef
OPTIMIZE_ADD
case BIT_STRING:
-
{
-
struct
pike_string
*r;
-
PCHARP buf;
-
ptrdiff
_
t tmp;
-
int max_shift=0;
-
-
size=0;
-
for
(
e=-
args
;e<0;e++
)
-
{
-
size+=sp[e].u.string->len
;
-
if(sp[e].u.string->size_shift > max_shift)
-
max_shift=sp[e].u.string->size_shift;
-
}
-
-
if(size == sp[-args].u.string->len)
-
{
-
pop_n_elems(args-1);
+
add
_
strings
(args);
return;
-
}
-
else if(args == 2 && (size == sp[-1].u.string->len))
-
{
-
stack_swap();
-
pop_stack();
-
return;
-
}
+
-
tmp=sp[-args].u.string->len;
-
r=new_realloc_shared_string(sp[-args].u.string,size,max_shift);
-
mark_free_svalue (sp - args);
-
buf=MKPCHARP_STR_OFF(r,tmp);
-
for(e=-args+1;e<0;e++)
-
{
-
if( sp[e].u.string->len )
-
{
-
update_flags_for_add( r, sp[e].u.string );
-
pike_string_cpy(buf,sp[e].u.string);
-
INC_PCHARP(buf,sp[e].u.string->len);
-
}
-
}
-
SET_SVAL(sp[-args], T_STRING, 0, string, low_end_shared_string(r));
-
-
for(e=-args+1;e<0;e++)
-
free_string(sp[e].u.string);
-
-
sp-=args-1;
-
-
break;
-
}
-
+
case BIT_STRING | BIT_INT: case BIT_STRING | BIT_FLOAT: case BIT_STRING | BIT_FLOAT | BIT_INT:
-
+
if ((TYPEOF(sp[-args]) != T_STRING) && (TYPEOF(sp[1-args]) != T_STRING))
{
-
struct
pike_string
*r;
-
PCHARP buf;
-
char buffer[MAX_NUM_BUF];
-
int max_shift=0, len;
-
-
if ((TYPEOF(sp[-args]) != T_STRING) && (TYPEOF(sp[1-args]) != T_STRING)) {
-
struct svalue *save_sp = sp;
-
/*
We
need
to
perform
a
normal
addition
first.
-
*/
-
for
(e=-args;
e
<
0;
e++) {
-
if (TYPEOF(save
_
sp[e]) == T_STRING)
-
break
;
-
*(sp++) = save_sp[e];
-
dmalloc_touch_svalue(Pike_sp-1);
+
/
*
Note:
Could
easily
use
pairwise
add
until
at
first
string
. */
+
goto
pairwise
_
add
;
}
-
/* Perform the addition. */
-
f_add(args+e);
-
dmalloc_touch_svalue(Pike_sp-1);
-
save_sp[--e] = *(--sp);
-
#ifdef PIKE_DEBUG
-
if (sp != save_sp) {
-
Pike_fatal("f_add(): Lost track of stack %p != %p\n", sp, save_sp);
-
}
-
#endif /* PIKE_DEBUG */
-
/* Perform the rest of the addition. */
-
f_add(-e);
-
#ifdef PIKE_DEBUG
-
if (sp != save_sp + 1 + e) {
-
Pike_fatal("f_add(): Lost track of stack (2) %p != %p\n",
-
sp, save_sp + 1 + e);
-
}
-
#endif /* PIKE_DEBUG */
-
/* Adjust the stack. */
-
save_sp[-args] = sp[-1];
-
sp = save_sp + 1 - args;
-
return;
-
} else {
-
e = -args;
-
}
-
-
size=0;
+
for(e=-args;e<0;e++)
-
+
if( TYPEOF(sp[e]) != PIKE_T_STRING )
{
-
switch(TYPEOF(sp[e]))
-
{
-
case T
_
STRING:
-
size+
=sp[e]
.u.string->len
;
-
if(sp[e].u.string->size_shift
>
max_shift)
-
max_shift=
sp[e]
.u.string->size_shift;
-
break;
-
-
case
T_INT:
-
size +
=
MAX
_
INT_SPRINTF_LEN
;
-
break;
-
-
case T
_
FLOAT:
-
size += MAX_FLOAT_SPRINTF_LEN
;
-
break;
+
*Pike
_
sp
=
sp[e];
Pike_sp++;
+
o_cast_to_string();
/*
free:s
old
sp[e]
*/
+
sp[e]
=
Pike
_
sp[-1]
;
+
Pike
_
sp--
;
}
-
}
+
add_strings(args);
+
return;
-
r=begin_wide_shared_string(size,max_shift);
-
buf=MKPCHARP_STR(r);
-
size=0;
-
-
for(e=-args;e<0;e++)
-
{
-
switch(TYPEOF(sp[e]))
-
{
-
case T_STRING:
-
pike_string_cpy(buf,sp[e].u.string);
-
INC_PCHARP(buf,sp[e].u.string->len);
-
break;
-
-
case T_INT:
-
sprintf(buffer,"%"PRINTPIKEINT"d",sp[e].u.integer);
-
#ifdef PIKE_DEBUG
-
if (strlen (buffer) > MAX_INT_SPRINTF_LEN)
-
Pike_fatal ("Formatted integer %s is %"PRINTSIZET"u, "
-
"longer than assumed max %"PRINTSIZET"u.\n",
-
buffer, strlen (buffer), MAX_INT_SPRINTF_LEN);
-
#endif
-
goto append_buffer;
-
-
case T_FLOAT:
-
sprintf(buffer,"%.*"PRINTPIKEFLOAT"g",
-
PIKEFLOAT_DIG, sp[e].u.float_number);
-
/* See comment for T_FLOAT in o_cast_to_string. */
-
if (!strchr (buffer, '.') && !strchr (buffer, 'e'))
-
strcat (buffer, ".0");
-
#ifdef PIKE_DEBUG
-
if (strlen (buffer) > MAX_FLOAT_SPRINTF_LEN)
-
Pike_fatal ("Formatted float %s is %"PRINTSIZET"u, "
-
"longer than assumed max %"PRINTSIZET"u.\n",
-
buffer, strlen (buffer), MAX_FLOAT_SPRINTF_LEN);
-
#endif
-
-
append_buffer:
-
len = strlen(buffer);
-
switch(max_shift)
-
{
-
case 0:
-
convert_0_to_0((p_wchar0 *)buf.ptr,buffer,len);
-
break;
-
-
case 1:
-
convert_0_to_1((p_wchar1 *)buf.ptr,(p_wchar0 *)buffer,len);
-
break;
-
-
case 2:
-
convert_0_to_2((p_wchar2 *)buf.ptr,(p_wchar0 *)buffer,len);
-
break;
-
}
-
INC_PCHARP(buf,len);
-
}
-
}
-
r = realloc_unlinked_string(r, SUBTRACT_PCHARP(buf, MKPCHARP_STR(r)));
-
r = low_end_shared_string(r);
-
pop_n_elems(args);
-
push_string(r);
-
break;
-
}
-
+
case BIT_INT: {
-
int
of
=
0;
-
size =
0
;
-
for(e = -
args
; e < 0; e++)
+
INT_TYPE
size =
sp[-args].u.integer
;
+
for(e = -
args+1
; e < 0; e++)
{ if (DO_INT_TYPE_ADD_OVERFLOW(size, sp[e].u.integer, &size)) { convert_svalue_to_bignum(sp-args); f_add(args); return; } } sp-=args; push_int(size);
-
break
;
-
+
return
;
} case BIT_FLOAT:
-
if
(args
>
2)
{
-
/*
Attempt
to
minimize
the
accumulated
summation
error
-
* by adding the smallest (absolute) values first
.
-
*
-
* Large accumulated errors can occur eg when the
number
-
*
of
values
to
add
is
of the same order as the largest
-
*
number
representable
by
the
mantissa
alone.
ie when
-
* the sum differs by an order of magnitude from a
-
* typical term
.
-
*/
-
/* Heapify */
-
for(e
= args
>>
1;
e--;)
{
-
float_heap_sift_down(
Pike_sp-
args,
e,
args)
;
+
{
+
double
res
=
Pike_sp[-args]
.
u.float_
number
;
+
for(e=args-1;
e>0;
e--
)
+
res
+=
sp[-e]
.
u.float_number;
+
Pike_sp
-
= args
-
1;
+
Pike_sp
[
-
1].u.float_number
=
res
;
}
-
while (args > 2) {
-
/* Pop the smallest element from the heap. */
-
FLOAT_ARG_TYPE top = Pike_sp[-args].u.float_number;
-
Pike_sp[-args] = Pike_sp[-1];
-
Pike_sp--;
-
args--;
-
float_heap_sift_down(Pike_sp-args, 0, args);
-
-
/* And add it to the second smallest. */
-
Pike_sp[-args].u.float_number += top;
-
float_heap_sift_down(Pike_sp-args, 0, args);
-
}
-
}
-
sp[-2].u.float_number += sp[-1].u.float_number;
-
sp--;
+
break; case BIT_FLOAT|BIT_INT: {
-
/*
For
improved
precision;
partition
the
values
-
*
into
floats
followed
by
ints,
so
that
we
-
*
can
add
the
integers
exactly.
-
*/
-
int
i
=
args-1;
-
e
=
0
;
-
while
(e
<
i)
{
-
for(;e
<
i;
i--)
{
-
if
(
TYPEOF(
sp[i-args]
)
=
=
T
_
FLOAT
)
break
;
+
double
res
=
Pike_sp[-args].u.float_number;
+
for(int i=i;i<args;i++)
+
if
(TYPEOF(sp[i-args])
==
T_FLOAT)
+
res +
=
Pike_sp[i-args].u.float_number
;
+
else
+
res
+=
(
double)Pike_
sp[i-args]
.u.integer;
+
Pike_sp-
=
args;
+
push
_
float(res
)
;
+
return
;
}
-
for(;e < i; e++) {
-
if (TYPEOF(sp[e-args]) == T_INT) break;
-
}
-
if (e < i) {
-
/* Swap */
-
struct svalue sval = sp[e-args];
-
sp[e-args] = sp[i-args];
-
sp[i-args] = sval;
-
}
-
}
-
if (TYPEOF(sp[e-args]) == T_FLOAT) e++;
-
/* Sum the integers. */
-
if (args - e > 1) {
-
f_add(args-e);
-
}
-
args = e+1;
-
o_cast(float_type_string, PIKE_T_FLOAT);
+
-
/* Now all the values should be floats. */
-
goto tail_recurse;
-
}
+
-
#define ADD
_WITH_UNDEFINED
(TYPE,
T_TYPEID,
ADD_FUNC, PUSH_FUNC) do {
\
-
int
e;
\
-
if
(TYPEOF(sp[-args])
==
T_INT)
{
\
-
if(IS_UNDEFINED(sp-args)) \
-
{ \
-
struct TYPE *x
;
\
-
\
-
for(e
=
1;e<args;e++)
\
-
if
(
TYPEOF(
sp
[e
-
args])
!= T_TYPEID) \
-
SIMPLE_ARG_TYPE_ERROR("`+"
,
e+1, #TYPE
);
\
-
\
-
x = ADD_FUNC(sp-args+1,args-1); \
-
pop_n_elems
(args);
\
-
PUSH_FUNC
(
x); \
-
return; \
-
} \
-
\
-
for(e=1;e<
args
;e++
)
\
-
if (TYPEOF(sp[e-args]) != T_INT) \
-
SIMPLE_ARG_TYPE_ERROR("`+", e+1, "int")
;
\
-
}
\
-
\
-
else { \
-
for(e=1;e<args;e++) \
-
if (TYPEOF(sp[e-args]) != T
_
TYPEID)
\
-
SIMPLE_ARG_TYPE_ERROR
(
"`+", e+1, #TYPE
);
\
-
}
\
-
\
-
DO_IF_DEBUG (Pike_fatal ("Shouldn't be reached.\n"))
;
\
-
break;
\
+
#define ADD(TYPE, ADD_FUNC, PUSH_FUNC) do { \
+
struct TYPE *x =
ADD_FUNC
(sp
-
args,
args
); \
+
pop_n_elems (args); \
+
PUSH
_
FUNC
(
x
); \
+
return
; \
} while (0)
-
#define
ADD
(TYPE
,
ADD_FUNC,
PUSH_FUNC)
do { \
-
struct
TYPE
*x
=
ADD_FUNC
(sp
-
args, args
)
; \
-
pop
_
n
_
elems
(
args
); \
-
PUSH_FUNC
(
x
); \
-
return
; \
-
}
while
(0)
+
#define
REMOVE_UNDEFINED
(TYPE
)
\
+
do {
\
+
int to =
-args,
i=-
args;
\
+
for(; i<0; i++) \
+
{ \
+
if(TYPEOF(Pike
_
sp[i]) == PIKE
_
T_INT)
\
+
{ \
+
if
(
!IS_UNDEFINED(Pike_sp+i
)
) \
+
SIMPLE_ARG_TYPE_ERROR("`+", args+i, #TYPE)
;
\
+
}
\
+
else if
(
to!=i
)
\
+
Pike_sp[to++] = Pike_sp[i]
;
\
+
}
\
+
for(int i=to
;
i<0;
i++)
\
+
TYPEOF(Pike_sp[i])=PIKE_T_INT;
\
+
Pike_sp += to; \
+
args += to; \
+
}while
(0)
;
-
+
// 1: removed undefineds..
case BIT_ARRAY|BIT_INT:
-
ADD_WITH_UNDEFINED
(array,
T_ARRAY,
add_arrays,
push
_array);
-
break;
-
+
REMOVE
_
UNDEFINED
(
array);
case BIT_ARRAY: ADD (array, add_arrays, push_array); break;
-
case BIT_MAPPING|BIT_INT:
-
ADD_WITH_UNDEFINED (mapping, T_MAPPING, add_mappings, push_mapping);
-
break;
+
-
+
case BIT_MAPPING|BIT_INT:
+
REMOVE_UNDEFINED (mapping);
case BIT_MAPPING: ADD (mapping, add_mappings, push_mapping); break; case BIT_MULTISET|BIT_INT:
-
ADD_WITH_UNDEFINED
(multiset,
T_MULTISET,
add_multisets,
push
_multiset);
-
break;
+
REMOVE
_
UNDEFINED(
multiset);
case BIT_MULTISET: ADD (multiset, add_multisets, push_multiset); break; #undef ADD_WITH_UNDEFINED #undef ADD
-
+
#endif
} }
-
+
}
static int generate_sum(node *n) { struct compilation *c = THIS_COMPILATION; node **first_arg, **second_arg, **third_arg; switch(count_args(CDR(n))) { case 0: return 0; case 1:
pike.git/src/operators.c:2202:
if(TYPEOF(sp[-2]) == T_INT && TYPEOF(sp[-1]) == T_FLOAT) { SET_SVAL(sp[-2], T_FLOAT, 0, float_number, (FLOAT_TYPE)sp[-2].u.integer); return 1; } else if(TYPEOF(sp[-1]) == T_INT && TYPEOF(sp[-2]) == T_FLOAT) { SET_SVAL(sp[-1], T_FLOAT, 0, float_number, (FLOAT_TYPE)sp[-1].u.integer); return 1; }
-
+
/* not needed: done in += etc
if(is_bignum_object_in_svalue(sp-2) && TYPEOF(sp[-1]) == T_FLOAT) { stack_swap(); ref_push_type_value(float_type_string); stack_swap(); f_cast(); stack_swap(); return 1; } else if(is_bignum_object_in_svalue(sp-1) && TYPEOF(sp[-2]) == T_FLOAT) { ref_push_type_value(float_type_string); stack_swap(); f_cast(); return 1; }
-
+
*/
+
return 0;
+
}
-
+
static int has_lfun( enum LFUN lfun, int arg )
+
{
+
struct program *p;
+
+
if(TYPEOF(sp[-arg]) == T_OBJECT && (p = sp[-arg].u.object->prog))
+
return FIND_LFUN(p->inherits[SUBTYPEOF(sp[-arg])].prog, lfun);
+
return -1;
+
}
+
+
static int call_lhs_lfun( enum LFUN lfun, int arg )
+
{
+
int i = has_lfun(lfun,arg);
+
+
if(i != -1)
+
{
+
apply_low(Pike_sp[-arg].u.object, i, arg-1);
+
return 1;
+
}
return 0; }
-
static int call_lfun(
int
left,
int
right)
+
static int call_lfun(
enum
LFUN
left,
enum
LFUN
right)
{ struct object *o; struct program *p; int i; if(TYPEOF(sp[-2]) == T_OBJECT && (p = (o = sp[-2].u.object)->prog) && (i = FIND_LFUN(p->inherits[SUBTYPEOF(sp[-2])].prog, left)) != -1) { apply_low(o, i, 1);
pike.git/src/operators.c:2313:
} } bad_arg_error("`-", sp-2, 2, 2, get_name_of_type(TYPEOF(sp[-2])), sp-1, "Subtract on different types.\n"); } switch(TYPEOF(sp[-2])) { case T_OBJECT:
-
CALL
_
OPERATOR
(LFUN_SUBTRACT,2);
-
break
;
+
if(!call
_
lfun
(LFUN_SUBTRACT,
LFUN_RSUBTRACT))
+
bad_arg_error("`-", sp-
2
, 2, 2, get_name_of_type(TYPEOF(sp[-2]
)
),
+
sp-1, "Subtract on objects without subtract operator.\n")
;
+
return
;
case T_ARRAY: { struct array *a; check_array_for_destruct(sp[-2].u.array); check_array_for_destruct(sp[-1].u.array); a = subtract_arrays(sp[-2].u.array, sp[-1].u.array); pop_n_elems(2); push_array(a);
pike.git/src/operators.c:2340:
struct mapping *m; m=merge_mappings(sp[-2].u.mapping, sp[-1].u.mapping,PIKE_ARRAY_OP_SUB); pop_n_elems(2); push_mapping(m); return; } case T_MULTISET: { struct multiset *l;
-
if (sp[-2].u.multiset->refs == 1) {
+
l=merge_multisets(sp[-2].u.multiset, sp[-1].u.multiset,
-
PIKE_ARRAY_OP_SUB | PIKE_MERGE_DESTR_A);
-
} else {
-
l=merge_multisets(sp[-2].u.multiset, sp[-1].u.multiset,
+
PIKE_ARRAY_OP_SUB);
-
}
+
pop_n_elems(2); push_multiset(l); return; } case T_FLOAT: sp--; sp[-1].u.float_number -= sp[0].u.float_number; return; case T_INT: if(INT_TYPE_SUB_OVERFLOW(sp[-2].u.integer, sp[-1].u.integer)) { convert_stack_top_to_bignum();
-
f
_
minus
(
2
);
+
call
_
lfun
(
LFUN_SUBTRACT, LFUN_RSUBTRACT
);
return; } sp--; SET_SVAL(sp[-1], PIKE_T_INT, NUMBER_NUMBER, integer, sp[-1].u.integer - sp[0].u.integer); return; case T_STRING: { struct pike_string *s,*ret;
pike.git/src/operators.c:2469:
case 0: SIMPLE_WRONG_NUM_ARGS_ERROR("`-", 1); case 1: o_negate(); break; case 2: o_subtract(); break; default: { INT32 e; TYPE_FIELD types = 0; struct svalue *s=sp-args; for(e=-args;e<0;e++) types |= 1<<TYPEOF(sp[e]);
-
+
#if 0
if ((types | BIT_INT | BIT_FLOAT) == (BIT_INT | BIT_FLOAT)) { INT32 carry = 0; if (types == BIT_INT) { f_add(args-1); o_subtract(); break; } /* Take advantage of the precision control in f_add(). */ for(e = 1; e < args; e++) { if (TYPEOF(s[e]) == PIKE_T_INT) {
pike.git/src/operators.c:2499:
s[e].u.float_number = -s[e].u.float_number; } } if (carry) { push_int(carry); args++; } f_add(args); break; }
-
+
#endif
push_svalue(s); for(e=1;e<args;e++) { push_svalue(s+e); o_subtract(); } assign_svalue(s,sp-1); pop_n_elems(sp-s-1); } }
pike.git/src/operators.c:2533:
do_docode(CDR(n),DO_NOT_COPY_TOPLEVEL); emit0(F_SUBTRACT); modify_stack_depth(-1); return 1; } return 0; } PMOD_EXPORT void o_and(void) {
-
if(TYPEOF(sp[-1]) != TYPEOF(sp[-2]))
+
if(
UNLIKELY(
TYPEOF(sp[-1]) != TYPEOF(sp[-2]))
)
{ if(call_lfun(LFUN_AND, LFUN_RAND)) return; else if (((TYPEOF(sp[-1]) == T_TYPE) || (TYPEOF(sp[-1]) == T_PROGRAM) || (TYPEOF(sp[-1]) == T_FUNCTION)) && ((TYPEOF(sp[-2]) == T_TYPE) || (TYPEOF(sp[-2]) == T_PROGRAM) || (TYPEOF(sp[-2]) == T_FUNCTION))) { if (TYPEOF(sp[-2]) != T_TYPE) {
pike.git/src/operators.c:2618:
else { int args = 2; SIMPLE_ARG_TYPE_ERROR("`&", 2, get_name_of_type(TYPEOF(sp[-2]))); } } switch(TYPEOF(sp[-2])) { case T_OBJECT:
-
CALL
_
OPERATOR
(LFUN_AND,
2
);
+
call
_
lfun
(LFUN_AND,
LFUN_RAND
);
break; case T_INT: sp--; SET_SVAL(sp[-1], PIKE_T_INT, NUMBER_NUMBER, integer, sp[-1].u.integer & sp[0].u.integer); break; case T_MAPPING: { struct mapping *m; m=merge_mappings(sp[-2].u.mapping, sp[-1].u.mapping, PIKE_ARRAY_OP_AND); pop_n_elems(2); push_mapping(m); return; } case T_MULTISET: { struct multiset *l;
-
if (sp[-2].u.multiset->refs == 1) {
+
l=merge_multisets(sp[-2].u.multiset, sp[-1].u.multiset,
-
PIKE_ARRAY_OP_AND | PIKE_MERGE_DESTR_A);
-
} else {
-
l=merge_multisets(sp[-2].u.multiset, sp[-1].u.multiset,
+
PIKE_ARRAY_OP_AND);
-
}
+
pop_n_elems(2); push_multiset(l); return; } case T_ARRAY: { struct array *a; a=and_arrays(sp[-2].u.array, sp[-1].u.array); pop_n_elems(2);
pike.git/src/operators.c:2846:
*! @[`|()], @[lfun::`&()], @[lfun::``&()] */ PMOD_EXPORT void f_and(INT32 args) { switch(args) { case 0: SIMPLE_WRONG_NUM_ARGS_ERROR("`&", 1); case 1: return; case 2: o_and(); return; default:
-
if(TYPEOF(sp[-args]) == T_OBJECT)
-
{
-
CALL_OPERATOR(LFUN_AND, args);
-
}else{
+
speedup(args, o_and); } }
-
}
+
static int generate_and(node *n) { struct compilation *c = THIS_COMPILATION; switch(count_args(CDR(n))) { case 1: do_docode(CDR(n),0); return 1;
pike.git/src/operators.c:2916:
} } else { int args = 2; SIMPLE_ARG_TYPE_ERROR("`|", 2, get_name_of_type(TYPEOF(sp[-2]))); } } switch(TYPEOF(sp[-2])) { case T_OBJECT:
-
CALL
_
OPERATOR
(LFUN_OR,
2
);
+
call
_
lfun
(
LFUN_OR,
LFUN_ROR
);
break; case T_INT: sp--; SET_SVAL(sp[-1], T_INT, NUMBER_NUMBER, integer, sp[-1].u.integer | sp[0].u.integer); break; case T_MAPPING: { struct mapping *m; m=merge_mappings(sp[-2].u.mapping, sp[-1].u.mapping, PIKE_ARRAY_OP_OR); pop_n_elems(2); push_mapping(m); return; } case T_MULTISET: { struct multiset *l;
-
if (sp[-2].u.multiset->refs == 1) {
+
l=merge_multisets(sp[-2].u.multiset, sp[-1].u.multiset,
-
PIKE_ARRAY_OP_OR_LEFT | PIKE_MERGE_DESTR_A);
-
} else {
-
l=merge_multisets(sp[-2].u.multiset, sp[-1].u.multiset,
+
PIKE_ARRAY_OP_OR_LEFT);
-
}
+
pop_n_elems(2); push_multiset(l); return; } case T_ARRAY: { if (sp[-1].u.array->size == 1) { /* Common case (typically the |= operator). */ int i = array_search(sp[-2].u.array, sp[-1].u.array->item, 0);
pike.git/src/operators.c:3101:
*! @[`&()], @[lfun::`|()], @[lfun::``|()] */ PMOD_EXPORT void f_or(INT32 args) { switch(args) { case 0: SIMPLE_WRONG_NUM_ARGS_ERROR("`|", 1); case 1: return; case 2: o_or(); return; default:
-
if(TYPEOF(sp[-args]) == T_OBJECT)
-
{
-
CALL_OPERATOR(LFUN_OR, args);
-
} else {
+
speedup(args, o_or); } }
-
}
+
static int generate_or(node *n) { struct compilation *c = THIS_COMPILATION; switch(count_args(CDR(n))) { case 1: do_docode(CDR(n),0); return 1;
pike.git/src/operators.c:3172:
} } else { int args = 2; SIMPLE_ARG_TYPE_ERROR("`^", 2, get_name_of_type(TYPEOF(sp[-2]))); } } switch(TYPEOF(sp[-2])) { case T_OBJECT:
-
CALL
_
OPERATOR
(LFUN_XOR,2);
+
if(!call
_
lfun
(LFUN_XOR,
LFUN_RXOR))
+
{
+
int args =
2
;
+
SIMPLE_ARG_TYPE_ERROR("`^", 1, "type"
);
+
}
break; case T_INT: sp--; SET_SVAL(sp[-1], T_INT, NUMBER_NUMBER, integer, sp[-1].u.integer ^ sp[0].u.integer); break; case T_MAPPING: { struct mapping *m; m=merge_mappings(sp[-2].u.mapping, sp[-1].u.mapping, PIKE_ARRAY_OP_XOR); pop_n_elems(2); push_mapping(m); return; } case T_MULTISET: { struct multiset *l;
-
if (sp[-2].u.multiset->refs == 1) {
+
l=merge_multisets(sp[-2].u.multiset, sp[-1].u.multiset,
-
PIKE_ARRAY_OP_XOR | PIKE_MERGE_DESTR_A);
-
} else {
-
l=merge_multisets(sp[-2].u.multiset, sp[-1].u.multiset,
+
PIKE_ARRAY_OP_XOR);
-
}
+
pop_n_elems(2); push_multiset(l); return; } case T_ARRAY: { struct array *a; a=merge_array_with_order(sp[-2].u.array, sp[-1].u.array, PIKE_ARRAY_OP_XOR); pop_n_elems(2);
pike.git/src/operators.c:3346:
*! @[`&()], @[`|()], @[lfun::`^()], @[lfun::``^()] */ PMOD_EXPORT void f_xor(INT32 args) { switch(args) { case 0: SIMPLE_WRONG_NUM_ARGS_ERROR("`^", 1); case 1: return; case 2: o_xor(); return; default:
-
if(TYPEOF(sp[-args]) == T_OBJECT)
-
{
-
CALL_OPERATOR(LFUN_XOR, args);
-
} else {
+
speedup(args, o_xor); } }
-
}
+
static int generate_xor(node *n) { struct compilation *c = THIS_COMPILATION; switch(count_args(CDR(n))) { case 1: do_docode(CDR(n),0); return 1;
pike.git/src/operators.c:3868:
*! @[`+()], @[`-()], @[`/()], @[lfun::`*()], @[lfun::``*()] */ PMOD_EXPORT void f_multiply(INT32 args) { switch(args) { case 0: SIMPLE_WRONG_NUM_ARGS_ERROR("`*", 1); case 1: return; case 2: o_multiply(); return; default:
-
if(TYPEOF(sp[-args]) == T_OBJECT)
+
{
-
CALL_OPERATOR(LFUN_MULTIPLY, args);
-
} else {
+
INT32 i = -args, j = -1; /* Reverse the arguments */ while(i < j) { struct svalue tmp = sp[i]; sp[i++] = sp[j]; sp[j--] = tmp; } while(--args > 0) { /* Restore the order, and multiply */ stack_swap();
pike.git/src/operators.c:4091:
return; } } PIKE_ERROR("`/", "Division on different types.\n", sp, 2); } switch(TYPEOF(sp[-2])) { case T_OBJECT:
-
do_lfun_division:
-
CALL
_
OPERATOR
(LFUN_DIVIDE,
2
);
+
call
_
lfun
(LFUN_DIVIDE,
LFUN_RDIVIDE
);
break; case T_STRING: { struct array *ret; ret=explode(sp[-2].u.string,sp[-1].u.string); free_string(sp[-2].u.string); free_string(sp[-1].u.string); SET_SVAL(sp[-2], T_ARRAY, 0, array, ret); sp--;
pike.git/src/operators.c:4133:
INT_TYPE tmp; if (sp[-1].u.integer == 0) OP_DIVISION_BY_ZERO_ERROR("`/"); if(INT_TYPE_DIV_OVERFLOW(sp[-2].u.integer, sp[-1].u.integer)) { stack_swap(); convert_stack_top_to_bignum(); stack_swap();
-
goto do
_lfun_
division
;
+
call
_lfun
(LFUN
_
DIVIDE,LFUN_RDIVIDE)
;
+
return;
} else tmp = sp[-2].u.integer/sp[-1].u.integer; sp--; /* What is this trying to solve? /Noring */ /* It fixes rounding towards negative infinity. /mast */ if((sp[-1].u.integer<0) != (sp[0].u.integer<0)) if(tmp*sp[0].u.integer!=sp[-1].u.integer) tmp--;
pike.git/src/operators.c:4319:
return; } } PIKE_ERROR("`%", "Modulo on different types.\n", sp, 2); } switch(TYPEOF(sp[-2])) { case T_OBJECT:
-
CALL
_
OPERATOR
(LFUN_MOD,2);
+
if(!call
_
lfun
(LFUN_MOD,
LFUN_RMOD))
+
PIKE_ERROR("`%", "Modulo on different types.\n", sp,
2);
break; case T_FLOAT: { FLOAT_TYPE foo; if(sp[-1].u.float_number == 0.0) OP_MODULO_BY_ZERO_ERROR("`%"); sp--; foo = (FLOAT_TYPE)(sp[-1].u.float_number / sp[0].u.float_number); foo = (FLOAT_TYPE)(sp[-1].u.float_number -
pike.git/src/operators.c:4540:
return 1; } return 0; } PMOD_EXPORT void o_compl(void) { switch(TYPEOF(sp[-1])) { case T_OBJECT:
-
CALL
_
OPERATOR
(LFUN_COMPL,1);
+
if(!call
_
lhs_lfun
(LFUN_COMPL,1)
)
+
PIKE_ERROR("`~", "Bad argument.\n", sp, 1)
;
break; case T_INT: SET_SVAL(sp[-1], T_INT, NUMBER_NUMBER, integer, ~sp[-1].u.integer); break; case T_FLOAT: sp[-1].u.float_number = (FLOAT_TYPE) -1.0 - sp[-1].u.float_number; break;
pike.git/src/operators.c:4660:
} return 0; } PMOD_EXPORT void o_negate(void) { switch(TYPEOF(sp[-1])) { case T_OBJECT: do_lfun_negate:
-
CALL
_
OPERATOR
(LFUN_SUBTRACT,1);
+
if(!call
_
lhs_lfun
(LFUN_SUBTRACT,1)
)
+
PIKE_ERROR("`-", "Bad argument.\n", sp, 1)
;
break; case T_FLOAT: sp[-1].u.float_number=-sp[-1].u.float_number; return; case T_INT: if(INT_TYPE_NEG_OVERFLOW(sp[-1].u.integer)) { convert_stack_top_to_bignum();