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. */
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"
e0cd662016-12-28Arne Goedeke #include "buffer.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) 
dfa5b31996-12-05Fredrik Hübinette (Hubbe) #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; };
13670c2015-05-25Martin Nilsson 
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) };
a5405e2016-06-21Per Hedbor /* The native types. * * Note that PIKE_T_INT is zero so that cleared memory * is filled with zeroes. */ enum PIKE_TYPE { PIKE_T_INT=0, PIKE_T_FLOAT=1, /* NB: The reference counted types all have bit 4 set. */ PIKE_T_ARRAY=8, PIKE_T_MAPPING=9, PIKE_T_MULTISET=10, PIKE_T_OBJECT=11, PIKE_T_FUNCTION=12, PIKE_T_PROGRAM=13, PIKE_T_STRING=14, PIKE_T_TYPE=15, /* The types above are valid types in svalues. * The following are only used by the internal systems. */ /* NB: 6 & 7 below are selected for easy backward compat with Pike 7.8. */ PIKE_T_ZERO= 6, /**< Can return 0, but nothing else */ T_UNFINISHED=7, /* * NOTE: The following types may show up on the stack, but are NOT * reference counted there. There they are mainly used for * lvalues. They MUST NOT have a value that has bit 3 (8) set. */ T_VOID= 16, /**< Can't return any value. Also used on stack to fill out the second * svalue on an lvalue when it isn't used. */ T_MANY= 17, PIKE_T_INT_UNTYPED= 18, /* Optimization of int type size */ /* 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. */ PIKE_T_FREE=19, /** svalue.u.lval points to an svalue. Primarily used in lvalues on * stack, but can also occur in arrays containing lvalue pairs. */ T_SVALUE_PTR=20, /** svalue.u.identifer is an identifier index in an object. Primarily * used in lvalues on stack, but can also occur in arrays containing * lvalue pairs. */ T_OBJ_INDEX=21, T_ARRAY_LVALUE=22,
200ea02019-12-19Henrik Grubbström (Grubba) /* No types above this value should appear on the stack. */ PIKE_T_STACK_MAX= T_ARRAY_LVALUE,
916c592020-01-28Henrik Grubbström (Grubba)  PIKE_T_GET_SET= 32, /* Getter setter. * Only valid in struct identifier */
200ea02019-12-19Henrik Grubbström (Grubba) /* * The following types are only used in compile-time types and * as markers in struct identifier. */
d785932020-01-14Henrik Grubbström (Grubba)  PIKE_T_LARRAY = 236, /* Limited array. Only for serialization. */ PIKE_T_LSTRING = 237, /* Limited string. Only for serialization. */
200ea02019-12-19Henrik Grubbström (Grubba)  PIKE_T_ATTRIBUTE = 238, /* Attribute node. */ PIKE_T_NSTRING = 239, /* Narrow string. Only for serialization. */ PIKE_T_RING = 240, PIKE_T_NAME = 241, /**< Named type. */ PIKE_T_SCOPE = 243, /**< Not supported yet */ PIKE_T_TUPLE = 244, /**< Not supported yet */ T_ASSIGN = 245, T_DELETED = 246,
522a332019-10-30Henrik Grubbström (Grubba)  /** Used to mark an svalue as free and not valid for input * to the svalue free functions. * Cf assert_free_svalue(). */ PIKE_T_UNKNOWN=247,
200ea02019-12-19Henrik Grubbström (Grubba) /* should only be used while compiling */ PIKE_T_AUTO = 248, /* Historic values: * T_OBJ_INDEX = 248, // Renumbered to 21. * T_LVALUE = 249, // Renamed to T_SVALUE_PTR and renumbered to 20. * T_ARRAY_LVALUE = 250, // Renumbered to 22. */ PIKE_T_MIXED = 251, T_NOT = 253, T_AND = 254, T_OR = 255, /* This flag is only valid in struct reference, and corresponds * to struct identifier identifier_flags IDENTIFIER_NO_THIS_REF. */ #define PIKE_T_NO_REF_FLAG 256 #define PIKE_T_NO_REF_OBJECT (PIKE_T_NO_REF_FLAG|PIKE_T_OBJECT) #define PIKE_T_NO_REF_FUNCTION (PIKE_T_NO_REF_FLAG|PIKE_T_FUNCTION) #define PIKE_T_NO_REF_MIXED (PIKE_T_NO_REF_FLAG|PIKE_T_MIXED) #define PIKE_T_NO_REF_INT (PIKE_T_NO_REF_FLAG|PIKE_T_INT) #define PIKE_T_NO_REF_FLOAT (PIKE_T_NO_REF_FLAG|PIKE_T_FLOAT) /* These are only used together with describe() and friends. */ #define T_STORAGE 10000 #define T_MAPPING_DATA 10001 #define T_PIKE_FRAME 10002 #define T_MULTISET_DATA 10003 #define T_STRUCT_CALLABLE 10004
a5405e2016-06-21Per Hedbor };
be227c2001-04-30Martin Stjernholm 
67a0a32005-09-12H. William Welliver III /** */
5267b71995-08-09Fredrik Hübinette (Hubbe) struct svalue {
a5cf652014-06-24Henrik Grubbström (Grubba)  union { struct {
c59ff42016-09-26Henrik Grubbström (Grubba)  /* NB: Ought to be "enum PIKE_TYPE type:16", but then the * machine code generator can't use the &-operator to * get the field offset. On the other hand the offset * should always be zero, so... */
a5cf652014-06-24Henrik Grubbström (Grubba)  unsigned short type; /**< the data type, see PIKE_T_... */ unsigned short subtype; /**< used to store the zero type, among others */ } t;
c59ff42016-09-26Henrik Grubbström (Grubba)  enum PIKE_TYPE named_type:16;
a5405e2016-06-21Per Hedbor 
6d89d12014-06-24Henrik Grubbström (Grubba) #if PIKE_BYTEORDER == 1234
a5cf652014-06-24Henrik Grubbström (Grubba)  ptrdiff_t type_subtype;
6d89d12014-06-24Henrik Grubbström (Grubba) #else /* For big-endian 64-bit architectures we don't want to require * 64-bit constants when setting the type_subtype field. */ INT32 type_subtype; #if SIZEOF_CHAR_P == 8
e5e0052019-12-20Henrik Grubbström (Grubba)  ptrdiff_t pad__;
6d89d12014-06-24Henrik Grubbström (Grubba) #endif #endif
a5cf652014-06-24Henrik Grubbström (Grubba)  } tu;
67a0a32005-09-12H. William Welliver III  union anything u; /**< contains the value */
5267b71995-08-09Fredrik Hübinette (Hubbe) };
455b892015-08-09Henrik Grubbström (Grubba) #define PIKE_TYPEOF(SVAL) ((SVAL).tu.t.type) #define PIKE_SUBTYPEOF(SVAL) ((SVAL).tu.t.subtype) #define TYPEOF(SVAL) PIKE_TYPEOF(SVAL) #define SUBTYPEOF(SVAL) PIKE_SUBTYPEOF(SVAL)
bf3c852014-06-26Henrik Grubbström (Grubba)  #define SET_SVAL_TYPE(SVAL, TYPE) (TYPEOF(SVAL) = (TYPE)) #define SET_SVAL_SUBTYPE(SVAL, TYPE) (SUBTYPEOF(SVAL) = (TYPE))
7666f82014-06-19Per Hedbor #if PIKE_BYTEORDER == 1234
ea43592014-07-02Arne Goedeke #define TYPE_SUBTYPE(X,Y) ((unsigned int)(X)|((unsigned int)(Y)<<16))
7666f82014-06-19Per Hedbor #else
ea43592014-07-02Arne Goedeke #define TYPE_SUBTYPE(X,Y) ((unsigned int)(Y)|((unsigned int)(X)<<16))
7666f82014-06-19Per Hedbor #endif #define SET_SVAL_TYPE_SUBTYPE(SVAL, TYPE, SUBTYPE) \
a5cf652014-06-24Henrik Grubbström (Grubba)  ((SVAL).tu.type_subtype = TYPE_SUBTYPE(TYPE,SUBTYPE))
722f712014-06-28Henrik Grubbström (Grubba) /* Setting the entire type_subtype field is probably faster than * just setting the type field. */ #define SET_SVAL_TYPE_DC(SVAL, TYPE) SET_SVAL_TYPE_SUBTYPE(SVAL, TYPE, 0)
7666f82014-06-19Per Hedbor 
5d5f7e2012-07-22Bill Welliver #define SET_SVAL(SVAL, TYPE, SUBTYPE, FIELD, EXPR) do { \
c0c9c42011-10-23Henrik Grubbström (Grubba)  /* Set the type afterwards to avoid a clobbered \ * svalue in case EXPR throws. */ \
a5cf652014-06-24Henrik Grubbström (Grubba)  struct svalue * __sv_ptr = &( SVAL ); \
5d5f7e2012-07-22Bill Welliver  __sv_ptr->u.FIELD = (EXPR); \
bf3c852014-06-26Henrik Grubbström (Grubba)  SET_SVAL_TYPE_SUBTYPE(*__sv_ptr, TYPE, SUBTYPE); \
c0c9c42011-10-23Henrik Grubbström (Grubba)  } while(0)
5d5f7e2012-07-22Bill Welliver  /* */
722f712014-06-28Henrik Grubbström (Grubba) #define INVALIDATE_SVAL(SVAL) SET_SVAL_TYPE_DC(SVAL, 99) /* an invalid type */
8b62072011-09-24Henrik Grubbström (Grubba) 
cc063b2014-12-07Henrik Grubbström (Grubba) 
833cae2013-06-12Henrik Grubbström (Grubba) /* NOTE: The t* macros below currently use the old type encoding * to be compatible with __parse_pike_type() in older * versions of Pike. */
45ee5d1999-02-10Fredrik Hübinette (Hubbe) #define tArr(VAL) "\000" VAL #define tArray tArr(tMix)
d785932020-01-14Henrik Grubbström (Grubba) #define tLArr(LEN, VAL) "\354" LEN VAL
45ee5d1999-02-10Fredrik Hübinette (Hubbe) #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"
d785932020-01-14Henrik Grubbström (Grubba) #define tLStr(LEN, VAL) "\355" LEN VAL
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"
369fdc2015-09-24Henrik Grubbström (Grubba) #define tIntNeg "\010\200\000\000\000\000\000\000\000"
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"
369fdc2015-09-24Henrik Grubbström (Grubba) #define tIntMinus "\010\200\000\000\000\377\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"
a8685d2013-05-29Henrik Grubbström (Grubba) #define tWord "\010\000\000\000\000\000\000\377\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)
2b73ad2015-10-19Per Hedbor #define tAttr(X,Y) "\356\0" X "\0" Y #define tName(X,Y) "\361\0" X "\0" Y
2220182002-11-22Henrik Grubbström (Grubba) #if PIKE_BYTEORDER == 1234 /* Little endian */
2b73ad2015-10-19Per Hedbor #define tAttr1(X,Y) "\356\5" X "\0\0" Y #define tAttr2(X,Y) "\356\6" X "\0\0\0\0" Y #define tName1(X,Y) "\361\5" X "\0\0" Y #define tName2(X,Y) "\361\6" X "\0\0\0\0" Y
2220182002-11-22Henrik Grubbström (Grubba) #else /* PIKE_BYTEORDER != 1234 */ /* Big endian */
2b73ad2015-10-19Per Hedbor #define tAttr1(X,Y) "\356\1" X "\0\0" Y #define tAttr2(X,Y) "\356\2" X "\0\0\0\0" Y #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)
1874052018-04-21Henrik Grubbström (Grubba) #define tUtf8Str tAttr("utf8", tStr8)
4835da2007-10-02Henrik Grubbström (Grubba) 
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) 
13670c2015-05-25Martin Nilsson /** 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
833cae2013-06-12Henrik Grubbström (Grubba)  * arguments have to be of this type.
3c04e81997-03-13Fredrik Hübinette (Hubbe)  */ #define BIT_MANY (1 << T_MANY)
5267b71995-08-09Fredrik Hübinette (Hubbe) #define BIT_NOTHING 0
0729e62013-06-15Henrik Grubbström (Grubba) #define BIT_MIXED 0xff7f
538e811999-12-10Henrik Grubbström (Grubba) #define BIT_BASIC (BIT_INT|BIT_FLOAT|BIT_STRING|BIT_TYPE)
898bb91999-06-07Fredrik Hübinette (Hubbe) #define BIT_CALLABLE (BIT_FUNCTION|BIT_PROGRAM|BIT_ARRAY|BIT_OBJECT)
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
833cae2013-06-12Henrik Grubbström (Grubba) /* Min type with ref count */ #define MIN_REF_TYPE PIKE_T_ARRAY
5267b71995-08-09Fredrik Hübinette (Hubbe) /* Max type handled by svalue primitives */
833cae2013-06-12Henrik Grubbström (Grubba) #define MAX_TYPE PIKE_T_TYPE
5267b71995-08-09Fredrik Hübinette (Hubbe) 
833cae2013-06-12Henrik Grubbström (Grubba) #define REFCOUNTED_TYPE(T) (((T) & ~(MIN_REF_TYPE - 1)) == MIN_REF_TYPE)
4a93e82013-06-11Henrik Grubbström (Grubba) 
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
38bb462013-08-14Marcus Comstedt extern PMOD_EXPORT const struct svalue svalue_undefined, svalue_int_zero; extern PMOD_EXPORT const struct svalue svalue_int_one;
e371f52008-05-30Martin Stjernholm 
76a8f52017-02-07Henrik Grubbström (Grubba) /* * Storage struct for a trampoline object * (not a part of the program type) */ struct pike_trampoline { struct pike_frame *frame; INT32 func; }; /* NB: From builtin.cmod. */ extern struct program *pike_trampoline_program;
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. */
455b892015-08-09Henrik Grubbström (Grubba) #define UNSAFE_IS_ZERO(X) (PIKE_TYPEOF(*(X))==PIKE_T_INT?(X)->u.integer==0:(1<<PIKE_TYPEOF(*(X)))&(BIT_OBJECT|BIT_FUNCTION)?!complex_svalue_is_true(X):0) #define SAFE_IS_ZERO(X) (PIKE_TYPEOF(*(X))==PIKE_T_INT?(X)->u.integer==0:(1<<PIKE_TYPEOF(*(X)))&(BIT_OBJECT|BIT_FUNCTION)?!safe_svalue_is_true(X):0)
5267b71995-08-09Fredrik Hübinette (Hubbe) 
455b892015-08-09Henrik Grubbström (Grubba) #define IS_UNDEFINED(X) (check_svalue (X), PIKE_TYPEOF(*(X))==PIKE_T_INT&&PIKE_SUBTYPEOF(*(X))==NUMBER_UNDEFINED)
3495fe1997-02-06Fredrik Hübinette (Hubbe) 
ce832b2015-05-21Tobias S. Josefowitz #define IS_DESTRUCTED(X) \
455b892015-08-09Henrik Grubbström (Grubba)  ((PIKE_TYPEOF(*(X)) == PIKE_T_OBJECT && !(X)->u.object->prog) || \ (PIKE_TYPEOF(*(X)) == PIKE_T_FUNCTION && \ PIKE_SUBTYPEOF(*(X)) != FUNCTION_BUILTIN \
ce832b2015-05-21Tobias S. Josefowitz  && (!(X)->u.object->prog \ || ((X)->u.object->prog == pike_trampoline_program \ && !((struct pike_trampoline *)(X)->u.object->storage) \
8284ad2015-05-21Tobias S. Josefowitz  ->frame->current_object->prog \
455b892015-08-09Henrik Grubbström (Grubba)  && PIKE_SUBTYPEOF(*(X)) == \ QUICK_FIND_LFUN(pike_trampoline_program, LFUN_CALL)))))
7a46d52011-09-24Henrik Grubbström (Grubba) 
453f4c1996-08-12Fredrik Hübinette (Hubbe) /* var MUST be a variable!!! */ #define safe_check_destructed(var) do{ \
d510982011-12-28Henrik Grubbström (Grubba)  if(IS_DESTRUCTED(var)) \ var=&svalue_int_zero; \ }while(0)
453f4c1996-08-12Fredrik Hübinette (Hubbe) 
d510982011-12-28Henrik Grubbström (Grubba) /* FIXME: Is this actually used for functions? */
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) 
557f742014-05-23Per Hedbor #define add_ref(X) ((void)((X)->refs++))
67b7312002-12-01Martin Stjernholm #define sub_ref(X) (--(X)->refs > 0)
e83eb92001-03-22Fredrik Hübinette (Hubbe) 
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 
cc063b2014-12-07Henrik Grubbström (Grubba) #define IS_INVALID_TYPE(T) is_invalid_stack_type(T)
69db482008-03-29Martin Stjernholm 
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); \
455b892015-08-09Henrik Grubbström (Grubba)  TYPE_T typ_ = PIKE_TYPEOF(*sval_); \
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. */ \
4a93e82013-06-11Henrik Grubbström (Grubba)  if (REFCOUNTED_TYPE(typ_)) \
6d77e12003-08-20Martin Stjernholm  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. */ \
455b892015-08-09Henrik Grubbström (Grubba)  if (REFCOUNTED_TYPE(PIKE_TYPEOF(*sval_))) \ low_thorough_check_short_svalue (&sval_->u, PIKE_TYPEOF(*sval_)); \
6d77e12003-08-20Martin Stjernholm  } 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);
cc063b2014-12-07Henrik Grubbström (Grubba) PMOD_EXPORT int is_invalid_stack_type(unsigned int t);
dd0fe02008-05-11Martin Stjernholm 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[];
455b892015-08-09Henrik Grubbström (Grubba) #define check_refs(S) do { \ if(REFCOUNTED_TYPE(PIKE_TYPEOF(*(S))) && \ (!(S)->u.refs || (S)->u.refs[0] < 0)) { \
f9bafd2008-12-12Martin Stjernholm  fprintf (stderr, "%s", msg_sval_obj_wo_refs); \
b9f3282004-04-03Martin Stjernholm  describe((S)->u.refs); \
f9bafd2008-12-12Martin Stjernholm  Pike_fatal("%s", msg_sval_obj_wo_refs); \
b9f3282004-04-03Martin Stjernholm  } }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 { \
4a93e82013-06-11Henrik Grubbström (Grubba) if(REFCOUNTED_TYPE(T) && (S)->refs && (S)->refs[0] <= 0) {\
92d0c42008-12-14Martin Stjernholm  fprintf (stderr, "%s", msg_ssval_obj_wo_refs); \
b9f3282004-04-03Martin Stjernholm  describe((S)->refs); \
92d0c42008-12-14Martin Stjernholm  Pike_fatal("%s", 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
01b9212016-01-12Per Hedbor static inline struct svalue PIKE_UNUSED_ATTRIBUTE *dmalloc_check_svalue(struct svalue *s, char *l)
ead2052000-06-16Fredrik Hübinette (Hubbe) {
455b892015-08-09Henrik Grubbström (Grubba)  if(s && REFCOUNTED_TYPE(PIKE_TYPEOF(*s)))
ead2052000-06-16Fredrik Hübinette (Hubbe)  debug_malloc_update_location(s->u.refs,l); return s; }
01b9212016-01-12Per Hedbor static inline struct svalue PIKE_UNUSED_ATTRIBUTE *dmalloc_check_svalues(struct svalue *s, size_t num, char *l)
e7f1322004-09-30Martin Stjernholm { while (num--) dmalloc_check_svalue (s + num, l); return s; }
01b9212016-01-12Per Hedbor static inline union anything PIKE_UNUSED_ATTRIBUTE *dmalloc_check_union(union anything *u,int type, char * l)
ead2052000-06-16Fredrik Hübinette (Hubbe) {
4a93e82013-06-11Henrik Grubbström (Grubba)  if(u && REFCOUNTED_TYPE(type))
ead2052000-06-16Fredrik Hübinette (Hubbe)  debug_malloc_update_location(u->refs,l); return u; }
e83eb92001-03-22Fredrik Hübinette (Hubbe) #undef add_ref
24bce62003-03-14Henrik Grubbström (Grubba) #define add_ref(X) (((INT32 *)debug_malloc_update_location( &((X)->refs), DMALLOC_NAMED_LOCATION(" add_ref")))[0]++)
557f742014-05-23Per Hedbor #undef sub_ref
24bce62003-03-14Henrik Grubbström (Grubba) #define sub_ref(X) (--((INT32 *)debug_malloc_update_location( &((X)->refs), DMALLOC_NAMED_LOCATION(" sub_ref")))[0] > 0)
e83eb92001-03-22Fredrik Hübinette (Hubbe) 
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)
7d269e2008-05-11Martin Stjernholm #endif /* !DEBUG_MALLOC */ /* To be used for type checking in macros. */
01b9212016-01-12Per Hedbor static inline struct array PIKE_UNUSED_ATTRIBUTE *pass_array (struct array *a) {return a;} static inline struct mapping PIKE_UNUSED_ATTRIBUTE *pass_mapping (struct mapping *m) {return m;} static inline struct multiset PIKE_UNUSED_ATTRIBUTE *pass_multiset (struct multiset *l) {return l;} static inline struct object PIKE_UNUSED_ATTRIBUTE *pass_object (struct object *o) {return o;} static inline struct program PIKE_UNUSED_ATTRIBUTE *pass_program (struct program *p) {return p;} static inline struct pike_string PIKE_UNUSED_ATTRIBUTE *pass_string (struct pike_string *s) {return s;} static inline struct pike_type PIKE_UNUSED_ATTRIBUTE *pass_type (struct pike_type *t) {return t;} static inline struct callable PIKE_UNUSED_ATTRIBUTE *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__); \
7a46d52011-09-24Henrik Grubbström (Grubba)  SET_SVAL_TYPE(*_X__, PIKE_T_FREE); \
1ab4ac2008-01-26Martin Stjernholm  } 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); \
7a46d52011-09-24Henrik Grubbström (Grubba)  SET_SVAL_TYPE(*_X__, 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) 
557f742014-05-23Per Hedbor #define swap_svalues(X,Y) do { \
708d8d2001-04-28Martin Stjernholm  struct svalue *_a=(X); \ struct svalue *_b=(Y); \ struct svalue _tmp; \
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. */
557f742014-05-23Per Hedbor #define free_svalue(X) do { \
aad99b2001-03-28Fredrik Hübinette (Hubbe)  struct svalue *_s=(X); \
1ab4ac2008-01-26Martin Stjernholm  DO_IF_DEBUG ( \
455b892015-08-09Henrik Grubbström (Grubba)  if (PIKE_TYPEOF(*_s) != PIKE_T_FREE) { \
df86912008-03-29Martin Stjernholm  check_svalue_type(_s); \
1ab4ac2008-01-26Martin Stjernholm  check_refs(_s); \ } \ ); \
455b892015-08-09Henrik Grubbström (Grubba)  if (!REFCOUNTED_TYPE(PIKE_TYPEOF(*_s))) \
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) \
455b892015-08-09Henrik Grubbström (Grubba)  gc_check_zapped (_s->u.ptr, PIKE_TYPEOF(*_s), __FILE__, __LINE__))); \
97a7332008-03-30Martin Stjernholm  if (sub_ref(_s->u.dummy) <=0) \ really_free_svalue(_s); \ else \ assert_free_svalue (_s); \ } \
aad99b2001-03-28Fredrik Hübinette (Hubbe) }while(0)
557f742014-05-23Per Hedbor #define free_short_svalue(X,T) do { \
aad99b2001-03-28Fredrik Hübinette (Hubbe)  union anything *_s=(X); TYPE_T _t=(T); \ check_type(_t); check_refs2(_s,_t); \
4a93e82013-06-11Henrik Grubbström (Grubba)  if(REFCOUNTED_TYPE(_t) && _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. */
557f742014-05-23Per Hedbor #define add_ref_svalue(X) do { \
aad99b2001-03-28Fredrik Hübinette (Hubbe)  struct svalue *_tmp=(X); \
1ab4ac2008-01-26Martin Stjernholm  DO_IF_DEBUG ( \
455b892015-08-09Henrik Grubbström (Grubba)  if (PIKE_TYPEOF(*_tmp) != PIKE_T_FREE) { \
df86912008-03-29Martin Stjernholm  check_svalue_type(_tmp); \
1ab4ac2008-01-26Martin Stjernholm  check_refs(_tmp); \ } \ ); \
455b892015-08-09Henrik Grubbström (Grubba)  if(REFCOUNTED_TYPE(PIKE_TYPEOF(*_tmp))) add_ref(_tmp->u.dummy); \
aad99b2001-03-28Fredrik Hübinette (Hubbe) }while(0)
1ab4ac2008-01-26Martin Stjernholm /* Handles PIKE_T_FREE. */
557f742014-05-23Per Hedbor #define assign_svalue_no_free(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 ( \
455b892015-08-09Henrik Grubbström (Grubba)  if (PIKE_TYPEOF(*_from) != 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; \
455b892015-08-09Henrik Grubbström (Grubba)  if(REFCOUNTED_TYPE(PIKE_TYPEOF(*_to))) add_ref(_to->u.dummy); \
aad99b2001-03-28Fredrik Hübinette (Hubbe) }while(0)
1ab4ac2008-01-26Martin Stjernholm /* Handles PIKE_T_FREE. */
557f742014-05-23Per Hedbor #define assign_svalue(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_++) \ { \
c0c9c42011-10-23Henrik Grubbström (Grubba)  SET_SVAL(*s_, PIKE_T_INT, (N), integer, 0); \
2ac9502001-08-14Fredrik Hübinette (Hubbe)  } \ }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 */
8e8c602018-11-03Henrik Grubbström (Grubba) PMOD_EXPORT void check_destructed(struct svalue *s);
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);
f509652018-04-27Henrik Grubbström (Grubba) PMOD_EXPORT void assign_no_ref_svalue(struct svalue *to, const struct svalue *val, const struct object *owner);
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);
a563932016-06-24Per Hedbor PMOD_EXPORT size_t hash_svalue(const struct svalue *s);
32f8952013-06-12Per Hedbor PMOD_EXPORT int complex_svalue_is_true(const struct svalue *s); /* only handles object + function */
3cd7482001-04-28Martin Stjernholm 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);
e0cd662016-12-28Arne Goedeke PMOD_EXPORT void describe_svalue(struct byte_buffer *buf, const struct svalue *s,int indent, struct processing *p); PMOD_EXPORT void safe_describe_svalue(struct byte_buffer *buf, 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);
d539042008-08-17Martin Stjernholm #ifdef PIKE_DEBUG PMOD_EXPORT void safe_pike_vfprintf (FILE *out, const char *fmt, va_list args); PMOD_EXPORT void safe_pike_fprintf (FILE *out, const char *fmt, ...); #endif
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);
1d3eae2014-08-27Per Hedbor PMOD_EXPORT INT_TYPE pike_sizeof(const struct svalue *s);
cca4872010-02-18Stephen R. van den Berg int svalues_are_constant(const struct svalue *s,
84387d2001-09-24Fredrik Hübinette (Hubbe)  INT32 num, TYPE_FIELD hint, struct processing *p);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
01b9212016-01-12Per Hedbor static inline TYPE_FIELD PIKE_UNUSED_ATTRIBUTE BITOF(struct svalue sv) {
455b892015-08-09Henrik Grubbström (Grubba)  if (PIKE_TYPEOF(sv) >= sizeof(TYPE_FIELD) * 8) {
3635f82014-01-11Tobias S. Josefowitz  return BIT_MIXED | BIT_UNFINISHED; }
455b892015-08-09Henrik Grubbström (Grubba)  return 1 << PIKE_TYPEOF(sv);
3635f82014-01-11Tobias S. Josefowitz }
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
01b9212016-01-12Per Hedbor static inline TYPE_FIELD PIKE_UNUSED_ATTRIBUTE dmalloc_gc_mark_svalues (struct svalue *s, size_t num, char *l)
e7f1322004-09-30Martin Stjernholm  {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())
01b9212016-01-12Per Hedbor static inline TYPE_FIELD PIKE_UNUSED_ATTRIBUTE dmalloc_gc_cycle_check_svalues (struct svalue *s, size_t num, char *l)
e7f1322004-09-30Martin Stjernholm  {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) 
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) 
abe64b2018-05-19Tobias S. Josefowitz #define PIKE_CONSTANT_MEMOBJ_INIT(refs, type) GC_HEADER_INIT(refs)
f4d7572001-04-15Martin Stjernholm 
e134902015-03-16Martin Nilsson #define INIT_PIKE_MEMOBJ(X, TYPE) do { \ struct ref_dummy *v_=(struct ref_dummy *)(X); \ v_->refs=0; \ add_ref(v_); /* For DMALLOC... */ \
45637c2001-04-07Fredrik Hübinette (Hubbe) }while(0)
e134902015-03-16Martin Nilsson #define EXIT_PIKE_MEMOBJ(X) do { \ struct ref_dummy *v_=(struct ref_dummy *)(X); \
45637c2001-04-07Fredrik Hübinette (Hubbe) }while(0) struct ref_dummy {
f426422015-03-17Martin Nilsson  INT32 refs;
45637c2001-04-07Fredrik Hübinette (Hubbe) };
538e811999-12-10Henrik Grubbström (Grubba) 
a5405e2016-06-21Per Hedbor /* The following macro is useful to initialize static svalues. . */ /* assumes sizeof void* >= all initialization arguments. */
86ebe12016-11-12Henrik Grubbström (Grubba) #ifdef HAVE_C99_STRUCT_INIT
a5405e2016-06-21Per Hedbor #define SVALUE_INIT(TYPE, SUBTYPE, VAL) {.tu.type_subtype=TYPE_SUBTYPE(TYPE, SUBTYPE),.u.refs=(void*)VAL}
86ebe12016-11-12Henrik Grubbström (Grubba) /* Depends on T_INT and NUMBER_NUMBER being 0. */ #define SVALUE_INIT_INT(VAL) {.tu.type_subtype=0,.u.integer=VAL} #else /* !HAVE_C99_STRUCT_INIT */ /* FIXME: Assumes that INT_TYPE and void * have the same size. */ #define SVALUE_INIT(TYPE, SUBTYPE, VAL) {{{TYPE, SUBTYPE}}, {(INT_TYPE)(void*)VAL}} #define SVALUE_INIT_INT(VAL) {{{PIKE_T_INT, NUMBER_NUMBER}}, {VAL}} #endif /* !HAVE_C99_STRUCT_INIT */
a5405e2016-06-21Per Hedbor  #define SVALUE_INIT_FREE SVALUE_INIT(PIKE_T_FREE,0,0)
3e130c2008-05-30Martin Stjernholm 
538e811999-12-10Henrik Grubbström (Grubba) #endif /* !SVALUE_H */