You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by zw...@apache.org on 2015/07/23 13:14:17 UTC
[20/43] trafficserver git commit: TS-3783 TS-3030 Add luajit v2.0.4
as a subtree
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/1f27b840/lib/luajit/src/lj_ctype.h
----------------------------------------------------------------------
diff --git a/lib/luajit/src/lj_ctype.h b/lib/luajit/src/lj_ctype.h
new file mode 100644
index 0000000..3df26f0
--- /dev/null
+++ b/lib/luajit/src/lj_ctype.h
@@ -0,0 +1,461 @@
+/*
+** C type management.
+** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
+*/
+
+#ifndef _LJ_CTYPE_H
+#define _LJ_CTYPE_H
+
+#include "lj_obj.h"
+#include "lj_gc.h"
+
+#if LJ_HASFFI
+
+/* -- C type definitions -------------------------------------------------- */
+
+/* C type numbers. Highest 4 bits of C type info. ORDER CT. */
+enum {
+ /* Externally visible types. */
+ CT_NUM, /* Integer or floating-point numbers. */
+ CT_STRUCT, /* Struct or union. */
+ CT_PTR, /* Pointer or reference. */
+ CT_ARRAY, /* Array or complex type. */
+ CT_MAYCONVERT = CT_ARRAY,
+ CT_VOID, /* Void type. */
+ CT_ENUM, /* Enumeration. */
+ CT_HASSIZE = CT_ENUM, /* Last type where ct->size holds the actual size. */
+ CT_FUNC, /* Function. */
+ CT_TYPEDEF, /* Typedef. */
+ CT_ATTRIB, /* Miscellaneous attributes. */
+ /* Internal element types. */
+ CT_FIELD, /* Struct/union field or function parameter. */
+ CT_BITFIELD, /* Struct/union bitfield. */
+ CT_CONSTVAL, /* Constant value. */
+ CT_EXTERN, /* External reference. */
+ CT_KW /* Keyword. */
+};
+
+LJ_STATIC_ASSERT(((int)CT_PTR & (int)CT_ARRAY) == CT_PTR);
+LJ_STATIC_ASSERT(((int)CT_STRUCT & (int)CT_ARRAY) == CT_STRUCT);
+
+/*
+** ---------- info ------------
+** |type flags... A cid | size | sib | next | name |
+** +----------------------------+--------+-------+-------+-------+--
+** |NUM BFvcUL.. A | size | | type | |
+** |STRUCT ..vcU..V A | size | field | name? | name? |
+** |PTR ..vcR... A cid | size | | type | |
+** |ARRAY VCvc...V A cid | size | | type | |
+** |VOID ..vc.... A | size | | type | |
+** |ENUM A cid | size | const | name? | name? |
+** |FUNC ....VS.. cc cid | nargs | field | name? | name? |
+** |TYPEDEF cid | | | name | name |
+** |ATTRIB attrnum cid | attr | sib? | type? | |
+** |FIELD cid | offset | field | | name? |
+** |BITFIELD B.vcU csz bsz pos | offset | field | | name? |
+** |CONSTVAL c cid | value | const | name | name |
+** |EXTERN cid | | sib? | name | name |
+** |KW tok | size | | name | name |
+** +----------------------------+--------+-------+-------+-------+--
+** ^^ ^^--- bits used for C type conversion dispatch
+*/
+
+/* C type info flags. TFFArrrr */
+#define CTF_BOOL 0x08000000u /* Boolean: NUM, BITFIELD. */
+#define CTF_FP 0x04000000u /* Floating-point: NUM. */
+#define CTF_CONST 0x02000000u /* Const qualifier. */
+#define CTF_VOLATILE 0x01000000u /* Volatile qualifier. */
+#define CTF_UNSIGNED 0x00800000u /* Unsigned: NUM, BITFIELD. */
+#define CTF_LONG 0x00400000u /* Long: NUM. */
+#define CTF_VLA 0x00100000u /* Variable-length: ARRAY, STRUCT. */
+#define CTF_REF 0x00800000u /* Reference: PTR. */
+#define CTF_VECTOR 0x08000000u /* Vector: ARRAY. */
+#define CTF_COMPLEX 0x04000000u /* Complex: ARRAY. */
+#define CTF_UNION 0x00800000u /* Union: STRUCT. */
+#define CTF_VARARG 0x00800000u /* Vararg: FUNC. */
+#define CTF_SSEREGPARM 0x00400000u /* SSE register parameters: FUNC. */
+
+#define CTF_QUAL (CTF_CONST|CTF_VOLATILE)
+#define CTF_ALIGN (CTMASK_ALIGN<<CTSHIFT_ALIGN)
+#define CTF_UCHAR ((char)-1 > 0 ? CTF_UNSIGNED : 0)
+
+/* Flags used in parser. .F.Ammvf cp->attr */
+#define CTFP_ALIGNED 0x00000001u /* cp->attr + ALIGN */
+#define CTFP_PACKED 0x00000002u /* cp->attr */
+/* ...C...f cp->fattr */
+#define CTFP_CCONV 0x00000001u /* cp->fattr + CCONV/[SSE]REGPARM */
+
+/* C type info bitfields. */
+#define CTMASK_CID 0x0000ffffu /* Max. 65536 type IDs. */
+#define CTMASK_NUM 0xf0000000u /* Max. 16 type numbers. */
+#define CTSHIFT_NUM 28
+#define CTMASK_ALIGN 15 /* Max. alignment is 2^15. */
+#define CTSHIFT_ALIGN 16
+#define CTMASK_ATTRIB 255 /* Max. 256 attributes. */
+#define CTSHIFT_ATTRIB 16
+#define CTMASK_CCONV 3 /* Max. 4 calling conventions. */
+#define CTSHIFT_CCONV 16
+#define CTMASK_REGPARM 3 /* Max. 0-3 regparms. */
+#define CTSHIFT_REGPARM 18
+/* Bitfields only used in parser. */
+#define CTMASK_VSIZEP 15 /* Max. vector size is 2^15. */
+#define CTSHIFT_VSIZEP 4
+#define CTMASK_MSIZEP 255 /* Max. type size (via mode) is 128. */
+#define CTSHIFT_MSIZEP 8
+
+/* Info bits for BITFIELD. Max. size of bitfield is 64 bits. */
+#define CTBSZ_MAX 32 /* Max. size of bitfield is 32 bit. */
+#define CTBSZ_FIELD 127 /* Temp. marker for regular field. */
+#define CTMASK_BITPOS 127
+#define CTMASK_BITBSZ 127
+#define CTMASK_BITCSZ 127
+#define CTSHIFT_BITPOS 0
+#define CTSHIFT_BITBSZ 8
+#define CTSHIFT_BITCSZ 16
+
+#define CTF_INSERT(info, field, val) \
+ info = (info & ~(CTMASK_##field<<CTSHIFT_##field)) | \
+ (((CTSize)(val) & CTMASK_##field) << CTSHIFT_##field)
+
+/* Calling conventions. ORDER CC */
+enum { CTCC_CDECL, CTCC_THISCALL, CTCC_FASTCALL, CTCC_STDCALL };
+
+/* Attribute numbers. */
+enum {
+ CTA_NONE, /* Ignored attribute. Must be zero. */
+ CTA_QUAL, /* Unmerged qualifiers. */
+ CTA_ALIGN, /* Alignment override. */
+ CTA_SUBTYPE, /* Transparent sub-type. */
+ CTA_REDIR, /* Redirected symbol name. */
+ CTA_BAD, /* To catch bad IDs. */
+ CTA__MAX
+};
+
+/* Special sizes. */
+#define CTSIZE_INVALID 0xffffffffu
+
+typedef uint32_t CTInfo; /* Type info. */
+typedef uint32_t CTSize; /* Type size. */
+typedef uint32_t CTypeID; /* Type ID. */
+typedef uint16_t CTypeID1; /* Minimum-sized type ID. */
+
+/* C type table element. */
+typedef struct CType {
+ CTInfo info; /* Type info. */
+ CTSize size; /* Type size or other info. */
+ CTypeID1 sib; /* Sibling element. */
+ CTypeID1 next; /* Next element in hash chain. */
+ GCRef name; /* Element name (GCstr). */
+} CType;
+
+#define CTHASH_SIZE 128 /* Number of hash anchors. */
+#define CTHASH_MASK (CTHASH_SIZE-1)
+
+/* Simplify target-specific configuration. Checked in lj_ccall.h. */
+#define CCALL_MAX_GPR 8
+#define CCALL_MAX_FPR 8
+
+typedef LJ_ALIGN(8) union FPRCBArg { double d; float f[2]; } FPRCBArg;
+
+/* C callback state. Defined here, to avoid dragging in lj_ccall.h. */
+
+typedef LJ_ALIGN(8) struct CCallback {
+ FPRCBArg fpr[CCALL_MAX_FPR]; /* Arguments/results in FPRs. */
+ intptr_t gpr[CCALL_MAX_GPR]; /* Arguments/results in GPRs. */
+ intptr_t *stack; /* Pointer to arguments on stack. */
+ void *mcode; /* Machine code for callback func. pointers. */
+ CTypeID1 *cbid; /* Callback type table. */
+ MSize sizeid; /* Size of callback type table. */
+ MSize topid; /* Highest unused callback type table slot. */
+ MSize slot; /* Current callback slot. */
+} CCallback;
+
+/* C type state. */
+typedef struct CTState {
+ CType *tab; /* C type table. */
+ CTypeID top; /* Current top of C type table. */
+ MSize sizetab; /* Size of C type table. */
+ lua_State *L; /* Lua state (needed for errors and allocations). */
+ global_State *g; /* Global state. */
+ GCtab *finalizer; /* Map of cdata to finalizer. */
+ GCtab *miscmap; /* Map of -CTypeID to metatable and cb slot to func. */
+ CCallback cb; /* Temporary callback state. */
+ CTypeID1 hash[CTHASH_SIZE]; /* Hash anchors for C type table. */
+} CTState;
+
+#define CTINFO(ct, flags) (((CTInfo)(ct) << CTSHIFT_NUM) + (flags))
+#define CTALIGN(al) ((CTSize)(al) << CTSHIFT_ALIGN)
+#define CTATTRIB(at) ((CTInfo)(at) << CTSHIFT_ATTRIB)
+
+#define ctype_type(info) ((info) >> CTSHIFT_NUM)
+#define ctype_cid(info) ((CTypeID)((info) & CTMASK_CID))
+#define ctype_align(info) (((info) >> CTSHIFT_ALIGN) & CTMASK_ALIGN)
+#define ctype_attrib(info) (((info) >> CTSHIFT_ATTRIB) & CTMASK_ATTRIB)
+#define ctype_bitpos(info) (((info) >> CTSHIFT_BITPOS) & CTMASK_BITPOS)
+#define ctype_bitbsz(info) (((info) >> CTSHIFT_BITBSZ) & CTMASK_BITBSZ)
+#define ctype_bitcsz(info) (((info) >> CTSHIFT_BITCSZ) & CTMASK_BITCSZ)
+#define ctype_vsizeP(info) (((info) >> CTSHIFT_VSIZEP) & CTMASK_VSIZEP)
+#define ctype_msizeP(info) (((info) >> CTSHIFT_MSIZEP) & CTMASK_MSIZEP)
+#define ctype_cconv(info) (((info) >> CTSHIFT_CCONV) & CTMASK_CCONV)
+
+/* Simple type checks. */
+#define ctype_isnum(info) (ctype_type((info)) == CT_NUM)
+#define ctype_isvoid(info) (ctype_type((info)) == CT_VOID)
+#define ctype_isptr(info) (ctype_type((info)) == CT_PTR)
+#define ctype_isarray(info) (ctype_type((info)) == CT_ARRAY)
+#define ctype_isstruct(info) (ctype_type((info)) == CT_STRUCT)
+#define ctype_isfunc(info) (ctype_type((info)) == CT_FUNC)
+#define ctype_isenum(info) (ctype_type((info)) == CT_ENUM)
+#define ctype_istypedef(info) (ctype_type((info)) == CT_TYPEDEF)
+#define ctype_isattrib(info) (ctype_type((info)) == CT_ATTRIB)
+#define ctype_isfield(info) (ctype_type((info)) == CT_FIELD)
+#define ctype_isbitfield(info) (ctype_type((info)) == CT_BITFIELD)
+#define ctype_isconstval(info) (ctype_type((info)) == CT_CONSTVAL)
+#define ctype_isextern(info) (ctype_type((info)) == CT_EXTERN)
+#define ctype_hassize(info) (ctype_type((info)) <= CT_HASSIZE)
+
+/* Combined type and flag checks. */
+#define ctype_isinteger(info) \
+ (((info) & (CTMASK_NUM|CTF_BOOL|CTF_FP)) == CTINFO(CT_NUM, 0))
+#define ctype_isinteger_or_bool(info) \
+ (((info) & (CTMASK_NUM|CTF_FP)) == CTINFO(CT_NUM, 0))
+#define ctype_isbool(info) \
+ (((info) & (CTMASK_NUM|CTF_BOOL)) == CTINFO(CT_NUM, CTF_BOOL))
+#define ctype_isfp(info) \
+ (((info) & (CTMASK_NUM|CTF_FP)) == CTINFO(CT_NUM, CTF_FP))
+
+#define ctype_ispointer(info) \
+ ((ctype_type(info) >> 1) == (CT_PTR >> 1)) /* Pointer or array. */
+#define ctype_isref(info) \
+ (((info) & (CTMASK_NUM|CTF_REF)) == CTINFO(CT_PTR, CTF_REF))
+
+#define ctype_isrefarray(info) \
+ (((info) & (CTMASK_NUM|CTF_VECTOR|CTF_COMPLEX)) == CTINFO(CT_ARRAY, 0))
+#define ctype_isvector(info) \
+ (((info) & (CTMASK_NUM|CTF_VECTOR)) == CTINFO(CT_ARRAY, CTF_VECTOR))
+#define ctype_iscomplex(info) \
+ (((info) & (CTMASK_NUM|CTF_COMPLEX)) == CTINFO(CT_ARRAY, CTF_COMPLEX))
+
+#define ctype_isvltype(info) \
+ (((info) & ((CTMASK_NUM|CTF_VLA) - (2u<<CTSHIFT_NUM))) == \
+ CTINFO(CT_STRUCT, CTF_VLA)) /* VL array or VL struct. */
+#define ctype_isvlarray(info) \
+ (((info) & (CTMASK_NUM|CTF_VLA)) == CTINFO(CT_ARRAY, CTF_VLA))
+
+#define ctype_isxattrib(info, at) \
+ (((info) & (CTMASK_NUM|CTATTRIB(CTMASK_ATTRIB))) == \
+ CTINFO(CT_ATTRIB, CTATTRIB(at)))
+
+/* Target-dependent sizes and alignments. */
+#if LJ_64
+#define CTSIZE_PTR 8
+#define CTALIGN_PTR CTALIGN(3)
+#else
+#define CTSIZE_PTR 4
+#define CTALIGN_PTR CTALIGN(2)
+#endif
+
+#define CTINFO_REF(ref) \
+ CTINFO(CT_PTR, (CTF_CONST|CTF_REF|CTALIGN_PTR) + (ref))
+
+#define CT_MEMALIGN 3 /* Alignment guaranteed by memory allocator. */
+
+/* -- Predefined types ---------------------------------------------------- */
+
+/* Target-dependent types. */
+#if LJ_TARGET_PPC || LJ_TARGET_PPCSPE
+#define CTTYDEFP(_) \
+ _(LINT32, 4, CT_NUM, CTF_LONG|CTALIGN(2))
+#else
+#define CTTYDEFP(_)
+#endif
+
+/* Common types. */
+#define CTTYDEF(_) \
+ _(NONE, 0, CT_ATTRIB, CTATTRIB(CTA_BAD)) \
+ _(VOID, -1, CT_VOID, CTALIGN(0)) \
+ _(CVOID, -1, CT_VOID, CTF_CONST|CTALIGN(0)) \
+ _(BOOL, 1, CT_NUM, CTF_BOOL|CTF_UNSIGNED|CTALIGN(0)) \
+ _(CCHAR, 1, CT_NUM, CTF_CONST|CTF_UCHAR|CTALIGN(0)) \
+ _(INT8, 1, CT_NUM, CTALIGN(0)) \
+ _(UINT8, 1, CT_NUM, CTF_UNSIGNED|CTALIGN(0)) \
+ _(INT16, 2, CT_NUM, CTALIGN(1)) \
+ _(UINT16, 2, CT_NUM, CTF_UNSIGNED|CTALIGN(1)) \
+ _(INT32, 4, CT_NUM, CTALIGN(2)) \
+ _(UINT32, 4, CT_NUM, CTF_UNSIGNED|CTALIGN(2)) \
+ _(INT64, 8, CT_NUM, CTF_LONG|CTALIGN(3)) \
+ _(UINT64, 8, CT_NUM, CTF_UNSIGNED|CTF_LONG|CTALIGN(3)) \
+ _(FLOAT, 4, CT_NUM, CTF_FP|CTALIGN(2)) \
+ _(DOUBLE, 8, CT_NUM, CTF_FP|CTALIGN(3)) \
+ _(COMPLEX_FLOAT, 8, CT_ARRAY, CTF_COMPLEX|CTALIGN(2)|CTID_FLOAT) \
+ _(COMPLEX_DOUBLE, 16, CT_ARRAY, CTF_COMPLEX|CTALIGN(3)|CTID_DOUBLE) \
+ _(P_VOID, CTSIZE_PTR, CT_PTR, CTALIGN_PTR|CTID_VOID) \
+ _(P_CVOID, CTSIZE_PTR, CT_PTR, CTALIGN_PTR|CTID_CVOID) \
+ _(P_CCHAR, CTSIZE_PTR, CT_PTR, CTALIGN_PTR|CTID_CCHAR) \
+ _(A_CCHAR, -1, CT_ARRAY, CTF_CONST|CTALIGN(0)|CTID_CCHAR) \
+ _(CTYPEID, 4, CT_ENUM, CTALIGN(2)|CTID_INT32) \
+ CTTYDEFP(_) \
+ /* End of type list. */
+
+/* Public predefined type IDs. */
+enum {
+#define CTTYIDDEF(id, sz, ct, info) CTID_##id,
+CTTYDEF(CTTYIDDEF)
+#undef CTTYIDDEF
+ /* Predefined typedefs and keywords follow. */
+ CTID_MAX = 65536
+};
+
+/* Target-dependent type IDs. */
+#if LJ_64
+#define CTID_INT_PSZ CTID_INT64
+#define CTID_UINT_PSZ CTID_UINT64
+#else
+#define CTID_INT_PSZ CTID_INT32
+#define CTID_UINT_PSZ CTID_UINT32
+#endif
+
+#if LJ_ABI_WIN
+#define CTID_WCHAR CTID_UINT16
+#elif LJ_TARGET_PPC
+#define CTID_WCHAR CTID_LINT32
+#else
+#define CTID_WCHAR CTID_INT32
+#endif
+
+/* -- C tokens and keywords ----------------------------------------------- */
+
+/* C lexer keywords. */
+#define CTOKDEF(_) \
+ _(IDENT, "<identifier>") _(STRING, "<string>") \
+ _(INTEGER, "<integer>") _(EOF, "<eof>") \
+ _(OROR, "||") _(ANDAND, "&&") _(EQ, "==") _(NE, "!=") \
+ _(LE, "<=") _(GE, ">=") _(SHL, "<<") _(SHR, ">>") _(DEREF, "->")
+
+/* Simple declaration specifiers. */
+#define CDSDEF(_) \
+ _(VOID) _(BOOL) _(CHAR) _(INT) _(FP) \
+ _(LONG) _(LONGLONG) _(SHORT) _(COMPLEX) _(SIGNED) _(UNSIGNED) \
+ _(CONST) _(VOLATILE) _(RESTRICT) _(INLINE) \
+ _(TYPEDEF) _(EXTERN) _(STATIC) _(AUTO) _(REGISTER)
+
+/* C keywords. */
+#define CKWDEF(_) \
+ CDSDEF(_) _(EXTENSION) _(ASM) _(ATTRIBUTE) \
+ _(DECLSPEC) _(CCDECL) _(PTRSZ) \
+ _(STRUCT) _(UNION) _(ENUM) \
+ _(SIZEOF) _(ALIGNOF)
+
+/* C token numbers. */
+enum {
+ CTOK_OFS = 255,
+#define CTOKNUM(name, sym) CTOK_##name,
+#define CKWNUM(name) CTOK_##name,
+CTOKDEF(CTOKNUM)
+CKWDEF(CKWNUM)
+#undef CTOKNUM
+#undef CKWNUM
+ CTOK_FIRSTDECL = CTOK_VOID,
+ CTOK_FIRSTSCL = CTOK_TYPEDEF,
+ CTOK_LASTDECLFLAG = CTOK_REGISTER,
+ CTOK_LASTDECL = CTOK_ENUM
+};
+
+/* Declaration specifier flags. */
+enum {
+#define CDSFLAG(name) CDF_##name = (1u << (CTOK_##name - CTOK_FIRSTDECL)),
+CDSDEF(CDSFLAG)
+#undef CDSFLAG
+ CDF__END
+};
+
+#define CDF_SCL (CDF_TYPEDEF|CDF_EXTERN|CDF_STATIC|CDF_AUTO|CDF_REGISTER)
+
+/* -- C type management --------------------------------------------------- */
+
+#define ctype_ctsG(g) (mref((g)->ctype_state, CTState))
+
+/* Get C type state. */
+static LJ_AINLINE CTState *ctype_cts(lua_State *L)
+{
+ CTState *cts = ctype_ctsG(G(L));
+ cts->L = L; /* Save L for errors and allocations. */
+ return cts;
+}
+
+/* Save and restore state of C type table. */
+#define LJ_CTYPE_SAVE(cts) CTState savects_ = *(cts)
+#define LJ_CTYPE_RESTORE(cts) \
+ ((cts)->top = savects_.top, \
+ memcpy((cts)->hash, savects_.hash, sizeof(savects_.hash)))
+
+/* Check C type ID for validity when assertions are enabled. */
+static LJ_AINLINE CTypeID ctype_check(CTState *cts, CTypeID id)
+{
+ lua_assert(id > 0 && id < cts->top); UNUSED(cts);
+ return id;
+}
+
+/* Get C type for C type ID. */
+static LJ_AINLINE CType *ctype_get(CTState *cts, CTypeID id)
+{
+ return &cts->tab[ctype_check(cts, id)];
+}
+
+/* Get C type ID for a C type. */
+#define ctype_typeid(cts, ct) ((CTypeID)((ct) - (cts)->tab))
+
+/* Get child C type. */
+static LJ_AINLINE CType *ctype_child(CTState *cts, CType *ct)
+{
+ lua_assert(!(ctype_isvoid(ct->info) || ctype_isstruct(ct->info) ||
+ ctype_isbitfield(ct->info))); /* These don't have children. */
+ return ctype_get(cts, ctype_cid(ct->info));
+}
+
+/* Get raw type for a C type ID. */
+static LJ_AINLINE CType *ctype_raw(CTState *cts, CTypeID id)
+{
+ CType *ct = ctype_get(cts, id);
+ while (ctype_isattrib(ct->info)) ct = ctype_child(cts, ct);
+ return ct;
+}
+
+/* Get raw type of the child of a C type. */
+static LJ_AINLINE CType *ctype_rawchild(CTState *cts, CType *ct)
+{
+ do { ct = ctype_child(cts, ct); } while (ctype_isattrib(ct->info));
+ return ct;
+}
+
+/* Set the name of a C type table element. */
+static LJ_AINLINE void ctype_setname(CType *ct, GCstr *s)
+{
+ /* NOBARRIER: mark string as fixed -- the C type table is never collected. */
+ fixstring(s);
+ setgcref(ct->name, obj2gco(s));
+}
+
+LJ_FUNC CTypeID lj_ctype_new(CTState *cts, CType **ctp);
+LJ_FUNC CTypeID lj_ctype_intern(CTState *cts, CTInfo info, CTSize size);
+LJ_FUNC void lj_ctype_addname(CTState *cts, CType *ct, CTypeID id);
+LJ_FUNC CTypeID lj_ctype_getname(CTState *cts, CType **ctp, GCstr *name,
+ uint32_t tmask);
+LJ_FUNC CType *lj_ctype_getfieldq(CTState *cts, CType *ct, GCstr *name,
+ CTSize *ofs, CTInfo *qual);
+#define lj_ctype_getfield(cts, ct, name, ofs) \
+ lj_ctype_getfieldq((cts), (ct), (name), (ofs), NULL)
+LJ_FUNC CType *lj_ctype_rawref(CTState *cts, CTypeID id);
+LJ_FUNC CTSize lj_ctype_size(CTState *cts, CTypeID id);
+LJ_FUNC CTSize lj_ctype_vlsize(CTState *cts, CType *ct, CTSize nelem);
+LJ_FUNC CTInfo lj_ctype_info(CTState *cts, CTypeID id, CTSize *szp);
+LJ_FUNC cTValue *lj_ctype_meta(CTState *cts, CTypeID id, MMS mm);
+LJ_FUNC GCstr *lj_ctype_repr(lua_State *L, CTypeID id, GCstr *name);
+LJ_FUNC GCstr *lj_ctype_repr_int64(lua_State *L, uint64_t n, int isunsigned);
+LJ_FUNC GCstr *lj_ctype_repr_complex(lua_State *L, void *sp, CTSize size);
+LJ_FUNC CTState *lj_ctype_init(lua_State *L);
+LJ_FUNC void lj_ctype_freestate(global_State *g);
+
+#endif
+
+#endif
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/1f27b840/lib/luajit/src/lj_debug.c
----------------------------------------------------------------------
diff --git a/lib/luajit/src/lj_debug.c b/lib/luajit/src/lj_debug.c
new file mode 100644
index 0000000..bd2fa1f
--- /dev/null
+++ b/lib/luajit/src/lj_debug.c
@@ -0,0 +1,605 @@
+/*
+** Debugging and introspection.
+** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
+*/
+
+#define lj_debug_c
+#define LUA_CORE
+
+#include "lj_obj.h"
+#include "lj_err.h"
+#include "lj_debug.h"
+#include "lj_str.h"
+#include "lj_tab.h"
+#include "lj_state.h"
+#include "lj_frame.h"
+#include "lj_bc.h"
+#include "lj_vm.h"
+#if LJ_HASJIT
+#include "lj_jit.h"
+#endif
+
+/* -- Frames -------------------------------------------------------------- */
+
+/* Get frame corresponding to a level. */
+cTValue *lj_debug_frame(lua_State *L, int level, int *size)
+{
+ cTValue *frame, *nextframe, *bot = tvref(L->stack);
+ /* Traverse frames backwards. */
+ for (nextframe = frame = L->base-1; frame > bot; ) {
+ if (frame_gc(frame) == obj2gco(L))
+ level++; /* Skip dummy frames. See lj_meta_call(). */
+ if (level-- == 0) {
+ *size = (int)(nextframe - frame);
+ return frame; /* Level found. */
+ }
+ nextframe = frame;
+ if (frame_islua(frame)) {
+ frame = frame_prevl(frame);
+ } else {
+ if (frame_isvarg(frame))
+ level++; /* Skip vararg pseudo-frame. */
+ frame = frame_prevd(frame);
+ }
+ }
+ *size = level;
+ return NULL; /* Level not found. */
+}
+
+/* Invalid bytecode position. */
+#define NO_BCPOS (~(BCPos)0)
+
+/* Return bytecode position for function/frame or NO_BCPOS. */
+static BCPos debug_framepc(lua_State *L, GCfunc *fn, cTValue *nextframe)
+{
+ const BCIns *ins;
+ GCproto *pt;
+ BCPos pos;
+ lua_assert(fn->c.gct == ~LJ_TFUNC || fn->c.gct == ~LJ_TTHREAD);
+ if (!isluafunc(fn)) { /* Cannot derive a PC for non-Lua functions. */
+ return NO_BCPOS;
+ } else if (nextframe == NULL) { /* Lua function on top. */
+ void *cf = cframe_raw(L->cframe);
+ if (cf == NULL || (char *)cframe_pc(cf) == (char *)cframe_L(cf))
+ return NO_BCPOS;
+ ins = cframe_pc(cf); /* Only happens during error/hook handling. */
+ } else {
+ if (frame_islua(nextframe)) {
+ ins = frame_pc(nextframe);
+ } else if (frame_iscont(nextframe)) {
+ ins = frame_contpc(nextframe);
+ } else {
+ /* Lua function below errfunc/gc/hook: find cframe to get the PC. */
+ void *cf = cframe_raw(L->cframe);
+ TValue *f = L->base-1;
+ for (;;) {
+ if (cf == NULL)
+ return NO_BCPOS;
+ while (cframe_nres(cf) < 0) {
+ if (f >= restorestack(L, -cframe_nres(cf)))
+ break;
+ cf = cframe_raw(cframe_prev(cf));
+ if (cf == NULL)
+ return NO_BCPOS;
+ }
+ if (f < nextframe)
+ break;
+ if (frame_islua(f)) {
+ f = frame_prevl(f);
+ } else {
+ if (frame_isc(f) || (LJ_HASFFI && frame_iscont(f) &&
+ (f-1)->u32.lo == LJ_CONT_FFI_CALLBACK))
+ cf = cframe_raw(cframe_prev(cf));
+ f = frame_prevd(f);
+ }
+ }
+ ins = cframe_pc(cf);
+ }
+ }
+ pt = funcproto(fn);
+ pos = proto_bcpos(pt, ins) - 1;
+#if LJ_HASJIT
+ if (pos > pt->sizebc) { /* Undo the effects of lj_trace_exit for JLOOP. */
+ GCtrace *T = (GCtrace *)((char *)(ins-1) - offsetof(GCtrace, startins));
+ lua_assert(bc_isret(bc_op(ins[-1])));
+ pos = proto_bcpos(pt, mref(T->startpc, const BCIns));
+ }
+#endif
+ return pos;
+}
+
+/* -- Line numbers -------------------------------------------------------- */
+
+/* Get line number for a bytecode position. */
+BCLine LJ_FASTCALL lj_debug_line(GCproto *pt, BCPos pc)
+{
+ const void *lineinfo = proto_lineinfo(pt);
+ if (pc <= pt->sizebc && lineinfo) {
+ BCLine first = pt->firstline;
+ if (pc == pt->sizebc) return first + pt->numline;
+ if (pc-- == 0) return first;
+ if (pt->numline < 256)
+ return first + (BCLine)((const uint8_t *)lineinfo)[pc];
+ else if (pt->numline < 65536)
+ return first + (BCLine)((const uint16_t *)lineinfo)[pc];
+ else
+ return first + (BCLine)((const uint32_t *)lineinfo)[pc];
+ }
+ return 0;
+}
+
+/* Get line number for function/frame. */
+static BCLine debug_frameline(lua_State *L, GCfunc *fn, cTValue *nextframe)
+{
+ BCPos pc = debug_framepc(L, fn, nextframe);
+ if (pc != NO_BCPOS) {
+ GCproto *pt = funcproto(fn);
+ lua_assert(pc <= pt->sizebc);
+ return lj_debug_line(pt, pc);
+ }
+ return -1;
+}
+
+/* -- Variable names ------------------------------------------------------ */
+
+/* Read ULEB128 value. */
+static uint32_t debug_read_uleb128(const uint8_t **pp)
+{
+ const uint8_t *p = *pp;
+ uint32_t v = *p++;
+ if (LJ_UNLIKELY(v >= 0x80)) {
+ int sh = 0;
+ v &= 0x7f;
+ do { v |= ((*p & 0x7f) << (sh += 7)); } while (*p++ >= 0x80);
+ }
+ *pp = p;
+ return v;
+}
+
+/* Get name of a local variable from slot number and PC. */
+static const char *debug_varname(const GCproto *pt, BCPos pc, BCReg slot)
+{
+ const uint8_t *p = proto_varinfo(pt);
+ if (p) {
+ BCPos lastpc = 0;
+ for (;;) {
+ const char *name = (const char *)p;
+ uint32_t vn = *p++;
+ BCPos startpc, endpc;
+ if (vn < VARNAME__MAX) {
+ if (vn == VARNAME_END) break; /* End of varinfo. */
+ } else {
+ while (*p++) ; /* Skip over variable name string. */
+ }
+ lastpc = startpc = lastpc + debug_read_uleb128(&p);
+ if (startpc > pc) break;
+ endpc = startpc + debug_read_uleb128(&p);
+ if (pc < endpc && slot-- == 0) {
+ if (vn < VARNAME__MAX) {
+#define VARNAMESTR(name, str) str "\0"
+ name = VARNAMEDEF(VARNAMESTR);
+#undef VARNAMESTR
+ if (--vn) while (*name++ || --vn) ;
+ }
+ return name;
+ }
+ }
+ }
+ return NULL;
+}
+
+/* Get name of local variable from 1-based slot number and function/frame. */
+static TValue *debug_localname(lua_State *L, const lua_Debug *ar,
+ const char **name, BCReg slot1)
+{
+ uint32_t offset = (uint32_t)ar->i_ci & 0xffff;
+ uint32_t size = (uint32_t)ar->i_ci >> 16;
+ TValue *frame = tvref(L->stack) + offset;
+ TValue *nextframe = size ? frame + size : NULL;
+ GCfunc *fn = frame_func(frame);
+ BCPos pc = debug_framepc(L, fn, nextframe);
+ if (!nextframe) nextframe = L->top;
+ if ((int)slot1 < 0) { /* Negative slot number is for varargs. */
+ if (pc != NO_BCPOS) {
+ GCproto *pt = funcproto(fn);
+ if ((pt->flags & PROTO_VARARG)) {
+ slot1 = pt->numparams + (BCReg)(-(int)slot1);
+ if (frame_isvarg(frame)) { /* Vararg frame has been set up? (pc!=0) */
+ nextframe = frame;
+ frame = frame_prevd(frame);
+ }
+ if (frame + slot1 < nextframe) {
+ *name = "(*vararg)";
+ return frame+slot1;
+ }
+ }
+ }
+ return NULL;
+ }
+ if (pc != NO_BCPOS &&
+ (*name = debug_varname(funcproto(fn), pc, slot1-1)) != NULL)
+ ;
+ else if (slot1 > 0 && frame + slot1 < nextframe)
+ *name = "(*temporary)";
+ return frame+slot1;
+}
+
+/* Get name of upvalue. */
+const char *lj_debug_uvname(GCproto *pt, uint32_t idx)
+{
+ const uint8_t *p = proto_uvinfo(pt);
+ lua_assert(idx < pt->sizeuv);
+ if (!p) return "";
+ if (idx) while (*p++ || --idx) ;
+ return (const char *)p;
+}
+
+/* Get name and value of upvalue. */
+const char *lj_debug_uvnamev(cTValue *o, uint32_t idx, TValue **tvp)
+{
+ if (tvisfunc(o)) {
+ GCfunc *fn = funcV(o);
+ if (isluafunc(fn)) {
+ GCproto *pt = funcproto(fn);
+ if (idx < pt->sizeuv) {
+ *tvp = uvval(&gcref(fn->l.uvptr[idx])->uv);
+ return lj_debug_uvname(pt, idx);
+ }
+ } else {
+ if (idx < fn->c.nupvalues) {
+ *tvp = &fn->c.upvalue[idx];
+ return "";
+ }
+ }
+ }
+ return NULL;
+}
+
+/* Deduce name of an object from slot number and PC. */
+const char *lj_debug_slotname(GCproto *pt, const BCIns *ip, BCReg slot,
+ const char **name)
+{
+ const char *lname;
+restart:
+ lname = debug_varname(pt, proto_bcpos(pt, ip), slot);
+ if (lname != NULL) { *name = lname; return "local"; }
+ while (--ip > proto_bc(pt)) {
+ BCIns ins = *ip;
+ BCOp op = bc_op(ins);
+ BCReg ra = bc_a(ins);
+ if (bcmode_a(op) == BCMbase) {
+ if (slot >= ra && (op != BC_KNIL || slot <= bc_d(ins)))
+ return NULL;
+ } else if (bcmode_a(op) == BCMdst && ra == slot) {
+ switch (bc_op(ins)) {
+ case BC_MOV:
+ if (ra == slot) { slot = bc_d(ins); goto restart; }
+ break;
+ case BC_GGET:
+ *name = strdata(gco2str(proto_kgc(pt, ~(ptrdiff_t)bc_d(ins))));
+ return "global";
+ case BC_TGETS:
+ *name = strdata(gco2str(proto_kgc(pt, ~(ptrdiff_t)bc_c(ins))));
+ if (ip > proto_bc(pt)) {
+ BCIns insp = ip[-1];
+ if (bc_op(insp) == BC_MOV && bc_a(insp) == ra+1 &&
+ bc_d(insp) == bc_b(ins))
+ return "method";
+ }
+ return "field";
+ case BC_UGET:
+ *name = lj_debug_uvname(pt, bc_d(ins));
+ return "upvalue";
+ default:
+ return NULL;
+ }
+ }
+ }
+ return NULL;
+}
+
+/* Deduce function name from caller of a frame. */
+const char *lj_debug_funcname(lua_State *L, TValue *frame, const char **name)
+{
+ TValue *pframe;
+ GCfunc *fn;
+ BCPos pc;
+ if (frame <= tvref(L->stack))
+ return NULL;
+ if (frame_isvarg(frame))
+ frame = frame_prevd(frame);
+ pframe = frame_prev(frame);
+ fn = frame_func(pframe);
+ pc = debug_framepc(L, fn, frame);
+ if (pc != NO_BCPOS) {
+ GCproto *pt = funcproto(fn);
+ const BCIns *ip = &proto_bc(pt)[check_exp(pc < pt->sizebc, pc)];
+ MMS mm = bcmode_mm(bc_op(*ip));
+ if (mm == MM_call) {
+ BCReg slot = bc_a(*ip);
+ if (bc_op(*ip) == BC_ITERC) slot -= 3;
+ return lj_debug_slotname(pt, ip, slot, name);
+ } else if (mm != MM__MAX) {
+ *name = strdata(mmname_str(G(L), mm));
+ return "metamethod";
+ }
+ }
+ return NULL;
+}
+
+/* -- Source code locations ----------------------------------------------- */
+
+/* Generate shortened source name. */
+void lj_debug_shortname(char *out, GCstr *str)
+{
+ const char *src = strdata(str);
+ if (*src == '=') {
+ strncpy(out, src+1, LUA_IDSIZE); /* Remove first char. */
+ out[LUA_IDSIZE-1] = '\0'; /* Ensures null termination. */
+ } else if (*src == '@') { /* Output "source", or "...source". */
+ size_t len = str->len-1;
+ src++; /* Skip the `@' */
+ if (len >= LUA_IDSIZE) {
+ src += len-(LUA_IDSIZE-4); /* Get last part of file name. */
+ *out++ = '.'; *out++ = '.'; *out++ = '.';
+ }
+ strcpy(out, src);
+ } else { /* Output [string "string"]. */
+ size_t len; /* Length, up to first control char. */
+ for (len = 0; len < LUA_IDSIZE-12; len++)
+ if (((const unsigned char *)src)[len] < ' ') break;
+ strcpy(out, "[string \""); out += 9;
+ if (src[len] != '\0') { /* Must truncate? */
+ if (len > LUA_IDSIZE-15) len = LUA_IDSIZE-15;
+ strncpy(out, src, len); out += len;
+ strcpy(out, "..."); out += 3;
+ } else {
+ strcpy(out, src); out += len;
+ }
+ strcpy(out, "\"]");
+ }
+}
+
+/* Add current location of a frame to error message. */
+void lj_debug_addloc(lua_State *L, const char *msg,
+ cTValue *frame, cTValue *nextframe)
+{
+ if (frame) {
+ GCfunc *fn = frame_func(frame);
+ if (isluafunc(fn)) {
+ BCLine line = debug_frameline(L, fn, nextframe);
+ if (line >= 0) {
+ char buf[LUA_IDSIZE];
+ lj_debug_shortname(buf, proto_chunkname(funcproto(fn)));
+ lj_str_pushf(L, "%s:%d: %s", buf, line, msg);
+ return;
+ }
+ }
+ }
+ lj_str_pushf(L, "%s", msg);
+}
+
+/* Push location string for a bytecode position to Lua stack. */
+void lj_debug_pushloc(lua_State *L, GCproto *pt, BCPos pc)
+{
+ GCstr *name = proto_chunkname(pt);
+ const char *s = strdata(name);
+ MSize i, len = name->len;
+ BCLine line = lj_debug_line(pt, pc);
+ if (*s == '@') {
+ s++; len--;
+ for (i = len; i > 0; i--)
+ if (s[i] == '/' || s[i] == '\\') {
+ s += i+1;
+ break;
+ }
+ lj_str_pushf(L, "%s:%d", s, line);
+ } else if (len > 40) {
+ lj_str_pushf(L, "%p:%d", pt, line);
+ } else if (*s == '=') {
+ lj_str_pushf(L, "%s:%d", s+1, line);
+ } else {
+ lj_str_pushf(L, "\"%s\":%d", s, line);
+ }
+}
+
+/* -- Public debug API ---------------------------------------------------- */
+
+/* lua_getupvalue() and lua_setupvalue() are in lj_api.c. */
+
+LUA_API const char *lua_getlocal(lua_State *L, const lua_Debug *ar, int n)
+{
+ const char *name = NULL;
+ if (ar) {
+ TValue *o = debug_localname(L, ar, &name, (BCReg)n);
+ if (name) {
+ copyTV(L, L->top, o);
+ incr_top(L);
+ }
+ } else if (tvisfunc(L->top-1) && isluafunc(funcV(L->top-1))) {
+ name = debug_varname(funcproto(funcV(L->top-1)), 0, (BCReg)n-1);
+ }
+ return name;
+}
+
+LUA_API const char *lua_setlocal(lua_State *L, const lua_Debug *ar, int n)
+{
+ const char *name = NULL;
+ TValue *o = debug_localname(L, ar, &name, (BCReg)n);
+ if (name)
+ copyTV(L, o, L->top-1);
+ L->top--;
+ return name;
+}
+
+int lj_debug_getinfo(lua_State *L, const char *what, lj_Debug *ar, int ext)
+{
+ int opt_f = 0, opt_L = 0;
+ TValue *frame = NULL;
+ TValue *nextframe = NULL;
+ GCfunc *fn;
+ if (*what == '>') {
+ TValue *func = L->top - 1;
+ api_check(L, tvisfunc(func));
+ fn = funcV(func);
+ L->top--;
+ what++;
+ } else {
+ uint32_t offset = (uint32_t)ar->i_ci & 0xffff;
+ uint32_t size = (uint32_t)ar->i_ci >> 16;
+ lua_assert(offset != 0);
+ frame = tvref(L->stack) + offset;
+ if (size) nextframe = frame + size;
+ lua_assert(frame <= tvref(L->maxstack) &&
+ (!nextframe || nextframe <= tvref(L->maxstack)));
+ fn = frame_func(frame);
+ lua_assert(fn->c.gct == ~LJ_TFUNC);
+ }
+ for (; *what; what++) {
+ if (*what == 'S') {
+ if (isluafunc(fn)) {
+ GCproto *pt = funcproto(fn);
+ BCLine firstline = pt->firstline;
+ GCstr *name = proto_chunkname(pt);
+ ar->source = strdata(name);
+ lj_debug_shortname(ar->short_src, name);
+ ar->linedefined = (int)firstline;
+ ar->lastlinedefined = (int)(firstline + pt->numline);
+ ar->what = (firstline || !pt->numline) ? "Lua" : "main";
+ } else {
+ ar->source = "=[C]";
+ ar->short_src[0] = '[';
+ ar->short_src[1] = 'C';
+ ar->short_src[2] = ']';
+ ar->short_src[3] = '\0';
+ ar->linedefined = -1;
+ ar->lastlinedefined = -1;
+ ar->what = "C";
+ }
+ } else if (*what == 'l') {
+ ar->currentline = frame ? debug_frameline(L, fn, nextframe) : -1;
+ } else if (*what == 'u') {
+ ar->nups = fn->c.nupvalues;
+ if (ext) {
+ if (isluafunc(fn)) {
+ GCproto *pt = funcproto(fn);
+ ar->nparams = pt->numparams;
+ ar->isvararg = !!(pt->flags & PROTO_VARARG);
+ } else {
+ ar->nparams = 0;
+ ar->isvararg = 1;
+ }
+ }
+ } else if (*what == 'n') {
+ ar->namewhat = frame ? lj_debug_funcname(L, frame, &ar->name) : NULL;
+ if (ar->namewhat == NULL) {
+ ar->namewhat = "";
+ ar->name = NULL;
+ }
+ } else if (*what == 'f') {
+ opt_f = 1;
+ } else if (*what == 'L') {
+ opt_L = 1;
+ } else {
+ return 0; /* Bad option. */
+ }
+ }
+ if (opt_f) {
+ setfuncV(L, L->top, fn);
+ incr_top(L);
+ }
+ if (opt_L) {
+ if (isluafunc(fn)) {
+ GCtab *t = lj_tab_new(L, 0, 0);
+ GCproto *pt = funcproto(fn);
+ const void *lineinfo = proto_lineinfo(pt);
+ if (lineinfo) {
+ BCLine first = pt->firstline;
+ int sz = pt->numline < 256 ? 1 : pt->numline < 65536 ? 2 : 4;
+ MSize i, szl = pt->sizebc-1;
+ for (i = 0; i < szl; i++) {
+ BCLine line = first +
+ (sz == 1 ? (BCLine)((const uint8_t *)lineinfo)[i] :
+ sz == 2 ? (BCLine)((const uint16_t *)lineinfo)[i] :
+ (BCLine)((const uint32_t *)lineinfo)[i]);
+ setboolV(lj_tab_setint(L, t, line), 1);
+ }
+ }
+ settabV(L, L->top, t);
+ } else {
+ setnilV(L->top);
+ }
+ incr_top(L);
+ }
+ return 1; /* Ok. */
+}
+
+LUA_API int lua_getinfo(lua_State *L, const char *what, lua_Debug *ar)
+{
+ return lj_debug_getinfo(L, what, (lj_Debug *)ar, 0);
+}
+
+LUA_API int lua_getstack(lua_State *L, int level, lua_Debug *ar)
+{
+ int size;
+ cTValue *frame = lj_debug_frame(L, level, &size);
+ if (frame) {
+ ar->i_ci = (size << 16) + (int)(frame - tvref(L->stack));
+ return 1;
+ } else {
+ ar->i_ci = level - size;
+ return 0;
+ }
+}
+
+/* Number of frames for the leading and trailing part of a traceback. */
+#define TRACEBACK_LEVELS1 12
+#define TRACEBACK_LEVELS2 10
+
+LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, const char *msg,
+ int level)
+{
+ int top = (int)(L->top - L->base);
+ int lim = TRACEBACK_LEVELS1;
+ lua_Debug ar;
+ if (msg) lua_pushfstring(L, "%s\n", msg);
+ lua_pushliteral(L, "stack traceback:");
+ while (lua_getstack(L1, level++, &ar)) {
+ GCfunc *fn;
+ if (level > lim) {
+ if (!lua_getstack(L1, level + TRACEBACK_LEVELS2, &ar)) {
+ level--;
+ } else {
+ lua_pushliteral(L, "\n\t...");
+ lua_getstack(L1, -10, &ar);
+ level = ar.i_ci - TRACEBACK_LEVELS2;
+ }
+ lim = 2147483647;
+ continue;
+ }
+ lua_getinfo(L1, "Snlf", &ar);
+ fn = funcV(L1->top-1); L1->top--;
+ if (isffunc(fn) && !*ar.namewhat)
+ lua_pushfstring(L, "\n\t[builtin#%d]:", fn->c.ffid);
+ else
+ lua_pushfstring(L, "\n\t%s:", ar.short_src);
+ if (ar.currentline > 0)
+ lua_pushfstring(L, "%d:", ar.currentline);
+ if (*ar.namewhat) {
+ lua_pushfstring(L, " in function " LUA_QS, ar.name);
+ } else {
+ if (*ar.what == 'm') {
+ lua_pushliteral(L, " in main chunk");
+ } else if (*ar.what == 'C') {
+ lua_pushfstring(L, " at %p", fn->c.f);
+ } else {
+ lua_pushfstring(L, " in function <%s:%d>",
+ ar.short_src, ar.linedefined);
+ }
+ }
+ if ((int)(L->top - L->base) - top >= 15)
+ lua_concat(L, (int)(L->top - L->base) - top);
+ }
+ lua_concat(L, (int)(L->top - L->base) - top);
+}
+
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/1f27b840/lib/luajit/src/lj_debug.h
----------------------------------------------------------------------
diff --git a/lib/luajit/src/lj_debug.h b/lib/luajit/src/lj_debug.h
new file mode 100644
index 0000000..fa8988c
--- /dev/null
+++ b/lib/luajit/src/lj_debug.h
@@ -0,0 +1,61 @@
+/*
+** Debugging and introspection.
+** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
+*/
+
+#ifndef _LJ_DEBUG_H
+#define _LJ_DEBUG_H
+
+#include "lj_obj.h"
+
+typedef struct lj_Debug {
+ /* Common fields. Must be in the same order as in lua.h. */
+ int event;
+ const char *name;
+ const char *namewhat;
+ const char *what;
+ const char *source;
+ int currentline;
+ int nups;
+ int linedefined;
+ int lastlinedefined;
+ char short_src[LUA_IDSIZE];
+ int i_ci;
+ /* Extended fields. Only valid if lj_debug_getinfo() is called with ext = 1.*/
+ int nparams;
+ int isvararg;
+} lj_Debug;
+
+LJ_FUNC cTValue *lj_debug_frame(lua_State *L, int level, int *size);
+LJ_FUNC BCLine LJ_FASTCALL lj_debug_line(GCproto *pt, BCPos pc);
+LJ_FUNC const char *lj_debug_uvname(GCproto *pt, uint32_t idx);
+LJ_FUNC const char *lj_debug_uvnamev(cTValue *o, uint32_t idx, TValue **tvp);
+LJ_FUNC const char *lj_debug_slotname(GCproto *pt, const BCIns *pc,
+ BCReg slot, const char **name);
+LJ_FUNC const char *lj_debug_funcname(lua_State *L, TValue *frame,
+ const char **name);
+LJ_FUNC void lj_debug_shortname(char *out, GCstr *str);
+LJ_FUNC void lj_debug_addloc(lua_State *L, const char *msg,
+ cTValue *frame, cTValue *nextframe);
+LJ_FUNC void lj_debug_pushloc(lua_State *L, GCproto *pt, BCPos pc);
+LJ_FUNC int lj_debug_getinfo(lua_State *L, const char *what, lj_Debug *ar,
+ int ext);
+
+/* Fixed internal variable names. */
+#define VARNAMEDEF(_) \
+ _(FOR_IDX, "(for index)") \
+ _(FOR_STOP, "(for limit)") \
+ _(FOR_STEP, "(for step)") \
+ _(FOR_GEN, "(for generator)") \
+ _(FOR_STATE, "(for state)") \
+ _(FOR_CTL, "(for control)")
+
+enum {
+ VARNAME_END,
+#define VARNAMEENUM(name, str) VARNAME_##name,
+ VARNAMEDEF(VARNAMEENUM)
+#undef VARNAMEENUM
+ VARNAME__MAX
+};
+
+#endif
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/1f27b840/lib/luajit/src/lj_def.h
----------------------------------------------------------------------
diff --git a/lib/luajit/src/lj_def.h b/lib/luajit/src/lj_def.h
new file mode 100644
index 0000000..e666c9e
--- /dev/null
+++ b/lib/luajit/src/lj_def.h
@@ -0,0 +1,353 @@
+/*
+** LuaJIT common internal definitions.
+** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
+*/
+
+#ifndef _LJ_DEF_H
+#define _LJ_DEF_H
+
+#include "lua.h"
+
+#if defined(_MSC_VER)
+/* MSVC is stuck in the last century and doesn't have C99's stdint.h. */
+typedef __int8 int8_t;
+typedef __int16 int16_t;
+typedef __int32 int32_t;
+typedef __int64 int64_t;
+typedef unsigned __int8 uint8_t;
+typedef unsigned __int16 uint16_t;
+typedef unsigned __int32 uint32_t;
+typedef unsigned __int64 uint64_t;
+#ifdef _WIN64
+typedef __int64 intptr_t;
+typedef unsigned __int64 uintptr_t;
+#else
+typedef __int32 intptr_t;
+typedef unsigned __int32 uintptr_t;
+#endif
+#elif defined(__symbian__)
+/* Cough. */
+typedef signed char int8_t;
+typedef short int int16_t;
+typedef int int32_t;
+typedef long long int64_t;
+typedef unsigned char uint8_t;
+typedef unsigned short int uint16_t;
+typedef unsigned int uint32_t;
+typedef unsigned long long uint64_t;
+typedef int intptr_t;
+typedef unsigned int uintptr_t;
+#else
+#include <stdint.h>
+#endif
+
+/* Needed everywhere. */
+#include <string.h>
+#include <stdlib.h>
+
+/* Various VM limits. */
+#define LJ_MAX_MEM 0x7fffff00 /* Max. total memory allocation. */
+#define LJ_MAX_ALLOC LJ_MAX_MEM /* Max. individual allocation length. */
+#define LJ_MAX_STR LJ_MAX_MEM /* Max. string length. */
+#define LJ_MAX_UDATA LJ_MAX_MEM /* Max. userdata length. */
+
+#define LJ_MAX_STRTAB (1<<26) /* Max. string table size. */
+#define LJ_MAX_HBITS 26 /* Max. hash bits. */
+#define LJ_MAX_ABITS 28 /* Max. bits of array key. */
+#define LJ_MAX_ASIZE ((1<<(LJ_MAX_ABITS-1))+1) /* Max. array part size. */
+#define LJ_MAX_COLOSIZE 16 /* Max. elems for colocated array. */
+
+#define LJ_MAX_LINE LJ_MAX_MEM /* Max. source code line number. */
+#define LJ_MAX_XLEVEL 200 /* Max. syntactic nesting level. */
+#define LJ_MAX_BCINS (1<<26) /* Max. # of bytecode instructions. */
+#define LJ_MAX_SLOTS 250 /* Max. # of slots in a Lua func. */
+#define LJ_MAX_LOCVAR 200 /* Max. # of local variables. */
+#define LJ_MAX_UPVAL 60 /* Max. # of upvalues. */
+
+#define LJ_MAX_IDXCHAIN 100 /* __index/__newindex chain limit. */
+#define LJ_STACK_EXTRA 5 /* Extra stack space (metamethods). */
+
+#define LJ_NUM_CBPAGE 1 /* Number of FFI callback pages. */
+
+/* Minimum table/buffer sizes. */
+#define LJ_MIN_GLOBAL 6 /* Min. global table size (hbits). */
+#define LJ_MIN_REGISTRY 2 /* Min. registry size (hbits). */
+#define LJ_MIN_STRTAB 256 /* Min. string table size (pow2). */
+#define LJ_MIN_SBUF 32 /* Min. string buffer length. */
+#define LJ_MIN_VECSZ 8 /* Min. size for growable vectors. */
+#define LJ_MIN_IRSZ 32 /* Min. size for growable IR. */
+#define LJ_MIN_K64SZ 16 /* Min. size for chained K64Array. */
+
+/* JIT compiler limits. */
+#define LJ_MAX_JSLOTS 250 /* Max. # of stack slots for a trace. */
+#define LJ_MAX_PHI 64 /* Max. # of PHIs for a loop. */
+#define LJ_MAX_EXITSTUBGR 16 /* Max. # of exit stub groups. */
+
+/* Various macros. */
+#ifndef UNUSED
+#define UNUSED(x) ((void)(x)) /* to avoid warnings */
+#endif
+
+#define U64x(hi, lo) (((uint64_t)0x##hi << 32) + (uint64_t)0x##lo)
+#define i32ptr(p) ((int32_t)(intptr_t)(void *)(p))
+#define u32ptr(p) ((uint32_t)(intptr_t)(void *)(p))
+
+#define checki8(x) ((x) == (int32_t)(int8_t)(x))
+#define checku8(x) ((x) == (int32_t)(uint8_t)(x))
+#define checki16(x) ((x) == (int32_t)(int16_t)(x))
+#define checku16(x) ((x) == (int32_t)(uint16_t)(x))
+#define checki32(x) ((x) == (int32_t)(x))
+#define checku32(x) ((x) == (uint32_t)(x))
+#define checkptr32(x) ((uintptr_t)(x) == (uint32_t)(uintptr_t)(x))
+
+/* Every half-decent C compiler transforms this into a rotate instruction. */
+#define lj_rol(x, n) (((x)<<(n)) | ((x)>>(-(int)(n)&(8*sizeof(x)-1))))
+#define lj_ror(x, n) (((x)<<(-(int)(n)&(8*sizeof(x)-1))) | ((x)>>(n)))
+
+/* A really naive Bloom filter. But sufficient for our needs. */
+typedef uintptr_t BloomFilter;
+#define BLOOM_MASK (8*sizeof(BloomFilter) - 1)
+#define bloombit(x) ((uintptr_t)1 << ((x) & BLOOM_MASK))
+#define bloomset(b, x) ((b) |= bloombit((x)))
+#define bloomtest(b, x) ((b) & bloombit((x)))
+
+#if defined(__GNUC__) || defined(__psp2__)
+
+#define LJ_NORET __attribute__((noreturn))
+#define LJ_ALIGN(n) __attribute__((aligned(n)))
+#define LJ_INLINE inline
+#define LJ_AINLINE inline __attribute__((always_inline))
+#define LJ_NOINLINE __attribute__((noinline))
+
+#if defined(__ELF__) || defined(__MACH__) || defined(__psp2__)
+#if !((defined(__sun__) && defined(__svr4__)) || defined(__CELLOS_LV2__))
+#define LJ_NOAPI extern __attribute__((visibility("hidden")))
+#endif
+#endif
+
+/* Note: it's only beneficial to use fastcall on x86 and then only for up to
+** two non-FP args. The amalgamated compile covers all LJ_FUNC cases. Only
+** indirect calls and related tail-called C functions are marked as fastcall.
+*/
+#if defined(__i386__)
+#define LJ_FASTCALL __attribute__((fastcall))
+#endif
+
+#define LJ_LIKELY(x) __builtin_expect(!!(x), 1)
+#define LJ_UNLIKELY(x) __builtin_expect(!!(x), 0)
+
+#define lj_ffs(x) ((uint32_t)__builtin_ctz(x))
+/* Don't ask ... */
+#if defined(__INTEL_COMPILER) && (defined(__i386__) || defined(__x86_64__))
+static LJ_AINLINE uint32_t lj_fls(uint32_t x)
+{
+ uint32_t r; __asm__("bsrl %1, %0" : "=r" (r) : "rm" (x) : "cc"); return r;
+}
+#else
+#define lj_fls(x) ((uint32_t)(__builtin_clz(x)^31))
+#endif
+
+#if defined(__arm__)
+static LJ_AINLINE uint32_t lj_bswap(uint32_t x)
+{
+#if defined(__psp2__)
+ return __builtin_rev(x);
+#else
+ uint32_t r;
+#if __ARM_ARCH_6__ || __ARM_ARCH_6J__ || __ARM_ARCH_6T2__ || __ARM_ARCH_6Z__ ||\
+ __ARM_ARCH_6ZK__ || __ARM_ARCH_7__ || __ARM_ARCH_7A__ || __ARM_ARCH_7R__
+ __asm__("rev %0, %1" : "=r" (r) : "r" (x));
+ return r;
+#else
+#ifdef __thumb__
+ r = x ^ lj_ror(x, 16);
+#else
+ __asm__("eor %0, %1, %1, ror #16" : "=r" (r) : "r" (x));
+#endif
+ return ((r & 0xff00ffffu) >> 8) ^ lj_ror(x, 8);
+#endif
+#endif
+}
+
+static LJ_AINLINE uint64_t lj_bswap64(uint64_t x)
+{
+ return ((uint64_t)lj_bswap((uint32_t)x)<<32) | lj_bswap((uint32_t)(x>>32));
+}
+#elif (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
+static LJ_AINLINE uint32_t lj_bswap(uint32_t x)
+{
+ return (uint32_t)__builtin_bswap32((int32_t)x);
+}
+
+static LJ_AINLINE uint64_t lj_bswap64(uint64_t x)
+{
+ return (uint64_t)__builtin_bswap64((int64_t)x);
+}
+#elif defined(__i386__) || defined(__x86_64__)
+static LJ_AINLINE uint32_t lj_bswap(uint32_t x)
+{
+ uint32_t r; __asm__("bswap %0" : "=r" (r) : "0" (x)); return r;
+}
+
+#if defined(__i386__)
+static LJ_AINLINE uint64_t lj_bswap64(uint64_t x)
+{
+ return ((uint64_t)lj_bswap((uint32_t)x)<<32) | lj_bswap((uint32_t)(x>>32));
+}
+#else
+static LJ_AINLINE uint64_t lj_bswap64(uint64_t x)
+{
+ uint64_t r; __asm__("bswap %0" : "=r" (r) : "0" (x)); return r;
+}
+#endif
+#else
+static LJ_AINLINE uint32_t lj_bswap(uint32_t x)
+{
+ return (x << 24) | ((x & 0xff00) << 8) | ((x >> 8) & 0xff00) | (x >> 24);
+}
+
+static LJ_AINLINE uint64_t lj_bswap64(uint64_t x)
+{
+ return (uint64_t)lj_bswap((uint32_t)(x >> 32)) |
+ ((uint64_t)lj_bswap((uint32_t)x) << 32);
+}
+#endif
+
+typedef union __attribute__((packed)) Unaligned16 {
+ uint16_t u;
+ uint8_t b[2];
+} Unaligned16;
+
+typedef union __attribute__((packed)) Unaligned32 {
+ uint32_t u;
+ uint8_t b[4];
+} Unaligned32;
+
+/* Unaligned load of uint16_t. */
+static LJ_AINLINE uint16_t lj_getu16(const void *p)
+{
+ return ((const Unaligned16 *)p)->u;
+}
+
+/* Unaligned load of uint32_t. */
+static LJ_AINLINE uint32_t lj_getu32(const void *p)
+{
+ return ((const Unaligned32 *)p)->u;
+}
+
+#elif defined(_MSC_VER)
+
+#define LJ_NORET __declspec(noreturn)
+#define LJ_ALIGN(n) __declspec(align(n))
+#define LJ_INLINE __inline
+#define LJ_AINLINE __forceinline
+#define LJ_NOINLINE __declspec(noinline)
+#if defined(_M_IX86)
+#define LJ_FASTCALL __fastcall
+#endif
+
+#ifdef _M_PPC
+unsigned int _CountLeadingZeros(long);
+#pragma intrinsic(_CountLeadingZeros)
+static LJ_AINLINE uint32_t lj_fls(uint32_t x)
+{
+ return _CountLeadingZeros(x) ^ 31;
+}
+#else
+unsigned char _BitScanForward(uint32_t *, unsigned long);
+unsigned char _BitScanReverse(uint32_t *, unsigned long);
+#pragma intrinsic(_BitScanForward)
+#pragma intrinsic(_BitScanReverse)
+
+static LJ_AINLINE uint32_t lj_ffs(uint32_t x)
+{
+ uint32_t r; _BitScanForward(&r, x); return r;
+}
+
+static LJ_AINLINE uint32_t lj_fls(uint32_t x)
+{
+ uint32_t r; _BitScanReverse(&r, x); return r;
+}
+#endif
+
+unsigned long _byteswap_ulong(unsigned long);
+uint64_t _byteswap_uint64(uint64_t);
+#define lj_bswap(x) (_byteswap_ulong((x)))
+#define lj_bswap64(x) (_byteswap_uint64((x)))
+
+#if defined(_M_PPC) && defined(LUAJIT_NO_UNALIGNED)
+/*
+** Replacement for unaligned loads on Xbox 360. Disabled by default since it's
+** usually more costly than the occasional stall when crossing a cache-line.
+*/
+static LJ_AINLINE uint16_t lj_getu16(const void *v)
+{
+ const uint8_t *p = (const uint8_t *)v;
+ return (uint16_t)((p[0]<<8) | p[1]);
+}
+static LJ_AINLINE uint32_t lj_getu32(const void *v)
+{
+ const uint8_t *p = (const uint8_t *)v;
+ return (uint32_t)((p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3]);
+}
+#else
+/* Unaligned loads are generally ok on x86/x64. */
+#define lj_getu16(p) (*(uint16_t *)(p))
+#define lj_getu32(p) (*(uint32_t *)(p))
+#endif
+
+#else
+#error "missing defines for your compiler"
+#endif
+
+/* Optional defines. */
+#ifndef LJ_FASTCALL
+#define LJ_FASTCALL
+#endif
+#ifndef LJ_NORET
+#define LJ_NORET
+#endif
+#ifndef LJ_NOAPI
+#define LJ_NOAPI extern
+#endif
+#ifndef LJ_LIKELY
+#define LJ_LIKELY(x) (x)
+#define LJ_UNLIKELY(x) (x)
+#endif
+
+/* Attributes for internal functions. */
+#define LJ_DATA LJ_NOAPI
+#define LJ_DATADEF
+#define LJ_ASMF LJ_NOAPI
+#define LJ_FUNCA LJ_NOAPI
+#if defined(ljamalg_c)
+#define LJ_FUNC static
+#else
+#define LJ_FUNC LJ_NOAPI
+#endif
+#define LJ_FUNC_NORET LJ_FUNC LJ_NORET
+#define LJ_FUNCA_NORET LJ_FUNCA LJ_NORET
+#define LJ_ASMF_NORET LJ_ASMF LJ_NORET
+
+/* Runtime assertions. */
+#ifdef lua_assert
+#define check_exp(c, e) (lua_assert(c), (e))
+#define api_check(l, e) lua_assert(e)
+#else
+#define lua_assert(c) ((void)0)
+#define check_exp(c, e) (e)
+#define api_check luai_apicheck
+#endif
+
+/* Static assertions. */
+#define LJ_ASSERT_NAME2(name, line) name ## line
+#define LJ_ASSERT_NAME(line) LJ_ASSERT_NAME2(lj_assert_, line)
+#ifdef __COUNTER__
+#define LJ_STATIC_ASSERT(cond) \
+ extern void LJ_ASSERT_NAME(__COUNTER__)(int STATIC_ASSERTION_FAILED[(cond)?1:-1])
+#else
+#define LJ_STATIC_ASSERT(cond) \
+ extern void LJ_ASSERT_NAME(__LINE__)(int STATIC_ASSERTION_FAILED[(cond)?1:-1])
+#endif
+
+#endif
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/1f27b840/lib/luajit/src/lj_dispatch.c
----------------------------------------------------------------------
diff --git a/lib/luajit/src/lj_dispatch.c b/lib/luajit/src/lj_dispatch.c
new file mode 100644
index 0000000..3725657
--- /dev/null
+++ b/lib/luajit/src/lj_dispatch.c
@@ -0,0 +1,494 @@
+/*
+** Instruction dispatch handling.
+** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
+*/
+
+#define lj_dispatch_c
+#define LUA_CORE
+
+#include "lj_obj.h"
+#include "lj_err.h"
+#include "lj_func.h"
+#include "lj_str.h"
+#include "lj_tab.h"
+#include "lj_meta.h"
+#include "lj_debug.h"
+#include "lj_state.h"
+#include "lj_frame.h"
+#include "lj_bc.h"
+#include "lj_ff.h"
+#if LJ_HASJIT
+#include "lj_jit.h"
+#endif
+#if LJ_HASFFI
+#include "lj_ccallback.h"
+#endif
+#include "lj_trace.h"
+#include "lj_dispatch.h"
+#include "lj_vm.h"
+#include "luajit.h"
+
+/* Bump GG_NUM_ASMFF in lj_dispatch.h as needed. Ugly. */
+LJ_STATIC_ASSERT(GG_NUM_ASMFF == FF_NUM_ASMFUNC);
+
+/* -- Dispatch table management ------------------------------------------- */
+
+#if LJ_TARGET_MIPS
+#include <math.h>
+LJ_FUNCA_NORET void LJ_FASTCALL lj_ffh_coroutine_wrap_err(lua_State *L,
+ lua_State *co);
+
+#define GOTFUNC(name) (ASMFunction)name,
+static const ASMFunction dispatch_got[] = {
+ GOTDEF(GOTFUNC)
+};
+#undef GOTFUNC
+#endif
+
+/* Initialize instruction dispatch table and hot counters. */
+void lj_dispatch_init(GG_State *GG)
+{
+ uint32_t i;
+ ASMFunction *disp = GG->dispatch;
+ for (i = 0; i < GG_LEN_SDISP; i++)
+ disp[GG_LEN_DDISP+i] = disp[i] = makeasmfunc(lj_bc_ofs[i]);
+ for (i = GG_LEN_SDISP; i < GG_LEN_DDISP; i++)
+ disp[i] = makeasmfunc(lj_bc_ofs[i]);
+ /* The JIT engine is off by default. luaopen_jit() turns it on. */
+ disp[BC_FORL] = disp[BC_IFORL];
+ disp[BC_ITERL] = disp[BC_IITERL];
+ disp[BC_LOOP] = disp[BC_ILOOP];
+ disp[BC_FUNCF] = disp[BC_IFUNCF];
+ disp[BC_FUNCV] = disp[BC_IFUNCV];
+ GG->g.bc_cfunc_ext = GG->g.bc_cfunc_int = BCINS_AD(BC_FUNCC, LUA_MINSTACK, 0);
+ for (i = 0; i < GG_NUM_ASMFF; i++)
+ GG->bcff[i] = BCINS_AD(BC__MAX+i, 0, 0);
+#if LJ_TARGET_MIPS
+ memcpy(GG->got, dispatch_got, LJ_GOT__MAX*4);
+#endif
+}
+
+#if LJ_HASJIT
+/* Initialize hotcount table. */
+void lj_dispatch_init_hotcount(global_State *g)
+{
+ int32_t hotloop = G2J(g)->param[JIT_P_hotloop];
+ HotCount start = (HotCount)(hotloop*HOTCOUNT_LOOP - 1);
+ HotCount *hotcount = G2GG(g)->hotcount;
+ uint32_t i;
+ for (i = 0; i < HOTCOUNT_SIZE; i++)
+ hotcount[i] = start;
+}
+#endif
+
+/* Internal dispatch mode bits. */
+#define DISPMODE_JIT 0x01 /* JIT compiler on. */
+#define DISPMODE_REC 0x02 /* Recording active. */
+#define DISPMODE_INS 0x04 /* Override instruction dispatch. */
+#define DISPMODE_CALL 0x08 /* Override call dispatch. */
+#define DISPMODE_RET 0x10 /* Override return dispatch. */
+
+/* Update dispatch table depending on various flags. */
+void lj_dispatch_update(global_State *g)
+{
+ uint8_t oldmode = g->dispatchmode;
+ uint8_t mode = 0;
+#if LJ_HASJIT
+ mode |= (G2J(g)->flags & JIT_F_ON) ? DISPMODE_JIT : 0;
+ mode |= G2J(g)->state != LJ_TRACE_IDLE ?
+ (DISPMODE_REC|DISPMODE_INS|DISPMODE_CALL) : 0;
+#endif
+ mode |= (g->hookmask & (LUA_MASKLINE|LUA_MASKCOUNT)) ? DISPMODE_INS : 0;
+ mode |= (g->hookmask & LUA_MASKCALL) ? DISPMODE_CALL : 0;
+ mode |= (g->hookmask & LUA_MASKRET) ? DISPMODE_RET : 0;
+ if (oldmode != mode) { /* Mode changed? */
+ ASMFunction *disp = G2GG(g)->dispatch;
+ ASMFunction f_forl, f_iterl, f_loop, f_funcf, f_funcv;
+ g->dispatchmode = mode;
+
+ /* Hotcount if JIT is on, but not while recording. */
+ if ((mode & (DISPMODE_JIT|DISPMODE_REC)) == DISPMODE_JIT) {
+ f_forl = makeasmfunc(lj_bc_ofs[BC_FORL]);
+ f_iterl = makeasmfunc(lj_bc_ofs[BC_ITERL]);
+ f_loop = makeasmfunc(lj_bc_ofs[BC_LOOP]);
+ f_funcf = makeasmfunc(lj_bc_ofs[BC_FUNCF]);
+ f_funcv = makeasmfunc(lj_bc_ofs[BC_FUNCV]);
+ } else { /* Otherwise use the non-hotcounting instructions. */
+ f_forl = disp[GG_LEN_DDISP+BC_IFORL];
+ f_iterl = disp[GG_LEN_DDISP+BC_IITERL];
+ f_loop = disp[GG_LEN_DDISP+BC_ILOOP];
+ f_funcf = makeasmfunc(lj_bc_ofs[BC_IFUNCF]);
+ f_funcv = makeasmfunc(lj_bc_ofs[BC_IFUNCV]);
+ }
+ /* Init static counting instruction dispatch first (may be copied below). */
+ disp[GG_LEN_DDISP+BC_FORL] = f_forl;
+ disp[GG_LEN_DDISP+BC_ITERL] = f_iterl;
+ disp[GG_LEN_DDISP+BC_LOOP] = f_loop;
+
+ /* Set dynamic instruction dispatch. */
+ if ((oldmode ^ mode) & (DISPMODE_REC|DISPMODE_INS)) {
+ /* Need to update the whole table. */
+ if (!(mode & (DISPMODE_REC|DISPMODE_INS))) { /* No ins dispatch? */
+ /* Copy static dispatch table to dynamic dispatch table. */
+ memcpy(&disp[0], &disp[GG_LEN_DDISP], GG_LEN_SDISP*sizeof(ASMFunction));
+ /* Overwrite with dynamic return dispatch. */
+ if ((mode & DISPMODE_RET)) {
+ disp[BC_RETM] = lj_vm_rethook;
+ disp[BC_RET] = lj_vm_rethook;
+ disp[BC_RET0] = lj_vm_rethook;
+ disp[BC_RET1] = lj_vm_rethook;
+ }
+ } else {
+ /* The recording dispatch also checks for hooks. */
+ ASMFunction f = (mode & DISPMODE_REC) ? lj_vm_record : lj_vm_inshook;
+ uint32_t i;
+ for (i = 0; i < GG_LEN_SDISP; i++)
+ disp[i] = f;
+ }
+ } else if (!(mode & (DISPMODE_REC|DISPMODE_INS))) {
+ /* Otherwise set dynamic counting ins. */
+ disp[BC_FORL] = f_forl;
+ disp[BC_ITERL] = f_iterl;
+ disp[BC_LOOP] = f_loop;
+ /* Set dynamic return dispatch. */
+ if ((mode & DISPMODE_RET)) {
+ disp[BC_RETM] = lj_vm_rethook;
+ disp[BC_RET] = lj_vm_rethook;
+ disp[BC_RET0] = lj_vm_rethook;
+ disp[BC_RET1] = lj_vm_rethook;
+ } else {
+ disp[BC_RETM] = disp[GG_LEN_DDISP+BC_RETM];
+ disp[BC_RET] = disp[GG_LEN_DDISP+BC_RET];
+ disp[BC_RET0] = disp[GG_LEN_DDISP+BC_RET0];
+ disp[BC_RET1] = disp[GG_LEN_DDISP+BC_RET1];
+ }
+ }
+
+ /* Set dynamic call dispatch. */
+ if ((oldmode ^ mode) & DISPMODE_CALL) { /* Update the whole table? */
+ uint32_t i;
+ if ((mode & DISPMODE_CALL) == 0) { /* No call hooks? */
+ for (i = GG_LEN_SDISP; i < GG_LEN_DDISP; i++)
+ disp[i] = makeasmfunc(lj_bc_ofs[i]);
+ } else {
+ for (i = GG_LEN_SDISP; i < GG_LEN_DDISP; i++)
+ disp[i] = lj_vm_callhook;
+ }
+ }
+ if (!(mode & DISPMODE_CALL)) { /* Overwrite dynamic counting ins. */
+ disp[BC_FUNCF] = f_funcf;
+ disp[BC_FUNCV] = f_funcv;
+ }
+
+#if LJ_HASJIT
+ /* Reset hotcounts for JIT off to on transition. */
+ if ((mode & DISPMODE_JIT) && !(oldmode & DISPMODE_JIT))
+ lj_dispatch_init_hotcount(g);
+#endif
+ }
+}
+
+/* -- JIT mode setting ---------------------------------------------------- */
+
+#if LJ_HASJIT
+/* Set JIT mode for a single prototype. */
+static void setptmode(global_State *g, GCproto *pt, int mode)
+{
+ if ((mode & LUAJIT_MODE_ON)) { /* (Re-)enable JIT compilation. */
+ pt->flags &= ~PROTO_NOJIT;
+ lj_trace_reenableproto(pt); /* Unpatch all ILOOP etc. bytecodes. */
+ } else { /* Flush and/or disable JIT compilation. */
+ if (!(mode & LUAJIT_MODE_FLUSH))
+ pt->flags |= PROTO_NOJIT;
+ lj_trace_flushproto(g, pt); /* Flush all traces of prototype. */
+ }
+}
+
+/* Recursively set the JIT mode for all children of a prototype. */
+static void setptmode_all(global_State *g, GCproto *pt, int mode)
+{
+ ptrdiff_t i;
+ if (!(pt->flags & PROTO_CHILD)) return;
+ for (i = -(ptrdiff_t)pt->sizekgc; i < 0; i++) {
+ GCobj *o = proto_kgc(pt, i);
+ if (o->gch.gct == ~LJ_TPROTO) {
+ setptmode(g, gco2pt(o), mode);
+ setptmode_all(g, gco2pt(o), mode);
+ }
+ }
+}
+#endif
+
+/* Public API function: control the JIT engine. */
+int luaJIT_setmode(lua_State *L, int idx, int mode)
+{
+ global_State *g = G(L);
+ int mm = mode & LUAJIT_MODE_MASK;
+ lj_trace_abort(g); /* Abort recording on any state change. */
+ /* Avoid pulling the rug from under our own feet. */
+ if ((g->hookmask & HOOK_GC))
+ lj_err_caller(L, LJ_ERR_NOGCMM);
+ switch (mm) {
+#if LJ_HASJIT
+ case LUAJIT_MODE_ENGINE:
+ if ((mode & LUAJIT_MODE_FLUSH)) {
+ lj_trace_flushall(L);
+ } else {
+ if (!(mode & LUAJIT_MODE_ON))
+ G2J(g)->flags &= ~(uint32_t)JIT_F_ON;
+#if LJ_TARGET_X86ORX64
+ else if ((G2J(g)->flags & JIT_F_SSE2))
+ G2J(g)->flags |= (uint32_t)JIT_F_ON;
+ else
+ return 0; /* Don't turn on JIT compiler without SSE2 support. */
+#else
+ else
+ G2J(g)->flags |= (uint32_t)JIT_F_ON;
+#endif
+ lj_dispatch_update(g);
+ }
+ break;
+ case LUAJIT_MODE_FUNC:
+ case LUAJIT_MODE_ALLFUNC:
+ case LUAJIT_MODE_ALLSUBFUNC: {
+ cTValue *tv = idx == 0 ? frame_prev(L->base-1) :
+ idx > 0 ? L->base + (idx-1) : L->top + idx;
+ GCproto *pt;
+ if ((idx == 0 || tvisfunc(tv)) && isluafunc(&gcval(tv)->fn))
+ pt = funcproto(&gcval(tv)->fn); /* Cannot use funcV() for frame slot. */
+ else if (tvisproto(tv))
+ pt = protoV(tv);
+ else
+ return 0; /* Failed. */
+ if (mm != LUAJIT_MODE_ALLSUBFUNC)
+ setptmode(g, pt, mode);
+ if (mm != LUAJIT_MODE_FUNC)
+ setptmode_all(g, pt, mode);
+ break;
+ }
+ case LUAJIT_MODE_TRACE:
+ if (!(mode & LUAJIT_MODE_FLUSH))
+ return 0; /* Failed. */
+ lj_trace_flush(G2J(g), idx);
+ break;
+#else
+ case LUAJIT_MODE_ENGINE:
+ case LUAJIT_MODE_FUNC:
+ case LUAJIT_MODE_ALLFUNC:
+ case LUAJIT_MODE_ALLSUBFUNC:
+ UNUSED(idx);
+ if ((mode & LUAJIT_MODE_ON))
+ return 0; /* Failed. */
+ break;
+#endif
+ case LUAJIT_MODE_WRAPCFUNC:
+ if ((mode & LUAJIT_MODE_ON)) {
+ if (idx != 0) {
+ cTValue *tv = idx > 0 ? L->base + (idx-1) : L->top + idx;
+ if (tvislightud(tv))
+ g->wrapf = (lua_CFunction)lightudV(tv);
+ else
+ return 0; /* Failed. */
+ } else {
+ return 0; /* Failed. */
+ }
+ g->bc_cfunc_ext = BCINS_AD(BC_FUNCCW, 0, 0);
+ } else {
+ g->bc_cfunc_ext = BCINS_AD(BC_FUNCC, 0, 0);
+ }
+ break;
+ default:
+ return 0; /* Failed. */
+ }
+ return 1; /* OK. */
+}
+
+/* Enforce (dynamic) linker error for version mismatches. See luajit.c. */
+LUA_API void LUAJIT_VERSION_SYM(void)
+{
+}
+
+/* -- Hooks --------------------------------------------------------------- */
+
+/* This function can be called asynchronously (e.g. during a signal). */
+LUA_API int lua_sethook(lua_State *L, lua_Hook func, int mask, int count)
+{
+ global_State *g = G(L);
+ mask &= HOOK_EVENTMASK;
+ if (func == NULL || mask == 0) { mask = 0; func = NULL; } /* Consistency. */
+ g->hookf = func;
+ g->hookcount = g->hookcstart = (int32_t)count;
+ g->hookmask = (uint8_t)((g->hookmask & ~HOOK_EVENTMASK) | mask);
+ lj_trace_abort(g); /* Abort recording on any hook change. */
+ lj_dispatch_update(g);
+ return 1;
+}
+
+LUA_API lua_Hook lua_gethook(lua_State *L)
+{
+ return G(L)->hookf;
+}
+
+LUA_API int lua_gethookmask(lua_State *L)
+{
+ return G(L)->hookmask & HOOK_EVENTMASK;
+}
+
+LUA_API int lua_gethookcount(lua_State *L)
+{
+ return (int)G(L)->hookcstart;
+}
+
+/* Call a hook. */
+static void callhook(lua_State *L, int event, BCLine line)
+{
+ global_State *g = G(L);
+ lua_Hook hookf = g->hookf;
+ if (hookf && !hook_active(g)) {
+ lua_Debug ar;
+ lj_trace_abort(g); /* Abort recording on any hook call. */
+ ar.event = event;
+ ar.currentline = line;
+ /* Top frame, nextframe = NULL. */
+ ar.i_ci = (int)((L->base-1) - tvref(L->stack));
+ lj_state_checkstack(L, 1+LUA_MINSTACK);
+ hook_enter(g);
+ hookf(L, &ar);
+ lua_assert(hook_active(g));
+ hook_leave(g);
+ }
+}
+
+/* -- Dispatch callbacks -------------------------------------------------- */
+
+/* Calculate number of used stack slots in the current frame. */
+static BCReg cur_topslot(GCproto *pt, const BCIns *pc, uint32_t nres)
+{
+ BCIns ins = pc[-1];
+ if (bc_op(ins) == BC_UCLO)
+ ins = pc[bc_j(ins)];
+ switch (bc_op(ins)) {
+ case BC_CALLM: case BC_CALLMT: return bc_a(ins) + bc_c(ins) + nres-1+1;
+ case BC_RETM: return bc_a(ins) + bc_d(ins) + nres-1;
+ case BC_TSETM: return bc_a(ins) + nres-1;
+ default: return pt->framesize;
+ }
+}
+
+/* Instruction dispatch. Used by instr/line/return hooks or when recording. */
+void LJ_FASTCALL lj_dispatch_ins(lua_State *L, const BCIns *pc)
+{
+ ERRNO_SAVE
+ GCfunc *fn = curr_func(L);
+ GCproto *pt = funcproto(fn);
+ void *cf = cframe_raw(L->cframe);
+ const BCIns *oldpc = cframe_pc(cf);
+ global_State *g = G(L);
+ BCReg slots;
+ setcframe_pc(cf, pc);
+ slots = cur_topslot(pt, pc, cframe_multres_n(cf));
+ L->top = L->base + slots; /* Fix top. */
+#if LJ_HASJIT
+ {
+ jit_State *J = G2J(g);
+ if (J->state != LJ_TRACE_IDLE) {
+#ifdef LUA_USE_ASSERT
+ ptrdiff_t delta = L->top - L->base;
+#endif
+ J->L = L;
+ lj_trace_ins(J, pc-1); /* The interpreter bytecode PC is offset by 1. */
+ lua_assert(L->top - L->base == delta);
+ }
+ }
+#endif
+ if ((g->hookmask & LUA_MASKCOUNT) && g->hookcount == 0) {
+ g->hookcount = g->hookcstart;
+ callhook(L, LUA_HOOKCOUNT, -1);
+ L->top = L->base + slots; /* Fix top again. */
+ }
+ if ((g->hookmask & LUA_MASKLINE)) {
+ BCPos npc = proto_bcpos(pt, pc) - 1;
+ BCPos opc = proto_bcpos(pt, oldpc) - 1;
+ BCLine line = lj_debug_line(pt, npc);
+ if (pc <= oldpc || opc >= pt->sizebc || line != lj_debug_line(pt, opc)) {
+ callhook(L, LUA_HOOKLINE, line);
+ L->top = L->base + slots; /* Fix top again. */
+ }
+ }
+ if ((g->hookmask & LUA_MASKRET) && bc_isret(bc_op(pc[-1])))
+ callhook(L, LUA_HOOKRET, -1);
+ ERRNO_RESTORE
+}
+
+/* Initialize call. Ensure stack space and return # of missing parameters. */
+static int call_init(lua_State *L, GCfunc *fn)
+{
+ if (isluafunc(fn)) {
+ GCproto *pt = funcproto(fn);
+ int numparams = pt->numparams;
+ int gotparams = (int)(L->top - L->base);
+ int need = pt->framesize;
+ if ((pt->flags & PROTO_VARARG)) need += 1+gotparams;
+ lj_state_checkstack(L, (MSize)need);
+ numparams -= gotparams;
+ return numparams >= 0 ? numparams : 0;
+ } else {
+ lj_state_checkstack(L, LUA_MINSTACK);
+ return 0;
+ }
+}
+
+/* Call dispatch. Used by call hooks, hot calls or when recording. */
+ASMFunction LJ_FASTCALL lj_dispatch_call(lua_State *L, const BCIns *pc)
+{
+ ERRNO_SAVE
+ GCfunc *fn = curr_func(L);
+ BCOp op;
+ global_State *g = G(L);
+#if LJ_HASJIT
+ jit_State *J = G2J(g);
+#endif
+ int missing = call_init(L, fn);
+#if LJ_HASJIT
+ J->L = L;
+ if ((uintptr_t)pc & 1) { /* Marker for hot call. */
+#ifdef LUA_USE_ASSERT
+ ptrdiff_t delta = L->top - L->base;
+#endif
+ pc = (const BCIns *)((uintptr_t)pc & ~(uintptr_t)1);
+ lj_trace_hot(J, pc);
+ lua_assert(L->top - L->base == delta);
+ goto out;
+ } else if (J->state != LJ_TRACE_IDLE &&
+ !(g->hookmask & (HOOK_GC|HOOK_VMEVENT))) {
+#ifdef LUA_USE_ASSERT
+ ptrdiff_t delta = L->top - L->base;
+#endif
+ /* Record the FUNC* bytecodes, too. */
+ lj_trace_ins(J, pc-1); /* The interpreter bytecode PC is offset by 1. */
+ lua_assert(L->top - L->base == delta);
+ }
+#endif
+ if ((g->hookmask & LUA_MASKCALL)) {
+ int i;
+ for (i = 0; i < missing; i++) /* Add missing parameters. */
+ setnilV(L->top++);
+ callhook(L, LUA_HOOKCALL, -1);
+ /* Preserve modifications of missing parameters by lua_setlocal(). */
+ while (missing-- > 0 && tvisnil(L->top - 1))
+ L->top--;
+ }
+#if LJ_HASJIT
+out:
+#endif
+ op = bc_op(pc[-1]); /* Get FUNC* op. */
+#if LJ_HASJIT
+ /* Use the non-hotcounting variants if JIT is off or while recording. */
+ if ((!(J->flags & JIT_F_ON) || J->state != LJ_TRACE_IDLE) &&
+ (op == BC_FUNCF || op == BC_FUNCV))
+ op = (BCOp)((int)op+(int)BC_IFUNCF-(int)BC_FUNCF);
+#endif
+ ERRNO_RESTORE
+ return makeasmfunc(lj_bc_ofs[op]); /* Return static dispatch target. */
+}
+
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/1f27b840/lib/luajit/src/lj_dispatch.h
----------------------------------------------------------------------
diff --git a/lib/luajit/src/lj_dispatch.h b/lib/luajit/src/lj_dispatch.h
new file mode 100644
index 0000000..778affc
--- /dev/null
+++ b/lib/luajit/src/lj_dispatch.h
@@ -0,0 +1,131 @@
+/*
+** Instruction dispatch handling.
+** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
+*/
+
+#ifndef _LJ_DISPATCH_H
+#define _LJ_DISPATCH_H
+
+#include "lj_obj.h"
+#include "lj_bc.h"
+#if LJ_HASJIT
+#include "lj_jit.h"
+#endif
+
+#if LJ_TARGET_MIPS
+/* Need our own global offset table for the dreaded MIPS calling conventions. */
+#if LJ_HASJIT
+#define JITGOTDEF(_) _(lj_trace_exit) _(lj_trace_hot)
+#else
+#define JITGOTDEF(_)
+#endif
+#if LJ_HASFFI
+#define FFIGOTDEF(_) \
+ _(lj_meta_equal_cd) _(lj_ccallback_enter) _(lj_ccallback_leave)
+#else
+#define FFIGOTDEF(_)
+#endif
+#define GOTDEF(_) \
+ _(floor) _(ceil) _(trunc) _(log) _(log10) _(exp) _(sin) _(cos) _(tan) \
+ _(asin) _(acos) _(atan) _(sinh) _(cosh) _(tanh) _(frexp) _(modf) _(atan2) \
+ _(pow) _(fmod) _(ldexp) \
+ _(lj_dispatch_call) _(lj_dispatch_ins) _(lj_err_throw) \
+ _(lj_ffh_coroutine_wrap_err) _(lj_func_closeuv) _(lj_func_newL_gc) \
+ _(lj_gc_barrieruv) _(lj_gc_step) _(lj_gc_step_fixtop) _(lj_meta_arith) \
+ _(lj_meta_call) _(lj_meta_cat) _(lj_meta_comp) _(lj_meta_equal) \
+ _(lj_meta_for) _(lj_meta_len) _(lj_meta_tget) _(lj_meta_tset) \
+ _(lj_state_growstack) _(lj_str_fromnum) _(lj_str_fromnumber) _(lj_str_new) \
+ _(lj_tab_dup) _(lj_tab_get) _(lj_tab_getinth) _(lj_tab_len) _(lj_tab_new) \
+ _(lj_tab_newkey) _(lj_tab_next) _(lj_tab_reasize) \
+ JITGOTDEF(_) FFIGOTDEF(_)
+
+enum {
+#define GOTENUM(name) LJ_GOT_##name,
+GOTDEF(GOTENUM)
+#undef GOTENUM
+ LJ_GOT__MAX
+};
+#endif
+
+/* Type of hot counter. Must match the code in the assembler VM. */
+/* 16 bits are sufficient. Only 0.0015% overhead with maximum slot penalty. */
+typedef uint16_t HotCount;
+
+/* Number of hot counter hash table entries (must be a power of two). */
+#define HOTCOUNT_SIZE 64
+#define HOTCOUNT_PCMASK ((HOTCOUNT_SIZE-1)*sizeof(HotCount))
+
+/* Hotcount decrements. */
+#define HOTCOUNT_LOOP 2
+#define HOTCOUNT_CALL 1
+
+/* This solves a circular dependency problem -- bump as needed. Sigh. */
+#define GG_NUM_ASMFF 62
+
+#define GG_LEN_DDISP (BC__MAX + GG_NUM_ASMFF)
+#define GG_LEN_SDISP BC_FUNCF
+#define GG_LEN_DISP (GG_LEN_DDISP + GG_LEN_SDISP)
+
+/* Global state, main thread and extra fields are allocated together. */
+typedef struct GG_State {
+ lua_State L; /* Main thread. */
+ global_State g; /* Global state. */
+#if LJ_TARGET_MIPS
+ ASMFunction got[LJ_GOT__MAX]; /* Global offset table. */
+#endif
+#if LJ_HASJIT
+ jit_State J; /* JIT state. */
+ HotCount hotcount[HOTCOUNT_SIZE]; /* Hot counters. */
+#endif
+ ASMFunction dispatch[GG_LEN_DISP]; /* Instruction dispatch tables. */
+ BCIns bcff[GG_NUM_ASMFF]; /* Bytecode for ASM fast functions. */
+} GG_State;
+
+#define GG_OFS(field) ((int)offsetof(GG_State, field))
+#define G2GG(gl) ((GG_State *)((char *)(gl) - GG_OFS(g)))
+#define J2GG(j) ((GG_State *)((char *)(j) - GG_OFS(J)))
+#define L2GG(L) (G2GG(G(L)))
+#define J2G(J) (&J2GG(J)->g)
+#define G2J(gl) (&G2GG(gl)->J)
+#define L2J(L) (&L2GG(L)->J)
+#define GG_G2DISP (GG_OFS(dispatch) - GG_OFS(g))
+#define GG_DISP2G (GG_OFS(g) - GG_OFS(dispatch))
+#define GG_DISP2J (GG_OFS(J) - GG_OFS(dispatch))
+#define GG_DISP2HOT (GG_OFS(hotcount) - GG_OFS(dispatch))
+#define GG_DISP2STATIC (GG_LEN_DDISP*(int)sizeof(ASMFunction))
+
+#define hotcount_get(gg, pc) \
+ (gg)->hotcount[(u32ptr(pc)>>2) & (HOTCOUNT_SIZE-1)]
+#define hotcount_set(gg, pc, val) \
+ (hotcount_get((gg), (pc)) = (HotCount)(val))
+
+/* Dispatch table management. */
+LJ_FUNC void lj_dispatch_init(GG_State *GG);
+#if LJ_HASJIT
+LJ_FUNC void lj_dispatch_init_hotcount(global_State *g);
+#endif
+LJ_FUNC void lj_dispatch_update(global_State *g);
+
+/* Instruction dispatch callback for hooks or when recording. */
+LJ_FUNCA void LJ_FASTCALL lj_dispatch_ins(lua_State *L, const BCIns *pc);
+LJ_FUNCA ASMFunction LJ_FASTCALL lj_dispatch_call(lua_State *L, const BCIns*pc);
+LJ_FUNCA void LJ_FASTCALL lj_dispatch_return(lua_State *L, const BCIns *pc);
+
+#if LJ_HASFFI && !defined(_BUILDVM_H)
+/* Save/restore errno and GetLastError() around hooks, exits and recording. */
+#include <errno.h>
+#if LJ_TARGET_WINDOWS
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#define ERRNO_SAVE int olderr = errno; DWORD oldwerr = GetLastError();
+#define ERRNO_RESTORE errno = olderr; SetLastError(oldwerr);
+#else
+#define ERRNO_SAVE int olderr = errno;
+#define ERRNO_RESTORE errno = olderr;
+#endif
+#else
+#define ERRNO_SAVE
+#define ERRNO_RESTORE
+#endif
+
+#endif
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/1f27b840/lib/luajit/src/lj_emit_arm.h
----------------------------------------------------------------------
diff --git a/lib/luajit/src/lj_emit_arm.h b/lib/luajit/src/lj_emit_arm.h
new file mode 100644
index 0000000..8c5e537
--- /dev/null
+++ b/lib/luajit/src/lj_emit_arm.h
@@ -0,0 +1,356 @@
+/*
+** ARM instruction emitter.
+** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
+*/
+
+/* -- Constant encoding --------------------------------------------------- */
+
+static uint8_t emit_invai[16] = {
+ /* AND */ (ARMI_AND^ARMI_BIC) >> 21,
+ /* EOR */ 0,
+ /* SUB */ (ARMI_SUB^ARMI_ADD) >> 21,
+ /* RSB */ 0,
+ /* ADD */ (ARMI_ADD^ARMI_SUB) >> 21,
+ /* ADC */ (ARMI_ADC^ARMI_SBC) >> 21,
+ /* SBC */ (ARMI_SBC^ARMI_ADC) >> 21,
+ /* RSC */ 0,
+ /* TST */ 0,
+ /* TEQ */ 0,
+ /* CMP */ (ARMI_CMP^ARMI_CMN) >> 21,
+ /* CMN */ (ARMI_CMN^ARMI_CMP) >> 21,
+ /* ORR */ 0,
+ /* MOV */ (ARMI_MOV^ARMI_MVN) >> 21,
+ /* BIC */ (ARMI_BIC^ARMI_AND) >> 21,
+ /* MVN */ (ARMI_MVN^ARMI_MOV) >> 21
+};
+
+/* Encode constant in K12 format for data processing instructions. */
+static uint32_t emit_isk12(ARMIns ai, int32_t n)
+{
+ uint32_t invai, i, m = (uint32_t)n;
+ /* K12: unsigned 8 bit value, rotated in steps of two bits. */
+ for (i = 0; i < 4096; i += 256, m = lj_rol(m, 2))
+ if (m <= 255) return ARMI_K12|m|i;
+ /* Otherwise try negation/complement with the inverse instruction. */
+ invai = emit_invai[((ai >> 21) & 15)];
+ if (!invai) return 0; /* Failed. No inverse instruction. */
+ m = ~(uint32_t)n;
+ if (invai == ((ARMI_SUB^ARMI_ADD) >> 21) ||
+ invai == (ARMI_CMP^ARMI_CMN) >> 21) m++;
+ for (i = 0; i < 4096; i += 256, m = lj_rol(m, 2))
+ if (m <= 255) return ARMI_K12|(invai<<21)|m|i;
+ return 0; /* Failed. */
+}
+
+/* -- Emit basic instructions --------------------------------------------- */
+
+static void emit_dnm(ASMState *as, ARMIns ai, Reg rd, Reg rn, Reg rm)
+{
+ *--as->mcp = ai | ARMF_D(rd) | ARMF_N(rn) | ARMF_M(rm);
+}
+
+static void emit_dm(ASMState *as, ARMIns ai, Reg rd, Reg rm)
+{
+ *--as->mcp = ai | ARMF_D(rd) | ARMF_M(rm);
+}
+
+static void emit_dn(ASMState *as, ARMIns ai, Reg rd, Reg rn)
+{
+ *--as->mcp = ai | ARMF_D(rd) | ARMF_N(rn);
+}
+
+static void emit_nm(ASMState *as, ARMIns ai, Reg rn, Reg rm)
+{
+ *--as->mcp = ai | ARMF_N(rn) | ARMF_M(rm);
+}
+
+static void emit_d(ASMState *as, ARMIns ai, Reg rd)
+{
+ *--as->mcp = ai | ARMF_D(rd);
+}
+
+static void emit_n(ASMState *as, ARMIns ai, Reg rn)
+{
+ *--as->mcp = ai | ARMF_N(rn);
+}
+
+static void emit_m(ASMState *as, ARMIns ai, Reg rm)
+{
+ *--as->mcp = ai | ARMF_M(rm);
+}
+
+static void emit_lsox(ASMState *as, ARMIns ai, Reg rd, Reg rn, int32_t ofs)
+{
+ lua_assert(ofs >= -255 && ofs <= 255);
+ if (ofs < 0) ofs = -ofs; else ai |= ARMI_LS_U;
+ *--as->mcp = ai | ARMI_LS_P | ARMI_LSX_I | ARMF_D(rd) | ARMF_N(rn) |
+ ((ofs & 0xf0) << 4) | (ofs & 0x0f);
+}
+
+static void emit_lso(ASMState *as, ARMIns ai, Reg rd, Reg rn, int32_t ofs)
+{
+ lua_assert(ofs >= -4095 && ofs <= 4095);
+ /* Combine LDR/STR pairs to LDRD/STRD. */
+ if (*as->mcp == (ai|ARMI_LS_P|ARMI_LS_U|ARMF_D(rd^1)|ARMF_N(rn)|(ofs^4)) &&
+ (ai & ~(ARMI_LDR^ARMI_STR)) == ARMI_STR && rd != rn &&
+ (uint32_t)ofs <= 252 && !(ofs & 3) && !((rd ^ (ofs >>2)) & 1) &&
+ as->mcp != as->mcloop) {
+ as->mcp++;
+ emit_lsox(as, ai == ARMI_LDR ? ARMI_LDRD : ARMI_STRD, rd&~1, rn, ofs&~4);
+ return;
+ }
+ if (ofs < 0) ofs = -ofs; else ai |= ARMI_LS_U;
+ *--as->mcp = ai | ARMI_LS_P | ARMF_D(rd) | ARMF_N(rn) | ofs;
+}
+
+#if !LJ_SOFTFP
+static void emit_vlso(ASMState *as, ARMIns ai, Reg rd, Reg rn, int32_t ofs)
+{
+ lua_assert(ofs >= -1020 && ofs <= 1020 && (ofs&3) == 0);
+ if (ofs < 0) ofs = -ofs; else ai |= ARMI_LS_U;
+ *--as->mcp = ai | ARMI_LS_P | ARMF_D(rd & 15) | ARMF_N(rn) | (ofs >> 2);
+}
+#endif
+
+/* -- Emit loads/stores --------------------------------------------------- */
+
+/* Prefer spills of BASE/L. */
+#define emit_canremat(ref) ((ref) < ASMREF_L)
+
+/* Try to find a one step delta relative to another constant. */
+static int emit_kdelta1(ASMState *as, Reg d, int32_t i)
+{
+ RegSet work = ~as->freeset & RSET_GPR;
+ while (work) {
+ Reg r = rset_picktop(work);
+ IRRef ref = regcost_ref(as->cost[r]);
+ lua_assert(r != d);
+ if (emit_canremat(ref)) {
+ int32_t delta = i - (ra_iskref(ref) ? ra_krefk(as, ref) : IR(ref)->i);
+ uint32_t k = emit_isk12(ARMI_ADD, delta);
+ if (k) {
+ if (k == ARMI_K12)
+ emit_dm(as, ARMI_MOV, d, r);
+ else
+ emit_dn(as, ARMI_ADD^k, d, r);
+ return 1;
+ }
+ }
+ rset_clear(work, r);
+ }
+ return 0; /* Failed. */
+}
+
+/* Try to find a two step delta relative to another constant. */
+static int emit_kdelta2(ASMState *as, Reg d, int32_t i)
+{
+ RegSet work = ~as->freeset & RSET_GPR;
+ while (work) {
+ Reg r = rset_picktop(work);
+ IRRef ref = regcost_ref(as->cost[r]);
+ lua_assert(r != d);
+ if (emit_canremat(ref)) {
+ int32_t other = ra_iskref(ref) ? ra_krefk(as, ref) : IR(ref)->i;
+ if (other) {
+ int32_t delta = i - other;
+ uint32_t sh, inv = 0, k2, k;
+ if (delta < 0) { delta = -delta; inv = ARMI_ADD^ARMI_SUB; }
+ sh = lj_ffs(delta) & ~1;
+ k2 = emit_isk12(0, delta & (255 << sh));
+ k = emit_isk12(0, delta & ~(255 << sh));
+ if (k) {
+ emit_dn(as, ARMI_ADD^k2^inv, d, d);
+ emit_dn(as, ARMI_ADD^k^inv, d, r);
+ return 1;
+ }
+ }
+ }
+ rset_clear(work, r);
+ }
+ return 0; /* Failed. */
+}
+
+/* Load a 32 bit constant into a GPR. */
+static void emit_loadi(ASMState *as, Reg r, int32_t i)
+{
+ uint32_t k = emit_isk12(ARMI_MOV, i);
+ lua_assert(rset_test(as->freeset, r) || r == RID_TMP);
+ if (k) {
+ /* Standard K12 constant. */
+ emit_d(as, ARMI_MOV^k, r);
+ } else if ((as->flags & JIT_F_ARMV6T2) && (uint32_t)i < 0x00010000u) {
+ /* 16 bit loword constant for ARMv6T2. */
+ emit_d(as, ARMI_MOVW|(i & 0x0fff)|((i & 0xf000)<<4), r);
+ } else if (emit_kdelta1(as, r, i)) {
+ /* One step delta relative to another constant. */
+ } else if ((as->flags & JIT_F_ARMV6T2)) {
+ /* 32 bit hiword/loword constant for ARMv6T2. */
+ emit_d(as, ARMI_MOVT|((i>>16) & 0x0fff)|(((i>>16) & 0xf000)<<4), r);
+ emit_d(as, ARMI_MOVW|(i & 0x0fff)|((i & 0xf000)<<4), r);
+ } else if (emit_kdelta2(as, r, i)) {
+ /* Two step delta relative to another constant. */
+ } else {
+ /* Otherwise construct the constant with up to 4 instructions. */
+ /* NYI: use mvn+bic, use pc-relative loads. */
+ for (;;) {
+ uint32_t sh = lj_ffs(i) & ~1;
+ int32_t m = i & (255 << sh);
+ i &= ~(255 << sh);
+ if (i == 0) {
+ emit_d(as, ARMI_MOV ^ emit_isk12(0, m), r);
+ break;
+ }
+ emit_dn(as, ARMI_ORR ^ emit_isk12(0, m), r, r);
+ }
+ }
+}
+
+#define emit_loada(as, r, addr) emit_loadi(as, (r), i32ptr((addr)))
+
+static Reg ra_allock(ASMState *as, int32_t k, RegSet allow);
+
+/* Get/set from constant pointer. */
+static void emit_lsptr(ASMState *as, ARMIns ai, Reg r, void *p)
+{
+ int32_t i = i32ptr(p);
+ emit_lso(as, ai, r, ra_allock(as, (i & ~4095), rset_exclude(RSET_GPR, r)),
+ (i & 4095));
+}
+
+#if !LJ_SOFTFP
+/* Load a number constant into an FPR. */
+static void emit_loadn(ASMState *as, Reg r, cTValue *tv)
+{
+ int32_t i;
+ if ((as->flags & JIT_F_VFPV3) && !tv->u32.lo) {
+ uint32_t hi = tv->u32.hi;
+ uint32_t b = ((hi >> 22) & 0x1ff);
+ if (!(hi & 0xffff) && (b == 0x100 || b == 0x0ff)) {
+ *--as->mcp = ARMI_VMOVI_D | ARMF_D(r & 15) |
+ ((tv->u32.hi >> 12) & 0x00080000) |
+ ((tv->u32.hi >> 4) & 0x00070000) |
+ ((tv->u32.hi >> 16) & 0x0000000f);
+ return;
+ }
+ }
+ i = i32ptr(tv);
+ emit_vlso(as, ARMI_VLDR_D, r,
+ ra_allock(as, (i & ~1020), RSET_GPR), (i & 1020));
+}
+#endif
+
+/* Get/set global_State fields. */
+#define emit_getgl(as, r, field) \
+ emit_lsptr(as, ARMI_LDR, (r), (void *)&J2G(as->J)->field)
+#define emit_setgl(as, r, field) \
+ emit_lsptr(as, ARMI_STR, (r), (void *)&J2G(as->J)->field)
+
+/* Trace number is determined from pc of exit instruction. */
+#define emit_setvmstate(as, i) UNUSED(i)
+
+/* -- Emit control-flow instructions -------------------------------------- */
+
+/* Label for internal jumps. */
+typedef MCode *MCLabel;
+
+/* Return label pointing to current PC. */
+#define emit_label(as) ((as)->mcp)
+
+static void emit_branch(ASMState *as, ARMIns ai, MCode *target)
+{
+ MCode *p = as->mcp;
+ ptrdiff_t delta = (target - p) - 1;
+ lua_assert(((delta + 0x00800000) >> 24) == 0);
+ *--p = ai | ((uint32_t)delta & 0x00ffffffu);
+ as->mcp = p;
+}
+
+#define emit_jmp(as, target) emit_branch(as, ARMI_B, (target))
+
+static void emit_call(ASMState *as, void *target)
+{
+ MCode *p = --as->mcp;
+ ptrdiff_t delta = ((char *)target - (char *)p) - 8;
+ if ((((delta>>2) + 0x00800000) >> 24) == 0) {
+ if ((delta & 1))
+ *p = ARMI_BLX | ((uint32_t)(delta>>2) & 0x00ffffffu) | ((delta&2) << 27);
+ else
+ *p = ARMI_BL | ((uint32_t)(delta>>2) & 0x00ffffffu);
+ } else { /* Target out of range: need indirect call. But don't use R0-R3. */
+ Reg r = ra_allock(as, i32ptr(target), RSET_RANGE(RID_R4, RID_R12+1));
+ *p = ARMI_BLXr | ARMF_M(r);
+ }
+}
+
+/* -- Emit generic operations --------------------------------------------- */
+
+/* Generic move between two regs. */
+static void emit_movrr(ASMState *as, IRIns *ir, Reg dst, Reg src)
+{
+#if LJ_SOFTFP
+ lua_assert(!irt_isnum(ir->t)); UNUSED(ir);
+#else
+ if (dst >= RID_MAX_GPR) {
+ emit_dm(as, irt_isnum(ir->t) ? ARMI_VMOV_D : ARMI_VMOV_S,
+ (dst & 15), (src & 15));
+ return;
+ }
+#endif
+ if (as->mcp != as->mcloop) { /* Swap early registers for loads/stores. */
+ MCode ins = *as->mcp, swp = (src^dst);
+ if ((ins & 0x0c000000) == 0x04000000 && (ins & 0x02000010) != 0x02000010) {
+ if (!((ins ^ (dst << 16)) & 0x000f0000))
+ *as->mcp = ins ^ (swp << 16); /* Swap N in load/store. */
+ if (!(ins & 0x00100000) && !((ins ^ (dst << 12)) & 0x0000f000))
+ *as->mcp = ins ^ (swp << 12); /* Swap D in store. */
+ }
+ }
+ emit_dm(as, ARMI_MOV, dst, src);
+}
+
+/* Generic load of register from stack slot. */
+static void emit_spload(ASMState *as, IRIns *ir, Reg r, int32_t ofs)
+{
+#if LJ_SOFTFP
+ lua_assert(!irt_isnum(ir->t)); UNUSED(ir);
+#else
+ if (r >= RID_MAX_GPR)
+ emit_vlso(as, irt_isnum(ir->t) ? ARMI_VLDR_D : ARMI_VLDR_S, r, RID_SP, ofs);
+ else
+#endif
+ emit_lso(as, ARMI_LDR, r, RID_SP, ofs);
+}
+
+/* Generic store of register to stack slot. */
+static void emit_spstore(ASMState *as, IRIns *ir, Reg r, int32_t ofs)
+{
+#if LJ_SOFTFP
+ lua_assert(!irt_isnum(ir->t)); UNUSED(ir);
+#else
+ if (r >= RID_MAX_GPR)
+ emit_vlso(as, irt_isnum(ir->t) ? ARMI_VSTR_D : ARMI_VSTR_S, r, RID_SP, ofs);
+ else
+#endif
+ emit_lso(as, ARMI_STR, r, RID_SP, ofs);
+}
+
+/* Emit an arithmetic/logic operation with a constant operand. */
+static void emit_opk(ASMState *as, ARMIns ai, Reg dest, Reg src,
+ int32_t i, RegSet allow)
+{
+ uint32_t k = emit_isk12(ai, i);
+ if (k)
+ emit_dn(as, ai^k, dest, src);
+ else
+ emit_dnm(as, ai, dest, src, ra_allock(as, i, allow));
+}
+
+/* Add offset to pointer. */
+static void emit_addptr(ASMState *as, Reg r, int32_t ofs)
+{
+ if (ofs)
+ emit_opk(as, ARMI_ADD, r, r, ofs, rset_exclude(RSET_GPR, r));
+}
+
+#define emit_spsub(as, ofs) emit_addptr(as, RID_SP, -(ofs))
+
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/1f27b840/lib/luajit/src/lj_emit_mips.h
----------------------------------------------------------------------
diff --git a/lib/luajit/src/lj_emit_mips.h b/lib/luajit/src/lj_emit_mips.h
new file mode 100644
index 0000000..0fc07d9
--- /dev/null
+++ b/lib/luajit/src/lj_emit_mips.h
@@ -0,0 +1,211 @@
+/*
+** MIPS instruction emitter.
+** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
+*/
+
+/* -- Emit basic instructions --------------------------------------------- */
+
+static void emit_dst(ASMState *as, MIPSIns mi, Reg rd, Reg rs, Reg rt)
+{
+ *--as->mcp = mi | MIPSF_D(rd) | MIPSF_S(rs) | MIPSF_T(rt);
+}
+
+static void emit_dta(ASMState *as, MIPSIns mi, Reg rd, Reg rt, uint32_t a)
+{
+ *--as->mcp = mi | MIPSF_D(rd) | MIPSF_T(rt) | MIPSF_A(a);
+}
+
+#define emit_ds(as, mi, rd, rs) emit_dst(as, (mi), (rd), (rs), 0)
+#define emit_tg(as, mi, rt, rg) emit_dst(as, (mi), (rg)&31, 0, (rt))
+
+static void emit_tsi(ASMState *as, MIPSIns mi, Reg rt, Reg rs, int32_t i)
+{
+ *--as->mcp = mi | MIPSF_T(rt) | MIPSF_S(rs) | (i & 0xffff);
+}
+
+#define emit_ti(as, mi, rt, i) emit_tsi(as, (mi), (rt), 0, (i))
+#define emit_hsi(as, mi, rh, rs, i) emit_tsi(as, (mi), (rh) & 31, (rs), (i))
+
+static void emit_fgh(ASMState *as, MIPSIns mi, Reg rf, Reg rg, Reg rh)
+{
+ *--as->mcp = mi | MIPSF_F(rf&31) | MIPSF_G(rg&31) | MIPSF_H(rh&31);
+}
+
+#define emit_fg(as, mi, rf, rg) emit_fgh(as, (mi), (rf), (rg), 0)
+
+static void emit_rotr(ASMState *as, Reg dest, Reg src, Reg tmp, uint32_t shift)
+{
+ if ((as->flags & JIT_F_MIPS32R2)) {
+ emit_dta(as, MIPSI_ROTR, dest, src, shift);
+ } else {
+ emit_dst(as, MIPSI_OR, dest, dest, tmp);
+ emit_dta(as, MIPSI_SLL, dest, src, (-shift)&31);
+ emit_dta(as, MIPSI_SRL, tmp, src, shift);
+ }
+}
+
+/* -- Emit loads/stores --------------------------------------------------- */
+
+/* Prefer rematerialization of BASE/L from global_State over spills. */
+#define emit_canremat(ref) ((ref) <= REF_BASE)
+
+/* Try to find a one step delta relative to another constant. */
+static int emit_kdelta1(ASMState *as, Reg t, int32_t i)
+{
+ RegSet work = ~as->freeset & RSET_GPR;
+ while (work) {
+ Reg r = rset_picktop(work);
+ IRRef ref = regcost_ref(as->cost[r]);
+ lua_assert(r != t);
+ if (ref < ASMREF_L) {
+ int32_t delta = i - (ra_iskref(ref) ? ra_krefk(as, ref) : IR(ref)->i);
+ if (checki16(delta)) {
+ emit_tsi(as, MIPSI_ADDIU, t, r, delta);
+ return 1;
+ }
+ }
+ rset_clear(work, r);
+ }
+ return 0; /* Failed. */
+}
+
+/* Load a 32 bit constant into a GPR. */
+static void emit_loadi(ASMState *as, Reg r, int32_t i)
+{
+ if (checki16(i)) {
+ emit_ti(as, MIPSI_LI, r, i);
+ } else {
+ if ((i & 0xffff)) {
+ int32_t jgl = i32ptr(J2G(as->J));
+ if ((uint32_t)(i-jgl) < 65536) {
+ emit_tsi(as, MIPSI_ADDIU, r, RID_JGL, i-jgl-32768);
+ return;
+ } else if (emit_kdelta1(as, r, i)) {
+ return;
+ } else if ((i >> 16) == 0) {
+ emit_tsi(as, MIPSI_ORI, r, RID_ZERO, i);
+ return;
+ }
+ emit_tsi(as, MIPSI_ORI, r, r, i);
+ }
+ emit_ti(as, MIPSI_LUI, r, (i >> 16));
+ }
+}
+
+#define emit_loada(as, r, addr) emit_loadi(as, (r), i32ptr((addr)))
+
+static Reg ra_allock(ASMState *as, int32_t k, RegSet allow);
+static void ra_allockreg(ASMState *as, int32_t k, Reg r);
+
+/* Get/set from constant pointer. */
+static void emit_lsptr(ASMState *as, MIPSIns mi, Reg r, void *p, RegSet allow)
+{
+ int32_t jgl = i32ptr(J2G(as->J));
+ int32_t i = i32ptr(p);
+ Reg base;
+ if ((uint32_t)(i-jgl) < 65536) {
+ i = i-jgl-32768;
+ base = RID_JGL;
+ } else {
+ base = ra_allock(as, i-(int16_t)i, allow);
+ }
+ emit_tsi(as, mi, r, base, i);
+}
+
+#define emit_loadn(as, r, tv) \
+ emit_lsptr(as, MIPSI_LDC1, ((r) & 31), (void *)(tv), RSET_GPR)
+
+/* Get/set global_State fields. */
+static void emit_lsglptr(ASMState *as, MIPSIns mi, Reg r, int32_t ofs)
+{
+ emit_tsi(as, mi, r, RID_JGL, ofs-32768);
+}
+
+#define emit_getgl(as, r, field) \
+ emit_lsglptr(as, MIPSI_LW, (r), (int32_t)offsetof(global_State, field))
+#define emit_setgl(as, r, field) \
+ emit_lsglptr(as, MIPSI_SW, (r), (int32_t)offsetof(global_State, field))
+
+/* Trace number is determined from per-trace exit stubs. */
+#define emit_setvmstate(as, i) UNUSED(i)
+
+/* -- Emit control-flow instructions -------------------------------------- */
+
+/* Label for internal jumps. */
+typedef MCode *MCLabel;
+
+/* Return label pointing to current PC. */
+#define emit_label(as) ((as)->mcp)
+
+static void emit_branch(ASMState *as, MIPSIns mi, Reg rs, Reg rt, MCode *target)
+{
+ MCode *p = as->mcp;
+ ptrdiff_t delta = target - p;
+ lua_assert(((delta + 0x8000) >> 16) == 0);
+ *--p = mi | MIPSF_S(rs) | MIPSF_T(rt) | ((uint32_t)delta & 0xffffu);
+ as->mcp = p;
+}
+
+static void emit_jmp(ASMState *as, MCode *target)
+{
+ *--as->mcp = MIPSI_NOP;
+ emit_branch(as, MIPSI_B, RID_ZERO, RID_ZERO, (target));
+}
+
+static void emit_call(ASMState *as, void *target)
+{
+ MCode *p = as->mcp;
+ *--p = MIPSI_NOP;
+ if ((((uintptr_t)target ^ (uintptr_t)p) >> 28) == 0)
+ *--p = MIPSI_JAL | (((uintptr_t)target >>2) & 0x03ffffffu);
+ else /* Target out of range: need indirect call. */
+ *--p = MIPSI_JALR | MIPSF_S(RID_CFUNCADDR);
+ as->mcp = p;
+ ra_allockreg(as, i32ptr(target), RID_CFUNCADDR);
+}
+
+/* -- Emit generic operations --------------------------------------------- */
+
+#define emit_move(as, dst, src) \
+ emit_ds(as, MIPSI_MOVE, (dst), (src))
+
+/* Generic move between two regs. */
+static void emit_movrr(ASMState *as, IRIns *ir, Reg dst, Reg src)
+{
+ if (dst < RID_MAX_GPR)
+ emit_move(as, dst, src);
+ else
+ emit_fg(as, irt_isnum(ir->t) ? MIPSI_MOV_D : MIPSI_MOV_S, dst, src);
+}
+
+/* Generic load of register from stack slot. */
+static void emit_spload(ASMState *as, IRIns *ir, Reg r, int32_t ofs)
+{
+ if (r < RID_MAX_GPR)
+ emit_tsi(as, MIPSI_LW, r, RID_SP, ofs);
+ else
+ emit_tsi(as, irt_isnum(ir->t) ? MIPSI_LDC1 : MIPSI_LWC1,
+ (r & 31), RID_SP, ofs);
+}
+
+/* Generic store of register to stack slot. */
+static void emit_spstore(ASMState *as, IRIns *ir, Reg r, int32_t ofs)
+{
+ if (r < RID_MAX_GPR)
+ emit_tsi(as, MIPSI_SW, r, RID_SP, ofs);
+ else
+ emit_tsi(as, irt_isnum(ir->t) ? MIPSI_SDC1 : MIPSI_SWC1,
+ (r&31), RID_SP, ofs);
+}
+
+/* Add offset to pointer. */
+static void emit_addptr(ASMState *as, Reg r, int32_t ofs)
+{
+ if (ofs) {
+ lua_assert(checki16(ofs));
+ emit_tsi(as, MIPSI_ADDIU, r, r, ofs);
+ }
+}
+
+#define emit_spsub(as, ofs) emit_addptr(as, RID_SP, -(ofs))
+