#include "jit-internal.h"
#include "jit-apply-rules.h"
#include "jit-rules.h"
struct _jit_type const _jit_type_void_def =
{1, JIT_TYPE_VOID, 0, 1, 0, 1, 1};
jit_type_t const jit_type_void = (jit_type_t)&_jit_type_void_def;
struct _jit_type const _jit_type_sbyte_def =
{1, JIT_TYPE_SBYTE, 0, 1, 0, sizeof(jit_sbyte), JIT_ALIGN_SBYTE};
jit_type_t const jit_type_sbyte = (jit_type_t)&_jit_type_sbyte_def;
struct _jit_type const _jit_type_ubyte_def =
{1, JIT_TYPE_UBYTE, 0, 1, 0, sizeof(jit_ubyte), JIT_ALIGN_UBYTE};
jit_type_t const jit_type_ubyte = (jit_type_t)&_jit_type_ubyte_def;
struct _jit_type const _jit_type_short_def =
{1, JIT_TYPE_SHORT, 0, 1, 0, sizeof(jit_short), JIT_ALIGN_SHORT};
jit_type_t const jit_type_short = (jit_type_t)&_jit_type_short_def;
struct _jit_type const _jit_type_ushort_def =
{1, JIT_TYPE_USHORT, 0, 1, 0, sizeof(jit_ushort), JIT_ALIGN_USHORT};
jit_type_t const jit_type_ushort = (jit_type_t)&_jit_type_ushort_def;
struct _jit_type const _jit_type_int_def =
{1, JIT_TYPE_INT, 0, 1, 0, sizeof(jit_int), JIT_ALIGN_INT};
jit_type_t const jit_type_int = (jit_type_t)&_jit_type_int_def;
struct _jit_type const _jit_type_uint_def =
{1, JIT_TYPE_UINT, 0, 1, 0, sizeof(jit_uint), JIT_ALIGN_UINT};
jit_type_t const jit_type_uint = (jit_type_t)&_jit_type_uint_def;
struct _jit_type const _jit_type_nint_def =
{1, JIT_TYPE_NINT, 0, 1, 0, sizeof(jit_nint), JIT_ALIGN_NINT};
jit_type_t const jit_type_nint = (jit_type_t)&_jit_type_nint_def;
struct _jit_type const _jit_type_nuint_def =
{1, JIT_TYPE_NUINT, 0, 1, 0, sizeof(jit_nuint), JIT_ALIGN_NUINT};
jit_type_t const jit_type_nuint = (jit_type_t)&_jit_type_nuint_def;
struct _jit_type const _jit_type_long_def =
{1, JIT_TYPE_LONG, 0, 1, 0, sizeof(jit_long), JIT_ALIGN_LONG};
jit_type_t const jit_type_long = (jit_type_t)&_jit_type_long_def;
struct _jit_type const _jit_type_ulong_def =
{1, JIT_TYPE_ULONG, 0, 1, 0, sizeof(jit_ulong), JIT_ALIGN_ULONG};
jit_type_t const jit_type_ulong = (jit_type_t)&_jit_type_ulong_def;
struct _jit_type const _jit_type_float32_def =
{1, JIT_TYPE_FLOAT32, 0, 1, 0, sizeof(jit_float32), JIT_ALIGN_FLOAT32};
jit_type_t const jit_type_float32 = (jit_type_t)&_jit_type_float32_def;
struct _jit_type const _jit_type_float64_def =
{1, JIT_TYPE_FLOAT64, 0, 1, 0, sizeof(jit_float64), JIT_ALIGN_FLOAT64};
jit_type_t const jit_type_float64 = (jit_type_t)&_jit_type_float64_def;
struct _jit_type const _jit_type_nfloat_def =
{1, JIT_TYPE_NFLOAT, 0, 1, 0, sizeof(jit_nfloat), JIT_ALIGN_NFLOAT};
jit_type_t const jit_type_nfloat = (jit_type_t)&_jit_type_nfloat_def;
struct _jit_type const _jit_type_void_ptr_def =
{1, JIT_TYPE_PTR, 0, 1, 0, sizeof(void *), JIT_ALIGN_PTR,
(jit_type_t)&_jit_type_void_def};
jit_type_t const jit_type_void_ptr = (jit_type_t)&_jit_type_void_ptr_def;
#define DECLARE_TAGGED(name,real,tag) \
static struct jit_tagged_type const name##_tagged = \
{{1, JIT_TYPE_FIRST_TAGGED + (tag), 0, 1, 0, 0, 0, \
(jit_type_t)&_jit_type_##real}, 0, 0}; \
jit_type_t const jit_type_##name = (jit_type_t)&name##_tagged
DECLARE_TAGGED(sys_bool, ubyte_def, JIT_TYPETAG_SYS_BOOL);
#ifdef __CHAR_UNSIGNED__
DECLARE_TAGGED(sys_char, ubyte_def, JIT_TYPETAG_SYS_CHAR);
#else
DECLARE_TAGGED(sys_char, sbyte_def, JIT_TYPETAG_SYS_CHAR);
#endif
DECLARE_TAGGED(sys_schar, sbyte_def, JIT_TYPETAG_SYS_SCHAR);
DECLARE_TAGGED(sys_uchar, ubyte_def, JIT_TYPETAG_SYS_UCHAR);
#if SIZEOF_SHORT == 4
DECLARE_TAGGED(sys_short, int_def, JIT_TYPETAG_SYS_SHORT);
DECLARE_TAGGED(sys_ushort, uint_def, JIT_TYPETAG_SYS_USHORT);
#elif SIZEOF_SHORT == 8
DECLARE_TAGGED(sys_short, long_def, JIT_TYPETAG_SYS_SHORT);
DECLARE_TAGGED(sys_ushort, ulong_def, JIT_TYPETAG_SYS_USHORT);
#else
DECLARE_TAGGED(sys_short, short_def, JIT_TYPETAG_SYS_SHORT);
DECLARE_TAGGED(sys_ushort, ushort_def, JIT_TYPETAG_SYS_USHORT);
#endif
#if SIZEOF_INT == 8
DECLARE_TAGGED(sys_int, long_def, JIT_TYPETAG_SYS_INT);
DECLARE_TAGGED(sys_uint, ulong_def, JIT_TYPETAG_SYS_UINT);
#elif SIZEOF_INT == 2
DECLARE_TAGGED(sys_int, short_def, JIT_TYPETAG_SYS_INT);
DECLARE_TAGGED(sys_uint, ushort_def, JIT_TYPETAG_SYS_UINT);
#else
DECLARE_TAGGED(sys_int, int_def, JIT_TYPETAG_SYS_INT);
DECLARE_TAGGED(sys_uint, uint_def, JIT_TYPETAG_SYS_UINT);
#endif
#if SIZEOF_LONG == 8
DECLARE_TAGGED(sys_long, long_def, JIT_TYPETAG_SYS_LONG);
DECLARE_TAGGED(sys_ulong, ulong_def, JIT_TYPETAG_SYS_ULONG);
#elif SIZEOF_LONG == 2
DECLARE_TAGGED(sys_long, short_def, JIT_TYPETAG_SYS_LONG);
DECLARE_TAGGED(sys_ulong, ushort_def, JIT_TYPETAG_SYS_ULONG);
#else
DECLARE_TAGGED(sys_long, int_def, JIT_TYPETAG_SYS_LONG);
DECLARE_TAGGED(sys_ulong, uint_def, JIT_TYPETAG_SYS_ULONG);
#endif
#if SIZEOF_LONG_LONG == 8 || SIZEOF___INT64 == 8
DECLARE_TAGGED(sys_longlong, long_def, JIT_TYPETAG_SYS_LONGLONG);
DECLARE_TAGGED(sys_ulonglong, ulong_def, JIT_TYPETAG_SYS_ULONGLONG);
#elif SIZEOF_LONG_LONG == 4
DECLARE_TAGGED(sys_longlong, int_def, JIT_TYPETAG_SYS_LONGLONG);
DECLARE_TAGGED(sys_ulonglong, uint_def, JIT_TYPETAG_SYS_ULONGLONG);
#elif SIZEOF_LONG_LONG == 2
DECLARE_TAGGED(sys_longlong, short_def, JIT_TYPETAG_SYS_LONGLONG);
DECLARE_TAGGED(sys_ulonglong, ushort_def, JIT_TYPETAG_SYS_ULONGLONG);
#else
DECLARE_TAGGED(sys_longlong, long_def, JIT_TYPETAG_SYS_LONGLONG);
DECLARE_TAGGED(sys_ulonglong, ulong_def, JIT_TYPETAG_SYS_ULONGLONG);
#endif
DECLARE_TAGGED(sys_float, float32_def, JIT_TYPETAG_SYS_FLOAT);
DECLARE_TAGGED(sys_double, float64_def, JIT_TYPETAG_SYS_DOUBLE);
DECLARE_TAGGED(sys_long_double, nfloat_def, JIT_TYPETAG_SYS_LONGDOUBLE);
#define JIT_OFFSET_IS_INTERNAL (((jit_nuint)1) << (sizeof(jit_nint) * 8 - 1))
#define JIT_OFFSET_NOT_SET (~((jit_nuint)0))
#define JIT_LAYOUT_NEEDED 1
#define JIT_LAYOUT_EXPLICIT_SIZE 2
#define JIT_LAYOUT_EXPLICIT_ALIGN 4
static void perform_layout(jit_type_t type)
{
jit_nuint size = 0;
jit_nuint maxSize = 0;
jit_nuint maxAlign = 1;
jit_nuint alignLimit;
jit_nuint fieldSize;
jit_nuint fieldAlign;
unsigned int index;
#ifdef JIT_ALIGN_OVERRIDES
if((type->layout_flags & JIT_LAYOUT_EXPLICIT_ALIGN) != 0)
{
alignLimit = type->alignment;
}
else
#endif
{
alignLimit = 0;
}
for(index = 0; index < type->num_components; ++index)
{
fieldSize = jit_type_get_size(type->components[index].type);
fieldAlign = jit_type_get_alignment(type->components[index].type);
if(alignLimit != 0 && fieldAlign > alignLimit)
{
fieldAlign = alignLimit;
}
if(type->kind == JIT_TYPE_STRUCT)
{
if((type->components[index].offset & JIT_OFFSET_IS_INTERNAL) != 0)
{
if((size % fieldAlign) != 0)
{
size += fieldAlign - (size % fieldAlign);
}
type->components[index].offset = JIT_OFFSET_IS_INTERNAL | size;
size += fieldSize;
}
else
{
size = type->components[index].offset + fieldSize;
}
if(size > maxSize)
{
maxSize = size;
}
}
else
{
type->components[index].offset = JIT_OFFSET_IS_INTERNAL | 0;
if((fieldSize % fieldAlign) != 0)
{
fieldSize += fieldAlign - (fieldSize % fieldAlign);
}
if(fieldSize > maxSize)
{
maxSize = fieldSize;
}
}
if(fieldAlign > maxAlign)
{
maxAlign = fieldAlign;
}
}
if((maxSize % maxAlign) != 0)
{
maxSize += maxAlign - (maxSize % maxAlign);
}
if((type->layout_flags & JIT_LAYOUT_EXPLICIT_SIZE) != 0)
{
if(maxSize > type->size)
{
type->size = maxSize;
}
}
else
{
type->size = maxSize;
}
if(maxAlign > type->alignment)
{
type->alignment = maxAlign;
}
}
jit_type_t jit_type_copy(jit_type_t type)
{
if(!type || type->is_fixed)
{
return type;
}
++(type->ref_count);
return type;
}
void jit_type_free(jit_type_t type)
{
unsigned int index;
if(!type || type->is_fixed)
{
return;
}
if(--(type->ref_count) != 0)
{
return;
}
jit_type_free(type->sub_type);
for(index = 0; index < type->num_components; ++index)
{
jit_type_free(type->components[index].type);
if(type->components[index].name)
{
jit_free(type->components[index].name);
}
}
if(type->kind >= JIT_TYPE_FIRST_TAGGED)
{
struct jit_tagged_type *tagged = (struct jit_tagged_type *)type;
if(tagged->free_func)
{
(*(tagged->free_func))(tagged->data);
}
}
jit_free(type);
}
static jit_type_t create_complex(int kind, jit_type_t *types,
unsigned int num, int incref)
{
jit_type_t type;
unsigned int index;
if(num <= 1)
{
type = jit_cnew(struct _jit_type);
}
else
{
type = (jit_type_t)jit_calloc
(1, sizeof(struct _jit_type) +
(num - 1) * sizeof(struct jit_component));
}
if(!type)
{
return 0;
}
type->ref_count = 1;
type->kind = kind;
type->layout_flags = JIT_LAYOUT_NEEDED;
type->num_components = num;
for(index = 0; index < num; ++index)
{
if(incref)
{
type->components[index].type = jit_type_copy(types[index]);
}
else
{
type->components[index].type = types[index];
}
type->components[index].offset = JIT_OFFSET_NOT_SET;
type->components[index].name = 0;
}
return type;
}
jit_type_t jit_type_create_struct(jit_type_t *fields, unsigned int num_fields,
int incref)
{
return create_complex(JIT_TYPE_STRUCT, fields, num_fields, incref);
}
jit_type_t jit_type_create_union(jit_type_t *fields, unsigned int num_fields,
int incref)
{
return create_complex(JIT_TYPE_UNION, fields, num_fields, incref);
}
jit_type_t jit_type_create_signature(jit_abi_t abi, jit_type_t return_type,
jit_type_t *params,
unsigned int num_params, int incref)
{
jit_type_t type;
type = create_complex(JIT_TYPE_SIGNATURE, params, num_params, incref);
if(type)
{
type->abi = (int)abi;
type->layout_flags = 0;
type->size = 0;
type->alignment = JIT_ALIGN_PTR;
if(incref)
{
type->sub_type = jit_type_copy(return_type);
}
else
{
type->sub_type = return_type;
}
}
return type;
}
jit_type_t jit_type_create_pointer(jit_type_t type, int incref)
{
jit_type_t ntype;
if(type == jit_type_void)
{
return jit_type_void_ptr;
}
if((ntype = jit_cnew(struct _jit_type)) == 0)
{
return 0;
}
ntype->ref_count = 1;
ntype->kind = JIT_TYPE_PTR;
ntype->size = sizeof(void *);
ntype->alignment = JIT_ALIGN_PTR;
if(incref)
{
ntype->sub_type = jit_type_copy(type);
}
else
{
ntype->sub_type = type;
}
return ntype;
}
jit_type_t jit_type_create_tagged(jit_type_t type, int kind, void *data,
jit_meta_free_func free_func, int incref)
{
struct jit_tagged_type *ntype;
if((ntype = jit_cnew(struct jit_tagged_type)) == 0)
{
return 0;
}
ntype->type.ref_count = 1;
ntype->type.kind = JIT_TYPE_FIRST_TAGGED + kind;
ntype->type.size = 0;
ntype->type.alignment = 1;
if(incref)
{
ntype->type.sub_type = jit_type_copy(type);
}
else
{
ntype->type.sub_type = type;
}
ntype->data = data;
ntype->free_func = free_func;
return &(ntype->type);
}
int jit_type_set_names(jit_type_t type, char **names, unsigned int num_names)
{
char *temp;
if(!type || type->is_fixed || !names)
{
return 1;
}
if(type->kind == JIT_TYPE_STRUCT || type->kind == JIT_TYPE_UNION ||
type->kind == JIT_TYPE_SIGNATURE)
{
if(num_names > type->num_components)
{
num_names = type->num_components;
}
while(num_names > 0)
{
--num_names;
if(type->components[num_names].name)
{
jit_free(type->components[num_names].name);
type->components[num_names].name = 0;
}
if(names[num_names])
{
temp = jit_strdup(names[num_names]);
if(!temp)
{
return 0;
}
type->components[num_names].name = temp;
}
}
}
return 1;
}
void jit_type_set_size_and_alignment(jit_type_t type, jit_nint size,
jit_nint alignment)
{
if(!type)
{
return;
}
if(type->kind == JIT_TYPE_STRUCT || type->kind == JIT_TYPE_UNION)
{
type->size = (jit_nuint)size;
type->alignment = (jit_nuint)alignment;
if(size != -1)
{
type->layout_flags |= JIT_LAYOUT_EXPLICIT_SIZE;
}
if(alignment != -1)
{
type->layout_flags |= JIT_LAYOUT_EXPLICIT_ALIGN;
}
type->layout_flags |= JIT_LAYOUT_NEEDED;
}
}
void jit_type_set_offset(jit_type_t type, unsigned int field_index,
jit_nuint offset)
{
if(!type || field_index >= type->num_components)
{
return;
}
if(type->kind == JIT_TYPE_STRUCT || type->kind == JIT_TYPE_UNION)
{
type->components[field_index].offset = offset;
type->layout_flags |= JIT_LAYOUT_NEEDED;
}
}
int jit_type_get_kind(jit_type_t type)
{
if(!type)
{
return JIT_TYPE_INVALID;
}
else
{
return type->kind;
}
}
jit_nuint jit_type_get_size(jit_type_t type)
{
if(!type)
{
return 0;
}
if(type->kind == JIT_TYPE_SIGNATURE)
{
return sizeof(void *);
}
else if(type->kind >= JIT_TYPE_FIRST_TAGGED)
{
return jit_type_get_size(type->sub_type);
}
if((type->layout_flags & JIT_LAYOUT_NEEDED) != 0)
{
perform_layout(type);
}
return type->size;
}
jit_nuint jit_type_get_alignment(jit_type_t type)
{
if(!type)
{
return 0;
}
if(type->kind >= JIT_TYPE_FIRST_TAGGED)
{
return jit_type_get_alignment(type->sub_type);
}
if((type->layout_flags & JIT_LAYOUT_NEEDED) != 0)
{
perform_layout(type);
}
return type->alignment;
}
unsigned int jit_type_num_fields(jit_type_t type)
{
if(!type ||
(type->kind != JIT_TYPE_STRUCT && type->kind != JIT_TYPE_UNION))
{
return 0;
}
else
{
return type->num_components;
}
}
jit_type_t jit_type_get_field(jit_type_t type, unsigned int field_index)
{
if(!type || field_index >= type->num_components)
{
return 0;
}
if(type->kind == JIT_TYPE_STRUCT || type->kind == JIT_TYPE_UNION)
{
return type->components[field_index].type;
}
return 0;
}
jit_nuint jit_type_get_offset(jit_type_t type, unsigned int field_index)
{
if(!type || field_index >= type->num_components)
{
return 0;
}
if(type->kind != JIT_TYPE_STRUCT && type->kind != JIT_TYPE_UNION)
{
return 0;
}
if((type->layout_flags & JIT_LAYOUT_NEEDED) != 0)
{
perform_layout(type);
}
return type->components[field_index].offset & ~JIT_OFFSET_IS_INTERNAL;
}
const char *jit_type_get_name(jit_type_t type, unsigned int index)
{
if(!type || index >= type->num_components)
{
return 0;
}
else
{
return type->components[index].name;
}
}
unsigned int jit_type_find_name(jit_type_t type, const char *name)
{
unsigned int index;
if(!type || !name)
{
return JIT_INVALID_NAME;
}
if(type->kind == JIT_TYPE_STRUCT || type->kind == JIT_TYPE_UNION ||
type->kind == JIT_TYPE_SIGNATURE)
{
for(index = 0; index < type->num_components; ++index)
{
if(type->components[index].name &&
!jit_strcmp(type->components[index].name, name))
{
return index;
}
}
}
return JIT_INVALID_NAME;
}
unsigned int jit_type_num_params(jit_type_t type)
{
if(!type || type->kind != JIT_TYPE_SIGNATURE)
{
return 0;
}
else
{
return type->num_components;
}
}
jit_type_t jit_type_get_return(jit_type_t type)
{
if(type)
{
if(type->kind == JIT_TYPE_SIGNATURE)
{
return type->sub_type;
}
}
return 0;
}
jit_type_t jit_type_get_param(jit_type_t type, unsigned int param_index)
{
if(!type || param_index >= type->num_components)
{
return 0;
}
if(type->kind == JIT_TYPE_SIGNATURE)
{
return type->components[param_index].type;
}
return 0;
}
jit_abi_t jit_type_get_abi(jit_type_t type)
{
if(type)
{
return (jit_abi_t)(type->abi);
}
else
{
return jit_abi_cdecl;
}
}
jit_type_t jit_type_get_ref(jit_type_t type)
{
if(type)
{
if(type->kind == JIT_TYPE_PTR)
{
return type->sub_type;
}
}
return 0;
}
jit_type_t jit_type_get_tagged_type(jit_type_t type)
{
if(type && type->kind >= JIT_TYPE_FIRST_TAGGED)
{
return type->sub_type;
}
else
{
return 0;
}
}
void jit_type_set_tagged_type(jit_type_t type, jit_type_t underlying,
int incref)
{
if(type && type->kind >= JIT_TYPE_FIRST_TAGGED)
{
if(type->sub_type != underlying)
{
jit_type_free(type->sub_type);
if(incref)
{
type->sub_type = jit_type_copy(underlying);
}
else
{
type->sub_type = underlying;
}
}
}
}
int jit_type_get_tagged_kind(jit_type_t type)
{
if(type && type->kind >= JIT_TYPE_FIRST_TAGGED)
{
return type->kind - JIT_TYPE_FIRST_TAGGED;
}
else
{
return -1;
}
}
void *jit_type_get_tagged_data(jit_type_t type)
{
if(type && type->kind >= JIT_TYPE_FIRST_TAGGED)
{
return ((struct jit_tagged_type *)type)->data;
}
else
{
return 0;
}
}
void jit_type_set_tagged_data(jit_type_t type, void *data,
jit_meta_free_func free_func)
{
if(type && type->kind >= JIT_TYPE_FIRST_TAGGED)
{
struct jit_tagged_type *tagged = (struct jit_tagged_type *)type;
if(tagged->data != data)
{
if(tagged->free_func)
{
(*(tagged->free_func))(tagged->data);
}
tagged->data = data;
tagged->free_func = free_func;
}
}
}
int jit_type_is_primitive(jit_type_t type)
{
if(type)
{
return (type->kind <= JIT_TYPE_MAX_PRIMITIVE);
}
else
{
return 0;
}
}
int jit_type_is_struct(jit_type_t type)
{
if(type)
{
return (type->kind == JIT_TYPE_STRUCT);
}
else
{
return 0;
}
}
int jit_type_is_union(jit_type_t type)
{
if(type)
{
return (type->kind == JIT_TYPE_UNION);
}
else
{
return 0;
}
}
int jit_type_is_signature(jit_type_t type)
{
if(type)
{
return (type->kind == JIT_TYPE_SIGNATURE);
}
else
{
return 0;
}
}
int jit_type_is_pointer(jit_type_t type)
{
if(type)
{
return (type->kind == JIT_TYPE_PTR);
}
else
{
return 0;
}
}
int jit_type_is_tagged(jit_type_t type)
{
if(type)
{
return (type->kind >= JIT_TYPE_FIRST_TAGGED);
}
else
{
return 0;
}
}
jit_nuint jit_type_best_alignment(void)
{
return JIT_BEST_ALIGNMENT;
}
jit_type_t jit_type_normalize(jit_type_t type)
{
while(type && type->kind >= JIT_TYPE_FIRST_TAGGED)
{
type = type->sub_type;
}
if(!type)
{
return type;
}
if(type == jit_type_nint || type->kind == JIT_TYPE_PTR ||
type->kind == JIT_TYPE_SIGNATURE)
{
#ifdef JIT_NATIVE_INT32
return jit_type_int;
#else
return jit_type_long;
#endif
}
else if(type == jit_type_nuint)
{
#ifdef JIT_NATIVE_INT32
return jit_type_uint;
#else
return jit_type_ulong;
#endif
}
else if(type == jit_type_nfloat)
{
if(sizeof(jit_nfloat) == sizeof(jit_float64))
{
return jit_type_float64;
}
else if(sizeof(jit_nfloat) == sizeof(jit_float32))
{
return jit_type_float32;
}
}
return type;
}
jit_type_t jit_type_remove_tags(jit_type_t type)
{
while(type && type->kind >= JIT_TYPE_FIRST_TAGGED)
{
type = type->sub_type;
}
return type;
}
jit_type_t jit_type_promote_int(jit_type_t type)
{
if(type == jit_type_sbyte || type == jit_type_short)
{
return jit_type_int;
}
else if(type == jit_type_ubyte || type == jit_type_ushort)
{
return jit_type_uint;
}
else
{
return type;
}
}
int jit_type_return_via_pointer(jit_type_t type)
{
extern unsigned char const _jit_apply_return_in_reg[];
unsigned int size;
type = jit_type_normalize(type);
if(!jit_type_is_struct(type) && !jit_type_is_union(type))
{
return 0;
}
size = jit_type_get_size(type);
if(size >= 1 && size <= 64)
{
if((_jit_apply_return_in_reg[(size - 1) / 8] &
(1 << ((size - 1) % 8))) != 0)
{
return 0;
}
}
return 1;
}
int jit_type_has_tag(jit_type_t type, int kind)
{
while(type != 0 && type->kind >= JIT_TYPE_FIRST_TAGGED)
{
if(type->kind == (JIT_TYPE_FIRST_TAGGED + kind))
{
return 1;
}
type = type->sub_type;
}
return 0;
}