00001
00002
00003
00004
00005
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;
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;
00077 struct svalue *lval;
00078 void *ptr;
00079 };
00080
00081 #ifndef STRUCT_SVALUE_DECLARED
00082 #define STRUCT_SVALUE_DECLARED
00083 #endif
00084
00085
00086
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
00107 #define T_UNFINISHED 15
00108
00109 #define T_VOID 16
00110
00111
00112
00113 #define T_MANY 17
00114
00115 #define PIKE_T_RING 240
00116 #define PIKE_T_NAME 241
00117 #define PIKE_T_SCOPE 243
00118 #define PIKE_T_TUPLE 244
00119 #define T_ASSIGN 245
00120 #define T_DELETED 246
00121 #define PIKE_T_UNKNOWN 247
00122
00123 #define T_OBJ_INDEX 248
00124
00125
00126
00127 #define T_SVALUE_PTR 249
00128
00129
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
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
00160
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
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
00218
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
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
00240
00241 #define BIT_UNFINISHED (1 << T_UNFINISHED)
00242
00243
00244
00245
00246 #define BIT_VOID (1 << T_VOID)
00247
00248
00249
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
00261 #define MAX_COMPLEX PIKE_T_PROGRAM
00262
00263 #define MAX_REF_TYPE PIKE_T_TYPE
00264
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
00277
00278
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
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 *);
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) \
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) \
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
00387
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
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
00446
00447
00448
00449
00450
00451
00452
00453
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
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
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
00694
00695 #if 0
00696
00697 #include "pike_error.h"
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707 #define assign_svalue_no_free assign_svalue_no_free_unlocked
00708 #define assign_svalue assign_svalue_unlocked
00709
00710
00711
00712
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
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
00800
00801 #ifdef PIKE_RUN_UNLOCKED
00802 #include "pike_threadlib.h"
00803 #endif
00804
00805
00806
00807
00808
00809
00810
00811
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_); \
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