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.
dc292e2008-07-09Martin Stjernholm || $Id: svalue.h,v 1.167 2008/07/09 20:41:30 mast 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"
c7f2712007-06-09Martin Stjernholm #include "dmalloc.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) 
38ac332003-11-14Martin Stjernholm #ifndef STRUCT_NODE_S_DECLARED #define STRUCT_NODE_S_DECLARED struct node_s; typedef struct node_s node; #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) 
67a0a32005-09-12H. William Welliver III /** the union of possible types in an svalue. */
5267b71995-08-09Fredrik Hübinette (Hubbe) union anything {
67a0a32005-09-12H. William Welliver III  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;
67a0a32005-09-12H. William Welliver III  int identifier; /**< Used with T_OBJ_INDEX. */ struct svalue *lval; /**< Used with T_SVALUE_PTR. */
a9e4112001-12-10Martin Stjernholm  void *ptr;
df86912008-03-29Martin Stjernholm #ifdef DEBUG_MALLOC
86100c2008-03-29Martin Stjernholm  char *loc; /* Only used for free svalue debugging. */
df86912008-03-29Martin Stjernholm #endif
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. */
67a0a32005-09-12H. William Welliver III /** */
5267b71995-08-09Fredrik Hübinette (Hubbe) struct svalue {
67a0a32005-09-12H. William Welliver III  unsigned INT16 type; /**< the data type, see PIKE_T_... */ unsigned INT16 subtype; /**< used to store the zero type, among others */ union anything u; /**< contains the value */
5267b71995-08-09Fredrik Hübinette (Hubbe) };
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) 
b6876b2007-04-21Henrik Grubbström (Grubba) /* The types above are valid types in svalues. * The following are only used by the internal systems. */
67a0a32005-09-12H. William Welliver III #define PIKE_T_ZERO 14 /**< Can return 0, but nothing else */
e5c2322003-04-28Martin Stjernholm #define T_UNFINISHED 15
a903032003-02-16Martin Stjernholm 
67a0a32005-09-12H. William Welliver III #define T_VOID 16 /**< Can't return any value. Also used on stack to fill out the second
a903032003-02-16Martin Stjernholm  * svalue on an lvalue when it isn't used. */
67a0a32005-09-12H. William Welliver III 
5bd05e1999-11-23Henrik Grubbström (Grubba) #define T_MANY 17
3c04e81997-03-13Fredrik Hübinette (Hubbe) 
13df5b2005-12-04Martin Nilsson #define PIKE_T_INT_UNTYPED 18 /* Optimization of int type size */
8097762006-10-27Henrik Grubbström (Grubba) #define PIKE_T_GET_SET 32 /* Getter setter. * Only valid in struct identifier */
1ab4ac2008-01-26Martin Stjernholm /* Type to put in freed svalues. Only the type field in such svalues * is defined. Freeing a PIKE_T_FREE svalue is allowed and does * nothing. mark_free_svalue() is preferably used to set this type. * * Traditionally T_INT has been used for this without setting a proper * subtype; if T_INT is to be used then the subtype must be set to * NUMBER_NUMBER. * * PIKE_T_FREE svalues are recorded as BIT_INT in type hint fields. */ #define PIKE_T_FREE 237
b6876b2007-04-21Henrik Grubbström (Grubba) #define PIKE_T_ATTRIBUTE 238 /* Attribute node. */
cf4e172007-03-03Henrik Grubbström (Grubba) #define PIKE_T_NSTRING 239 /* Narrow string. Only for serialization. */
ce88d62001-03-19Henrik Grubbström (Grubba) #define PIKE_T_RING 240
67a0a32005-09-12H. William Welliver III #define PIKE_T_NAME 241 /**< Named type. */ #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 
67a0a32005-09-12H. William Welliver III /** svalue.u.identifer is an identifier index in an object. Primarily
69db482008-03-29Martin Stjernholm  * used in lvalues on stack, but can also occur in arrays containing * lvalue pairs. */
67a0a32005-09-12H. William Welliver III #define T_OBJ_INDEX 248
a903032003-02-16Martin Stjernholm 
67a0a32005-09-12H. William Welliver III /** svalue.u.lval points to an svalue. Primarily used in lvalues on
69db482008-03-29Martin Stjernholm  * stack, but can also occur in arrays containing lvalue pairs. */
67a0a32005-09-12H. William Welliver III #define T_SVALUE_PTR 249
a903032003-02-16Martin Stjernholm 
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
6d77e12003-08-20Martin Stjernholm #define T_STRUCT_CALLABLE 10004
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"
317de92008-06-18Henrik Grubbström (Grubba) #define tNStr(T) "\357" T
4e6c082007-05-02Henrik Grubbström (Grubba) #define tStr0 "\357" tZero #define tStr7 "\357" "\010\000\000\000\000\000\000\000\177" #define tStr8 "\357" "\010\000\000\000\000\000\000\000\377" #define tStr16 "\357" "\010\000\000\000\000\000\000\377\377"
cf4e172007-03-03Henrik Grubbström (Grubba) #define tStr32 "\006"
54f8ac2001-03-17Henrik Grubbström (Grubba) #define tType(T) "\007" T
13df5b2005-12-04Martin Nilsson #define tInt "\022"
5a59441999-12-11Henrik Grubbström (Grubba) #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"
4cb9f82007-05-01Martin Nilsson #define tInt07 "\010\000\000\000\000\000\000\000\007" #define tInt08 "\010\000\000\000\000\000\000\000\010" #define tInt09 "\010\000\000\000\000\000\000\000\011"
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"
23b8272003-11-04Henrik Grubbström (Grubba) #define tInt_10 "\010\377\377\377\377\000\000\000\000"
bc06612005-03-21Martin Nilsson #define tInt_11 "\010\377\377\377\377\000\000\000\001"
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)
6179f52007-04-21Henrik Grubbström (Grubba) #define tAttr(X,Y) "\356\0"X"\0"Y
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 */
6179f52007-04-21Henrik Grubbström (Grubba) #define tAttr1(X,Y) "\356\5"X"\0\0"Y #define tAttr2(X,Y) "\356\6"X"\0\0\0\0"Y
2220182002-11-22Henrik Grubbström (Grubba) #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 */
6179f52007-04-21Henrik Grubbström (Grubba) #define tAttr1(X,Y) "\356\1"X"\0\0"Y #define tAttr2(X,Y) "\356\2"X"\0\0\0\0"Y
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) 
4835da2007-10-02Henrik Grubbström (Grubba) /* Some convenience macros for common attributes. */ #define tSprintfFormat(X) tAttr("sprintf_format", X) #define tSprintfArgs(X) tAttr("sprintf_args", X) #define tDeprecated(X) tAttr("deprecated", X)
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)
67a0a32005-09-12H. William Welliver III /** Used to signify that the type field hasn't been set according to
e5c2322003-04-28Martin Stjernholm  * reality. */
5bd05e1999-11-23Henrik Grubbström (Grubba) #define BIT_UNFINISHED (1 << T_UNFINISHED)
4eb50a1996-05-16Fredrik Hübinette (Hubbe) 
67a0a32005-09-12H. William Welliver III /** This is only used in typechecking to signify that this
3c04e81997-03-13Fredrik Hübinette (Hubbe)  * argument may be omitted. */
5bd05e1999-11-23Henrik Grubbström (Grubba) #define BIT_VOID (1 << T_VOID)
3c04e81997-03-13Fredrik Hübinette (Hubbe) 
67a0a32005-09-12H. William Welliver III /** This is used in typechecking to signify that the rest of the
3c04e81997-03-13Fredrik Hübinette (Hubbe)  * 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)
5756661996-09-23Fredrik Hübinette (Hubbe) #define BIT_COMPLEX (BIT_ARRAY|BIT_MULTISET|BIT_OBJECT|BIT_PROGRAM|BIT_MAPPING|BIT_FUNCTION)
898bb91999-06-07Fredrik Hübinette (Hubbe) #define BIT_CALLABLE (BIT_FUNCTION|BIT_PROGRAM|BIT_ARRAY|BIT_OBJECT)
e5c2322003-04-28Martin Stjernholm #define BIT_REF_TYPES (BIT_STRING|BIT_TYPE|BIT_COMPLEX)
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
dc292e2008-07-09Martin Stjernholm PMOD_EXPORT const struct svalue svalue_undefined, svalue_int_zero;
e371f52008-05-30Martin Stjernholm #ifdef HAVE_UNION_INIT PMOD_EXPORT const struct svalue svalue_int_one; #else /* The value 1 is initialized first thing in init_pike. */ PMOD_EXPORT struct svalue svalue_int_one; #endif
bce86c1996-02-25Fredrik Hübinette (Hubbe) #define is_gt(a,b) is_lt(b,a)
f5971b2004-11-27Martin Stjernholm #define is_ge(a,b) is_le(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) 
1286e72008-06-28Per Hedbor #define IS_UNDEFINED(X) (check_svalue (X), (X)->type==PIKE_T_INT&&(X)->subtype==NUMBER_UNDEFINED)
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) \
e371f52008-05-30Martin Stjernholm  var=&svalue_int_zero; \
453f4c1996-08-12Fredrik Hübinette (Hubbe) }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[];
bfeae62005-09-06Henrik Grubbström (Grubba) PMOD_EXPORT extern const char msg_assign_svalue_error[];
69db482008-03-29Martin Stjernholm  #define IS_INVALID_TYPE(T) \ ((T > MAX_TYPE && T < T_OBJ_INDEX && T != T_VOID) || T > T_ARRAY_LVALUE)
8cbd552008-01-29Martin Stjernholm #define check_type(T) do { \
69db482008-03-29Martin Stjernholm  TYPE_T typ_ = (T); \ if (IS_INVALID_TYPE (typ_)) Pike_fatal(msg_type_error, typ_); \
8cbd552008-01-29Martin Stjernholm  } while (0)
a4033e2000-04-14Fredrik Hübinette (Hubbe) 
df86912008-03-29Martin Stjernholm #define check_svalue_type(S) do { \ const struct svalue *sval_ = (S); \ TYPE_T typ_ = sval_->type; \
69db482008-03-29Martin Stjernholm  if (IS_INVALID_TYPE (typ_)) debug_svalue_type_error (sval_); \
df86912008-03-29Martin Stjernholm  } while (0)
433d5d2000-06-16Fredrik Hübinette (Hubbe) #define check_svalue(S) debug_check_svalue(dmalloc_check_svalue(S,DMALLOC_LOCATION()))
e2d9e62000-06-10Martin Stjernholm 
6d77e12003-08-20Martin Stjernholm void low_thorough_check_short_svalue (const union anything *u, TYPE_T type); #define thorough_check_short_svalue(U, T) do { \ union anything *anyth_ = (U); \ TYPE_T typ_ = (T); \ check_short_svalue (anyth_, typ_); \ if (d_flag <= 50) /* Done directly by check_svalue otherwise. */ \ if (typ_ <= MAX_REF_TYPE) \ low_thorough_check_short_svalue (anyth_, typ_); \ } while (0) #define thorough_check_svalue(S) do { \ struct svalue *sval_ = (S); \ check_svalue (sval_); \ if (d_flag <= 50) /* Done directly by check_svalue otherwise. */ \ if (sval_->type <= MAX_REF_TYPE) \ low_thorough_check_short_svalue (&sval_->u, sval_->type); \ } while (0)
dd0fe02008-05-11Martin Stjernholm void check_short_svalue(const union anything *u, TYPE_T type); PMOD_EXPORT void debug_svalue_type_error (const struct svalue *s); PMOD_EXPORT void debug_check_svalue(const struct svalue *s); void debug_check_type_hint (const struct svalue *svals, size_t num, TYPE_FIELD type_hint); PMOD_EXPORT void real_gc_mark_external_svalues(const struct svalue *s, ptrdiff_t num, const char *place);
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)) { \
b9f3282004-04-03Martin Stjernholm  fprintf (stderr, msg_sval_obj_wo_refs); \ describe((S)->u.refs); \ Pike_fatal(msg_sval_obj_wo_refs); \ } }while(0)
a4033e2000-04-14Fredrik Hübinette (Hubbe) 
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) {\
b9f3282004-04-03Martin Stjernholm  fprintf (stderr, msg_ssval_obj_wo_refs); \ describe((S)->refs); \ Pike_fatal(msg_ssval_obj_wo_refs); \
a4033e2000-04-14Fredrik Hübinette (Hubbe) } }while(0)
5267b71995-08-09Fredrik Hübinette (Hubbe) 
e5c2322003-04-28Martin Stjernholm #define check_type_hint(SVALS, NUM, TYPE_HINT) \ debug_check_type_hint ((SVALS), (NUM), (TYPE_HINT))
8c83371998-04-16Fredrik Hübinette (Hubbe) #ifdef DEBUG_MALLOC
54a1302004-06-02Martin Nilsson static INLINE struct svalue *dmalloc_check_svalue(struct svalue *s, char *l)
ead2052000-06-16Fredrik Hübinette (Hubbe) {
e7f1322004-09-30Martin Stjernholm #if 0 /* What's this supposed to accomplish? Dmalloc tracks memory blocks, * not single svalues that point to them. /mast */
ead2052000-06-16Fredrik Hübinette (Hubbe)  debug_malloc_update_location(s,l);
e7f1322004-09-30Martin Stjernholm #endif
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; }
e7f1322004-09-30Martin Stjernholm static INLINE struct svalue *dmalloc_check_svalues(struct svalue *s, size_t num, char *l) { while (num--) dmalloc_check_svalue (s + num, l); return s; }
54a1302004-06-02Martin Nilsson static INLINE union anything *dmalloc_check_union(union anything *u,int type, char * l)
ead2052000-06-16Fredrik Hübinette (Hubbe) {
e7f1322004-09-30Martin Stjernholm #if 0
ead2052000-06-16Fredrik Hübinette (Hubbe)  debug_malloc_update_location(u,l);
e7f1322004-09-30Martin Stjernholm #endif
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
7d269e2008-05-11Martin Stjernholm #else /* !DEBUG_MALLOC */
ead2052000-06-16Fredrik Hübinette (Hubbe) #define dmalloc_check_svalue(S,L) (S)
e7f1322004-09-30Martin Stjernholm #define dmalloc_check_svalues(S,L,N) (S)
ead2052000-06-16Fredrik Hübinette (Hubbe) #define dmalloc_check_union(U,T,L) (U)
8c83371998-04-16Fredrik Hübinette (Hubbe) 
7d269e2008-05-11Martin Stjernholm #endif /* !DEBUG_MALLOC */ /* To be used for type checking in macros. */ static INLINE struct array *pass_array (struct array *a) {return a;} static INLINE struct mapping *pass_mapping (struct mapping *m) {return m;} static INLINE struct multiset *pass_multiset (struct multiset *l) {return l;} static INLINE struct object *pass_object (struct object *o) {return o;} static INLINE struct program *pass_program (struct program *p) {return p;} static INLINE struct pike_string *pass_string (struct pike_string *s) {return s;} static INLINE struct pike_type *pass_type (struct pike_type *t) {return t;} static INLINE struct callable *pass_callable (struct callable *c) {return c;}
8c83371998-04-16Fredrik Hübinette (Hubbe) 
e5c2322003-04-28Martin Stjernholm #else /* !PIKE_DEBUG */
5267b71995-08-09Fredrik Hübinette (Hubbe) 
ed3dca2008-06-29Martin Stjernholm #define check_svalue(S) ((void) 0) #define check_short_svalue(U, T) ((void) 0)
8cbd552008-01-29Martin Stjernholm #define check_type(T) do {} while (0)
df86912008-03-29Martin Stjernholm #define check_svalue_type(S) do {} while (0)
8cbd552008-01-29Martin Stjernholm #define check_refs(S) do {} while (0) #define check_refs2(S,T) do {} while (0)
ed3dca2008-06-29Martin Stjernholm #define check_type_hint(SVALS, NUM, TYPE_HINT) ((void) 0)
ce6ab02000-07-04Martin Stjernholm #define dmalloc_check_svalue(S,L) (S)
e7f1322004-09-30Martin Stjernholm #define dmalloc_check_svalues(S,L,N) (S)
ce6ab02000-07-04Martin Stjernholm #define dmalloc_check_union(U,T,L) (U)
e83eb92001-03-22Fredrik Hübinette (Hubbe) 
7d269e2008-05-11Martin Stjernholm #define pass_array(A) (A) #define pass_mapping(M) (M) #define pass_multiset(L) (L) #define pass_object(O) (O) #define pass_program(P) (P) #define pass_string(S) (S) #define pass_type(T) (T) #define pass_callable(C) (C)
e5c2322003-04-28Martin Stjernholm #endif /* !PIKE_DEBUG */
5267b71995-08-09Fredrik Hübinette (Hubbe) 
1ab4ac2008-01-26Martin Stjernholm /* This marks an svalue as free. After this it may only be used as * input to the svalue free functions (which do nothing with it). Only * the type field is defined (see PIKE_T_FREE above). */ #define mark_free_svalue(X) do { \ struct svalue *_X__ = (X); \
df86912008-03-29Martin Stjernholm  DO_IF_DMALLOC ( \ _X__->u.loc = " " __FILE__ ":" DEFINETOSTR (__LINE__); \ _X__->u.loc++; /* Attempt to achieve an odd address. */ \ ); \
1ab4ac2008-01-26Martin Stjernholm  PIKE_MEM_WO(*_X__); \ _X__->type = PIKE_T_FREE; \ } while (0) /* This is a debug macro to assert that an svalue is free and * shouldn't be read at all until it's overwritten. As opposed to * mark_free_svalue, it is not valid input to the svalue free * functions and no field in it is defined. */ #define assert_free_svalue(X) do { \ DO_IF_DEBUG ( \ struct svalue *_X__ = (X); \ _X__->type = PIKE_T_UNKNOWN; \
df86912008-03-29Martin Stjernholm  DO_IF_DMALLOC ( \ _X__->u.loc = " " __FILE__ ":" DEFINETOSTR (__LINE__); \ _X__->u.loc++; /* Attempt to achieve an odd address. */ \ ); \ DO_IF_NOT_DMALLOC (_X__->u.ptr = (void *) -1); \
1ab4ac2008-01-26Martin Stjernholm  PIKE_MEM_WO (*_X__); \ ); \ } while (0)
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)
1ab4ac2008-01-26Martin Stjernholm /* Handles PIKE_T_FREE. */
aad99b2001-03-28Fredrik Hübinette (Hubbe) #define free_svalue_unlocked(X) do { \ struct svalue *_s=(X); \ assert_svalue_locked(_s); \
1ab4ac2008-01-26Martin Stjernholm  DO_IF_DEBUG ( \ if (_s->type != PIKE_T_FREE) { \
df86912008-03-29Martin Stjernholm  check_svalue_type(_s); \
1ab4ac2008-01-26Martin Stjernholm  check_refs(_s); \ } \ ); \
97a7332008-03-30Martin Stjernholm  if (_s->type > MAX_REF_TYPE) \
1ab4ac2008-01-26Martin Stjernholm  assert_free_svalue (_s); \
97a7332008-03-30Martin Stjernholm  else { \ DO_IF_DEBUG ( \ DO_IF_PIKE_CLEANUP ( \ if (gc_external_refs_zapped) \ gc_check_zapped (_s->u.ptr, _s->type, __FILE__, __LINE__))); \ if (sub_ref(_s->u.dummy) <=0) \ really_free_svalue(_s); \ else \ assert_free_svalue (_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) { \
97a7332008-03-30Martin Stjernholm  DO_IF_DEBUG ( \ DO_IF_PIKE_CLEANUP ( \ if (gc_external_refs_zapped) \ gc_check_zapped (_s->ptr, _t, __FILE__, __LINE__))); \
aad99b2001-03-28Fredrik Hübinette (Hubbe)  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)
1ab4ac2008-01-26Martin Stjernholm /* Handles PIKE_T_FREE. */
aad99b2001-03-28Fredrik Hübinette (Hubbe) #define add_ref_svalue_unlocked(X) do { \ struct svalue *_tmp=(X); \
1ab4ac2008-01-26Martin Stjernholm  DO_IF_DEBUG ( \ if (_tmp->type != PIKE_T_FREE) { \
df86912008-03-29Martin Stjernholm  check_svalue_type(_tmp); \
1ab4ac2008-01-26Martin Stjernholm  check_refs(_tmp); \ } \ ); \
aad99b2001-03-28Fredrik Hübinette (Hubbe)  if(_tmp->type <= MAX_REF_TYPE) add_ref(_tmp->u.dummy); \ }while(0)
1ab4ac2008-01-26Martin Stjernholm /* Handles PIKE_T_FREE. */
aad99b2001-03-28Fredrik Hübinette (Hubbe) #define assign_svalue_no_free_unlocked(X,Y) do { \
708d8d2001-04-28Martin Stjernholm  struct svalue *_to=(X); \
3cd7482001-04-28Martin Stjernholm  const struct svalue *_from=(Y); \
1ab4ac2008-01-26Martin Stjernholm  DO_IF_DEBUG ( \ if (_from->type != PIKE_T_FREE) { \
df86912008-03-29Martin Stjernholm  check_svalue_type(_from); \
1ab4ac2008-01-26Martin Stjernholm  check_refs(_from); \ } \ if (_to == _from) \ Pike_fatal(msg_assign_svalue_error, _to); \ ); \
bfeae62005-09-06Henrik Grubbström (Grubba)  *_to=*_from; \ if(_to->type <= MAX_REF_TYPE) add_ref(_to->u.dummy); \
aad99b2001-03-28Fredrik Hübinette (Hubbe) }while(0)
1ab4ac2008-01-26Martin Stjernholm /* Handles PIKE_T_FREE. */
aad99b2001-03-28Fredrik Hübinette (Hubbe) #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) 
1ab4ac2008-01-26Martin Stjernholm /* Handles PIKE_T_FREE. */
941cf22002-11-23Martin Stjernholm #define move_svalue(TO, FROM) do { \ struct svalue *_to = (TO); \ struct svalue *_from = (FROM); \ dmalloc_touch_svalue(_from); \ *_to = *_from; \
1ab4ac2008-01-26Martin Stjernholm  assert_free_svalue (_from); \
941cf22002-11-23Martin Stjernholm  } while (0)
1ab4ac2008-01-26Martin Stjernholm /* Handles PIKE_T_FREE. */
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_++); \ } \
31268a2003-05-13Martin Stjernholm }while(0)
2ac9502001-08-14Fredrik Hübinette (Hubbe) 
1ab4ac2008-01-26Martin Stjernholm /* Handles PIKE_T_FREE. */
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);
e5c2322003-04-28Martin Stjernholm PMOD_EXPORT TYPE_FIELD assign_svalues_no_free(struct svalue *to, const struct svalue *from, size_t num, TYPE_FIELD type_hint); PMOD_EXPORT TYPE_FIELD assign_svalues(struct svalue *to, const struct svalue *from, size_t num, TYPE_FIELD type_hint);
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);
f5971b2004-11-27Martin Stjernholm PMOD_EXPORT int is_le(const struct svalue *a, const struct svalue *b);
3cd7482001-04-28Martin Stjernholm PMOD_EXPORT void describe_svalue(const struct svalue *s,int indent,struct processing *p);
6a45bb2006-02-28Martin Stjernholm PMOD_EXPORT void safe_describe_svalue(const struct svalue *s,int indent,struct processing *p);
3cd7482001-04-28Martin Stjernholm PMOD_EXPORT void print_svalue (FILE *out, const struct svalue *s);
e6f6de2007-10-12Martin Stjernholm PMOD_EXPORT void safe_print_svalue (FILE *out, const struct svalue *s);
99cee92004-04-03Martin Stjernholm PMOD_EXPORT void print_short_svalue (FILE *out, const union anything *a, TYPE_T type);
e6f6de2007-10-12Martin Stjernholm PMOD_EXPORT void safe_print_short_svalue (FILE *out, const union anything *a, TYPE_T type);
3a5d8a2003-09-09Martin Stjernholm PMOD_EXPORT void print_svalue_compact (FILE *out, const struct svalue *s);
e6f6de2007-10-12Martin Stjernholm PMOD_EXPORT void safe_print_svalue_compact (FILE *out, const struct svalue *s);
99cee92004-04-03Martin Stjernholm PMOD_EXPORT void print_short_svalue_compact (FILE *out, const union anything *a, TYPE_T type);
e6f6de2007-10-12Martin Stjernholm PMOD_EXPORT void safe_print_short_svalue_compact (FILE *out, const union anything *a, TYPE_T type);
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void copy_svalues_recursively_no_free(struct svalue *to,
9cc28d2004-05-28Henrik Grubbström (Grubba)  const struct svalue *from, size_t num, struct mapping *m);
3cd7482001-04-28Martin Stjernholm 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) 
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
e7f1322004-09-30Martin Stjernholm #define gc_mark_external_svalues(S, NUM, PLACE) do { \ size_t num__ = (NUM); \ real_gc_mark_external_svalues ( \ dmalloc_check_svalues ((S), num__, DMALLOC_LOCATION()), num__, (PLACE)); \ } while (0) #define gc_check_svalues(S, NUM) do { \ size_t num__ = (NUM); \ real_gc_check_svalues ( \ dmalloc_check_svalues ((S), num__, DMALLOC_LOCATION()), num__); \ } while (0) #ifdef DEBUG_MALLOC static INLINE TYPE_FIELD dmalloc_gc_mark_svalues (struct svalue *s, size_t num, char *l) {return real_gc_mark_svalues (dmalloc_check_svalues (s, num, l), num);} #define gc_mark_svalues(S, NUM) dmalloc_gc_mark_svalues ((S), (NUM), DMALLOC_LOCATION()) static INLINE TYPE_FIELD dmalloc_gc_cycle_check_svalues (struct svalue *s, size_t num, char *l) {return real_gc_cycle_check_svalues (dmalloc_check_svalues (s, num, l), num);} #define gc_cycle_check_svalues(S, NUM) dmalloc_gc_cycle_check_svalues ((S), (NUM), DMALLOC_LOCATION()) #else #define gc_mark_svalues real_gc_mark_svalues #define gc_cycle_check_svalues real_gc_cycle_check_svalues #endif
433d5d2000-06-16Fredrik Hübinette (Hubbe) #define gc_check_short_svalue(U,T) real_gc_check_short_svalue(dmalloc_check_union((U),(T),DMALLOC_LOCATION()),T) #define gc_mark_short_svalue(U,T) real_gc_mark_short_svalue(dmalloc_check_union((U),(T),DMALLOC_LOCATION()),T) #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) 
0542ef1999-11-17Fredrik Hübinette (Hubbe) #ifndef NO_PIKE_SHORTHAND #define T_ARRAY PIKE_T_ARRAY #define T_MAPPING PIKE_T_MAPPING #define T_MULTISET PIKE_T_MULTISET #define T_OBJECT PIKE_T_OBJECT #define T_FUNCTION PIKE_T_FUNCTION #define T_PROGRAM PIKE_T_PROGRAM #define T_STRING PIKE_T_STRING
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
54a1302004-06-02Martin Nilsson static INLINE void free_svalue(struct svalue *s)
aad99b2001-03-28Fredrik Hübinette (Hubbe) { INT64 tmp; struct svalue zero; zero.type=PIKE_T_INT;
1ab4ac2008-01-26Martin Stjernholm  zero.subtype = NUMBER_NUMBER;
aad99b2001-03-28Fredrik Hübinette (Hubbe)  tmp=pike_atomic_swap64((INT64 *)s, *(INT64 *)&zero); free_svalue_unlocked((struct svalue *)&tmp); } #endif #ifndef free_short_svalue
54a1302004-06-02Martin Nilsson static INLINE void free_short_svalue(union anything *s, int t)
aad99b2001-03-28Fredrik Hübinette (Hubbe) { 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
54a1302004-06-02Martin Nilsson static INLINE void add_ref_svalue(struct svalue *s)
aad99b2001-03-28Fredrik Hübinette (Hubbe) { 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
54a1302004-06-02Martin Nilsson 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) 
3e130c2008-05-30Martin Stjernholm /* The following macro is useful to initialize static svalues. Note * that the value isn't always set. */ #ifdef HAVE_UNION_INIT
e371f52008-05-30Martin Stjernholm #define SVALUE_INIT(TYPE, SUBTYPE, VAL) {TYPE, SUBTYPE, {VAL}}
3e130c2008-05-30Martin Stjernholm #define SVALUE_INIT_INT(VAL) {T_INT, NUMBER_NUMBER, {VAL}} #define SVALUE_INIT_FREE {PIKE_T_FREE, NUMBER_NUMBER, {0}} #else
e371f52008-05-30Martin Stjernholm #define SVALUE_INIT(TYPE, SUBTYPE, VAL) {TYPE, SUBTYPE}
3e130c2008-05-30Martin Stjernholm #define SVALUE_INIT_INT(VAL) {T_INT, NUMBER_NUMBER} #define SVALUE_INIT_FREE {PIKE_T_FREE, NUMBER_NUMBER} #endif
538e811999-12-10Henrik Grubbström (Grubba) #endif /* !SVALUE_H */