1 /*
2  * datatypes.h
3  *  Copyright (C) 2002-2015, Parrot Foundation.
4  *  License:  Artistic 2.0, see README.pod and LICENSE for details
5  *  Overview:
6  *     Parrot and native data types enums and type names.
7  *
8  *  Caveat:
9  *     Changing types here might break some tests.
10  *     Though appending a type and a name should be safe.
11  */
12 
13 #ifndef PARROT_DATATYPES_H_GUARD
14 #define PARROT_DATATYPES_H_GUARD
15 
16 #include "parrot/has_header.h"
17 
18 /* &gen_from_enum(datatypes.pasm) subst(s/enum_type_(\w+)/uc("DATATYPE_$1")/e) */
19 typedef enum {
20     enum_type_undef = 0,        /* illegal */
21     enum_first_type = 1,
22 
23     enum_type_INTVAL = 1,       /* parrot types */
24     enum_type_FLOATVAL,
25     enum_type_STRING,
26     enum_type_PMC,
27 
28     enum_type_char,             /* native integer types */
29     enum_type_short,
30     enum_type_int,
31     enum_type_long,
32     enum_type_longlong,
33 
34     enum_type_uchar,            /* native unsigned types */
35     enum_type_ushort,
36     enum_type_uint,
37     enum_type_ulong,
38     enum_type_ulonglong,
39 
40     enum_type_float,            /* native float types */
41     enum_type_double,
42     enum_type_longdouble,
43     enum_type_float128,
44 
45     enum_type_int8,             /* fixed size types */
46     enum_type_int16,
47     enum_type_int32,
48     enum_type_int64,
49 
50     enum_type_bit,
51     enum_type_uint1 = enum_type_bit,
52     enum_type_uint4,
53     enum_type_uint8,            /* unsigned variants */
54     enum_type_uint16,
55     enum_type_uint32,
56     enum_type_uint64,
57 
58     enum_type_void,
59 
60     enum_type_ptr,              /* native pointer */
61     enum_type_cstr,             /* 't' c string */
62     enum_type_struct_ptr,       /* pointer to another struct */
63     enum_type_struct,           /* a struct */
64     enum_type_union,            /* a union */
65     enum_type_func_ptr,         /* a function pointer */
66     enum_type_pshort,           /* '2' Integer PMC -> short */
67     enum_type_pint,             /* '3' Integer PMC -> int */
68     enum_type_plong,            /* '4' Integer PMC -> long */
69 
70     enum_type_sized,
71 
72     enum_last_type,             /* + one */
73 
74     enum_type_ref_flag = 0x40   /* call-by-reference */
75 } PARROT_DATA_TYPE;
76 
77 /* &end_gen */
78 struct _data_types {
79     PARROT_OBSERVER const char *name;
80     size_t size;
81     size_t align;
82 };
83 
84 #ifdef PARROT_HAS_COMPILER_OFFSETOF_ALIGNOF
85 #  define ALIGNOF(name, x) offsetof(struct {char c; x d;}, d)
86 #  define ALIGNOF1(x)      offsetof(struct {char c; x d;}, d)
87 #else
88 #  define ALIGNOF(name, x) PARROT_ALIGNOF_##name
89 #  define ALIGNOF1(name)   PARROT_ALIGNOF_##name
90 #endif
91 
92 extern const struct _data_types data_types[];
93 #if defined(INSIDE_GLOBAL_SETUP)
94 const struct _data_types data_types[] = {
95     /* parrot types */
96     { "INTVAL",     sizeof (INTVAL),             ALIGNOF(intval, INTVAL) },
97     { "FLOATVAL",   sizeof (FLOATVAL),           ALIGNOF(floatval, FLOATVAL) },
98     { "STRING",     sizeof (STRING *),           ALIGNOF(stringptr, STRING *) },
99     { "PMC",        sizeof (PMC *),              ALIGNOF(pmcptr, PMC *) },
100 
101     /* native integer types */
102     { "char",       sizeof (char),               ALIGNOF1(char) },
103     { "short",      sizeof (short),              ALIGNOF1(short) },
104     { "int",        sizeof (int),                ALIGNOF1(int) },
105     { "long",       sizeof (long),               ALIGNOF1(long) },
106 #  if PARROT_HAS_LONGLONG
107     { "longlong",   sizeof (long long),          ALIGNOF(longlong, long long) },
108 #  else
109     { "longlong",   0,                           0 },
110 #  endif
111 
112     /* native unsigned types */
113     { "uchar",      sizeof (unsigned char),      ALIGNOF(uchar, unsigned char) },
114     { "ushort",     sizeof (unsigned short),     ALIGNOF(ushort, unsigned short) },
115     { "uint",       sizeof (unsigned int),       ALIGNOF(uint, unsigned int) },
116     { "ulong",      sizeof (unsigned long),      ALIGNOF(ulong, unsigned long) },
117 #  if PARROT_HAS_LONGLONG
118     { "ulonglong",  sizeof (unsigned long long), ALIGNOF(ulonglong, unsigned long long) },
119 #  else
120     { "ulonglong",  0,                           0 },
121 #  endif
122 
123     /* native float types */
124     { "float",      sizeof (float),              ALIGNOF1(float) },
125     { "double",     sizeof (double),             ALIGNOF1(double) },
126     { "longdouble", sizeof (long double),        ALIGNOF(longdouble, long double)},
127 #  ifdef PARROT_HAS_FLOAT128
128     { "__float128", sizeof (__float128),         ALIGNOF1(__float128)},
129 #  else
130     { "__float128", 0,         			0 },
131 #  endif
132 
133     /* explicitly sized integer types */
134     { "int8",       1,                           ALIGNOF1(Parrot_Int1) },
135     { "int16",      2,                           ALIGNOF1(Parrot_Int2) },
136     { "int32",      4,                           ALIGNOF1(Parrot_Int4) },
137 #  if PARROT_HAS_INT64
138     { "int64",      8,                           ALIGNOF1(Parrot_Int8) },
139 #  else
140     { "int64",      0,                           0 },
141 #  endif
142 
143     /* unsigned variants */
144     { "uint1",      0,                           0 }, /* = bit */
145     { "uint4",      0,                           0 },
146     { "uint8",      1,                           ALIGNOF1(Parrot_Int1) },
147     { "uint16",     2,                           ALIGNOF1(Parrot_Int2) },
148     { "uint32",     4,                           ALIGNOF1(Parrot_Int4) },
149 #  if PARROT_HAS_INT64
150     { "uint64",     8,                           ALIGNOF1(Parrot_Int8) },
151 #  else
152     { "uint64",     0,                           0 },
153 #  endif
154 
155     { "void",       0,                           0 },
156 
157     { "ptr",        sizeof (void *),             ALIGNOF(voidptr, void *) },
158     { "cstr",       sizeof (char *),             ALIGNOF(charptr, char *) },
159     { "struct_ptr", sizeof (void *),             ALIGNOF(voidptr, void *) },
160     { "struct",     0,                           0 },
161     { "union",      0,                           0 },
162     { "func_ptr",   sizeof (funcptr_t),          ALIGNOF1(funcptr_t) },
163     { "pshort",     sizeof (short),              ALIGNOF1(short) },
164     { "pint",       sizeof (int),                ALIGNOF1(int) },
165     { "plong",      sizeof (long),               ALIGNOF1(long) },
166 
167     { "sized",      0,                           0 },
168 
169     { "illegal",    0,                           0 }
170 };
171 #endif /* INSIDE_GLOBAL_SETUP */
172 
173 #ifdef PARROT_HAS_INF_NAN
174 #  include <math.h>
175 #  define PARROT_FLOATVAL_INF_POSITIVE	INFINITY
176 #  define PARROT_FLOATVAL_INF_NEGATIVE	-INFINITY
177 #  define PARROT_FLOATVAL_NAN_QUIET	NAN
178 #  define PARROT_FLOATVAL_IS_POSINF(x)  (isinf(x) && (x) > 0)
179 #  define PARROT_FLOATVAL_IS_NEGINF(x)  (isinf(x) && (x) < 0)
180 #  define PARROT_FLOATVAL_IS_NAN(x)     isnan(x)
181 #  define PARROT_FLOATVAL_IS_INF_OR_NAN(x) (isnan(x) || isinf(x))
182 #else
183 #  define PARROT_FLOATVAL_INF_POSITIVE  Parrot_dt_divide_floatval_by_zero(interp, 1.0)
184 #  define PARROT_FLOATVAL_INF_NEGATIVE  Parrot_dt_divide_floatval_by_zero(interp, -1.0)
185 #  define PARROT_FLOATVAL_NAN_QUIET     Parrot_dt_divide_floatval_by_zero(interp, 0.0)
186 #  define PARROT_FLOATVAL_IS_POSINF(x)  ((x) == PARROT_FLOATVAL_INF_POSITIVE)
187 #  define PARROT_FLOATVAL_IS_NEGINF(x)  ((x) == PARROT_FLOATVAL_INF_NEGATIVE)
188 #  define PARROT_FLOATVAL_IS_NAN(x)     ((x) != (x))
189 #  define PARROT_FLOATVAL_IS_INF_OR_NAN(x) (PARROT_FLOATVAL_IS_POSINF(x) \
190           || PARROT_FLOATVAL_IS_NEGINF(x) || PARROT_FLOATVAL_IS_NAN(x))
191 #endif
192 
193 #define PARROT_CSTRING_INF_POSITIVE    "Inf"
194 #define PARROT_CSTRING_INF_NEGATIVE    "-Inf"
195 #define PARROT_CSTRING_NAN_QUIET       "NaN"
196 
197 
198 /* HEADERIZER BEGIN: src/datatypes.c */
199 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
200 
201 PARROT_EXPORT
202 FLOATVAL Parrot_dt_divide_floatval_by_zero(PARROT_INTERP, FLOATVAL num);
203 
204 PARROT_EXPORT
205 PARROT_WARN_UNUSED_RESULT
206 INTVAL Parrot_dt_get_datatype_enum(PARROT_INTERP, ARGIN(STRING *type_name))
207         __attribute__nonnull__(1)
208         __attribute__nonnull__(2);
209 
210 PARROT_EXPORT
211 PARROT_WARN_UNUSED_RESULT
212 PARROT_CANNOT_RETURN_NULL
213 STRING * Parrot_dt_get_datatype_name(PARROT_INTERP, INTVAL type)
214         __attribute__nonnull__(1);
215 
216 #define ASSERT_ARGS_Parrot_dt_divide_floatval_by_zero \
217      __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
218 #define ASSERT_ARGS_Parrot_dt_get_datatype_enum __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
219        PARROT_ASSERT_ARG(interp) \
220     , PARROT_ASSERT_ARG(type_name))
221 #define ASSERT_ARGS_Parrot_dt_get_datatype_name __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
222        PARROT_ASSERT_ARG(interp))
223 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
224 /* HEADERIZER END: src/datatypes.c */
225 
226 #endif /* PARROT_DATATYPES_H_GUARD */
227 
228 /*
229  * Local variables:
230  *   c-file-style: "parrot"
231  * End:
232  * vim: expandtab shiftwidth=4 cinoptions='\:2=2' :
233  */
234