[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The functions that are defined in <jit/jit-type.h>
allow
the library user to create and manipulate objects that represent
native system types. For example, jit_type_int
represents
the signed 32-bit integer type.
Each jit_type_t
object represents a basic system type,
be it a primitive, a struct, a union, a pointer, or a function signature.
The library uses this information to lay out values in memory.
The following pre-defined types are available:
jit_type_void
Represents the void
type.
jit_type_sbyte
Represents a signed 8-bit integer type.
jit_type_ubyte
Represents an unsigned 8-bit integer type.
jit_type_short
Represents a signed 16-bit integer type.
jit_type_ushort
Represents an unsigned 16-bit integer type.
jit_type_int
Represents a signed 32-bit integer type.
jit_type_uint
Represents an unsigned 32-bit integer type.
jit_type_nint
Represents a signed integer type that has the same size and alignment as a native pointer.
jit_type_nuint
Represents an unsigned integer type that has the same size and alignment as a native pointer.
jit_type_long
Represents a signed 64-bit integer type.
jit_type_ulong
Represents an unsigned 64-bit integer type.
jit_type_float32
Represents a 32-bit floating point type.
jit_type_float64
Represents a 64-bit floating point type.
jit_type_nfloat
Represents a floating point type that represents the greatest precision supported on the native platform.
jit_type_void_ptr
Represents the system’s void *
type. This can be used wherever
a native pointer type is required.
Type descriptors are reference counted. You can make a copy of a type
descriptor using the jit_type_copy
function, and free the copy with
jit_type_free
.
Some languages have special versions of the primitive numeric types
(e.g. boolean types, 16-bit Unicode character types, enumerations, etc).
If it is important to distinguish these special versions from the
numeric types, then you should use the jit_type_create_tagged
function below.
The following types correspond to the system types on the local
platform. i.e. jit_type_sys_int
will be the same size as
long
on the local platform, whereas jit_type_long
is
always 64 bits in size. These types should not be used to compile
code that is intended to work identically on all platforms:
jit_type_sys_bool
Corresponds to the system bool
type.
jit_type_sys_char
Corresponds to the system char
type. This may be either signed
or unsigned, depending upon the underlying system.
jit_type_sys_schar
Corresponds to the system signed char
type.
jit_type_sys_uchar
Corresponds to the system unsigned char
type.
jit_type_sys_short
Corresponds to the system short
type.
jit_type_sys_ushort
Corresponds to the system unsigned short
type.
jit_type_sys_int
Corresponds to the system int
type.
jit_type_sys_uint
Corresponds to the system unsigned int
type.
jit_type_sys_long
Corresponds to the system long
type.
jit_type_sys_ulong
Corresponds to the system unsigned long
type.
jit_type_sys_longlong
Corresponds to the system long long
type (__int64
under Win32).
jit_type_sys_ulonglong
Corresponds to the system unsigned long long
type
(unsigned __int64
under Win32).
jit_type_sys_float
Corresponds to the system float
type.
jit_type_sys_double
Corresponds to the system double
type.
jit_type_sys_long_double
Corresponds to the system long double
type.
Make a copy of the type descriptor type by increasing its reference count.
Free a type descriptor by decreasing its reference count. This function is safe to use on pre-defined types, which are never actually freed.
Create a type descriptor for a structure. Returns NULL if out of memory. If there are no fields, then the size of the structure will be zero. It is necessary to add a padding field if the language does not allow zero-sized structures. The reference counts on the field types are incremented if incref is non-zero.
The libjit
library does not provide any special support for
implementing structure inheritance, where one structure extends the
definition of another. The effect of inheritance can be achieved
by always allocating the first field of a structure to be an instance
of the inherited structure. Multiple inheritance can be supported
by allocating several special fields at the front of an inheriting
structure.
Similarly, no special support is provided for vtables. The program is responsible for allocating an appropriate slot in a structure to contain the vtable pointer, and dereferencing it wherever necessary. The vtable will itself be a structure, containing signature types for each of the method slots.
The choice not to provide special support for inheritance and vtables
in libjit
was deliberate. The layout of objects and vtables
is highly specific to the language and virtual machine being emulated,
and no single scheme can hope to capture all possibilities.
Create a type descriptor for a union. Returns NULL if out of memory. If there are no fields, then the size of the union will be zero. It is necessary to add a padding field if the language does not allow zero-sized unions. The reference counts on the field types are incremented if incref is non-zero.
Create a type descriptor for a function signature. Returns NULL if out of memory. The reference counts on the component types are incremented if incref is non-zero.
When used as a structure or union field, function signatures are laid out like pointers. That is, they represent a pointer to a function that has the specified parameters and return type.
The abi parameter specifies the Application Binary Interface (ABI) that the function uses. It may be one of the following values:
jit_abi_cdecl
Use the native C ABI definitions of the underlying platform.
jit_abi_vararg
Use the native C ABI definitions of the underlying platform, and allow for an optional list of variable argument parameters.
jit_abi_stdcall
Use the Win32 STDCALL ABI definitions, whereby the callee pops
its arguments rather than the caller. If the platform does
not support this type of ABI, then jit_abi_stdcall
will be
identical to jit_abi_cdecl
.
jit_abi_fastcall
Use the Win32 FASTCALL ABI definitions, whereby the callee pops
its arguments rather than the caller, and the first two word
arguments are passed in ECX and EDX. If the platform does
not support this type of ABI, then jit_abi_fastcall
will be
identical to jit_abi_cdecl
.
Create a type descriptor for a pointer to another type. Returns NULL if out of memory. The reference count on type is incremented if incref is non-zero.
Tag a type with some additional user data. Tagging is typically used by
higher-level programs to embed extra information about a type that
libjit
itself does not support.
As an example, a language might have a 16-bit Unicode character type
and a 16-bit unsigned integer type that are distinct types, even though
they share the same fundamental representation (jit_ushort
).
Tagging allows the program to distinguish these two types, when
it is necessary to do so, without affecting libjit
’s ability
to compile the code efficiently.
The kind is a small positive integer value that the program
can use to distinguish multiple tag types. The data pointer is
the actual data that you wish to store. And free_func is a
function that is used to free data when the type is freed
with jit_type_free
.
If you need to store more than one piece of information, you can
tag a type multiple times. The order in which multiple tags are
applied is irrelevant to libjit
, although it may be relevant
to the higher-level program.
Tag kinds of 10000 or greater are reserved for libjit
itself.
The following special tag kinds are currently provided in the
base implementation:
JIT_TYPETAG_NAME
The data pointer is a char *
string indicating a friendly
name to display for the type.
JIT_TYPETAG_STRUCT_NAME
JIT_TYPETAG_UNION_NAME
JIT_TYPETAG_ENUM_NAME
The data pointer is a char *
string indicating a friendly
name to display for a struct
, union
, or enum
type.
This is for languages like C that have separate naming scopes for
typedef’s and structures.
JIT_TYPETAG_CONST
The underlying value is assumed to have const
semantics.
The libjit
library doesn’t enforce such semantics: it is
up to the front-end to only use constant values in appopriate contexts.
JIT_TYPETAG_VOLATILE
The underlying value is assumed to be volatile. The libjit
library will automatically call jit_value_set_volatile
when a
value is constructed using this type.
JIT_TYPETAG_REFERENCE
The underlying value is a pointer, but it is assumed to refer to a pass-by-reference parameter.
JIT_TYPETAG_OUTPUT
This is similar to JIT_TYPETAG_REFERENCE
, except that the
underlying parameter is assumed to be output-only.
JIT_TYPETAG_RESTRICT
The underlying type is marked as restrict
. Normally ignored.
JIT_TYPETAG_SYS_BOOL
JIT_TYPETAG_SYS_CHAR
JIT_TYPETAG_SYS_SCHAR
JIT_TYPETAG_SYS_UCHAR
JIT_TYPETAG_SYS_SHORT
JIT_TYPETAG_SYS_USHORT
JIT_TYPETAG_SYS_INT
JIT_TYPETAG_SYS_UINT
JIT_TYPETAG_SYS_LONG
JIT_TYPETAG_SYS_ULONG
JIT_TYPETAG_SYS_LONGLONG
JIT_TYPETAG_SYS_ULONGLONG
JIT_TYPETAG_SYS_FLOAT
JIT_TYPETAG_SYS_DOUBLE
JIT_TYPETAG_SYS_LONGDOUBLE
Used to mark types that we know for a fact correspond to the system
C types of the corresponding names. This is primarily used to distinguish
system types like int
and long
types on 32-bit platforms
when it is necessary to do so. The jit_type_sys_xxx
values are
all tagged in this manner.
Set the field or parameter names for type. Returns zero if there is insufficient memory to set the names.
Normally fields are accessed via their index. Field names are a convenience for front ends that prefer to use names to indices.
Set the size and alignment information for a structure or union type. Use this for performing explicit type layout. Normally the size is computed automatically. Ignored if not a structure or union type. Setting either value to -1 will cause that value to be computed automatically.
Set the offset of a specific structure field. Use this for performing explicit type layout. Normally the offset is computed automatically. Ignored if not a structure type, or the field index is out of range.
Get a value that indicates the kind of type. This allows callers to quickly classify a type to determine how it should be handled further.
JIT_TYPE_INVALID
The value of the type parameter is NULL.
JIT_TYPE_VOID
The type is jit_type_void
.
JIT_TYPE_SBYTE
The type is jit_type_sbyte
.
JIT_TYPE_UBYTE
The type is jit_type_ubyte
.
JIT_TYPE_SHORT
The type is jit_type_short
.
JIT_TYPE_USHORT
The type is jit_type_ushort
.
JIT_TYPE_INT
The type is jit_type_int
.
JIT_TYPE_UINT
The type is jit_type_uint
.
JIT_TYPE_NINT
The type is jit_type_nint
.
JIT_TYPE_NUINT
The type is jit_type_nuint
.
JIT_TYPE_LONG
The type is jit_type_long
.
JIT_TYPE_ULONG
The type is jit_type_ulong
.
JIT_TYPE_FLOAT32
The type is jit_type_float32
.
JIT_TYPE_FLOAT64
The type is jit_type_float64
.
JIT_TYPE_NFLOAT
The type is jit_type_nfloat
.
JIT_TYPE_STRUCT
The type is the result of calling jit_type_create_struct
.
JIT_TYPE_UNION
The type is the result of calling jit_type_create_union
.
JIT_TYPE_SIGNATURE
The type is the result of calling jit_type_create_signature
.
JIT_TYPE_PTR
The type is the result of calling jit_type_create_pointer
.
If this function returns JIT_TYPE_FIRST_TAGGED
or higher,
then the type is tagged and its tag kind is the return value minus
JIT_TYPE_FIRST_TAGGED
. That is, the following two expressions
will be identical if type is tagged:
jit_type_get_tagged_kind(type) jit_type_get_kind(type) - JIT_TYPE_FIRST_TAGGED
Get the size of a type in bytes.
Get the alignment of a type. An alignment value of 2 indicates that the type should be aligned on a two-byte boundary, for example.
Get the number of fields in a structure or union type.
Get the type of a specific field within a structure or union. Returns NULL if not a structure or union, or the index is out of range.
Get the offset of a specific field within a structure. Returns zero if not a structure, or the index is out of range, so this is safe to use on non-structure types.
Get the name of a structure, union, or signature field/parameter. Returns NULL if not a structure, union, or signature, the index is out of range, or there is no name associated with the component.
Find the field/parameter index for a particular name. Returns
JIT_INVALID_NAME
if the name was not present.
Get the number of parameters in a signature type.
Get the return type from a signature type. Returns NULL if not a signature type.
Get a specific parameter from a signature type. Returns NULL if not a signature type or the index is out of range.
Get the ABI code from a signature type. Returns jit_abi_cdecl
if not a signature type.
Get the type that is referred to by a pointer type. Returns NULL if not a pointer type.
Get the type that underlies a tagged type. Returns NULL if not a tagged type.
Set the type that underlies a tagged type. Ignored if type is not a tagged type. If type already has an underlying type, then the original is freed.
This function is typically used to flesh out the body of a forward-declared type. The tag is used as a placeholder until the definition can be located.
Get the kind of tag that is applied to a tagged type. Returns -1 if not a tagged type.
Get the user data is associated with a tagged type. Returns NULL if not a tagged type.
Set the user data is associated with a tagged type. The original data, if any, is freed.
Determine if a type is primitive.
Determine if a type is a structure.
Determine if a type is a union.
Determine if a type is a function signature.
Determine if a type is a pointer.
Determine if a type is a tagged type.
Get the best alignment value for this platform.
Normalize a type to its basic numeric form. e.g. "jit_type_nint" is turned into "jit_type_int" or "jit_type_long", depending upon the underlying platform. Pointers are normalized like "jit_type_nint". If the type does not have a normalized form, it is left unchanged.
Normalization is typically used prior to applying a binary numeric instruction, to make it easier to determine the common type. It will also remove tags from the specified type.
Remove tags from a type, and return the underlying type. This is different from normalization, which will also collapses native types to their basic numeric counterparts.
If type is jit_type_sbyte
or jit_type_short
,
then return jit_type_int
. If type is
jit_type_ubyte
or jit_type_ushort
, then return
jit_type_uint
. Otherwise return type as-is.
Determine if a type should be returned via a pointer if it appears as the return type in a signature.
Determine if type has a specific kind of tag. This will resolve multiple levels of tagging.
[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This document was generated on April 29, 2015 using texi2html 5.0.