Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Tagged value 的 struct 定義
- typedef LJ_ALIGN(8) union TValue {
- uint64_t u64; /* 64 bit pattern overlaps number. */
- lua_Number n; /* Number object overlaps split tag/value object. */
- struct {
- LJ_ENDIAN_LOHI(
- union {
- GCRef gcr; /* GCobj reference (if any). */
- int32_t i; /* Integer value. */
- };
- , uint32_t it; /* Internal object tag. Must overlap MSW of number. */
- )
- };
- struct {
- LJ_ENDIAN_LOHI(
- GCRef func; /* Function for next frame (or dummy L). */
- , FrameLink tp; /* Link to previous frame. */
- )
- } fr;
- struct {
- LJ_ENDIAN_LOHI(
- uint32_t lo; /* Lower 32 bits of number. */
- , uint32_t hi; /* Upper 32 bits of number. */
- )
- } u32;
- } TValue;
- // Tag 的型別規格
- /* Internal object tags.
- **
- ** Internal tags overlap the MSW of a number object (must be a double).
- ** Interpreted as a double these are special NaNs. The FPU only generates
- ** one type of NaN (0xfff8_0000_0000_0000). So MSWs > 0xfff80000 are available
- ** for use as internal tags. Small negative numbers are used to shorten the
- ** encoding of type comparisons (reg/mem against sign-ext. 8 bit immediate).
- **
- ** ---MSW---.---LSW---
- ** primitive types | itype | |
- ** lightuserdata | itype | void * | (32 bit platforms)
- ** lightuserdata |ffff| void * | (64 bit platforms, 47 bit pointers)
- ** GC objects | itype | GCRef |
- ** int (LJ_DUALNUM)| itype | int |
- ** number -------double------
- **
- ** ORDER LJ_T
- ** Primitive types nil/false/true must be first, lightuserdata next.
- ** GC objects are at the end, table/userdata must be lowest.
- ** Also check lj_ir.h for similar ordering constraints.
- */
- #define LJ_TNIL (~0u)
- #define LJ_TFALSE (~1u)
- #define LJ_TTRUE (~2u)
- #define LJ_TLIGHTUD (~3u)
- #define LJ_TSTR (~4u)
- #define LJ_TUPVAL (~5u)
- #define LJ_TTHREAD (~6u)
- #define LJ_TPROTO (~7u)
- #define LJ_TFUNC (~8u)
- #define LJ_TTRACE (~9u)
- #define LJ_TCDATA (~10u)
- #define LJ_TTAB (~11u)
- #define LJ_TUDATA (~12u)
- /* This is just the canonical number type used in some places. */
- #define LJ_TNUMX (~13u)
- // 判斷型別的方式
- /* Macros to test types. */
- #define itype(o) ((o)->it)
- #define tvisnil(o) (itype(o) == LJ_TNIL)
- #define tvisfalse(o) (itype(o) == LJ_TFALSE)
- #define tvistrue(o) (itype(o) == LJ_TTRUE)
- #define tvisbool(o) (tvisfalse(o) || tvistrue(o))
- #if LJ_64
- #define tvislightud(o) (((int32_t)itype(o) >> 15) == -2)
- #else
- #define tvislightud(o) (itype(o) == LJ_TLIGHTUD)
- #endif
- #define tvisstr(o) (itype(o) == LJ_TSTR)
- #define tvisfunc(o) (itype(o) == LJ_TFUNC)
- #define tvisthread(o) (itype(o) == LJ_TTHREAD)
- #define tvisproto(o) (itype(o) == LJ_TPROTO)
- #define tviscdata(o) (itype(o) == LJ_TCDATA)
- #define tvistab(o) (itype(o) == LJ_TTAB)
- #define tvisudata(o) (itype(o) == LJ_TUDATA)
- #define tvisnumber(o) (itype(o) <= LJ_TISNUM)
- #define tvisint(o) (LJ_DUALNUM && itype(o) == LJ_TISNUM)
- #define tvisnum(o) (itype(o) < LJ_TISNUM)
- #define tvistruecond(o) (itype(o) < LJ_TISTRUECOND)
- #define tvispri(o) (itype(o) >= LJ_TISPRI)
- #define tvistabud(o) (itype(o) <= LJ_TISTABUD) /* && !tvisnum() */
- #define tvisgcv(o) ((itype(o) - LJ_TISGCV) > (LJ_TNUMX - LJ_TISGCV))
- /* Special macros to test numbers for NaN, +0, -0, +1 and raw equality. */
- #define tvisnan(o) ((o)->n != (o)->n)
- #if LJ_64
- #define tviszero(o) (((o)->u64 << 1) == 0)
- #else
- #define tviszero(o) (((o)->u32.lo | ((o)->u32.hi << 1)) == 0)
- #endif
- #define tvispzero(o) ((o)->u64 == 0)
- #define tvismzero(o) ((o)->u64 == U64x(80000000,00000000))
- #define tvispone(o) ((o)->u64 == U64x(3ff00000,00000000))
- #define rawnumequal(o1, o2) ((o1)->u64 == (o2)->u64)
Add Comment
Please, Sign In to add comment