e576bb2002-10-11Martin Nilsson /* || 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.
24bce62003-03-14Henrik Grubbström (Grubba) || $Id: svalue.h,v 1.117 2003/03/14 15:43:22 grubba Exp $
e576bb2002-10-11Martin Nilsson */
24ddc71998-03-28Henrik Grubbström (Grubba) 
5267b71995-08-09Fredrik Hübinette (Hubbe) #ifndef SVALUE_H #define SVALUE_H
bed9601997-05-19Fredrik Hübinette (Hubbe) #include "global.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) 
dfa5b31996-12-05Fredrik Hübinette (Hubbe) #ifndef STRUCT_ARRAY_DECLARED #define STRUCT_ARRAY_DECLARED
5267b71995-08-09Fredrik Hübinette (Hubbe) struct array;
dfa5b31996-12-05Fredrik Hübinette (Hubbe) #endif #ifndef STRUCT_MAPPING_DECLARED #define STRUCT_MAPPING_DECLARED
5267b71995-08-09Fredrik Hübinette (Hubbe) struct mapping;
dfa5b31996-12-05Fredrik Hübinette (Hubbe) #endif #ifndef STRUCT_MULTISET_DECLARED #define STRUCT_MULTISET_DECLARED
06983f1996-09-22Fredrik Hübinette (Hubbe) struct multiset;
dfa5b31996-12-05Fredrik Hübinette (Hubbe) #endif #ifndef STRUCT_OBJECT_DECLARED #define STRUCT_OBJECT_DECLARED
5267b71995-08-09Fredrik Hübinette (Hubbe) struct object;
dfa5b31996-12-05Fredrik Hübinette (Hubbe) #endif #ifndef STRUCT_PROGRAM_DECLARED #define STRUCT_PROGRAM_DECLARED
5267b71995-08-09Fredrik Hübinette (Hubbe) struct program;
dfa5b31996-12-05Fredrik Hübinette (Hubbe) #endif #ifndef STRUCT_PIKE_STRING_DECLARED #define STRUCT_PIKE_STRING_DECLARED
06983f1996-09-22Fredrik Hübinette (Hubbe) struct pike_string;
dfa5b31996-12-05Fredrik Hübinette (Hubbe) #endif #ifndef STRUCT_CALLABLE_DECLARED #define STRUCT_CALLABLE_DECLARED
5267b71995-08-09Fredrik Hübinette (Hubbe) struct callable;
dfa5b31996-12-05Fredrik Hübinette (Hubbe) #endif
5267b71995-08-09Fredrik Hübinette (Hubbe)  struct processing { struct processing *next; void *pointer_a, *pointer_b; };
45637c2001-04-07Fredrik Hübinette (Hubbe)  struct ref_dummy;
e83eb92001-03-22Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe) union anything {
e30b292001-08-14Martin Stjernholm  INT_TYPE integer; /* Union initializations assume this first. */
5267b71995-08-09Fredrik Hübinette (Hubbe)  struct callable *efun; struct array *array; struct mapping *mapping;
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct multiset *multiset;
5267b71995-08-09Fredrik Hübinette (Hubbe)  struct object *object; struct program *program;
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string *string;
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *type;
b032b92000-08-10Henrik Grubbström (Grubba)  INT32 *refs;
e83eb92001-03-22Fredrik Hübinette (Hubbe)  struct ref_dummy *dummy;
5267b71995-08-09Fredrik Hübinette (Hubbe)  FLOAT_TYPE float_number;
a903032003-02-16Martin Stjernholm  int identifier; /* Used with T_OBJ_INDEX. */ struct svalue *lval; /* Used with T_SVALUE_PTR. */
a9e4112001-12-10Martin Stjernholm  void *ptr;
5267b71995-08-09Fredrik Hübinette (Hubbe) };
dfa5b31996-12-05Fredrik Hübinette (Hubbe) #ifndef STRUCT_SVALUE_DECLARED #define STRUCT_SVALUE_DECLARED #endif
3cd7482001-04-28Martin Stjernholm 
c299402001-11-10Martin Stjernholm /* Note: At least multisets overlays the type field and uses the top 4
be227c2001-04-30Martin Stjernholm  * bits in it internally. */
5267b71995-08-09Fredrik Hübinette (Hubbe) struct svalue {
39e0bd1996-06-09Fredrik Hübinette (Hubbe)  unsigned INT16 type;
bdb5091996-09-25Fredrik Hübinette (Hubbe)  unsigned INT16 subtype;
5267b71995-08-09Fredrik Hübinette (Hubbe)  union anything u; };
0542ef1999-11-17Fredrik Hübinette (Hubbe) #define PIKE_T_ARRAY 0 #define PIKE_T_MAPPING 1 #define PIKE_T_MULTISET 2 #define PIKE_T_OBJECT 3 #define PIKE_T_FUNCTION 4 #define PIKE_T_PROGRAM 5 #define PIKE_T_STRING 6
02964b2001-03-03Henrik Grubbström (Grubba) #define PIKE_T_TYPE 7
5a59441999-12-11Henrik Grubbström (Grubba) #define PIKE_T_INT 8 #define PIKE_T_FLOAT 9
5267b71995-08-09Fredrik Hübinette (Hubbe) 
5bd05e1999-11-23Henrik Grubbström (Grubba) #define PIKE_T_ZERO 14 /* Can return 0, but nothing else */ #define T_UNFINISHED 15 /* Reserved for the garbage-collector */
a903032003-02-16Martin Stjernholm  #define T_VOID 16 /* Can't return any value. Also used on stack to fill out the second * svalue on an lvalue when it isn't used. */
5bd05e1999-11-23Henrik Grubbström (Grubba) #define T_MANY 17
3c04e81997-03-13Fredrik Hübinette (Hubbe) 
ce88d62001-03-19Henrik Grubbström (Grubba) #define PIKE_T_RING 240
3913502002-06-25Henrik Grubbström (Grubba) #define PIKE_T_NAME 241 /* Named type. */
538e811999-12-10Henrik Grubbström (Grubba) #define PIKE_T_SCOPE 243 /* Not supported yet */ #define PIKE_T_TUPLE 244 /* Not supported yet */
9e52381998-03-01Fredrik Hübinette (Hubbe) #define T_ASSIGN 245
39e0bd1996-06-09Fredrik Hübinette (Hubbe) #define T_DELETED 246
04966d2000-10-03Fredrik Hübinette (Hubbe) #define PIKE_T_UNKNOWN 247
a903032003-02-16Martin Stjernholm  #define T_OBJ_INDEX 248 /* svalue.u.identifer is an identifier index in an object. Primarily * used in lvalues on stack. */ #define T_SVALUE_PTR 249 /* svalue.u.lval points to an svalue. Primarily used in lvalues on * stack. */
fe25591999-12-19Henrik Grubbström (Grubba) #define T_ARRAY_LVALUE 250
2cd8ca2000-07-28Fredrik Hübinette (Hubbe) #define PIKE_T_MIXED 251
fe25591999-12-19Henrik Grubbström (Grubba) #define T_NOT 253 #define T_AND 254 #define T_OR 255
5267b71995-08-09Fredrik Hübinette (Hubbe) 
9e51952001-08-20Martin Stjernholm /* These are only used together with describe() and friends. */ #define T_STORAGE 10000 #define T_MAPPING_DATA 10001 #define T_PIKE_FRAME 10002
a9e4112001-12-10Martin Stjernholm #define T_MULTISET_DATA 10003
54db6c1999-03-27Henrik Grubbström (Grubba) 
45ee5d1999-02-10Fredrik Hübinette (Hubbe) #define tArr(VAL) "\000" VAL #define tArray tArr(tMix) #define tMap(IND,VAL) "\001" IND VAL #define tMapping tMap(tMix,tMix) #define tSet(IND) "\002" IND #define tMultiset tSet(tMix) #define tObj "\003\000\000\000\000\000"
efa5fa1999-08-06Fredrik Hübinette (Hubbe)  #define tFuncV(ARGS,REST,RET) MagictFuncV(RET,REST,ARGS) #define tFunc(ARGS,RET) MagictFunc(RET,ARGS)
538e811999-12-10Henrik Grubbström (Grubba) #define tTuple(T1,T2) "\364" T1 T2 #define tTriple(T1,T2,T3) tTuple(T1, tTuple(T2, T3)) #define tQuad(T1,T2,T3,T4) tTriple(tTuple(T1, T2), T3, T4)
efa5fa1999-08-06Fredrik Hübinette (Hubbe) /* These two magic funcions are used to make MSVC++ work * even if 'ARGS' is empty. */ #define MagictFuncV(RET,REST,ARGS) "\004" ARGS "\021" REST RET #define MagictFunc(RET,ARGS) tFuncV(ARGS "", tVoid, RET)
3123ab2000-01-03Martin Stjernholm #define tFunction tFuncV("" ,tOr(tZero,tVoid),tOr(tMix,tVoid))
e64f5a1999-06-19Fredrik Hübinette (Hubbe) #define tNone ""
8c953a2001-03-28Henrik Grubbström (Grubba) #define tPrg(X) "\005" X #define tProgram(X) "\005" X
45ee5d1999-02-10Fredrik Hübinette (Hubbe) #define tStr "\006" #define tString "\006"
54f8ac2001-03-17Henrik Grubbström (Grubba) #define tType(T) "\007" T
5a59441999-12-11Henrik Grubbström (Grubba) #define tInt "\010\200\000\000\000\177\377\377\377" #define tInt0 "\010\000\000\000\000\000\000\000\000" #define tInt1 "\010\000\000\000\001\000\000\000\001"
c3965a2000-04-19Henrik Grubbström (Grubba) #define tInt2 "\010\000\000\000\002\000\000\000\002"
5a59441999-12-11Henrik Grubbström (Grubba) #define tInt01 "\010\000\000\000\000\000\000\000\001"
69dfee1999-12-14Martin Stjernholm #define tInt02 "\010\000\000\000\000\000\000\000\002" #define tInt03 "\010\000\000\000\000\000\000\000\003" #define tInt04 "\010\000\000\000\000\000\000\000\004" #define tInt05 "\010\000\000\000\000\000\000\000\005"
e456092000-08-29Martin Stjernholm #define tInt06 "\010\000\000\000\000\000\000\000\006"
5a59441999-12-11Henrik Grubbström (Grubba) #define tIntPos "\010\000\000\000\000\177\377\377\377"
c3965a2000-04-19Henrik Grubbström (Grubba) #define tInt1Plus "\010\000\000\000\001\177\377\377\377" #define tInt2Plus "\010\000\000\000\002\177\377\377\377"
5a59441999-12-11Henrik Grubbström (Grubba) #define tByte "\010\000\000\000\000\000\000\000\377"
fe25591999-12-19Henrik Grubbström (Grubba) #define tFlt "\011" #define tFloat "\011"
45ee5d1999-02-10Fredrik Hübinette (Hubbe) 
5bd05e1999-11-23Henrik Grubbström (Grubba) #define tZero "\016"
45ee5d1999-02-10Fredrik Hübinette (Hubbe) #define tVoid "\020" #define tVar(X) #X #define tSetvar(X,Y) "\365" #X Y
538e811999-12-10Henrik Grubbström (Grubba) #define tScope(X,T) "\363" #X Y
fe25591999-12-19Henrik Grubbström (Grubba) #define tNot(X) "\375" X #define tAnd(X,Y) "\376" X Y #define tOr(X,Y) "\377" X Y
45ee5d1999-02-10Fredrik Hübinette (Hubbe) #define tOr3(X,Y,Z) tOr(X,tOr(Y,Z)) #define tOr4(X,Y,Z,A) tOr(X,tOr(Y,tOr(Z,A))) #define tOr5(X,Y,Z,A,B) tOr(X,tOr(Y,tOr(Z,tOr(A,B)))) #define tOr6(X,Y,Z,A,B,C) tOr(X,tOr(Y,tOr(Z,tOr(A,tOr(B,C))))) #define tOr7(X,Y,Z,A,B,C,D) tOr(X,tOr(Y,tOr(Z,tOr(A,tOr(B,tOr(C,D))))))
b93cd71999-07-27Mirar (Pontus Hagland) #define tOr8(A,B,C,D,E,F,G,H) tOr(A,tOr7(B,C,D,E,F,G,H))
9f0d2e2000-09-26Henrik Wallin #define tOr9(A,B,C,D,E,F,G,H,I) tOr(A,tOr8(B,C,D,E,F,G,H,I))
fe25591999-12-19Henrik Grubbström (Grubba) #define tMix "\373" #define tMixed "\373"
8c953a2001-03-28Henrik Grubbström (Grubba) #define tComplex tOr6(tArray,tMapping,tMultiset,tObj,tFunction,tPrg(tObj)) #define tStringIndicable tOr5(tMapping,tObj,tFunction,tPrg(tObj),tMultiset)
45ee5d1999-02-10Fredrik Hübinette (Hubbe) #define tRef tOr(tString,tComplex) #define tIfnot(X,Y) tAnd(tNot(X),Y)
be07701999-11-25Martin Stjernholm #define tAny tOr(tVoid,tMix)
f64b272002-11-21Marcus Comstedt #define tName(X,Y) "\361\0"X"\0"Y
2220182002-11-22Henrik Grubbström (Grubba) #if PIKE_BYTEORDER == 1234 /* Little endian */ #define tName1(X,Y) "\361\5"X"\0\0"Y #define tName2(X,Y) "\361\6"X"\0\0\0\0"Y #else /* PIKE_BYTEORDER != 1234 */ /* Big endian */
f64b272002-11-21Marcus Comstedt #define tName1(X,Y) "\361\1"X"\0\0"Y #define tName2(X,Y) "\361\2"X"\0\0\0\0"Y
2220182002-11-22Henrik Grubbström (Grubba) #endif /* PIKE_BYTEORDER == 1234 */
45ee5d1999-02-10Fredrik Hübinette (Hubbe) 
1f21332000-07-28Fredrik Hübinette (Hubbe) #define tSimpleCallable tOr3(tArray,tFunction,tObj) #define tCallable tOr3(tArr(tSimpleCallable),tFunction,tObj)
0542ef1999-11-17Fredrik Hübinette (Hubbe) #define BIT_ARRAY (1<<PIKE_T_ARRAY) #define BIT_MAPPING (1<<PIKE_T_MAPPING) #define BIT_MULTISET (1<<PIKE_T_MULTISET) #define BIT_OBJECT (1<<PIKE_T_OBJECT) #define BIT_FUNCTION (1<<PIKE_T_FUNCTION) #define BIT_PROGRAM (1<<PIKE_T_PROGRAM) #define BIT_STRING (1<<PIKE_T_STRING)
538e811999-12-10Henrik Grubbström (Grubba) #define BIT_TYPE (1<<PIKE_T_TYPE)
0542ef1999-11-17Fredrik Hübinette (Hubbe) #define BIT_INT (1<<PIKE_T_INT) #define BIT_FLOAT (1<<PIKE_T_FLOAT)
5267b71995-08-09Fredrik Hübinette (Hubbe) 
5bd05e1999-11-23Henrik Grubbström (Grubba) #define BIT_ZERO (1<<PIKE_T_ZERO)
3c04e81997-03-13Fredrik Hübinette (Hubbe) /* Used to signify that this array might not be finished yet */
4eb50a1996-05-16Fredrik Hübinette (Hubbe) /* garbage collect uses this */
5bd05e1999-11-23Henrik Grubbström (Grubba) #define BIT_UNFINISHED (1 << T_UNFINISHED)
4eb50a1996-05-16Fredrik Hübinette (Hubbe) 
3c04e81997-03-13Fredrik Hübinette (Hubbe) /* This is only used in typechecking to signify that this * argument may be omitted. */
5bd05e1999-11-23Henrik Grubbström (Grubba) #define BIT_VOID (1 << T_VOID)
3c04e81997-03-13Fredrik Hübinette (Hubbe)  /* This is used in typechecking to signify that the rest of the * arguments has to be of this type. */ #define BIT_MANY (1 << T_MANY)
5267b71995-08-09Fredrik Hübinette (Hubbe) #define BIT_NOTHING 0
4eb50a1996-05-16Fredrik Hübinette (Hubbe) #define BIT_MIXED 0x7fff
538e811999-12-10Henrik Grubbström (Grubba) #define BIT_BASIC (BIT_INT|BIT_FLOAT|BIT_STRING|BIT_TYPE)
898bb91999-06-07Fredrik Hübinette (Hubbe) #define BIT_CALLABLE (BIT_FUNCTION|BIT_PROGRAM|BIT_ARRAY|BIT_OBJECT)
624d091996-02-24Fredrik Hübinette (Hubbe) 
7e97c31999-01-21Fredrik Hübinette (Hubbe) /* Max type which contains svalues */
0542ef1999-11-17Fredrik Hübinette (Hubbe) #define MAX_COMPLEX PIKE_T_PROGRAM
5267b71995-08-09Fredrik Hübinette (Hubbe) /* Max type with ref count */
538e811999-12-10Henrik Grubbström (Grubba) #define MAX_REF_TYPE PIKE_T_TYPE
5267b71995-08-09Fredrik Hübinette (Hubbe) /* Max type handled by svalue primitives */
5a59441999-12-11Henrik Grubbström (Grubba) #define MAX_TYPE PIKE_T_FLOAT
5267b71995-08-09Fredrik Hübinette (Hubbe)  #define NUMBER_NUMBER 0 #define NUMBER_UNDEFINED 1 #define NUMBER_DESTRUCTED 2
bdb5091996-09-25Fredrik Hübinette (Hubbe) #define FUNCTION_BUILTIN USHRT_MAX
bce86c1996-02-25Fredrik Hübinette (Hubbe) #define is_gt(a,b) is_lt(b,a)
0167142001-12-16Martin Stjernholm  /* SAFE_IS_ZERO is compatible with the old IS_ZERO, but you should * consider using UNSAFE_IS_ZERO instead, since exceptions thrown from * `! functions will be propagated correctly then. */ #define UNSAFE_IS_ZERO(X) ((X)->type==PIKE_T_INT?(X)->u.integer==0:(1<<(X)->type)&(BIT_OBJECT|BIT_FUNCTION)?!svalue_is_true(X):0) #define SAFE_IS_ZERO(X) ((X)->type==PIKE_T_INT?(X)->u.integer==0:(1<<(X)->type)&(BIT_OBJECT|BIT_FUNCTION)?!safe_svalue_is_true(X):0)
5267b71995-08-09Fredrik Hübinette (Hubbe) 
0542ef1999-11-17Fredrik Hübinette (Hubbe) #define IS_UNDEFINED(X) ((X)->type==PIKE_T_INT&&!(X)->u.integer&&(X)->subtype==1)
3495fe1997-02-06Fredrik Hübinette (Hubbe) 
d026152000-09-04Martin Stjernholm #define IS_DESTRUCTED(X) \ (((X)->type == PIKE_T_OBJECT || (X)->type==PIKE_T_FUNCTION) && !(X)->u.object->prog)
5267b71995-08-09Fredrik Hübinette (Hubbe) #define check_destructed(S) \ do{ \ struct svalue *_s=(S); \
d026152000-09-04Martin Stjernholm  if(IS_DESTRUCTED(_s)) { \
5267b71995-08-09Fredrik Hübinette (Hubbe)  free_object(_s->u.object); \
0542ef1999-11-17Fredrik Hübinette (Hubbe)  _s->type = PIKE_T_INT; \
5267b71995-08-09Fredrik Hübinette (Hubbe)  _s->subtype = NUMBER_DESTRUCTED ; \ _s->u.integer = 0; \ } \ }while(0)
453f4c1996-08-12Fredrik Hübinette (Hubbe) /* var MUST be a variable!!! */ #define safe_check_destructed(var) do{ \
0542ef1999-11-17Fredrik Hübinette (Hubbe)  if((var->type == PIKE_T_OBJECT || var->type==PIKE_T_FUNCTION) && !var->u.object->prog) \
453f4c1996-08-12Fredrik Hübinette (Hubbe)  var=&dest_ob_zero; \ }while(0)
5267b71995-08-09Fredrik Hübinette (Hubbe) #define check_short_destructed(U,T) \ do{ \ union anything *_u=(U); \ if(( (1<<(T)) & (BIT_OBJECT | BIT_FUNCTION) ) && \ _u->object && !_u->object->prog) { \ free_object(_u->object); \ _u->object = 0; \ } \ }while(0)
e83eb92001-03-22Fredrik Hübinette (Hubbe)  #ifdef PIKE_RUN_UNLOCKED
aad99b2001-03-28Fredrik Hübinette (Hubbe) #define add_ref(X) pike_atomic_inc32(&(X)->refs) #define sub_ref(X) pike_atomic_dec_and_test32(&(X)->refs)
45637c2001-04-07Fredrik Hübinette (Hubbe)  #if 0 #define IF_LOCAL_MUTEX(X) X #define USE_LOCAL_MUTEX #define pike_lock_data(X) mt_lock(&(X)->mutex) #define pike_unlock_data(X) mt_unlock(&(X)->mutex)
e83eb92001-03-22Fredrik Hübinette (Hubbe) #else
45637c2001-04-07Fredrik Hübinette (Hubbe) #define IF_LOCAL_MUTEX(X) #define pike_lock_data(X) pike_lockmem((X)) #define pike_unlock_data(X) pike_unlockmem((X)) #endif #else #define IF_LOCAL_MUTEX(X)
aad99b2001-03-28Fredrik Hübinette (Hubbe) #define add_ref(X) (void)((X)->refs++)
67b7312002-12-01Martin Stjernholm #define sub_ref(X) (--(X)->refs > 0)
45637c2001-04-07Fredrik Hübinette (Hubbe) #define pike_lock_data(X) (void)(X) #define pike_unlock_data(X) (void)(X)
e83eb92001-03-22Fredrik Hübinette (Hubbe) #endif
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
fb42db2000-12-13Fredrik Hübinette (Hubbe) PMOD_EXPORT extern void describe(void *); /* defined in gc.c */
c299402001-11-10Martin Stjernholm PMOD_EXPORT extern const char msg_type_error[];
a903032003-02-16Martin Stjernholm #define check_type(T) if(T > MAX_TYPE && T!=T_SVALUE_PTR && T!=T_OBJ_INDEX && T!=T_VOID && T!=T_DELETED && T!=T_ARRAY_LVALUE) Pike_fatal(msg_type_error,T)
a4033e2000-04-14Fredrik Hübinette (Hubbe) 
433d5d2000-06-16Fredrik Hübinette (Hubbe) #define check_svalue(S) debug_check_svalue(dmalloc_check_svalue(S,DMALLOC_LOCATION()))
e2d9e62000-06-10Martin Stjernholm 
c299402001-11-10Martin Stjernholm PMOD_EXPORT extern const char msg_sval_obj_wo_refs[];
a4033e2000-04-14Fredrik Hübinette (Hubbe) #define check_refs(S) do {\
0d3fd42000-04-17Martin Stjernholm  if((S)->type <= MAX_REF_TYPE && (!(S)->u.refs || (S)->u.refs[0] < 0)) { \
a4033e2000-04-14Fredrik Hübinette (Hubbe)  describe((S)->u.refs); \
5aad932002-08-15Marcus Comstedt  Pike_fatal(msg_sval_obj_wo_refs); \
a4033e2000-04-14Fredrik Hübinette (Hubbe) } }while(0)
c299402001-11-10Martin Stjernholm PMOD_EXPORT extern const char msg_ssval_obj_wo_refs[];
a4033e2000-04-14Fredrik Hübinette (Hubbe) #define check_refs2(S,T) do { \
0d3fd42000-04-17Martin Stjernholm if((T) <= MAX_REF_TYPE && (S)->refs && (S)->refs[0] <= 0) {\
a4033e2000-04-14Fredrik Hübinette (Hubbe)  describe((S)->refs); \
5aad932002-08-15Marcus Comstedt  Pike_fatal(msg_ssval_obj_wo_refs); \
a4033e2000-04-14Fredrik Hübinette (Hubbe) } }while(0)
5267b71995-08-09Fredrik Hübinette (Hubbe) 
8c83371998-04-16Fredrik Hübinette (Hubbe) #ifdef DEBUG_MALLOC
ead2052000-06-16Fredrik Hübinette (Hubbe) static inline struct svalue *dmalloc_check_svalue(struct svalue *s, char *l) { debug_malloc_update_location(s,l);
e046002001-07-05Martin Stjernholm #if 1 if(s && s->type <= MAX_REF_TYPE)
ead2052000-06-16Fredrik Hübinette (Hubbe)  debug_malloc_update_location(s->u.refs,l);
433d5d2000-06-16Fredrik Hübinette (Hubbe) #endif
ead2052000-06-16Fredrik Hübinette (Hubbe)  return s; }
433d5d2000-06-16Fredrik Hübinette (Hubbe) static inline union anything *dmalloc_check_union(union anything *u,int type, char * l)
ead2052000-06-16Fredrik Hübinette (Hubbe) { debug_malloc_update_location(u,l);
e046002001-07-05Martin Stjernholm #if 1 if(u && type <= MAX_REF_TYPE)
ead2052000-06-16Fredrik Hübinette (Hubbe)  debug_malloc_update_location(u->refs,l);
433d5d2000-06-16Fredrik Hübinette (Hubbe) #endif
ead2052000-06-16Fredrik Hübinette (Hubbe)  return u; }
e83eb92001-03-22Fredrik Hübinette (Hubbe) #undef add_ref #undef sub_ref #ifdef PIKE_RUN_UNLOCKED
24bce62003-03-14Henrik Grubbström (Grubba) #define add_ref(X) pike_atomic_inc32((INT32 *)debug_malloc_update_location( &((X)->refs), DMALLOC_NAMED_LOCATION(" add_ref"))) #define sub_ref(X) pike_atomic_dec_and_test32((INT32 *)debug_malloc_update_location( &((X)->refs), DMALLOC_NAMED_LOCATION(" sub_ref")))
e83eb92001-03-22Fredrik Hübinette (Hubbe) #else
24bce62003-03-14Henrik Grubbström (Grubba) #define add_ref(X) (((INT32 *)debug_malloc_update_location( &((X)->refs), DMALLOC_NAMED_LOCATION(" add_ref")))[0]++) #define sub_ref(X) (--((INT32 *)debug_malloc_update_location( &((X)->refs), DMALLOC_NAMED_LOCATION(" sub_ref")))[0] > 0)
e83eb92001-03-22Fredrik Hübinette (Hubbe) #endif
8c83371998-04-16Fredrik Hübinette (Hubbe) #else
ead2052000-06-16Fredrik Hübinette (Hubbe) #define dmalloc_check_svalue(S,L) (S) #define dmalloc_check_union(U,T,L) (U)
8c83371998-04-16Fredrik Hübinette (Hubbe) 
e83eb92001-03-22Fredrik Hübinette (Hubbe) #endif
8c83371998-04-16Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe) #else
e2d9e62000-06-10Martin Stjernholm #define check_svalue(S)
5267b71995-08-09Fredrik Hübinette (Hubbe) #define check_type(T) #define check_refs(S) #define check_refs2(S,T)
ce6ab02000-07-04Martin Stjernholm #define dmalloc_check_svalue(S,L) (S) #define dmalloc_check_union(U,T,L) (U)
e83eb92001-03-22Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe) #endif
aad99b2001-03-28Fredrik Hübinette (Hubbe)  /* This define * should check that the svalue address (X) is on the local stack, * the processor stack or in a locked memory object * * Or, it could just try to make sure it's not in an unlocked memory * object... */ #define assert_svalue_locked(X) #define swap_svalues_unlocked(X,Y) do { \
708d8d2001-04-28Martin Stjernholm  struct svalue *_a=(X); \ struct svalue *_b=(Y); \ struct svalue _tmp; \
aad99b2001-03-28Fredrik Hübinette (Hubbe)  assert_svalue_locked(_a); assert_svalue_locked(_b); \
8de8c22003-02-15Martin Stjernholm  dmalloc_touch_svalue(_a); \ dmalloc_touch_svalue(_b); \
aad99b2001-03-28Fredrik Hübinette (Hubbe)  _tmp=*_a; *_a=*_b; *_b=_tmp; \ }while(0) #define free_svalue_unlocked(X) do { \ struct svalue *_s=(X); \ assert_svalue_locked(_s); \ check_type(_s->type); check_refs(_s); \ if(_s->type<=MAX_REF_TYPE) { \ if(sub_ref(_s->u.dummy) <=0) { really_free_svalue(_s); } \ } \
aff3602002-11-23Martin Stjernholm  DO_IF_DMALLOC(_s->type=PIKE_T_UNKNOWN;_s->u.refs=(void *)-1); \ PIKE_MEM_WO(*_s); \
aad99b2001-03-28Fredrik Hübinette (Hubbe) }while(0) #define free_short_svalue_unlocked(X,T) do { \ union anything *_s=(X); TYPE_T _t=(T); \ check_type(_t); check_refs2(_s,_t); \ assert_svalue_locked(_s); \ if(_t<=MAX_REF_TYPE && _s->refs) { \ if(sub_ref(_s->dummy) <= 0) really_free_short_svalue(_s,_t); \ } \
aff3602002-11-23Martin Stjernholm  DO_IF_DMALLOC(_s->refs=(void *)-1); \ PIKE_MEM_WO(_s->refs); \
aad99b2001-03-28Fredrik Hübinette (Hubbe) }while(0) #define add_ref_svalue_unlocked(X) do { \ struct svalue *_tmp=(X); \ check_type(_tmp->type); check_refs(_tmp); \ if(_tmp->type <= MAX_REF_TYPE) add_ref(_tmp->u.dummy); \ }while(0) #define assign_svalue_no_free_unlocked(X,Y) do { \
708d8d2001-04-28Martin Stjernholm  struct svalue _tmp; \ struct svalue *_to=(X); \
3cd7482001-04-28Martin Stjernholm  const struct svalue *_from=(Y); \
aad99b2001-03-28Fredrik Hübinette (Hubbe)  check_type(_from->type); check_refs(_from); \ *_to=_tmp=*_from; \ if(_tmp.type <= MAX_REF_TYPE) add_ref(_tmp.u.dummy); \ }while(0) #define assign_svalue_unlocked(X,Y) do { \
3cd7482001-04-28Martin Stjernholm  struct svalue *_to2=(X); \ const struct svalue *_from2=(Y); \
aad99b2001-03-28Fredrik Hübinette (Hubbe)  if (_to2 != _from2) { \ free_svalue(_to2); \ assign_svalue_no_free(_to2, _from2); \ } \ }while(0)
d3d1721997-01-31Fredrik Hübinette (Hubbe) 
941cf22002-11-23Martin Stjernholm #define move_svalue(TO, FROM) do { \ struct svalue *_to = (TO); \ struct svalue *_from = (FROM); \ dmalloc_touch_svalue(_from); \ *_to = *_from; \ DO_IF_DMALLOC(_from->type = PIKE_T_UNKNOWN; _from->u.refs = (void *) -1); \ PIKE_MEM_WO(*_from); \ } while (0)
453f4c1996-08-12Fredrik Hübinette (Hubbe) extern struct svalue dest_ob_zero;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
2ac9502001-08-14Fredrik Hübinette (Hubbe) #define free_mixed_svalues(X,Y) do { \ struct svalue *s_=(X); \ ptrdiff_t num_=(Y); \ while(num_--) \ { \ dmalloc_touch_svalue(s_); \ free_svalue(s_++); \ } \ }while(0);
07ae471998-04-23Fredrik Hübinette (Hubbe) #ifdef DEBUG_MALLOC
24bce62003-03-14Henrik Grubbström (Grubba) #define free_svalues(X,Y,Z) debug_free_svalues((X),(Y),(Z), DMALLOC_NAMED_LOCATION(" free_svalues"));
07ae471998-04-23Fredrik Hübinette (Hubbe) #else
2ac9502001-08-14Fredrik Hübinette (Hubbe) #define free_svalues(X,Y,Z) debug_free_svalues((X),(Y),(Z));
07ae471998-04-23Fredrik Hübinette (Hubbe) #endif
2ac9502001-08-14Fredrik Hübinette (Hubbe) #define low_clear_svalues(X,Y,N) do { \ struct svalue *s_=(X); \ ptrdiff_t num_=(Y); \ for(;num_-- > 0;s_++) \ { \ s_->type=PIKE_T_INT; \ s_->subtype=(N); \ s_->u.integer=0; \ } \ }while(0) #define clear_svalues(X,Y) low_clear_svalues((X),(Y),NUMBER_NUMBER) #define clear_svalues_undefined(X,Y) low_clear_svalues((X),(Y),NUMBER_UNDEFINED)
97e42a2002-05-02Martin Stjernholm #define really_free_short_svalue(U, TYPE) do { \ union anything *any_ = (U); \
8de8c22003-02-15Martin Stjernholm  debug_malloc_touch (any_->ptr); \
97e42a2002-05-02Martin Stjernholm  really_free_short_svalue_ptr (&any_->ptr, (TYPE)); \ } while (0)
5267b71995-08-09Fredrik Hübinette (Hubbe) /* Prototypes begin here */
97e42a2002-05-02Martin Stjernholm PMOD_EXPORT void really_free_short_svalue_ptr(void **s, TYPE_T type);
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void really_free_svalue(struct svalue *s); PMOD_EXPORT void do_free_svalue(struct svalue *s); PMOD_EXPORT void debug_free_svalues(struct svalue *s, size_t num, INT32 type_hint DMALLOC_LINE_ARGS);
84387d2001-09-24Fredrik Hübinette (Hubbe) PMOD_EXPORT void debug_free_mixed_svalues(struct svalue *s, size_t num, INT32 type_hint DMALLOC_LINE_ARGS);
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void assign_svalues_no_free(struct svalue *to,
3cd7482001-04-28Martin Stjernholm  const struct svalue *from,
19c79c2000-06-29Henrik Grubbström (Grubba)  size_t num,
3cd7482001-04-28Martin Stjernholm  TYPE_FIELD type_hint);
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void assign_svalues(struct svalue *to,
3cd7482001-04-28Martin Stjernholm  const struct svalue *from,
19c79c2000-06-29Henrik Grubbström (Grubba)  size_t num,
99946c1996-02-17Fredrik Hübinette (Hubbe)  TYPE_FIELD types);
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void assign_to_short_svalue(union anything *u,
5267b71995-08-09Fredrik Hübinette (Hubbe)  TYPE_T type,
3cd7482001-04-28Martin Stjernholm  const struct svalue *s);
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void assign_to_short_svalue_no_free(union anything *u,
fc76951996-02-17Fredrik Hübinette (Hubbe)  TYPE_T type,
3cd7482001-04-28Martin Stjernholm  const struct svalue *s);
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void assign_from_short_svalue_no_free(struct svalue *s,
3cd7482001-04-28Martin Stjernholm  const union anything *u,
569d5e1998-09-18Fredrik Hübinette (Hubbe)  TYPE_T type);
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void assign_short_svalue_no_free(union anything *to,
3cd7482001-04-28Martin Stjernholm  const union anything *from,
5267b71995-08-09Fredrik Hübinette (Hubbe)  TYPE_T type);
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void assign_short_svalue(union anything *to,
3cd7482001-04-28Martin Stjernholm  const union anything *from,
5267b71995-08-09Fredrik Hübinette (Hubbe)  TYPE_T type);
3cd7482001-04-28Martin Stjernholm PMOD_EXPORT unsigned INT32 hash_svalue(const struct svalue *s); PMOD_EXPORT int svalue_is_true(const struct svalue *s);
0167142001-12-16Martin Stjernholm PMOD_EXPORT int safe_svalue_is_true(const struct svalue *s);
3cd7482001-04-28Martin Stjernholm PMOD_EXPORT int is_identical(const struct svalue *a, const struct svalue *b); PMOD_EXPORT int is_eq(const struct svalue *a, const struct svalue *b); PMOD_EXPORT int low_is_equal(const struct svalue *a, const struct svalue *b,
5267b71995-08-09Fredrik Hübinette (Hubbe)  struct processing *p);
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT int low_short_is_equal(const union anything *a,
5267b71995-08-09Fredrik Hübinette (Hubbe)  const union anything *b, TYPE_T type, struct processing *p);
3cd7482001-04-28Martin Stjernholm PMOD_EXPORT int is_equal(const struct svalue *a, const struct svalue *b); PMOD_EXPORT int is_lt(const struct svalue *a, const struct svalue *b); PMOD_EXPORT void describe_svalue(const struct svalue *s,int indent,struct processing *p); PMOD_EXPORT void print_svalue (FILE *out, const struct svalue *s);
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void copy_svalues_recursively_no_free(struct svalue *to,
3cd7482001-04-28Martin Stjernholm  const struct svalue *from,
19c79c2000-06-29Henrik Grubbström (Grubba)  size_t num,
5267b71995-08-09Fredrik Hübinette (Hubbe)  struct processing *p);
3cd7482001-04-28Martin Stjernholm void check_short_svalue(const union anything *u, TYPE_T type); void debug_check_svalue(const struct svalue *s); PMOD_EXPORT void real_gc_xmark_svalues(const struct svalue *s, ptrdiff_t num); PMOD_EXPORT void real_gc_check_svalues(const struct svalue *s, size_t num); void gc_check_weak_svalues(const struct svalue *s, size_t num); PMOD_EXPORT void real_gc_check_short_svalue(const union anything *u, TYPE_T type); void gc_check_weak_short_svalue(const union anything *u, TYPE_T type);
d6896c2000-12-16Marcus Comstedt PMOD_EXPORT TYPE_FIELD real_gc_mark_svalues(struct svalue *s, size_t num);
19c79c2000-06-29Henrik Grubbström (Grubba) TYPE_FIELD gc_mark_weak_svalues(struct svalue *s, size_t num);
1f21332000-07-28Fredrik Hübinette (Hubbe) int real_gc_mark_short_svalue(union anything *u, TYPE_T type);
e2d9e62000-06-10Martin Stjernholm int gc_mark_weak_short_svalue(union anything *u, TYPE_T type);
7f947e2001-06-05Martin Stjernholm int gc_mark_without_recurse(struct svalue *s); int gc_mark_weak_without_recurse(struct svalue *s);
d6896c2000-12-16Marcus Comstedt PMOD_EXPORT TYPE_FIELD real_gc_cycle_check_svalues(struct svalue *s, size_t num);
19c79c2000-06-29Henrik Grubbström (Grubba) TYPE_FIELD gc_cycle_check_weak_svalues(struct svalue *s, size_t num);
d6896c2000-12-16Marcus Comstedt PMOD_EXPORT int real_gc_cycle_check_short_svalue(union anything *u, TYPE_T type);
e2d9e62000-06-10Martin Stjernholm int gc_cycle_check_weak_short_svalue(union anything *u, TYPE_T type);
7972742000-12-14Martin Stjernholm void real_gc_free_svalue(struct svalue *s); void real_gc_free_short_svalue(union anything *u, TYPE_T type);
3cd7482001-04-28Martin Stjernholm PMOD_EXPORT INT32 pike_sizeof(const struct svalue *s);
84387d2001-09-24Fredrik Hübinette (Hubbe) int svalues_are_constant(struct svalue *s, INT32 num, TYPE_FIELD hint, struct processing *p);
5267b71995-08-09Fredrik Hübinette (Hubbe) /* Prototypes end here */
84387d2001-09-24Fredrik Hübinette (Hubbe) #define gc_cycle_check_without_recurse gc_mark_without_recurse #define gc_cycle_check_weak_without_recurse gc_mark_without_recurse
433d5d2000-06-16Fredrik Hübinette (Hubbe) #define gc_xmark_svalues(S,N) real_gc_xmark_svalues(dmalloc_check_svalue(S,DMALLOC_LOCATION()),N) #define gc_check_svalues(S,N) real_gc_check_svalues(dmalloc_check_svalue(S,DMALLOC_LOCATION()),N) #define gc_check_short_svalue(U,T) real_gc_check_short_svalue(dmalloc_check_union((U),(T),DMALLOC_LOCATION()),T) #define gc_mark_svalues(S,N) real_gc_mark_svalues(dmalloc_check_svalue((S),DMALLOC_LOCATION()),N) #define gc_mark_short_svalue(U,T) real_gc_mark_short_svalue(dmalloc_check_union((U),(T),DMALLOC_LOCATION()),T) #define gc_cycle_check_svalues(S,N) real_gc_cycle_check_svalues(dmalloc_check_svalue(S,DMALLOC_LOCATION()),N) #define gc_cycle_check_short_svalue(U,T) real_gc_cycle_check_short_svalue(dmalloc_check_union((U),(T),DMALLOC_LOCATION()),(T))
7972742000-12-14Martin Stjernholm #define gc_free_svalue(S) real_gc_free_svalue(dmalloc_check_svalue(S,DMALLOC_LOCATION())) #define gc_free_short_svalue(U,T) real_gc_free_short_svalue(dmalloc_check_union((U),(T),DMALLOC_LOCATION()),(T))
103dc02000-04-12Henrik Grubbström (Grubba) 
538e811999-12-10Henrik Grubbström (Grubba) #define T_TYPE PIKE_T_TYPE
0542ef1999-11-17Fredrik Hübinette (Hubbe) #define T_FLOAT PIKE_T_FLOAT #define T_INT PIKE_T_INT
5bd05e1999-11-23Henrik Grubbström (Grubba) #define T_ZERO PIKE_T_ZERO
538e811999-12-10Henrik Grubbström (Grubba) #define T_TUPLE PIKE_T_TUPLE #define T_SCOPE PIKE_T_SCOPE
2cd8ca2000-07-28Fredrik Hübinette (Hubbe) #define T_MIXED PIKE_T_MIXED
0542ef1999-11-17Fredrik Hübinette (Hubbe) 
538e811999-12-10Henrik Grubbström (Grubba) #endif /* !NO_PIKE_SHORTHAND */
0542ef1999-11-17Fredrik Hübinette (Hubbe) 
8690fe2001-03-29Fredrik Hübinette (Hubbe) #if 0 /* PIKE_RUN_UNLOCKED */
aad99b2001-03-28Fredrik Hübinette (Hubbe)  #include "pike_error.h" /*#define swap_svalues swap_svalues*/ /*#define free_svalue free_svalue_unlocked*/ /*#define free_short_svalue free_short_svalue_unlocked */ /*#define add_ref_svalue add_ref_svalue_unlocked*/ /* * These don't work right now - Hubbe */ #define assign_svalue_no_free assign_svalue_no_free_unlocked #define assign_svalue assign_svalue_unlocked /* FIXME: * These routines assumes that pointers are 32 bit * and svalues 64 bit!!!!! - Hubbe */ #ifndef swap_svalues #define swap_svalues swap_svalues_unlocked #endif #ifndef free_svalue static inline void free_svalue(struct svalue *s) { INT64 tmp; struct svalue zero; zero.type=PIKE_T_INT; tmp=pike_atomic_swap64((INT64 *)s, *(INT64 *)&zero); free_svalue_unlocked((struct svalue *)&tmp); } #endif #ifndef free_short_svalue static inline void free_short_svalue(union anything *s, INT16 t) { if(t <= MAX_REF_TYPE) { INT32 tmp; tmp=pike_atomic_swap32((INT32 *)s, 0); free_short_svalue_unlocked((union anything *)&tmp, t); } } #endif #ifndef add_ref_svalue static inline void add_ref_svalue(struct svalue *s) { INT64 sv; sv=pike_atomic_get64((INT64 *)s); add_ref_svalue_unlocked((struct svalue *)&sv); } #endif #ifndef assign_svalue_no_free
3cd7482001-04-28Martin Stjernholm void assign_svalue_no_free(struct svalue *to, const struct svalue *from)
aad99b2001-03-28Fredrik Hübinette (Hubbe) { INT64 tmp, sv; sv=pike_atomic_get64((INT64 *)from); #ifdef PIKE_DEBUG if(sv != *(INT64*)from) { fprintf(stderr,"pike_atomic_get64() is broken %llx != %llx (%08x%08x)!\n", sv, *(INT64*)from, ((INT32*)from)[1], ((INT32*)from)[0]); abort(); } #endif add_ref_svalue_unlocked((struct svalue *)&sv); pike_atomic_set64((INT64 *)to, sv); #ifdef PIKE_DEBUG if(*(INT64*)to != *(INT64*)from) { fprintf(stderr,"pike_atomic_set64() is broken!\n"); abort(); } #endif } #endif #ifndef assign_svalue
3cd7482001-04-28Martin Stjernholm static inline void assign_svalue(struct svalue *to, const struct svalue *from)
aad99b2001-03-28Fredrik Hübinette (Hubbe) { INT64 tmp, sv; if(to != from) { sv=pike_atomic_get64((INT64 *)from); add_ref_svalue_unlocked((struct svalue *)&sv); tmp=pike_atomic_swap64((INT64 *)to, sv); free_svalue_unlocked((struct svalue *)&tmp); } } #endif #else /* FOO_PIKE_RUN_UNLOCKED */ #define swap_svalues swap_svalues #define free_svalue free_svalue_unlocked #define free_short_svalue free_short_svalue_unlocked #define add_ref_svalue add_ref_svalue_unlocked #define assign_svalue_no_free assign_svalue_no_free_unlocked #define assign_svalue assign_svalue_unlocked #endif /* FOO_PIKE_RUN_UNLOCKED */
45637c2001-04-07Fredrik Hübinette (Hubbe) #ifdef PIKE_RUN_UNLOCKED #include "pike_threadlib.h" #endif /* * Note to self: * It might be better to use a static array of mutexes instead * and just lock mutex ptr % array_size instead. * That way I wouldn't need a mutex in each memory object, * but it would cost a couple of cycles in every lock/unlock * operation instead. */ #define PIKE_MEMORY_OBJECT_MEMBERS \ INT32 refs \ DO_IF_SECURITY(; struct object *prot) \ IF_LOCAL_MUTEX(; PIKE_MUTEX_T mutex)
f4d7572001-04-15Martin Stjernholm #ifdef PIKE_SECURITY #ifdef USE_LOCAL_MUTEX #define PIKE_CONSTANT_MEMOBJ_INIT(refs) refs, 0, PTHREAD_MUTEX_INITIALIZER #else #define PIKE_CONSTANT_MEMOBJ_INIT(refs) refs, 0 #endif #else #ifdef USE_LOCAL_MUTEX #define PIKE_CONSTANT_MEMOBJ_INIT(refs) refs, PTHREAD_MUTEX_INITIALIZER #else #define PIKE_CONSTANT_MEMOBJ_INIT(refs) refs #endif #endif
45637c2001-04-07Fredrik Hübinette (Hubbe) #define INIT_PIKE_MEMOBJ(X) do { \ struct ref_dummy *v_=(struct ref_dummy *)(X); \
24bce62003-03-14Henrik Grubbström (Grubba)  v_->refs=0; \ add_ref(v_); /* For DMALLOC... */ \
45637c2001-04-07Fredrik Hübinette (Hubbe)  DO_IF_SECURITY( INITIALIZE_PROT(v_) ); \ IF_LOCAL_MUTEX(mt_init_recursive(&(v_->mutex))); \ }while(0) #define EXIT_PIKE_MEMOBJ(X) do { \ struct ref_dummy *v_=(struct ref_dummy *)(X); \ DO_IF_SECURITY( FREE_PROT(v_) ); \ IF_LOCAL_MUTEX(mt_destroy(&(v_->mutex))); \ }while(0)
aad99b2001-03-28Fredrik Hübinette (Hubbe) 
45637c2001-04-07Fredrik Hübinette (Hubbe) struct ref_dummy { PIKE_MEMORY_OBJECT_MEMBERS; };
538e811999-12-10Henrik Grubbström (Grubba)  #endif /* !SVALUE_H */