Main Page | Class List | Directories | File List | Class Members | File Members

svalue.h

Go to the documentation of this file.
00001 /*
00002 || This file is part of Pike. For copyright information see COPYRIGHT.
00003 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
00004 || for more information.
00005 || $Id: svalue.h,v 1.134 2005/03/21 07:09:38 nilsson Exp $
00006 */
00007 
00008 #ifndef SVALUE_H
00009 #define SVALUE_H
00010 
00011 #include "global.h"
00012 
00013 #ifndef STRUCT_ARRAY_DECLARED
00014 #define STRUCT_ARRAY_DECLARED
00015 struct array;
00016 #endif
00017 
00018 #ifndef STRUCT_MAPPING_DECLARED
00019 #define STRUCT_MAPPING_DECLARED
00020 struct mapping;
00021 #endif
00022 
00023 #ifndef STRUCT_MULTISET_DECLARED
00024 #define STRUCT_MULTISET_DECLARED
00025 struct multiset;
00026 #endif
00027 
00028 #ifndef STRUCT_OBJECT_DECLARED
00029 #define STRUCT_OBJECT_DECLARED
00030 struct object;
00031 #endif
00032 
00033 #ifndef STRUCT_PROGRAM_DECLARED
00034 #define STRUCT_PROGRAM_DECLARED
00035 struct program;
00036 #endif
00037 
00038 #ifndef STRUCT_PIKE_STRING_DECLARED
00039 #define STRUCT_PIKE_STRING_DECLARED
00040 struct pike_string;
00041 #endif
00042 
00043 #ifndef STRUCT_CALLABLE_DECLARED
00044 #define STRUCT_CALLABLE_DECLARED
00045 struct callable;
00046 #endif
00047 
00048 #ifndef STRUCT_NODE_S_DECLARED
00049 #define STRUCT_NODE_S_DECLARED
00050 struct node_s;
00051 typedef struct node_s node;
00052 #endif
00053 
00054 struct processing
00055 {
00056   struct processing *next;
00057   void *pointer_a, *pointer_b;
00058 };
00059    
00060 struct ref_dummy;
00061 
00062 union anything
00063 {
00064   INT_TYPE integer;             /* Union initializations assume this first. */
00065   struct callable *efun;
00066   struct array *array;
00067   struct mapping *mapping;
00068   struct multiset *multiset;
00069   struct object *object;
00070   struct program *program;
00071   struct pike_string *string;
00072   struct pike_type *type;
00073   INT32 *refs;
00074   struct ref_dummy *dummy;
00075   FLOAT_TYPE float_number;
00076   int identifier;               /* Used with T_OBJ_INDEX. */
00077   struct svalue *lval;          /* Used with T_SVALUE_PTR. */
00078   void *ptr;
00079 };
00080 
00081 #ifndef STRUCT_SVALUE_DECLARED
00082 #define STRUCT_SVALUE_DECLARED
00083 #endif
00084 
00085 /* Note: At least multisets overlays the type field and uses the top 4
00086  * bits in it internally. */
00087 
00088 struct svalue
00089 {
00090   unsigned INT16 type;
00091   unsigned INT16 subtype;
00092   union anything u;
00093 };
00094 
00095 #define PIKE_T_ARRAY 0
00096 #define PIKE_T_MAPPING 1
00097 #define PIKE_T_MULTISET 2
00098 #define PIKE_T_OBJECT 3
00099 #define PIKE_T_FUNCTION 4
00100 #define PIKE_T_PROGRAM 5
00101 #define PIKE_T_STRING 6
00102 #define PIKE_T_TYPE 7
00103 #define PIKE_T_INT 8
00104 #define PIKE_T_FLOAT 9
00105 
00106 #define PIKE_T_ZERO  14 /* Can return 0, but nothing else */
00107 #define T_UNFINISHED 15
00108 
00109 #define T_VOID       16
00110 /* Can't return any value. Also used on stack to fill out the second
00111  * svalue on an lvalue when it isn't used. */
00112 
00113 #define T_MANY       17
00114 
00115 #define PIKE_T_RING 240
00116 #define PIKE_T_NAME 241         /* Named type. */
00117 #define PIKE_T_SCOPE 243        /* Not supported yet */
00118 #define PIKE_T_TUPLE 244        /* Not supported yet */
00119 #define T_ASSIGN 245
00120 #define T_DELETED 246
00121 #define PIKE_T_UNKNOWN 247
00122 
00123 #define T_OBJ_INDEX 248
00124 /* svalue.u.identifer is an identifier index in an object. Primarily
00125  * used in lvalues on stack. */
00126 
00127 #define T_SVALUE_PTR 249
00128 /* svalue.u.lval points to an svalue. Primarily used in lvalues on
00129  * stack. */
00130 
00131 #define T_ARRAY_LVALUE 250
00132 #define PIKE_T_MIXED 251
00133 #define T_NOT 253
00134 #define T_AND 254
00135 #define T_OR 255
00136 
00137 /* These are only used together with describe() and friends. */
00138 #define T_STORAGE 10000
00139 #define T_MAPPING_DATA 10001
00140 #define T_PIKE_FRAME 10002
00141 #define T_MULTISET_DATA 10003
00142 #define T_STRUCT_CALLABLE 10004
00143 
00144 #define tArr(VAL) "\000" VAL
00145 #define tArray tArr(tMix)
00146 #define tMap(IND,VAL) "\001" IND VAL
00147 #define tMapping tMap(tMix,tMix)
00148 #define tSet(IND) "\002" IND
00149 #define tMultiset tSet(tMix)
00150 #define tObj "\003\000\000\000\000\000"
00151 
00152 #define tFuncV(ARGS,REST,RET) MagictFuncV(RET,REST,ARGS)
00153 #define tFunc(ARGS,RET) MagictFunc(RET,ARGS)
00154 
00155 #define tTuple(T1,T2)           "\364" T1 T2
00156 #define tTriple(T1,T2,T3)       tTuple(T1, tTuple(T2, T3))
00157 #define tQuad(T1,T2,T3,T4)      tTriple(tTuple(T1, T2), T3, T4)
00158 
00159 /* These two magic funcions are used to make MSVC++ work
00160  * even if 'ARGS' is empty.
00161  */
00162 #define MagictFuncV(RET,REST,ARGS) "\004" ARGS "\021" REST RET
00163 #define MagictFunc(RET,ARGS) tFuncV(ARGS "", tVoid, RET)
00164 #define tFunction tFuncV("" ,tOr(tZero,tVoid),tOr(tMix,tVoid))
00165 #define tNone ""
00166 #define tPrg(X) "\005" X
00167 #define tProgram(X) "\005" X
00168 #define tStr "\006"
00169 #define tString "\006"
00170 #define tType(T) "\007" T
00171 #define tInt "\010\200\000\000\000\177\377\377\377"
00172 #define tInt0 "\010\000\000\000\000\000\000\000\000"
00173 #define tInt1 "\010\000\000\000\001\000\000\000\001"
00174 #define tInt2 "\010\000\000\000\002\000\000\000\002"
00175 #define tInt01 "\010\000\000\000\000\000\000\000\001"
00176 #define tInt02 "\010\000\000\000\000\000\000\000\002"
00177 #define tInt03 "\010\000\000\000\000\000\000\000\003"
00178 #define tInt04 "\010\000\000\000\000\000\000\000\004"
00179 #define tInt05 "\010\000\000\000\000\000\000\000\005"
00180 #define tInt06 "\010\000\000\000\000\000\000\000\006"
00181 #define tIntPos "\010\000\000\000\000\177\377\377\377"
00182 #define tInt1Plus "\010\000\000\000\001\177\377\377\377"
00183 #define tInt2Plus "\010\000\000\000\002\177\377\377\377"
00184 #define tInt_10 "\010\377\377\377\377\000\000\000\000"
00185 #define tInt_11 "\010\377\377\377\377\000\000\000\001"
00186 #define tByte "\010\000\000\000\000\000\000\000\377"
00187 #define tFlt "\011"
00188 #define tFloat "\011"
00189 
00190 #define tZero "\016"
00191 #define tVoid "\020"
00192 #define tVar(X) #X
00193 #define tSetvar(X,Y) "\365" #X Y
00194 #define tScope(X,T) "\363" #X Y
00195 #define tNot(X) "\375" X
00196 #define tAnd(X,Y) "\376" X Y
00197 #define tOr(X,Y) "\377" X Y
00198 #define tOr3(X,Y,Z) tOr(X,tOr(Y,Z))
00199 #define tOr4(X,Y,Z,A) tOr(X,tOr(Y,tOr(Z,A)))
00200 #define tOr5(X,Y,Z,A,B) tOr(X,tOr(Y,tOr(Z,tOr(A,B))))
00201 #define tOr6(X,Y,Z,A,B,C) tOr(X,tOr(Y,tOr(Z,tOr(A,tOr(B,C)))))
00202 #define tOr7(X,Y,Z,A,B,C,D) tOr(X,tOr(Y,tOr(Z,tOr(A,tOr(B,tOr(C,D))))))
00203 #define tOr8(A,B,C,D,E,F,G,H) tOr(A,tOr7(B,C,D,E,F,G,H))
00204 #define tOr9(A,B,C,D,E,F,G,H,I) tOr(A,tOr8(B,C,D,E,F,G,H,I))
00205 #define tMix "\373"
00206 #define tMixed "\373"
00207 #define tComplex tOr6(tArray,tMapping,tMultiset,tObj,tFunction,tPrg(tObj))
00208 #define tStringIndicable tOr5(tMapping,tObj,tFunction,tPrg(tObj),tMultiset)
00209 #define tRef tOr(tString,tComplex)
00210 #define tIfnot(X,Y) tAnd(tNot(X),Y)
00211 #define tAny tOr(tVoid,tMix)
00212 #define tName(X,Y) "\361\0"X"\0"Y
00213 #if PIKE_BYTEORDER == 1234
00214 /* Little endian */
00215 #define tName1(X,Y) "\361\5"X"\0\0"Y
00216 #define tName2(X,Y) "\361\6"X"\0\0\0\0"Y
00217 #else /* PIKE_BYTEORDER != 1234 */
00218 /* Big endian */
00219 #define tName1(X,Y) "\361\1"X"\0\0"Y
00220 #define tName2(X,Y) "\361\2"X"\0\0\0\0"Y
00221 #endif /* PIKE_BYTEORDER == 1234 */
00222 
00223 #define tSimpleCallable tOr3(tArray,tFunction,tObj)
00224 #define tCallable tOr3(tArr(tSimpleCallable),tFunction,tObj)
00225 
00226 #define BIT_ARRAY (1<<PIKE_T_ARRAY)
00227 #define BIT_MAPPING (1<<PIKE_T_MAPPING)
00228 #define BIT_MULTISET (1<<PIKE_T_MULTISET)
00229 #define BIT_OBJECT (1<<PIKE_T_OBJECT)
00230 #define BIT_FUNCTION (1<<PIKE_T_FUNCTION)
00231 #define BIT_PROGRAM (1<<PIKE_T_PROGRAM)
00232 #define BIT_STRING (1<<PIKE_T_STRING)
00233 #define BIT_TYPE (1<<PIKE_T_TYPE)
00234 #define BIT_INT (1<<PIKE_T_INT)
00235 #define BIT_FLOAT (1<<PIKE_T_FLOAT)
00236 
00237 #define BIT_ZERO (1<<PIKE_T_ZERO)
00238 
00239 /* Used to signify that the type field hasn't been set according to
00240  * reality. */
00241 #define BIT_UNFINISHED (1 << T_UNFINISHED)
00242 
00243 /* This is only used in typechecking to signify that this 
00244  * argument may be omitted.
00245  */
00246 #define BIT_VOID (1 << T_VOID)
00247 
00248 /* This is used in typechecking to signify that the rest of the
00249  * arguments has to be of this type.
00250  */
00251 #define BIT_MANY (1 << T_MANY)
00252 
00253 #define BIT_NOTHING 0
00254 #define BIT_MIXED 0x7fff
00255 #define BIT_BASIC (BIT_INT|BIT_FLOAT|BIT_STRING|BIT_TYPE)
00256 #define BIT_COMPLEX (BIT_ARRAY|BIT_MULTISET|BIT_OBJECT|BIT_PROGRAM|BIT_MAPPING|BIT_FUNCTION)
00257 #define BIT_CALLABLE (BIT_FUNCTION|BIT_PROGRAM|BIT_ARRAY|BIT_OBJECT)
00258 #define BIT_REF_TYPES (BIT_STRING|BIT_TYPE|BIT_COMPLEX)
00259 
00260 /* Max type which contains svalues */
00261 #define MAX_COMPLEX PIKE_T_PROGRAM
00262 /* Max type with ref count */
00263 #define MAX_REF_TYPE PIKE_T_TYPE
00264 /* Max type handled by svalue primitives */
00265 #define MAX_TYPE PIKE_T_FLOAT
00266 
00267 #define NUMBER_NUMBER 0
00268 #define NUMBER_UNDEFINED 1
00269 #define NUMBER_DESTRUCTED 2
00270 
00271 #define FUNCTION_BUILTIN USHRT_MAX
00272 
00273 #define is_gt(a,b) is_lt(b,a)
00274 #define is_ge(a,b) is_le(b,a)
00275 
00276 /* SAFE_IS_ZERO is compatible with the old IS_ZERO, but you should
00277  * consider using UNSAFE_IS_ZERO instead, since exceptions thrown from
00278  * `! functions will be propagated correctly then. */
00279 #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)
00280 #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)
00281 
00282 #define IS_UNDEFINED(X) ((X)->type==PIKE_T_INT&&!(X)->u.integer&&(X)->subtype==1)
00283 
00284 #define IS_DESTRUCTED(X) \
00285   (((X)->type == PIKE_T_OBJECT || (X)->type==PIKE_T_FUNCTION) && !(X)->u.object->prog)
00286 
00287 #define check_destructed(S) \
00288 do{ \
00289   struct svalue *_s=(S); \
00290   if(IS_DESTRUCTED(_s)) { \
00291     free_object(_s->u.object); \
00292     _s->type = PIKE_T_INT; \
00293     _s->subtype = NUMBER_DESTRUCTED ; \
00294     _s->u.integer = 0; \
00295   } \
00296 }while(0)
00297 
00298 /* var MUST be a variable!!! */
00299 #define safe_check_destructed(var) do{ \
00300   if((var->type == PIKE_T_OBJECT || var->type==PIKE_T_FUNCTION) && !var->u.object->prog) \
00301     var=&dest_ob_zero; \
00302 }while(0)
00303 
00304 #define check_short_destructed(U,T) \
00305 do{ \
00306   union anything *_u=(U); \
00307   if(( (1<<(T)) & (BIT_OBJECT | BIT_FUNCTION) ) && \
00308      _u->object && !_u->object->prog) { \
00309     free_object(_u->object); \
00310     _u->object = 0; \
00311   } \
00312 }while(0)
00313 
00314 
00315 #ifdef PIKE_RUN_UNLOCKED
00316 #define add_ref(X) pike_atomic_inc32(&(X)->refs)
00317 #define sub_ref(X) pike_atomic_dec_and_test32(&(X)->refs)
00318 
00319 #if 0
00320 #define IF_LOCAL_MUTEX(X) X
00321 #define USE_LOCAL_MUTEX
00322 #define pike_lock_data(X) mt_lock(&(X)->mutex)
00323 #define pike_unlock_data(X) mt_unlock(&(X)->mutex)
00324 #else
00325 #define IF_LOCAL_MUTEX(X)
00326 #define pike_lock_data(X) pike_lockmem((X))
00327 #define pike_unlock_data(X) pike_unlockmem((X))
00328 #endif
00329 
00330 #else
00331 #define IF_LOCAL_MUTEX(X)
00332 #define add_ref(X) (void)((X)->refs++)
00333 #define sub_ref(X) (--(X)->refs > 0)
00334 #define pike_lock_data(X) (void)(X)
00335 #define pike_unlock_data(X) (void)(X)
00336 #endif
00337 
00338 
00339 #ifdef PIKE_DEBUG
00340 PMOD_EXPORT extern void describe(void *); /* defined in gc.c */
00341 PMOD_EXPORT extern const char msg_type_error[];
00342 #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)
00343 
00344 #define check_svalue(S) debug_check_svalue(dmalloc_check_svalue(S,DMALLOC_LOCATION()))
00345 
00346 void low_thorough_check_short_svalue (const union anything *u, TYPE_T type);
00347 #define thorough_check_short_svalue(U, T) do {                          \
00348     union anything *anyth_ = (U);                                       \
00349     TYPE_T typ_ = (T);                                                  \
00350     check_short_svalue (anyth_, typ_);                                  \
00351     if (d_flag <= 50) /* Done directly by check_svalue otherwise. */    \
00352       if (typ_ <= MAX_REF_TYPE)                                         \
00353         low_thorough_check_short_svalue (anyth_, typ_);                 \
00354   } while (0)
00355 #define thorough_check_svalue(S) do {                                   \
00356     struct svalue *sval_ = (S);                                         \
00357     check_svalue (sval_);                                               \
00358     if (d_flag <= 50) /* Done directly by check_svalue otherwise. */    \
00359       if (sval_->type <= MAX_REF_TYPE)                                  \
00360         low_thorough_check_short_svalue (&sval_->u, sval_->type);       \
00361   } while (0)
00362 
00363 PMOD_EXPORT extern const char msg_sval_obj_wo_refs[];
00364 #define check_refs(S) do {\
00365  if((S)->type <= MAX_REF_TYPE && (!(S)->u.refs || (S)->u.refs[0] < 0)) { \
00366    fprintf (stderr, msg_sval_obj_wo_refs);                              \
00367    describe((S)->u.refs);                                               \
00368    Pike_fatal(msg_sval_obj_wo_refs);                                    \
00369  } }while(0)
00370 
00371 PMOD_EXPORT extern const char msg_ssval_obj_wo_refs[];
00372 #define check_refs2(S,T) do { \
00373 if((T) <= MAX_REF_TYPE && (S)->refs && (S)->refs[0] <= 0) {\
00374   fprintf (stderr, msg_ssval_obj_wo_refs);                 \
00375   describe((S)->refs);                                     \
00376   Pike_fatal(msg_ssval_obj_wo_refs);                       \
00377 } }while(0)
00378 
00379 #define check_type_hint(SVALS, NUM, TYPE_HINT)                          \
00380   debug_check_type_hint ((SVALS), (NUM), (TYPE_HINT))
00381 
00382 #ifdef DEBUG_MALLOC
00383 static INLINE struct svalue *dmalloc_check_svalue(struct svalue *s, char *l)
00384 {
00385 #if 0
00386   /* What's this supposed to accomplish? Dmalloc tracks memory blocks,
00387    * not single svalues that point to them. /mast */
00388   debug_malloc_update_location(s,l);
00389 #endif
00390 #if 1
00391   if(s && s->type <= MAX_REF_TYPE)
00392     debug_malloc_update_location(s->u.refs,l);
00393 #endif
00394   return s;
00395 }
00396 
00397 static INLINE struct svalue *dmalloc_check_svalues(struct svalue *s, size_t num, char *l)
00398 {
00399   while (num--) dmalloc_check_svalue (s + num, l);
00400   return s;
00401 }
00402 
00403 static INLINE union anything *dmalloc_check_union(union anything *u,int type, char * l)
00404 {
00405 #if 0
00406   debug_malloc_update_location(u,l);
00407 #endif
00408 #if 1
00409   if(u && type <= MAX_REF_TYPE)
00410     debug_malloc_update_location(u->refs,l);
00411 #endif
00412   return u;
00413 }
00414 
00415 #undef add_ref
00416 #undef sub_ref
00417 
00418 #ifdef PIKE_RUN_UNLOCKED
00419 #define add_ref(X) pike_atomic_inc32((INT32 *)debug_malloc_update_location( &((X)->refs), DMALLOC_NAMED_LOCATION(" add_ref")))
00420 #define sub_ref(X) pike_atomic_dec_and_test32((INT32 *)debug_malloc_update_location( &((X)->refs), DMALLOC_NAMED_LOCATION(" sub_ref")))
00421 #else
00422 #define add_ref(X) (((INT32 *)debug_malloc_update_location( &((X)->refs), DMALLOC_NAMED_LOCATION(" add_ref")))[0]++)
00423 #define sub_ref(X) (--((INT32 *)debug_malloc_update_location( &((X)->refs), DMALLOC_NAMED_LOCATION(" sub_ref")))[0] > 0)
00424 #endif
00425 
00426 
00427 #else
00428 #define dmalloc_check_svalue(S,L) (S)
00429 #define dmalloc_check_svalues(S,L,N) (S)
00430 #define dmalloc_check_union(U,T,L) (U)
00431 
00432 #endif
00433 
00434 #else  /* !PIKE_DEBUG */
00435 
00436 #define check_svalue(S)
00437 #define check_type(T)
00438 #define check_refs(S)
00439 #define check_refs2(S,T)
00440 #define check_type_hint(SVALS, NUM, TYPE_HINT)
00441 #define dmalloc_check_svalue(S,L) (S)
00442 #define dmalloc_check_svalues(S,L,N) (S)
00443 #define dmalloc_check_union(U,T,L) (U)
00444 
00445 #endif  /* !PIKE_DEBUG */
00446 
00447 
00448 /* This define
00449  * should check that the svalue address (X) is on the local stack,
00450  * the processor stack or in a locked memory object
00451  *
00452  * Or, it could just try to make sure it's not in an unlocked memory
00453  * object...
00454  */
00455 #define assert_svalue_locked(X)
00456 
00457 
00458 #define swap_svalues_unlocked(X,Y)  do {                \
00459   struct svalue *_a=(X);                                \
00460   struct svalue *_b=(Y);                                \
00461   struct svalue _tmp;                                   \
00462   assert_svalue_locked(_a); assert_svalue_locked(_b);   \
00463   dmalloc_touch_svalue(_a);                             \
00464   dmalloc_touch_svalue(_b);                             \
00465   _tmp=*_a; *_a=*_b; *_b=_tmp;                          \
00466 }while(0)
00467 
00468 #define free_svalue_unlocked(X) do {                            \
00469   struct svalue *_s=(X);                                        \
00470   assert_svalue_locked(_s);                                     \
00471   check_type(_s->type); check_refs(_s);                         \
00472   if(_s->type<=MAX_REF_TYPE) {                                  \
00473     if(sub_ref(_s->u.dummy) <=0) { really_free_svalue(_s); }    \
00474   }                                                             \
00475   DO_IF_DMALLOC(_s->type=PIKE_T_UNKNOWN;_s->u.refs=(void *)-1); \
00476   PIKE_MEM_WO(*_s);                                             \
00477 }while(0)
00478 
00479 #define free_short_svalue_unlocked(X,T) do {                            \
00480   union anything *_s=(X); TYPE_T _t=(T);                                \
00481   check_type(_t); check_refs2(_s,_t);                                   \
00482   assert_svalue_locked(_s);                                             \
00483   if(_t<=MAX_REF_TYPE && _s->refs) {                                    \
00484     if(sub_ref(_s->dummy) <= 0) really_free_short_svalue(_s,_t);        \
00485   }                                                                     \
00486   DO_IF_DMALLOC(_s->refs=(void *)-1);                                   \
00487   PIKE_MEM_WO(_s->refs);                                                \
00488 }while(0)
00489 
00490 #define add_ref_svalue_unlocked(X) do {                         \
00491   struct svalue *_tmp=(X);                                      \
00492   check_type(_tmp->type); check_refs(_tmp);                     \
00493   if(_tmp->type <= MAX_REF_TYPE) add_ref(_tmp->u.dummy);        \
00494 }while(0)
00495 
00496 #define assign_svalue_no_free_unlocked(X,Y) do {        \
00497   struct svalue _tmp;                                   \
00498   struct svalue *_to=(X);                               \
00499   const struct svalue *_from=(Y);                       \
00500   check_type(_from->type); check_refs(_from);           \
00501   *_to=_tmp=*_from;                                     \
00502   if(_tmp.type <= MAX_REF_TYPE) add_ref(_tmp.u.dummy);  \
00503 }while(0)
00504 
00505 #define assign_svalue_unlocked(X,Y) do {        \
00506   struct svalue *_to2=(X);                      \
00507   const struct svalue *_from2=(Y);              \
00508   if (_to2 != _from2) {                         \
00509     free_svalue(_to2);                          \
00510      assign_svalue_no_free(_to2, _from2);       \
00511   }                                             \
00512 }while(0)
00513 
00514 #define move_svalue(TO, FROM) do {                                      \
00515     struct svalue *_to = (TO);                                          \
00516     struct svalue *_from = (FROM);                                      \
00517     dmalloc_touch_svalue(_from);                                        \
00518     *_to = *_from;                                                      \
00519     DO_IF_DMALLOC(_from->type = PIKE_T_UNKNOWN; _from->u.refs = (void *) -1); \
00520     PIKE_MEM_WO(*_from);                                                \
00521   } while (0)
00522 
00523 extern const struct svalue dest_ob_zero;
00524 
00525 #define free_mixed_svalues(X,Y) do {            \
00526   struct svalue *s_=(X);                        \
00527   ptrdiff_t num_=(Y);                           \
00528   while(num_--)                                 \
00529   {                                             \
00530     dmalloc_touch_svalue(s_);                   \
00531     free_svalue(s_++);                          \
00532   }                                             \
00533 }while(0)
00534 
00535 #ifdef DEBUG_MALLOC
00536 #define free_svalues(X,Y,Z) debug_free_svalues((X),(Y),(Z), DMALLOC_NAMED_LOCATION(" free_svalues"));
00537 #else
00538 #define free_svalues(X,Y,Z) debug_free_svalues((X),(Y),(Z));
00539 #endif
00540 
00541 #define low_clear_svalues(X,Y,N) do {           \
00542   struct svalue *s_=(X);                        \
00543   ptrdiff_t num_=(Y);                           \
00544   for(;num_-- > 0;s_++)                         \
00545   {                                             \
00546       s_->type=PIKE_T_INT;                      \
00547       s_->subtype=(N);                          \
00548       s_->u.integer=0;                          \
00549   }                                             \
00550 }while(0)
00551 
00552 #define clear_svalues(X,Y) low_clear_svalues((X),(Y),NUMBER_NUMBER)
00553 #define clear_svalues_undefined(X,Y) low_clear_svalues((X),(Y),NUMBER_UNDEFINED)
00554 
00555 #define really_free_short_svalue(U, TYPE) do {                          \
00556     union anything *any_ = (U);                                         \
00557     debug_malloc_touch (any_->ptr);                                     \
00558     really_free_short_svalue_ptr (&any_->ptr, (TYPE));                  \
00559   } while (0)
00560 
00561 /* Prototypes begin here */
00562 PMOD_EXPORT void really_free_short_svalue_ptr(void **s, TYPE_T type);
00563 PMOD_EXPORT void really_free_svalue(struct svalue *s);
00564 PMOD_EXPORT void do_free_svalue(struct svalue *s);
00565 PMOD_EXPORT void debug_free_svalues(struct svalue *s, size_t num, INT32 type_hint DMALLOC_LINE_ARGS);
00566 PMOD_EXPORT void debug_free_mixed_svalues(struct svalue *s, size_t num, INT32 type_hint DMALLOC_LINE_ARGS);
00567 PMOD_EXPORT TYPE_FIELD assign_svalues_no_free(struct svalue *to,
00568                                               const struct svalue *from,
00569                                               size_t num,
00570                                               TYPE_FIELD type_hint);
00571 PMOD_EXPORT TYPE_FIELD assign_svalues(struct svalue *to,
00572                                       const struct svalue *from,
00573                                       size_t num,
00574                                       TYPE_FIELD type_hint);
00575 PMOD_EXPORT void assign_to_short_svalue(union anything *u,
00576                             TYPE_T type,
00577                             const struct svalue *s);
00578 PMOD_EXPORT void assign_to_short_svalue_no_free(union anything *u,
00579                                     TYPE_T type,
00580                                     const struct svalue *s);
00581 PMOD_EXPORT void assign_from_short_svalue_no_free(struct svalue *s,
00582                                       const union anything *u,
00583                                       TYPE_T type);
00584 PMOD_EXPORT void assign_short_svalue_no_free(union anything *to,
00585                                  const union anything *from,
00586                                  TYPE_T type);
00587 PMOD_EXPORT void assign_short_svalue(union anything *to,
00588                          const union anything *from,
00589                          TYPE_T type);
00590 PMOD_EXPORT unsigned INT32 hash_svalue(const struct svalue *s);
00591 PMOD_EXPORT int svalue_is_true(const struct svalue *s);
00592 PMOD_EXPORT int safe_svalue_is_true(const struct svalue *s);
00593 PMOD_EXPORT int is_identical(const struct svalue *a, const struct svalue *b);
00594 PMOD_EXPORT int is_eq(const struct svalue *a, const struct svalue *b);
00595 PMOD_EXPORT int low_is_equal(const struct svalue *a,
00596                  const struct svalue *b,
00597                  struct processing *p);
00598 PMOD_EXPORT int low_short_is_equal(const union anything *a,
00599                        const union anything *b,
00600                        TYPE_T type,
00601                        struct processing *p);
00602 PMOD_EXPORT int is_equal(const struct svalue *a, const struct svalue *b);
00603 PMOD_EXPORT int is_lt(const struct svalue *a, const struct svalue *b);
00604 PMOD_EXPORT int is_le(const struct svalue *a, const struct svalue *b);
00605 PMOD_EXPORT void describe_svalue(const struct svalue *s,int indent,struct processing *p);
00606 PMOD_EXPORT void print_svalue (FILE *out, const struct svalue *s);
00607 PMOD_EXPORT void print_short_svalue (FILE *out, const union anything *a, TYPE_T type);
00608 PMOD_EXPORT void print_svalue_compact (FILE *out, const struct svalue *s);
00609 PMOD_EXPORT void print_short_svalue_compact (FILE *out, const union anything *a, TYPE_T type);
00610 PMOD_EXPORT void copy_svalues_recursively_no_free(struct svalue *to,
00611                                                   const struct svalue *from,
00612                                                   size_t num,
00613                                                   struct mapping *m);
00614 void check_short_svalue(const union anything *u, TYPE_T type);
00615 void debug_check_svalue(const struct svalue *s);
00616 void debug_check_type_hint (const struct svalue *svals, size_t num, TYPE_FIELD type_hint);
00617 PMOD_EXPORT void real_gc_mark_external_svalues(const struct svalue *s, ptrdiff_t num,
00618                                                const char *place);
00619 PMOD_EXPORT void real_gc_check_svalues(const struct svalue *s, size_t num);
00620 void gc_check_weak_svalues(const struct svalue *s, size_t num);
00621 PMOD_EXPORT void real_gc_check_short_svalue(const union anything *u, TYPE_T type);
00622 void gc_check_weak_short_svalue(const union anything *u, TYPE_T type);
00623 PMOD_EXPORT TYPE_FIELD real_gc_mark_svalues(struct svalue *s, size_t num);
00624 TYPE_FIELD gc_mark_weak_svalues(struct svalue *s, size_t num);
00625 int real_gc_mark_short_svalue(union anything *u, TYPE_T type);
00626 int gc_mark_weak_short_svalue(union anything *u, TYPE_T type);
00627 int gc_mark_without_recurse(struct svalue *s);
00628 int gc_mark_weak_without_recurse(struct svalue *s);
00629 PMOD_EXPORT TYPE_FIELD real_gc_cycle_check_svalues(struct svalue *s, size_t num);
00630 TYPE_FIELD gc_cycle_check_weak_svalues(struct svalue *s, size_t num);
00631 PMOD_EXPORT int real_gc_cycle_check_short_svalue(union anything *u, TYPE_T type);
00632 int gc_cycle_check_weak_short_svalue(union anything *u, TYPE_T type);
00633 void real_gc_free_svalue(struct svalue *s);
00634 void real_gc_free_short_svalue(union anything *u, TYPE_T type);
00635 PMOD_EXPORT INT32 pike_sizeof(const struct svalue *s);
00636 int svalues_are_constant(struct svalue *s,
00637                          INT32 num,
00638                          TYPE_FIELD hint,
00639                          struct processing *p);
00640 /* Prototypes end here */
00641 
00642 #define gc_cycle_check_without_recurse gc_mark_without_recurse
00643 #define gc_cycle_check_weak_without_recurse gc_mark_without_recurse
00644 
00645 #define gc_mark_external_svalues(S, NUM, PLACE) do {                    \
00646     size_t num__ = (NUM);                                               \
00647     real_gc_mark_external_svalues (                                     \
00648       dmalloc_check_svalues ((S), num__, DMALLOC_LOCATION()), num__, (PLACE)); \
00649   } while (0)
00650 #define gc_check_svalues(S, NUM) do {                                   \
00651     size_t num__ = (NUM);                                               \
00652     real_gc_check_svalues (                                             \
00653       dmalloc_check_svalues ((S), num__, DMALLOC_LOCATION()), num__);   \
00654   } while (0)
00655 
00656 #ifdef DEBUG_MALLOC
00657 static INLINE TYPE_FIELD dmalloc_gc_mark_svalues (struct svalue *s, size_t num, char *l)
00658   {return real_gc_mark_svalues (dmalloc_check_svalues (s, num, l), num);}
00659 #define gc_mark_svalues(S, NUM) dmalloc_gc_mark_svalues ((S), (NUM), DMALLOC_LOCATION())
00660 static INLINE TYPE_FIELD dmalloc_gc_cycle_check_svalues (struct svalue *s, size_t num, char *l)
00661   {return real_gc_cycle_check_svalues (dmalloc_check_svalues (s, num, l), num);}
00662 #define gc_cycle_check_svalues(S, NUM) dmalloc_gc_cycle_check_svalues ((S), (NUM), DMALLOC_LOCATION())
00663 #else
00664 #define gc_mark_svalues real_gc_mark_svalues
00665 #define gc_cycle_check_svalues real_gc_cycle_check_svalues
00666 #endif
00667 
00668 #define gc_check_short_svalue(U,T) real_gc_check_short_svalue(dmalloc_check_union((U),(T),DMALLOC_LOCATION()),T)
00669 #define gc_mark_short_svalue(U,T) real_gc_mark_short_svalue(dmalloc_check_union((U),(T),DMALLOC_LOCATION()),T)
00670 #define gc_cycle_check_short_svalue(U,T) real_gc_cycle_check_short_svalue(dmalloc_check_union((U),(T),DMALLOC_LOCATION()),(T))
00671 #define gc_free_svalue(S) real_gc_free_svalue(dmalloc_check_svalue(S,DMALLOC_LOCATION()))
00672 #define gc_free_short_svalue(U,T) real_gc_free_short_svalue(dmalloc_check_union((U),(T),DMALLOC_LOCATION()),(T))
00673 
00674 #ifndef NO_PIKE_SHORTHAND
00675 
00676 #define T_ARRAY    PIKE_T_ARRAY
00677 #define T_MAPPING  PIKE_T_MAPPING
00678 #define T_MULTISET PIKE_T_MULTISET
00679 #define T_OBJECT   PIKE_T_OBJECT
00680 #define T_FUNCTION PIKE_T_FUNCTION
00681 #define T_PROGRAM  PIKE_T_PROGRAM
00682 #define T_STRING   PIKE_T_STRING
00683 #define T_TYPE     PIKE_T_TYPE
00684 #define T_FLOAT    PIKE_T_FLOAT
00685 #define T_INT      PIKE_T_INT
00686 
00687 #define T_ZERO     PIKE_T_ZERO
00688 
00689 #define T_TUPLE    PIKE_T_TUPLE
00690 #define T_SCOPE    PIKE_T_SCOPE
00691 #define T_MIXED    PIKE_T_MIXED
00692 
00693 #endif /* !NO_PIKE_SHORTHAND */
00694 
00695 #if 0 /* PIKE_RUN_UNLOCKED */
00696 
00697 #include "pike_error.h"
00698 
00699 /*#define swap_svalues swap_svalues*/
00700 /*#define free_svalue free_svalue_unlocked*/
00701 /*#define free_short_svalue free_short_svalue_unlocked */
00702 /*#define add_ref_svalue add_ref_svalue_unlocked*/
00703 
00704 /*
00705  * These don't work right now - Hubbe
00706  */
00707 #define assign_svalue_no_free assign_svalue_no_free_unlocked
00708 #define assign_svalue assign_svalue_unlocked
00709 
00710 /* FIXME:
00711  * These routines assumes that pointers are 32 bit
00712  * and svalues 64 bit!!!!! - Hubbe
00713  */
00714 
00715 #ifndef swap_svalues 
00716 #define swap_svalues swap_svalues_unlocked
00717 #endif
00718 
00719 #ifndef free_svalue
00720 static INLINE void free_svalue(struct svalue *s)
00721 {
00722   INT64 tmp;
00723   struct svalue zero;
00724   zero.type=PIKE_T_INT;
00725   tmp=pike_atomic_swap64((INT64 *)s, *(INT64 *)&zero);
00726   free_svalue_unlocked((struct svalue *)&tmp);
00727 }
00728 #endif
00729 
00730 #ifndef free_short_svalue
00731 static INLINE void free_short_svalue(union anything *s, int t)
00732 {
00733   if(t <= MAX_REF_TYPE)
00734   {
00735     INT32 tmp;
00736     tmp=pike_atomic_swap32((INT32 *)s, 0);
00737     free_short_svalue_unlocked((union anything *)&tmp, t);
00738   }
00739 }
00740 #endif
00741 
00742 #ifndef add_ref_svalue
00743 static INLINE void add_ref_svalue(struct svalue *s)
00744 {
00745   INT64 sv;
00746   sv=pike_atomic_get64((INT64 *)s);
00747   add_ref_svalue_unlocked((struct svalue *)&sv);
00748 }
00749 #endif
00750 
00751 #ifndef assign_svalue_no_free
00752 void assign_svalue_no_free(struct svalue *to, const struct svalue *from)
00753 {
00754   INT64 tmp, sv;
00755   sv=pike_atomic_get64((INT64 *)from);
00756 #ifdef PIKE_DEBUG
00757   if(sv != *(INT64*)from)
00758   {
00759     fprintf(stderr,"pike_atomic_get64() is broken %llx != %llx (%08x%08x)!\n",
00760             sv,
00761             *(INT64*)from,
00762             ((INT32*)from)[1], ((INT32*)from)[0]);
00763     abort();
00764   }
00765 #endif
00766   add_ref_svalue_unlocked((struct svalue *)&sv);
00767   pike_atomic_set64((INT64 *)to, sv);
00768 #ifdef PIKE_DEBUG
00769   if(*(INT64*)to != *(INT64*)from)
00770   {
00771     fprintf(stderr,"pike_atomic_set64() is broken!\n");
00772     abort();
00773   }
00774 #endif
00775 }
00776 #endif
00777 
00778 #ifndef assign_svalue
00779 static INLINE void assign_svalue(struct svalue *to, const struct svalue *from)
00780 {
00781   INT64 tmp, sv;
00782   if(to != from)
00783   {
00784     sv=pike_atomic_get64((INT64 *)from);
00785     add_ref_svalue_unlocked((struct svalue *)&sv);
00786     tmp=pike_atomic_swap64((INT64 *)to, sv);
00787     free_svalue_unlocked((struct svalue *)&tmp);
00788   }
00789 }
00790 #endif
00791 
00792 #else /* FOO_PIKE_RUN_UNLOCKED */
00793 #define swap_svalues swap_svalues
00794 #define free_svalue free_svalue_unlocked
00795 #define free_short_svalue free_short_svalue_unlocked 
00796 #define add_ref_svalue add_ref_svalue_unlocked
00797 #define assign_svalue_no_free assign_svalue_no_free_unlocked
00798 #define assign_svalue assign_svalue_unlocked
00799 #endif /* FOO_PIKE_RUN_UNLOCKED */
00800 
00801 #ifdef PIKE_RUN_UNLOCKED
00802 #include "pike_threadlib.h"
00803 #endif
00804 
00805 /* 
00806  * Note to self:
00807  * It might be better to use a static array of mutexes instead
00808  * and just lock mutex ptr % array_size instead.
00809  * That way I wouldn't need a mutex in each memory object,
00810  * but it would cost a couple of cycles in every lock/unlock
00811  * operation instead.
00812  */
00813 #define PIKE_MEMORY_OBJECT_MEMBERS \
00814   INT32 refs \
00815   DO_IF_SECURITY(; struct object *prot) \
00816   IF_LOCAL_MUTEX(; PIKE_MUTEX_T mutex)
00817 
00818 #ifdef PIKE_SECURITY
00819 #ifdef USE_LOCAL_MUTEX
00820 #define PIKE_CONSTANT_MEMOBJ_INIT(refs) refs, 0, PTHREAD_MUTEX_INITIALIZER
00821 #else
00822 #define PIKE_CONSTANT_MEMOBJ_INIT(refs) refs, 0
00823 #endif
00824 #else
00825 #ifdef USE_LOCAL_MUTEX
00826 #define PIKE_CONSTANT_MEMOBJ_INIT(refs) refs, PTHREAD_MUTEX_INITIALIZER
00827 #else
00828 #define PIKE_CONSTANT_MEMOBJ_INIT(refs) refs
00829 #endif
00830 #endif
00831 
00832 #define INIT_PIKE_MEMOBJ(X) do {                        \
00833   struct ref_dummy *v_=(struct ref_dummy *)(X);         \
00834   v_->refs=0;                                           \
00835   add_ref(v_); /* For DMALLOC... */                     \
00836   DO_IF_SECURITY( INITIALIZE_PROT(v_) );                \
00837   IF_LOCAL_MUTEX(mt_init_recursive(&(v_->mutex)));      \
00838 }while(0)
00839 
00840 #define EXIT_PIKE_MEMOBJ(X) do {                \
00841   struct ref_dummy *v_=(struct ref_dummy *)(X);         \
00842   DO_IF_SECURITY( FREE_PROT(v_) );              \
00843   IF_LOCAL_MUTEX(mt_destroy(&(v_->mutex)));     \
00844 }while(0)
00845 
00846 
00847 struct ref_dummy
00848 {
00849   PIKE_MEMORY_OBJECT_MEMBERS;
00850 };
00851 
00852 #endif /* !SVALUE_H */

Generated on Fri Jul 22 23:44:27 2005 for Pike by  doxygen 1.3.9.1