pike.git/
src/
operators.c
Branch:
Tag:
Non-build tags
All tags
No tags
2004-09-20
2004-09-20 12:10:52 by Martin Stjernholm <mast@lysator.liu.se>
b9803dcb5f55c24a0ecc1fb9777891851e668b58 (
198
lines) (+
127
/-
71
)
[
Show
|
Annotate
]
Branch:
7.6
Casting a destructed object should behave like casting a zero.
Rev: src/operators.c:1.190
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: operators.c,v 1.
189
2004/
04
/
15
00
:
11
:
51
nilsson
Exp $
+
|| $Id: operators.c,v 1.
190
2004/
09
/
20
12
:
10
:
52
mast
Exp $
*/ #include "global.h" #include <math.h>
-
RCSID("$Id: operators.c,v 1.
189
2004/
04
/
15
00
:
11
:
51
nilsson
Exp $");
+
RCSID("$Id: operators.c,v 1.
190
2004/
09
/
20
12
:
10
:
52
mast
Exp $");
#include "interpret.h" #include "svalue.h" #include "multiset.h"
225:
switch(sp[-1].type) { 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 {
{
-
+
struct object *o = sp[-1].u.object;
struct pike_string *s;
-
+
int f = FIND_LFUN(o->prog,LFUN_CAST);
+
if(f == -1)
+
Pike_error("No cast method in object.\n");
REF_MAKE_CONST_STRING(s, "int"); push_string(s);
-
if(!sp[-2].u.object->prog)
-
Pike_error("Cast called on destructed object.\n");
-
if(FIND_LFUN(sp[-2].u.object->prog,LFUN_CAST) == -1)
-
Pike_error("No cast method in object.\n");
-
apply_
lfun
(
sp[-2].u.object
,
LFUN_CAST
, 1);
-
free_svalue(sp-2);
-
sp[-2]=sp[-1];
-
sp--;
-
dmalloc
_
touch
_
svalue
(
sp
);
+
apply_
low
(
o
,
f
, 1);
+
stack
_
pop
_
keep_top
();
}
-
+
if(sp[-1].type != PIKE_T_INT) { if(sp[-1].type == T_OBJECT && sp[-1].u.object->prog)
258:
Pike_error("Cast failed, wanted int, got %s\n", get_name_of_type(sp[-1].type)); }
+
}
+
break; case T_FLOAT:
336:
return; 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 {
{
-
+
struct object *o = sp[-1].u.object;
struct pike_string *s;
-
+
int f = FIND_LFUN(o->prog,LFUN_CAST);
+
if(f == -1)
+
Pike_error("No cast method in object.\n");
REF_MAKE_CONST_STRING(s, "string"); push_string(s);
-
if(!sp[-2].u.object->prog)
-
Pike_error("Cast called on destructed object.\n");
-
if(FIND_LFUN(sp[-2].u.object->prog,LFUN_CAST) == -1)
-
Pike_error("No cast method in object.\n");
-
apply_
lfun
(
sp[-2].u.object
,
LFUN_CAST
, 1);
-
free_svalue(sp-2);
-
sp[-2]=sp[-1];
-
sp--;
-
dmalloc
_
touch
_
svalue
(
sp
);
+
apply_
low
(
o
,
f
, 1);
+
stack
_
pop
_
keep_top
();
}
-
+
if(sp[-1].type != PIKE_T_STRING) { if(sp[-1].type == T_OBJECT && sp[-1].u.object->prog)
370:
get_name_of_type(sp[-1].type)); } return;
+
}
-
+
/* Fall through. */
+
+
case T_INT:
+
sprintf(buf, "%"PRINTPIKEINT"d", sp[-1].u.integer);
+
break;
+
case T_ARRAY: { int i;
443:
} return;
-
case T_INT:
-
sprintf(buf, "%"PRINTPIKEINT"d", sp[-1].u.integer);
-
break;
-
+
case T_FLOAT: sprintf(buf, "%f", (double)sp[-1].u.float_number); break;
466:
if(run_time_type == T_MIXED) return;
+
if (sp[-1].type == T_OBJECT && !sp[-1].u.object->prog) {
+
/* Casting a destructed object should be like casting a zero. */
+
pop_stack();
+
push_int (0);
+
}
+
if(sp[-1].type == T_OBJECT) {
-
+
struct object *o = sp[-1].u.object;
struct pike_string *s;
-
+
int f = FIND_LFUN(o->prog,LFUN_CAST);
+
if(f == -1)
+
Pike_error("No cast method in object.\n");
s=describe_type(type); push_string(s);
-
if(!sp[-2].u.object->prog)
-
Pike_error("Cast called on destructed object.\n");
-
if(FIND_LFUN(sp[-2].u.object->prog,LFUN_CAST) == -1)
-
Pike_error("No cast method in object.\n");
-
apply_lfun(
sp[-2].u.object
,
LFUN_CAST
, 1);
-
free
_
svalue(sp-2);
-
sp[-2]=sp[-1];
-
sp--;
-
dmalloc
_
touch
_
svalue
(
sp
);
+
apply_lfun(
o
,
f
, 1);
+
stack
_
pop
_
keep
_
top
();
}else switch(run_time_type)
983:
*/ COMPARISON(f_eq,"`==", is_eq)
+
/* HERE */
+
/*! @decl int(0..1) `<(mixed arg1, mixed arg2, mixed ... extras) *! *! Less than test.
991:
*! this function, i.e. @expr{a<b@} is the same as *! @expr{predef::`<(a,b)@}. *!
+
*! If more than two arguments are given, each argument is compared
+
*! with the following one as described below, and the test is
+
*! successful iff all comparisons are successful. Thus a single
+
*! call can be used to test if a whole list of values are in
+
*! strictly increasing order.
+
*!
+
*! If the first argument is an object with an @[lfun::`<()], that
+
*! function is called with the second as argument, and the test is
+
*! successful iff its result is nonzero (according to @[`!]).
+
*!
+
*! Otherwise, if the second argument is an object with an
+
*! @[lfun::`==()], that function is called with the first as
+
*! argument, and the test is successful iff its result is nonzero
+
*! (according to @[`!]).
+
*!
+
*! Otherwise, if the arguments are of different types, the test is
+
*! unsuccessful. Function pointers to programs are automatically
+
*! converted to program pointers if necessary, though.
+
*!
+
*! Otherwise the test depends on the type of the arguments:
+
*! @mixed
+
*! @type int
+
*! Successful iff the two integers are numerically equal.
+
*! @type float
+
*! Successful iff the two floats are numerically equal or if
+
*! both are NaN.
+
*! @type string
+
*! Successful iff the two strings are identical, character for
+
*! character. (Since all strings are kept unique, this is
+
*! actually a test whether the arguments point to the same
+
*! string, and it therefore run in constant time.)
+
*! @type array|mapping|multiset|object|function|program|type
+
*! Successful iff the two arguments point to the same instance.
+
*! @endmixed
+
*!
*! @returns *! Returns @expr{1@} if the test is successful, @expr{0@} *! otherwise.