4 * (c)Copyright 1993-2014, Matthew Dillon, All Rights Reserved. See the
5 * COPYRIGHT file at the base of the distribution.
7 * See libsupport/coretype.h for definitions of runesize_t and a few others.
9 #ifndef _LIBRUNE_TYPE_H_
10 #define _LIBRUNE_TYPE_H_
18 * These are used everywhere but the structure definitions are more
26 typedef struct RunContext *runctx_p;
27 typedef struct GenContext *genctx_p;
30 * PointerInfo - This structure is typically stored as part of the RefStor
31 * or stack context. It contains the auxillary data needed to
34 * Auxillary data is essentially static and the code generator
35 * can cache bits and pieces of it as necessary. The s_Info
36 * pointer itself may change when the pointer is reassigned,
37 * but does not change for nominal pointer arithmatic within
38 * the pointer's current domain.
40 * in_Beg and in_End are only used for PCheck operations and
41 * may require a dynamic info structure, which is not usually
42 * implemented. All info structures are taken from the
43 * type's static ty_Info template.
45 * PointerStor - This structure represents a pointer, consisting of the
46 * actual pointer and a secondary pointer to the related
49 * LValueStor - This structure represents an LValue and is essentially the
50 * same format as a PointerStor now, but we treat it separately
51 * to reduce confusion. Unlike pointers, the pointer embedded
52 * in an LValueStor cannot change and has already been validated.
54 * NOTE: PointerInfo.s_Type is the pointer target type, not the pointer type.
56 * WARNING: These structures are hard-coded in various places.
58 typedef struct PointerInfo {
59 struct RefStor *in_RefStor;
60 char *in_Beg; /* (only for pointer tracking) */
61 char *in_End; /* (only for pointer tracking) */
62 struct Type *in_Type; /* pointer TARGET type */
63 void **in_DynVec; /* broken-out of the type */
64 struct PointerInfo *in_Next;
68 #define PINFO_STATIC ((runesize_t)0x00000001)
69 #define PINFO_INCR ((runesize_t)0x00000002)
72 * NOTE: s_Info->in_Type is the type of the object pointed to by s_Addr.
73 * That is, the pointer target type, not the pointer type.
75 typedef struct PointerStor {
76 char *s_Addr; /* The actual pointer */
77 PointerInfo *s_Info; /* Auxillary information */
78 } __aligned(16) PointerStor;
80 #define SIZE_SIZE ((runesize_t)(sizeof(runesize_t)))
81 #define CPOINTER_SIZE ((runesize_t)(sizeof(void *)))
82 #define CPOINTER_ALIGN ((runesize_t)(CPOINTER_SIZE - 1))
83 #define POINTERINFO_SIZE ((runesize_t)(sizeof(PointerInfo)))
84 #define POINTERSTOR_SIZE ((runesize_t)(sizeof(PointerStor)))
85 #define LVALUESTOR_SIZE ((runesize_t)(sizeof(LValueStor)))
86 #define POINTERSTOR_ALIGN ((runesize_t)(sizeof(PointerStor) - 1))
87 #define LVALUESTOR_ALIGN ((runesize_t)(sizeof(LValueStor) - 1))
89 #define EXTRA_INTERNAL_SPACE (CPOINTER_SIZE * 6)
91 #define RUNE_PTRSTOR_ADDR offsetof(PointerStor, s_Addr)
92 #define RUNE_PTRSTOR_INFO offsetof(PointerStor, s_Info)
93 #define RUNE_LVSTOR_ADDR offsetof(LValueStor, s_Addr)
94 #define RUNE_LVSTOR_INFO offsetof(LValueStor, s_Info)
96 #define RUNE_PINFO_REFSTOR offsetof(PointerInfo, in_RefStor)
97 #define RUNE_PINFO_BEG offsetof(PointerInfo, in_Beg)
98 #define RUNE_PINFO_END offsetof(PointerInfo, in_End)
99 #define RUNE_PINFO_TYPE offsetof(PointerInfo, in_Type)
100 #define RUNE_PINFO_DYNVEC offsetof(PointerInfo, in_DynVec)
105 * This structure is the run-time representation of an lvalue object. It
106 * is typically used to present lvalue arguments and return values for method
107 * calls but may also represent special storage mechanics such as "heap"
108 * and "persist", as well as interpreter-related objects.
110 * LValue objects are always considered to be valid. They are not pointers
111 * in that their s_Addr cannot be changed, and the s_Info structure always
112 * points to the type's static ty_Info (in_Beg and in_End are always NULL).
114 * NOTE: s_Info->in_Type is the type of the object pointed to by s_Addr.
115 * That is, the target type (which is also how PointerStor works).
117 typedef struct LValueStor {
118 void *s_Addr; /* the actual pointer */
119 PointerInfo *s_Info; /* Auxillary information */
120 } __aligned(16) LValueStor;
123 * Interpreter's temporary storage structure.
125 * Note, however, that an exp should never store more data into the
126 * RunTmpStor than it's ex_Type says it can because higher level calls
127 * (like InterpCompoundExp()) will attempt to avoid copies by directly
128 * passing the destination storage as the TmpStor.
130 * NOTE: Expression-temporaries never store LValueStor's, which are entities
131 * that can exist in SemGroups. The type's SF_LVALUE flag is not
132 * related to the LValueStor structure.
134 typedef union RunTmpStor {
141 int64_t ts_Int64Ary[2];
147 u_int64_t ts_UInt64Ary[2];
150 long double ts_Float128;
151 PointerStor ts_Pointer;
157 * Data element for interpreter. Note that the data pointer itself is
158 * returned directly as a return value as a means of maintaining high
159 * interpreter performance. Callers must reassociate the data pointer with
160 * the data object upon return prior to making any calls to data-centric
161 * support routines. This allows low-level operators to mostly ignore
162 * RunData when operating on basic data.
164 * mrs - Sideband ref on the memory containing the object.
166 * Non-temporary objects remain valid when discarded. Their content is
167 * only dereferenced when they are content-dropped by other means.
168 * Temporaries are always content-dropped when discarded.
170 typedef struct RunData {
187 rundata_clear(rundata_t *data)
196 rundata_copy(rundata_t *src, void *ptr, rundata_t *dst)
200 dst->rollup = src->rollup;
201 if (ptr == &src->ts) {
202 bcopy(&src->ts, &dst->ts, sizeof(src->ts));
203 dst->data = &dst->ts;
208 * Data element for code generator.
210 * minfo - Sideband info for the storage containing the object,
211 * typically needed when evaluating lvalue objects and
213 * rssg - Static generation semgroup so static address output can
214 * figure out the correct info reference.
216 * Non-temporary objects remain valid when discarded. Their content is
217 * only dereferenced when they are content-dropped by other means.
218 * Temporaries are always content-dropped when discarded.
220 typedef struct GenData {
227 int64_t offset; /* also used for immediate value */
228 int64_t immhi; /* if 128-bit immediate */
231 * s_Beg, s_End used by the generator's global data init
232 * during interpretation to calculate relative offsets of
233 * ps->s_Beg and ps->s_End for global pointer initialization.
235 runesize_t s_Beg; /* (generator global data init only) */
236 runesize_t s_End; /* (generator global data init only) */
239 * implied_mask is a bitmask for up to the first 64 LValueStor's
240 * (SCOPE_LVALUE elements) of a compound type, or of a
241 * SCOPE_LVALUE type (such as a lvalue return). If a bit is
242 * set it indicates that the lvalue element has an implied lock
243 * and should not be LVPUT/LVREL'd on drop.
245 * We can do this optimization for lvalue elements because the
246 * caller is not allowed to modify the lvs->s_RefStor itself,
247 * and will separately ref/lock any copy it makes. Such situations
248 * are strictly temporary so the original code setting the bits
249 * knows the content will be done when it disposes of them.
250 * And because of that, implied locks can be chained.
252 uint64_t implied_mask; /* implied locks on LVALUEs */
254 void *cache_id; /* non-NULL means cacheable */
255 struct Type *load_type; /* for memory load/store only */
256 struct GenData *minfo; /* sideband PointerInfo on memory */
257 struct GenData *type; /* extracted Type, NULL if not dyn */
258 struct SemGroup *rssg; /* list of decls */
261 typedef gendata_t *gendata_p;
266 #define EA_UNUSED03 3
267 #define EA_IMMEDIATE 4
268 #define EA_IMMEDIATE16 5 /* 128-bit immediate */
272 * The storage fields above represent the nominal storage mode for
273 * the target content of an object, not the memory containing the object.
274 * It is only applicable to references, pointers, lvalues, and compound
275 * types (and only recurses via compound types). The storage mode for
276 * elements making up e.g. class objects are governed by the class's
279 * For a pointer or reference, for example, 'storage' represents how
280 * the target object represented by PointerStor.s_Info is lock+refd,
281 * not how the memory containing the pointer is lock+refd, or how each
282 * element of a compound type is handled recursively for compound types.
284 * However, the storage field does NOT classify the elements of a structure.
285 * it strictly classifies only the 'top' element. A pointer or reference
286 * is different from a structure containing a pointer or reference.
288 * LValues are a bit more confusing. An LValue's 'storage' specification
289 * represents how its LValueStor.s_Info is lock+refd and nothing more.
290 * If the LValue represents a pointer/reference type then it is an
291 * LValueStor that points to a PointerStor, but the lock+refd mode of the
292 * PointerStor's target is NOT determined by the 'storage' specification.
294 * If an LValueStor represents a compound type (verses a pointer to a compound
295 * type), the storage specification recurses as per normal for compound types.
297 * In method calls, the LValue object is an LValueStor that points to
298 * the object, NOT an LValueStor that pointers to a PointerStor. It is
299 * NOT a pointer semantically. Hence why method procedures access the
300 * object using dot notation, as in 'this.BLAH'.
302 * DEFAULT STORAGE MODES:
303 * Method target objects GENSTAT_LOCKH (default)
304 * GENSTAT_LOCK ('soft')
305 * GENSTAT_NONE ('untracked') (note 1)
306 * Procedure arguments GENSTAT_ARGDEF (note 2)
307 * Procedure return GENSTAT_RETDEF (note 2)
308 * local variables GENSTAT_STKDEF (note 2)
309 * expression temporaries GENSTAT_EXPDEF
310 * structural elements GENSTAT_MEMDEF (note 3)
311 * compound types (recursion for passed-in storage mode)
313 * note 1 - In untracked mode no refs or locks are obtained. Untracked
314 * pointers cannot be cast (as this required a sideband info
317 * note 2 - If the address is taken of an element or the element is
318 * used as an lvalue it needs to be GENSTAT_REFD (XXX)
320 * note 3 - For maximum compatibility, structural elements are
321 * GENSTAT_REFD. The 'storage' field for a class object
322 * is not applicable (its only applicable for pointers,
323 * references, and lvalues).
325 * NONE Nominal storage status is nothing.
326 * REFD Nominal storage status is REFD.
327 * LOCK Nominal storage status is LOCK+REFD.
328 * LOCKH Nominal storage status is LOCK+REFD using a hard lock.
330 * EMPTY (flag) indicates no prior contents to storage, allows
331 * unnecessary PUTs(etc) to be optimized out.
333 #define GENSTAT_NONE 0
334 #define GENSTAT_REFD 1
335 #define GENSTAT_LOCK 2
336 #define GENSTAT_LOCKH 3
337 #define GENSTAT_UNSPEC 4 /* when storage mode not known */
339 #define GENSTATF_EMPTY 0x10
341 #define GENSTAT_EXPDEF GENSTAT_NONE /* expression temporaries */
342 #define GENSTAT_ARGDEF GENSTAT_NONE /* argument declarations */
343 #define GENSTAT_RETDEF GENSTAT_NONE /* return declaration */
344 #define GENSTAT_STKDEF GENSTAT_NONE /* local declarations */
345 #define GENSTAT_MEMDEF GENSTAT_REFD /* nominal memory */
346 #define GENSTAT_METDEF GENSTAT_LOCKH /* method object */
347 #define GENSTAT_ARYDEF GENSTAT_REFD /* array elements */
348 #define GENSTAT_TYPDEF GENSTAT_NONE /* type default initialization */
350 #define REGF_PTR 0x80000000U
351 #define REGF_MASK 0x00FFFFFFU
352 #define REGF_USRMASK 0x7F000000U
353 #define REGF_USRBASE 0x01000000U
355 #define REG_FIRSTTMP 100
357 #define REG_NEWDAT ((uint32_t)-1 & REGF_MASK)
358 #define REG_NEWPTR (REGF_PTR | ((uint32_t)-1 & REGF_MASK))
360 #define REG_SG (REGF_PTR | 9) /* semgroup pointer (varargs calls) */
361 #define REG_RP (REGF_PTR | 10) /* return data pointer */
362 #define REG_DB (REGF_PTR | 11) /* data & module base */
363 #define REG_TP (REGF_PTR | 12) /* thread pointer */
364 #define REG_AP (REGF_PTR | 13) /* argument pointer */
365 #define REG_FP (REGF_PTR | 14) /* frame pointer */
366 #define REG_PC (REGF_PTR | 15) /* program counter */
369 #define REG_NULL (REGF_PTR | 0)
370 #define REG_ABS REG_NULL
373 * Branch label element for code generator
376 genctx_p ct; /* (for accounting only) */
379 runesize_t bytes; /* string constants only */
382 typedef genlabel_t *genlabel_p;
385 * Type - the type structure. Types are various forms of instantiated
388 * (note 1) - TY_DYNAMIC types are special. During run-time an
389 * expression that normally returns a dynamic type must
390 * either be cast to the type you want (which is hinted
391 * into exp->ex_Type, replacing the dynamic type), or
392 * it must be marked as returning a type.
394 * Normally a returned type is simply stored in ex_Type,
395 * but this doesn't work when making run-time changes
396 * (due to reusing the Exp's in a threaded environment).
397 * In this case the expression leaves ex_Type set to
398 * a TY_DYNAMIC type and will return a pointer to
402 * (note 2) - The visibility of a type's contents is set in
403 * resolveType() and based on where the type's base
404 * class or compound type was defined vs where it
407 * WARNING: Must match classes/sys/runtime.d
410 typedef RUNE_HEAD(typelist, Type) typelist_t;
412 typedef struct Type {
413 RUNE_ENTRY(Type) ty_Node;
414 typelist_t ty_QList; /* qualified type (ptr-to, etc...) */
415 int ty_Op; /* type opcode (TY_*) */
416 int ty_Flags; /* type flags (must be int) */
417 runesize_t ty_Bytes; /* size of type in bytes */
418 runesize_t ty_AlignMask; /* alignment mask */
419 int ty_SQFlags; /* qualifiers, if any */
420 int ty_Visibility; /* visib of type's contents (note 2) */
421 typelist_t *ty_SQList; /* qualifications list (shared) */
422 struct Exp *ty_AssExp; /* assigned default for type */
423 runesize_t ty_TmpBytes; /* temporary required for assignment */
424 runesize_t ty_TmpAlignMask;/* temporary space alignment mask */
425 void **ty_DynamicVector; /* placeholder for generator */
426 PointerInfo ty_Info; /* info template for NULL pointer */
429 struct SemGroup *et_SemGroup; /* list of decls */
430 struct Type *et_Super; /* superclass */
433 struct SemGroup *et_SemGroup; /* list of decls */
436 struct Type *et_Type; /* pointer to type */
439 struct SemGroup *et_SemGroup; /* for sem search */
440 struct Exp *et_ArySize; /* size exp or NULL */
441 struct Type *et_Type; /* array of this type */
442 runesize_t et_Count; /* resolved elements */
445 struct SemGroup *et_SemGroup; /* list of decls */
448 struct SemGroup *et_SemGroup; /* list of decls */
449 struct Type *et_Type; /* type to extend */
452 struct Type *et_ArgsType; /* args (compound) */
453 struct Type *et_RetType; /* return type */
454 runesize_t et_ArgCount; /* # of args */
457 runesize_t et_Bytes; /* size in bytes */
460 runesize_t et_Unused00;
463 string_t *et_DottedId; /* a, b, c, NULL */
464 struct SemGroup *et_SemGroup; /* for sem search */
465 struct SemGroup *et_ImportSemGroup; /* for sem search */
476 #define RUNE_TYPE_DYNAMIC_VECTOR \
477 ((runesize_t)offsetof(Type, ty_DynamicVector))
478 #define RUNE_TYPE_INFO \
479 ((runesize_t)offsetof(Type, ty_Info))
482 * Weak aliases to the actual type label for well-defined type names
486 typedef RUNE_HEAD(typereglist, TypeRegNode) typereglist_t;
488 typedef struct TypeRegNode {
489 RUNE_ENTRY(TypeRegNode) tr_Node;
491 const char *tr_LinkName;
495 #define ty_ClassType u.ClassType
496 #define ty_ImportType u.ImportType
497 #define ty_PtrType u.PtrType
498 #define ty_CPtrType u.PtrType
499 #define ty_AryType u.AryType
500 #define ty_CompType u.CompType
501 #define ty_ArgsType u.CompType
502 #define ty_VarType u.VarType
503 #define ty_ProcType u.ProcType
504 #define ty_QualType u.QualType
505 #define ty_StorType u.StorType
506 #define ty_UnresType u.UnresType
507 #define ty_RefType u.PtrType /* must be same as PtrType */
509 #define TY_CLASS 1 /* the type represents a base class */
510 #define TY_PTRTO 2 /* the type is a pointer to BLAH */
511 #define TY_ARYOF 3 /* the type is an array of BLAH */
512 #define TY_COMPOUND 4 /* the type is compound, made up of BLAH */
513 #define TY_PROC 5 /* the type is a procedure */
515 #define TY_STORAGE 7 /* as a special raw-storage type */
516 #define TY_ARGS 8 /* procedure arguments (compound) type */
517 #define TY_VAR 9 /* variable procedure arguments */
518 #define TY_DYNAMIC 10 /* run-time type (must be cast) (note 1) */
519 #define TY_UNRESOLVED 11 /* unresolved identifier path */
520 #define TY_REFTO 12 /* reference type (no indrection) */
521 #define TY_CPTRTO 13 /* C pointer type (no PointerStor) */
523 #define TF_RESOLVING 0x000001 /* type fully resolved */
524 #define TF_RESOLVED 0x000002 /* type fully resolved */
525 #define TF_DEFINED 0x000004 /* type has been defined, else only refd */
526 #define TF_NOINIT 0x000008 /* (interpreter - status) */
527 #define TF_HASLVPTR 0x000010 /* is or contains arg-lvalue, or ptr */
528 #define TF_HASCONSTRUCT 0x000020 /* contains constructor */
529 #define TF_HASDESTRUCT 0x000040 /* contains destructor */
530 #define TF_TMPRESOLVED 0x000080 /* temporary storage for exp eval resolv */
531 #define TF_CONDESDATA 0x000100 /* constr/destruct data as well as procs */
532 #define TF_HASGCONSTRUCT 0x00200 /* contains global constructor */
533 #define TF_HASGDESTRUCT 0x000400 /* contains global destructor */
534 #define TF_ISUNSIGNED 0x000800 /* Unsigned Integer (helper) */
535 #define TF_ISFLOATING 0x001000 /* Floating Point (helper) */
536 #define TF_ISINTEGER 0x002000 /* Unsigned or signed integer (helper) */
537 #define TF_HASASS 0x004000 /* has or contains assignments {*/
538 #define TF_ISBOOL 0x008000 /* Boolean (helper) */
539 #define TF_GENERATING 0x010000 /* backend generation */
540 #define TF_COLLAPSED 0x020000 /* collapse pass in prog or done */
541 #define TF_LAYOUT 0x040000 /* available for global layout */
542 #define TF_ISINTERNAL 0x080000 /* special internal type, do not collapse */
543 #define TF_ALIGNRESOLVED 0x100000 /* alignment resolved */
546 * Special storage qualifier masks
548 #define SF_MASK_ARY_INHERIT (SF_CONST|SF_VOLATILE|SF_LVALUE|SF_NOZERO)
551 * Global Info structure
553 typedef struct GlobInfo {
554 char *gi_Label; /* location of global entity */
555 runesize_t gi_Offset;
560 struct SemGroup *gi_RSSG; /* SG for global RefStor */
561 struct GlobInfo *gi_HNext;
564 #define GLF_GENERATING 0x00000001
569 Type *TypeToQualType(Type *otype, Type *ntype, int sqFlags, struct Exp *exp);
573 AddTypeQual(Type *type, int sqFlags)
575 return(TypeToQualType(type, NULL, type->ty_SQFlags | sqFlags, NULL));
580 DelTypeQual(Type *type, int sqFlags)
582 return(TypeToQualType(type, NULL, type->ty_SQFlags & ~sqFlags, NULL));
585 #define dassert_type(type, cond) dassert(cond)