@ -1,5 +1,5 @@
/*
* * $ Id : lobject . h $
* * $ Id : lobject . h , v 2.117 .1 .1 2017 / 04 / 19 17 : 39 : 34 roberto Exp $
* * Type definitions for Lua objects
* * See Copyright Notice in lua . h
*/
@ -27,8 +27,57 @@
*/
# define LUA_TOTALTAGS (LUA_TPROTO + 2)
/*
* * tags for Tagged Values have the following use of bits :
* * bits 0 - 3 : actual tag ( a LUA_T * value )
* * bits 4 - 5 : variant bits
* * bit 6 : whether value is collectable
*/
/*
* * LUA_TFUNCTION variants :
* * 0 - Lua function
* * 1 - light C function
* * 2 - regular C function ( closure )
* * 4 - fast light C dunction ( Ravi extension )
*/
/* Variant tags for functions */
# define LUA_TLCL (LUA_TFUNCTION | (0 << 4)) /* Lua closure */
# define LUA_TLCF (LUA_TFUNCTION | (1 << 4)) /* light C function */
# define LUA_TCCL (LUA_TFUNCTION | (2 << 4)) /* C closure */
# define RAVI_TFCF (LUA_TFUNCTION | (4 << 4)) /* fast light C function */
/* Variant tags for strings */
# define LUA_TSHRSTR (LUA_TSTRING | (0 << 4)) /* short strings */
# define LUA_TLNGSTR (LUA_TSTRING | (1 << 4)) /* long strings */
/* Variant tags for numbers */
# define LUA_TNUMFLT (LUA_TNUMBER | (0 << 4)) /* float numbers */
# define LUA_TNUMINT (LUA_TNUMBER | (1 << 4)) /* integer numbers */
/** RAVI table subtypes **/
# define RAVI_TIARRAY (LUA_TTABLE | (1 << 4)) /* Ravi int array */
# define RAVI_TFARRAY (LUA_TTABLE | (2 << 4)) /* Ravi float array */
/* Bit mark for collectable types */
# define BIT_ISCOLLECTABLE (1 << 15)
/* mark a tag as collectable */
# define ctb(t) ((t) | BIT_ISCOLLECTABLE)
/*
* * Common type for all collectable objects
*/
typedef struct GCObject GCObject ;
/*
* * In Ravi , value type is extended to 16 - bits so that we can hold more info .
* * Value type extended to 16 - bits so that we can hold more info .
* * The actual type code is still 1 byte ( least significant byte )
* * and in particular all GC - able type codes must fit into 1 byte because
* * the GC CommonHeader only allows 1 byte for the type code .
@ -38,83 +87,23 @@
typedef uint16_t LuaType ;
/*
* * tags for Tagged Values have the following use of bits :
* * bits 0 - 3 : actual tag ( a LUA_T * value )
* * bits 4 - 5 : variant bit s
* * bit 15 : whether value is collectabl e
* * Common Header for all collectable objects ( in macro form , to be
* * included in other objects )
* * Note that tt field is a byte - this means that a GC object ' s
* * type must have all information in the first byt e
*/
# define CommonHeader GCObject *next; lu_byte tt; lu_byte marked
/* add variant bits to a type */
# define makevariant(t,v) ((t) | ((v) << 4))
/*
* * Common type has only the common header
*/
struct GCObject {
CommonHeader ;
} ;
/* RAVI: Following are the types we will use
* * use in parsing . The rationale for types is
* * performance - as of now these are the only types that
* * we care about from a performance point of view - if any
* * other types appear then they are all treated as ANY
* */
typedef enum {
RAVI_TI_NIL ,
RAVI_TI_FALSE ,
RAVI_TI_TRUE ,
RAVI_TI_INTEGER ,
RAVI_TI_FLOAT ,
RAVI_TI_INTEGER_ARRAY ,
RAVI_TI_FLOAT_ARRAY ,
RAVI_TI_TABLE ,
RAVI_TI_STRING ,
RAVI_TI_FUNCTION ,
RAVI_TI_USERDATA ,
RAVI_TI_OTHER
} ravi_type_index ;
typedef uint32_t ravi_type_map ;
# define RAVI_TM_NIL (((ravi_type_map)1)<<RAVI_TI_NIL)
# define RAVI_TM_FALSE (((ravi_type_map)1)<<RAVI_TI_FALSE)
# define RAVI_TM_TRUE (((ravi_type_map)1)<<RAVI_TI_TRUE)
# define RAVI_TM_INTEGER (((ravi_type_map)1)<<RAVI_TI_INTEGER)
# define RAVI_TM_FLOAT (((ravi_type_map)1)<<RAVI_TI_FLOAT)
# define RAVI_TM_INTEGER_ARRAY (((ravi_type_map)1)<<RAVI_TI_INTEGER_ARRAY)
# define RAVI_TM_FLOAT_ARRAY (((ravi_type_map)1)<<RAVI_TI_FLOAT_ARRAY)
# define RAVI_TM_TABLE (((ravi_type_map)1)<<RAVI_TI_TABLE)
# define RAVI_TM_STRING (((ravi_type_map)1)<<RAVI_TI_STRING)
# define RAVI_TM_FUNCTION (((ravi_type_map)1)<<RAVI_TI_FUNCTION)
# define RAVI_TM_USERDATA (((ravi_type_map)1)<<RAVI_TI_USERDATA)
# define RAVI_TM_OTHER (((ravi_type_map)1)<<RAVI_TI_OTHER)
# define RAVI_TM_FALSISH (RAVI_TM_NIL | RAVI_TM_FALSE)
# define RAVI_TM_TRUISH (~RAVI_TM_FALSISH)
# define RAVI_TM_BOOLEAN (RAVI_TM_FALSE | RAVI_TM_TRUE)
# define RAVI_TM_NUMBER (RAVI_TM_INTEGER | RAVI_TM_FLOAT)
# define RAVI_TM_STRING_OR_NIL (RAVI_TM_STRING | RAVI_TM_NIL)
# define RAVI_TM_FUNCTION_OR_NIL (RAVI_TM_FUNCTION | RAVI_TM_NIL)
# define RAVI_TM_BOOLEAN_OR_NIL (RAVI_TM_BOOLEAN | RAVI_TM_NIL)
# define RAVI_TM_USERDATA_OR_NIL (RAVI_TM_USERDATA | RAVI_TM_NIL)
# define RAVI_TM_INTEGER_OR_NIL (RAVI_TM_INTEGER | RAVI_TM_NIL)
# define RAVI_TM_FLOAT_OR_NIL (RAVI_TM_FLOAT | RAVI_TM_NIL)
# define RAVI_TM_TABLE_OR_NIL (RAVI_TM_TABLE | RAVI_TM_NIL)
# define RAVI_TM_INDEXABLE (RAVI_TM_INTEGER_ARRAY | RAVI_TM_FLOAT_ARRAY | RAVI_TM_TABLE)
# define RAVI_TM_ANY (~0)
typedef enum {
RAVI_TNIL = RAVI_TM_NIL , /* NIL */
RAVI_TNUMINT = RAVI_TM_INTEGER , /* integer number */
RAVI_TNUMFLT = RAVI_TM_FLOAT , /* floating point number */
RAVI_TNUMBER = RAVI_TM_NUMBER ,
RAVI_TARRAYINT = RAVI_TM_INTEGER_ARRAY , /* array of ints */
RAVI_TARRAYFLT = RAVI_TM_FLOAT_ARRAY , /* array of doubles */
RAVI_TTABLE = RAVI_TM_TABLE , /* Lua table */
RAVI_TSTRING = RAVI_TM_STRING , /* string */
RAVI_TFUNCTION = RAVI_TM_FUNCTION , /* Lua or C Function */
RAVI_TBOOLEAN = RAVI_TM_BOOLEAN , /* boolean */
RAVI_TTRUE = RAVI_TM_TRUE ,
RAVI_TFALSE = RAVI_TM_FALSE ,
RAVI_TUSERDATA = RAVI_TM_USERDATA , /* userdata or lightuserdata */
RAVI_TANY = RAVI_TM_ANY , /* Lua dynamic type */
} ravitype_t ;
/*
* * Tagged Values . This is the basic representation of values in Lua ,
@ -125,7 +114,7 @@ typedef enum {
* * Union of all Lua values
*/
typedef union Value {
struct GCObject * gc ; /* collectable objects */
GCObject * gc ; /* collectable objects */
void * p ; /* light userdata */
int b ; /* booleans */
lua_CFunction f ; /* light C functions */
@ -134,19 +123,22 @@ typedef union Value {
} Value ;
/*
* * Tagged Values . This is the basic representation of values in Lua :
* * an actual value plus a tag with its type .
*/
# define TValuefields Value value_; LuaType tt_
typedef struct lua_TValue {
TValuefields ;
} TValue ;
/* macro defining a nil value */
# define NILCONSTANT {NULL}, LUA_TNIL
# define val_(o) ((o)->value_)
/* raw type tag of a TValue */
# define rttype(o) ((o)->tt_)
@ -164,196 +156,198 @@ typedef struct lua_TValue {
/* Macros to test type */
# define checktag(o,t) (rttype(o) == (t))
# define checktype(o,t) (ttnov(o) == (t))
# define ttisnumber(o) checktype((o), LUA_TNUMBER)
# define ttisfloat(o) checktag((o), LUA_TNUMFLT)
# define ttisinteger(o) checktag((o), LUA_TNUMINT)
# define ttisnil(o) checktag((o), LUA_TNIL)
# define ttisboolean(o) checktag((o), LUA_TBOOLEAN)
# define ttislightuserdata(o) checktag((o), LUA_TLIGHTUSERDATA)
# define ttisstring(o) checktype((o), LUA_TSTRING)
# define ttisshrstring(o) checktag((o), ctb(LUA_TSHRSTR))
# define ttislngstring(o) checktag((o), ctb(LUA_TLNGSTR))
/* RAVI change: we support two sub types of table type
and hence need to distinguish between the types .
ttistable ( ) returns true for all table types
ttisLtable ( ) only returns true if the value is a Lua table
ttisiarray ( ) only returns true if the value is a Ravi subtype integer [ ]
ttisfarray ( ) only returns true if the value is a Ravi subtype number [ ]
*/
# define ttistable(o) checktype((o), LUA_TTABLE)
# define ttisiarray(o) checktag((o), ctb(RAVI_TIARRAY))
# define ttisfarray(o) checktag((o), ctb(RAVI_TFARRAY))
# define ttisLtable(o) checktag((o), ctb(LUA_TTABLE))
# define ttisfunction(o) checktype(o, LUA_TFUNCTION)
# define ttisclosure(o) ((rttype(o) & 0x1F) == LUA_TFUNCTION)
# define ttisCclosure(o) checktag((o), ctb(LUA_TCCL))
# define ttisLclosure(o) checktag((o), ctb(LUA_TLCL))
# define ttislcf(o) checktag((o), LUA_TLCF)
# define ttisfcf(o) (ttype(o) == RAVI_TFCF)
# define ttisfulluserdata(o) checktag((o), ctb(LUA_TUSERDATA))
# define ttisthread(o) checktag((o), ctb(LUA_TTHREAD))
# define ttisdeadkey(o) checktag((o), LUA_TDEADKEY)
/* Macros for internal tests */
/* Macros to access values */
# define ivalue(o) check_exp(ttisinteger(o), val_(o).i)
# define fltvalue(o) check_exp(ttisfloat(o), val_(o).n)
# define nvalue(o) check_exp(ttisnumber(o), \
( ttisinteger ( o ) ? cast_num ( ivalue ( o ) ) : fltvalue ( o ) ) )
# define gcvalue(o) check_exp(iscollectable(o), val_(o).gc)
# define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p)
# define tsvalue(o) check_exp(ttisstring(o), gco2ts(val_(o).gc))
# define uvalue(o) check_exp(ttisfulluserdata(o), gco2u(val_(o).gc))
# define clvalue(o) check_exp(ttisclosure(o), gco2cl(val_(o).gc))
# define clLvalue(o) check_exp(ttisLclosure(o), gco2lcl(val_(o).gc))
# define clCvalue(o) check_exp(ttisCclosure(o), gco2ccl(val_(o).gc))
# define fvalue(o) check_exp(ttislcf(o), val_(o).f)
# define fcfvalue(o) check_exp(ttisfcf(o), val_(o).p)
# define hvalue(o) check_exp(ttistable(o), gco2t(val_(o).gc))
# define bvalue(o) check_exp(ttisboolean(o), val_(o).b)
# define thvalue(o) check_exp(ttisthread(o), gco2th(val_(o).gc))
/* a dead value may get the 'gc' field, but cannot access its contents */
# define deadvalue(o) check_exp(ttisdeadkey(o), cast(void *, val_(o).gc))
# define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0))
/* collectable object has the same tag as the original value */
# define iscollectable(o) (rttype(o) & BIT_ISCOLLECTABLE)
/* Macros for internal tests */
# define righttt(obj) (ttype(obj) == gcvalue(obj)->tt)
/*
* * Any value being manipulated by the program either is non
* * collectable , or the collectable object has the right tag
* * and it is not dead .
*/
# define checkliveness(L,obj) \
lua_longassert ( ! iscollectable ( obj ) | | \
( righttt ( obj ) & & ( L = = NULL | | ! isdead ( G ( L ) , gcvalue ( obj ) ) ) ) )
/* Macros to set values */
/* set a value's tag */
# define settt_(o,t) ((o)->tt_=(t))
# define setfltvalue(obj,x) \
{ TValue * io = ( obj ) ; val_ ( io ) . n = ( x ) ; settt_ ( io , LUA_TNUMFLT ) ; }
/* main macro to copy values (from 'obj1' to 'obj2') */
# define setobj(L,obj1,obj2) \
{ TValue * io1 = ( obj1 ) ; const TValue * io2 = ( obj2 ) ; \
io1 - > value_ = io2 - > value_ ; settt_ ( io1 , io2 - > tt_ ) ; \
( void ) L ; checkliveness ( L , io1 ) ; }
/*
* * different types of assignments , according to destination
*/
/* from stack to (same) stack */
# define setobjs2s setobj
/* to stack (not from same stack) */
# define setobj2s setobj
/* from table to same table */
# define setobjt2t setobj
/* to new object */
# define setobj2n setobj
/* to table */
# define setobj2t setobj
# define chgfltvalue(obj,x) \
{ TValue * io = ( obj ) ; lua_assert ( ttisfloat ( io ) ) ; val_ ( io ) . n = ( x ) ; }
typedef TValue * StkId ; /* index to stack elements */
/*
* * { = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
* * Nil
* * = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
# define setivalue(obj,x) \
{ TValue * io = ( obj ) ; val_ ( io ) . i = ( x ) ; settt_ ( io , LUA_TNUMINT ) ; }
/* macro defining a nil value */
# define NILCONSTANT {NULL}, LUA_TNIL
/* macro to test for (any kind of) nil */
# define ttisnil(o) checktag((o), LUA_TNIL)
# define chgivalue(obj,x) \
{ TValue * io = ( obj ) ; lua_assert ( ttisinteger ( io ) ) ; val_ ( io ) . i = ( x ) ; }
# define setnilvalue(obj) settt_(obj, LUA_TNIL)
/* }================================================================== */
/*
* * { = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
* * Booleans
* * = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
# define setfvalue(obj,x) \
{ TValue * io = ( obj ) ; val_ ( io ) . f = ( x ) ; settt_ ( io , LUA_TLCF ) ; }
/* The Fast C function call type is encoded as two
bytes . The Hi Byte holds a function tag . The Lo Byte
holds the Lua typecode */
# define setfvalue_fastcall(obj, x, tag) \
{ \
TValue * io = ( obj ) ; \
lua_assert ( tag > = 1 & & tag < 0x80 ) ; \
val_ ( io ) . p = ( x ) ; \
settt_ ( io , ( ( tag < < 8 ) | RAVI_TFCF ) ) ; \
}
# define getfcf_tag(typecode) (typecode >> 8)
# define ttisboolean(o) checktag((o), LUA_TBOOLEAN)
# define bvalue(o) check_exp(ttisboolean(o), val_(o).b)
# define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0))
# define setpvalue(obj,x) \
{ TValue * io = ( obj ) ; val_ ( io ) . p = ( x ) ; settt_ ( io , LUA_TLIGHTUSERDATA ) ; }
# define setbvalue(obj,x) \
{ TValue * io = ( obj ) ; val_ ( io ) . b = ( x ) ; settt_ ( io , LUA_TBOOLEAN ) ; }
/* }================================================================== */
# define setgcovalue(L,obj,x) \
{ TValue * io = ( obj ) ; GCObject * i_g = ( x ) ; \
val_ ( io ) . gc = i_g ; settt_ ( io , ctb ( i_g - > tt ) ) ; }
/*
* * { = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
* * Threads
* * = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
# define setsvalue(L,obj,x) \
{ TValue * io = ( obj ) ; TString * x_ = ( x ) ; \
val_ ( io ) . gc = obj2gco ( x_ ) ; settt_ ( io , ctb ( x_ - > tt ) ) ; \
checkliveness ( L , io ) ; }
# define ttisthread(o) checktag((o), ctb(LUA_TTHREAD))
# define thvalue(o) check_exp(ttisthread(o), gco2th(val_(o).gc))
# define setuvalue(L,obj,x) \
{ TValue * io = ( obj ) ; Udata * x_ = ( x ) ; \
val_ ( io ) . gc = obj2gco ( x_ ) ; settt_ ( io , ctb ( LUA_TUSERDATA ) ) ; \
checkliveness ( L , io ) ; }
# define setthvalue(L,obj,x) \
{ TValue * io = ( obj ) ; lua_State * x_ = ( x ) ; \
val_ ( io ) . gc = obj2gco ( x_ ) ; settt_ ( io , ctb ( LUA_TTHREAD ) ) ; \
checkliveness ( L , io ) ; }
# define setclLvalue(L,obj,x) \
{ TValue * io = ( obj ) ; LClosure * x_ = ( x ) ; \
val_ ( io ) . gc = obj2gco ( x_ ) ; settt_ ( io , ctb ( LUA_TLCL ) ) ; \
checkliveness ( L , io ) ; }
/* }================================================================== */
/*
* * { = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
* * Collectable Objects
* * = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
/*
* * Common Header for all collectable objects ( in macro form , to be
* * included in other objects )
* * Note that tt field is a byte .
*/
# define CommonHeader struct GCObject *next; lu_byte tt; lu_byte marked
/* Common type for all collectable objects */
typedef struct GCObject {
CommonHeader ;
} GCObject ;
# define setclCvalue(L,obj,x) \
{ TValue * io = ( obj ) ; CClosure * x_ = ( x ) ; \
val_ ( io ) . gc = obj2gco ( x_ ) ; settt_ ( io , ctb ( LUA_TCCL ) ) ; \
checkliveness ( L , io ) ; }
# define sethvalue(L,obj,x) \
{ TValue * io = ( obj ) ; Table * x_ = ( x ) ; \
val_ ( io ) . gc = obj2gco ( x_ ) ; settt_ ( io , ctb ( LUA_TTABLE ) ) ; \
checkliveness ( L , io ) ; }
/* Bit mark for collectable types */
# define BIT_ISCOLLECTABLE (1 << 15)
/** RAVI extension **/
# define setiarrayvalue(L,obj,x) \
{ TValue * io = ( obj ) ; Table * x_ = ( x ) ; \
val_ ( io ) . gc = obj2gco ( x_ ) ; settt_ ( io , ctb ( RAVI_TIARRAY ) ) ; \
checkliveness ( L , io ) ; }
# define iscollectable(o) (rttype(o) & BIT_ISCOLLECTABLE)
/** RAVI extension **/
# define setfarrayvalue(L,obj,x) \
{ TValue * io = ( obj ) ; Table * x_ = ( x ) ; \
val_ ( io ) . gc = obj2gco ( x_ ) ; settt_ ( io , ctb ( RAVI_TFARRAY ) ) ; \
checkliveness ( L , io ) ; }
/* mark a tag as collectable */
# define ctb(t) ((t) | BIT_ISCOLLECTABLE)
# define setdeadvalue(obj) settt_(obj, LUA_TDEADKEY)
# define gcvalue(o) check_exp(iscollectable(o), val_(o).gc)
# define setgcovalue(L,obj,x) \
{ TValue * io = ( obj ) ; GCObject * i_g = ( x ) ; \
val_ ( io ) . gc = i_g ; settt_ ( io , ctb ( i_g - > tt ) ) ; }
/* }================================================================== */
# define setobj(L,obj1,obj2) \
{ TValue * io1 = ( obj1 ) ; const TValue * io2 = ( obj2 ) ; \
io1 - > value_ = io2 - > value_ ; io1 - > tt_ = io2 - > tt_ ; \
( void ) L ; checkliveness ( L , io1 ) ; }
/*
* * { = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
* * Numbers
* * = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
* * different types of assignments , according to destination
*/
/* Variant tags for numbers */
# define LUA_TNUMFLT makevariant(LUA_TNUMBER, 0) /* float numbers */
# define LUA_TNUMINT makevariant(LUA_TNUMBER, 1) /* integer numbers */
# define ttisnumber(o) checktype((o), LUA_TNUMBER)
# define ttisfloat(o) checktag((o), LUA_TNUMFLT)
# define ttisinteger(o) checktag((o), LUA_TNUMINT)
# define nvalue(o) check_exp(ttisnumber(o), \
( ttisinteger ( o ) ? cast_num ( ivalue ( o ) ) : fltvalue ( o ) ) )
# define fltvalue(o) check_exp(ttisfloat(o), val_(o).n)
# define ivalue(o) check_exp(ttisinteger(o), val_(o).i)
# define setfltvalue(obj,x) \
{ TValue * io = ( obj ) ; val_ ( io ) . n = ( x ) ; settt_ ( io , LUA_TNUMFLT ) ; }
# define chgfltvalue(obj,x) \
{ TValue * io = ( obj ) ; lua_assert ( ttisfloat ( io ) ) ; val_ ( io ) . n = ( x ) ; }
# define setivalue(obj,x) \
{ TValue * io = ( obj ) ; val_ ( io ) . i = ( x ) ; settt_ ( io , LUA_TNUMINT ) ; }
/* from stack to (same) stack */
# define setobjs2s setobj
/* to stack (not from same stack) */
# define setobj2s setobj
# define setsvalue2s setsvalue
# define sethvalue2s sethvalue
# define setptvalue2s setptvalue
/* from table to same table */
# define setobjt2t setobj
/* to new object */
# define setobj2n setobj
# define setsvalue2n setsvalue
/* to table */
# define setobj2t setobj
# define chgivalue(obj,x) \
{ TValue * io = ( obj ) ; lua_assert ( ttisinteger ( io ) ) ; val_ ( io ) . i = ( x ) ; }
/* }================================================================== */
/*
* * { = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
* * String s
* * = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
* * { = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
* * types and prototype s
* * = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
/* Variant tags for strings */
# define LUA_TSHRSTR makevariant(LUA_TSTRING, 0) /* short strings */
# define LUA_TLNGSTR makevariant(LUA_TSTRING, 1) /* long strings */
# define ttisstring(o) checktype((o), LUA_TSTRING)
# define ttisshrstring(o) checktag((o), ctb(LUA_TSHRSTR))
# define ttislngstring(o) checktag((o), ctb(LUA_TLNGSTR))
typedef TValue * StkId ; /* index to stack elements */
# define tsvalue(o) check_exp(ttisstring(o), gco2ts(val_(o).gc))
# define setsvalue(L,obj,x) \
{ TValue * io = ( obj ) ; TString * x_ = ( x ) ; \
val_ ( io ) . gc = obj2gco ( x_ ) ; settt_ ( io , ctb ( x_ - > tt ) ) ; \
checkliveness ( L , io ) ; }
/* set a string to the stack */
# define setsvalue2s setsvalue
/* set a string to a new object */
# define setsvalue2n setsvalue
/*
* * Header for string value ; string bytes follow the end of this structure
@ -379,6 +373,7 @@ typedef union UTString {
TString tsv ;
} UTString ;
/*
* * Get the actual string ( array of bytes ) from a ' TString ' .
* * ( Access to ' extra ' ensures that value is really a ' TString ' . )
@ -396,34 +391,6 @@ typedef union UTString {
/* get string length from 'TValue *o' */
# define vslen(o) tsslen(tsvalue(o))
/* }================================================================== */
/*
* * { = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
* * Userdata
* * = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
/*
* * Light userdata should be a variant of userdata , but for compatibility
* * reasons they are also different types .
*/
# define ttislightuserdata(o) checktag((o), LUA_TLIGHTUSERDATA)
# define ttisfulluserdata(o) checktag((o), ctb(LUA_TUSERDATA))
# define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p)
# define uvalue(o) check_exp(ttisfulluserdata(o), gco2u(val_(o).gc))
# define setpvalue(obj,x) \
{ TValue * io = ( obj ) ; val_ ( io ) . p = ( x ) ; settt_ ( io , LUA_TLIGHTUSERDATA ) ; }
# define setuvalue(L,obj,x) \
{ TValue * io = ( obj ) ; Udata * x_ = ( x ) ; \
val_ ( io ) . gc = obj2gco ( x_ ) ; settt_ ( io , ctb ( LUA_TUSERDATA ) ) ; \
checkliveness ( L , io ) ; }
/*
* * Header for userdata ; memory area follows the end of this structure
@ -465,14 +432,25 @@ typedef union UUdata {
io - > value_ = iu - > user_ ; settt_ ( io , iu - > ttuv_ ) ; \
checkliveness ( L , io ) ; }
/* }================================================================== */
/*
* * { = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
* * Prototypes
* * = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
/* RAVI: Following are the types we will use
* * use in parsing . The rationale for types is
* * performance - as of now these are the only types that
* * we care about from a performance point of view - if any
* * other types appear then they are all treated as ANY
* */
typedef enum {
RAVI_TANY = 0 , /* Lua dynamic type */
RAVI_TNUMINT = 1 , /* integer number */
RAVI_TNUMFLT , /* floating point number */
RAVI_TARRAYINT , /* array of ints */
RAVI_TARRAYFLT , /* array of doubles */
RAVI_TFUNCTION , /* Lua or C Function */
RAVI_TTABLE , /* Lua table */
RAVI_TSTRING , /* string */
RAVI_TNIL , /* NIL */
RAVI_TBOOLEAN , /* boolean */
RAVI_TUSERDATA /* userdata or lightuserdata */
} ravitype_t ;
/*
* * Description of an upvalue for function prototypes
@ -480,7 +458,7 @@ typedef union UUdata {
typedef struct Upvaldesc {
TString * name ; /* upvalue name (for debug information) */
TString * usertype ; /* RAVI extension: name of user type */
ravi_type_map ravi_type_map ; /* RAVI type of upvalue */
lu_byte ravi_type ; /* RAVI type of upvalue */
lu_byte instack ; /* whether it is in stack (register) */
lu_byte idx ; /* index of upvalue (in stack or in outer function's list) */
} Upvaldesc ;
@ -495,7 +473,7 @@ typedef struct LocVar {
TString * usertype ; /* RAVI extension: name of user type */
int startpc ; /* first point where variable is active */
int endpc ; /* first point where variable is dead */
ravi_type_map ravi_type_map ; /* RAVI type of the variable - RAVI_TANY if unknown */
lu_byte ravi_type ; /* RAVI type of the variable - RAVI_TANY if unknown */
} LocVar ;
/** RAVI changes start */
@ -524,7 +502,7 @@ typedef struct RaviJITProto {
*/
typedef struct Proto {
CommonHeader ;
lu_byte numparams ; /* number of fixed (named) parameters */
lu_byte numparams ; /* number of fixed parameters */
lu_byte is_vararg ;
lu_byte maxstacksize ; /* number of registers needed by this function */
int sizeupvalues ; /* size of 'upvalues' */
@ -548,119 +526,18 @@ typedef struct Proto {
RaviJITProto ravi_jit ;
} Proto ;
/*
* * { = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
* * Closures
* * = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
/*
* * LUA_TFUNCTION variants :
* * 0 - Lua function
* * 1 - light C function
* * 2 - regular C function ( closure )
* * 4 - fast light C dunction ( Ravi extension )
* * Lua Upvalues
*/
typedef struct UpVal UpVal ;
/* Variant tags for functions */
# define LUA_TLCL makevariant(LUA_TFUNCTION, 0) /* Lua closure */
# define LUA_TLCF makevariant(LUA_TFUNCTION, 1) /* light C function */
# define LUA_TCCL makevariant(LUA_TFUNCTION, 2) /* C closure */
# define RAVI_TFCF makevariant(LUA_TFUNCTION, 4) /* Ravi extension: fast light C function */
# define ttisfunction(o) checktype(o, LUA_TFUNCTION)
# define ttisclosure(o) ((rttype(o) & 0x1F) == LUA_TFUNCTION)
# define ttisLclosure(o) checktag((o), ctb(LUA_TLCL))
# define ttislcf(o) checktag((o), LUA_TLCF)
# define ttisCclosure(o) checktag((o), ctb(LUA_TCCL))
# define ttisfcf(o) (ttype(o) == RAVI_TFCF)
# define isLfunction(o) ttisLclosure(o)
# define clvalue(o) check_exp(ttisclosure(o), gco2cl(val_(o).gc))
# define clLvalue(o) check_exp(ttisLclosure(o), gco2lcl(val_(o).gc))
# define fvalue(o) check_exp(ttislcf(o), val_(o).f)
# define clCvalue(o) check_exp(ttisCclosure(o), gco2ccl(val_(o).gc))
# define fcfvalue(o) check_exp(ttisfcf(o), val_(o).p)
# define setclLvalue(L,obj,x) \
{ TValue * io = ( obj ) ; LClosure * x_ = ( x ) ; \
val_ ( io ) . gc = obj2gco ( x_ ) ; settt_ ( io , ctb ( LUA_TLCL ) ) ; \
checkliveness ( L , io ) ; }
# define setfvalue(obj,x) \
{ TValue * io = ( obj ) ; val_ ( io ) . f = ( x ) ; settt_ ( io , LUA_TLCF ) ; }
# define setclCvalue(L,obj,x) \
{ TValue * io = ( obj ) ; CClosure * x_ = ( x ) ; \
val_ ( io ) . gc = obj2gco ( x_ ) ; settt_ ( io , ctb ( LUA_TCCL ) ) ; \
checkliveness ( L , io ) ; }
/* The Fast C function call type is encoded as two
bytes . The Hi Byte holds a function tag . The Lo Byte
holds the Lua typecode */
# define setfvalue_fastcall(obj, x, tag) \
{ \
TValue * io = ( obj ) ; \
lua_assert ( tag > = 1 & & tag < 0x80 ) ; \
val_ ( io ) . p = ( x ) ; \
settt_ ( io , ( ( tag < < 8 ) | RAVI_TFCF ) ) ; \
}
# define getfcf_tag(typecode) (typecode >> 8)
/*
* Upvalues for Lua closures . The UpVal structure mediates the connection between a
* closure and a variable . An upvalue may be two states : open or closed .
* When the upvalue is created , it is open , and its pointer points to the corresponding
* variable in the Lua stack . That is , an open upvalue is one that ' s v is pointing to
* the stack . When the upvalue is closed , the value is moved from the stack to the
* UpVal structure itself ( value ) and the pointer v is corrected to point internally .
*
* At any point a variable can have at most one upvalue pointing to it , and all
* closures that reference the upvalue access this shared upvalue . Lua keeps a
* linked list of open upvalues of a stack . This list is ordered by the level of the
* corresponding variables on the stack . When Lua needs an upvalue for a local variable
* it traverse this linked list . If it finds an upvalue for the variable it reuses it
* thus ensuring that closures share the same upvalue .
*
* Because the list is ordered and there is at most one upvalue for each variable
* the maximum number of elements to be traversed when looking for a variable in this
* list can be known at compile time . This maximum is the number of variables that escape
* to inner closures and that are declared between the closure and the external variable .
* For instance
*
* function foo ( )
* local a , b , c , d
* local f1 = function ( ) return d + b end
* local f2 = function ( ) return f ( ) + a end
*
* When Lua instantiates f2 it will traverse exactly three upvalues before realizing
* that a has no upvalue yet : f1 , d , and b in that order .
*
* When a variable goes out of scope , its corrsponding update ( if there is one ) must
* be closed . The list of open upvalues is also used for this task . When compiling a
* block that contains variables that escape , a " close " operation must be emitted ( in Ravi
* there is no explicit close op , the JMP instruction takes care of it ) to close all
* upvalues up to this level , at the end of the block .
* * Closures
*/
typedef struct UpVal {
TValue * v ; /* points to stack or to its own value */
unsigned int refcount ; /* reference counter */
unsigned int flags ; /* Used to mark deferred values */
union {
struct { /* (when open) */
struct UpVal * next ; /* linked list */
int touched ; /* mark to avoid cycles with dead threads */
} open ;
TValue value ; /* the value (when closed) */
} u ;
} UpVal ;
# define ClosureHeader \
CommonHeader ; lu_byte nupvalues ; GCObject * gclist
@ -674,7 +551,7 @@ typedef struct CClosure {
typedef struct LClosure {
ClosureHeader ;
struct Proto * p ;
UpVal * upvals [ 1 ] ; /* list of upvalues - each upvalue represents one non-local variable used by the closure */
UpVal * upvals [ 1 ] ; /* list of upvalues */
} LClosure ;
@ -684,64 +561,15 @@ typedef union Closure {
} Closure ;
# define getproto(o) (clLvalue(o)->p )
# define isLfunction(o) ttisLclosure(o )
/* }================================================================== */
# define getproto(o) (clLvalue(o)->p)
/*
* * { = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
* * Tables
* * = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
/* RAVI change: we support two sub types of table type
and hence need to distinguish between the types .
ttistable ( ) returns true for all table types
ttisLtable ( ) only returns true if the value is a Lua table
ttisiarray ( ) only returns true if the value is a Ravi subtype integer [ ]
ttisfarray ( ) only returns true if the value is a Ravi subtype number [ ]
*/
/** RAVI table subtypes **/
# define RAVI_TIARRAY makevariant(LUA_TTABLE, 1) /* Ravi int array */
# define RAVI_TFARRAY makevariant(LUA_TTABLE, 2) /* Ravi float array */
# define ttistable(o) checktype((o), LUA_TTABLE)
# define ttisiarray(o) checktag((o), ctb(RAVI_TIARRAY))
# define ttisfarray(o) checktag((o), ctb(RAVI_TFARRAY))
# define ttisarray(o) (ttisiarray(o) || ttisfarray(o))
# define ttisLtable(o) checktag((o), ctb(LUA_TTABLE))
# define ttisdeadkey(o) checktag((o), LUA_TDEADKEY)
/* Macros to access values */
# define hvalue(o) check_exp(ttisLtable(o), gco2t(val_(o).gc))
# define arrvalue(o) check_exp(ttisarray(o), gco2array(val_(o).gc))
/* a dead value may get the 'gc' field, but cannot access its contents */
# define deadvalue(o) check_exp(ttisdeadkey(o), cast(void *, val_(o).gc))
# define sethvalue(L,obj,x) \
{ TValue * io = ( obj ) ; Table * x_ = ( x ) ; \
val_ ( io ) . gc = obj2gco ( x_ ) ; settt_ ( io , ctb ( LUA_TTABLE ) ) ; \
checkliveness ( L , io ) ; }
/** RAVI extension **/
# define setiarrayvalue(L,obj,x) \
{ TValue * io = ( obj ) ; RaviArray * x_ = ( x ) ; \
val_ ( io ) . gc = obj2gco ( x_ ) ; settt_ ( io , ctb ( RAVI_TIARRAY ) ) ; \
checkliveness ( L , io ) ; }
/** RAVI extension **/
# define setfarrayvalue(L,obj,x) \
{ TValue * io = ( obj ) ; RaviArray * x_ = ( x ) ; \
val_ ( io ) . gc = obj2gco ( x_ ) ; settt_ ( io , ctb ( RAVI_TFARRAY ) ) ; \
checkliveness ( L , io ) ; }
# define sethvalue2s sethvalue
# define setptvalue2s setptvalue
typedef union TKey {
struct {
TValuefields ;
@ -751,6 +579,11 @@ typedef union TKey {
} TKey ;
/* copy a value into a key without messing up field 'next' */
# define setnodekey(L,key,obj) \
{ TKey * k_ = ( key ) ; const TValue * io_ = ( obj ) ; \
k_ - > nk . value_ = io_ - > value_ ; k_ - > nk . tt_ = io_ - > tt_ ; \
( void ) L ; checkliveness ( L , io_ ) ; }
typedef struct Node {
@ -758,11 +591,20 @@ typedef struct Node {
TKey i_key ;
} Node ;
/* copy a value into a key without messing up field 'next' */
# define setnodekey(L,key,obj) \
{ TKey * k_ = ( key ) ; const TValue * io_ = ( obj ) ; \
k_ - > nk . value_ = io_ - > value_ ; k_ - > nk . tt_ = io_ - > tt_ ; \
( void ) L ; checkliveness ( L , io_ ) ; }
/** RAVI extension */
typedef enum RaviArrayModifer {
RAVI_ARRAY_SLICE = 1 ,
RAVI_ARRAY_FIXEDSIZE = 2
} RaviArrayModifier ;
/** RAVI extension */
typedef struct RaviArray {
char * data ; /* Note that the array data is 0-based so this holds 1+Lua length items */
unsigned int len ; /* RAVI len specialization, holds real length which is 1+Lua length */
unsigned int size ; /* amount of memory allocated */
lu_byte array_type ; /* RAVI specialization */
lu_byte array_modifier ; /* Flags that affect how the array is handled */
} RaviArray ;
typedef struct Table {
CommonHeader ;
@ -774,74 +616,15 @@ typedef struct Table {
Node * lastfree ; /* any free position is before this position */
struct Table * metatable ;
GCObject * gclist ;
/** RAVI extension */
RaviArray ravi_array ;
# if RAVI_USE_NEWHASH
// TODO we should reorganize this structure
unsigned int hmask ; /* Hash part mask (size of hash part - 1) - borrowed from LuaJIT */
# endif
} Table ;
/*
* * Macros to manipulate keys inserted in nodes
*/
# define keytt(node) ((node)->i_key.nk.tt_)
# define keyval(node) ((node)->i_key.nk.value_)
# define keyisnil(node) (keytt(node) == LUA_TNIL)
# define keyisinteger(node) (keytt(node) == LUA_TNUMINT)
# define keyival(node) (keyval(node).i)
# define keyfltval(node) (keyval(node).n)
# define keyfval(node) (keyval(node).f)
# define keypval(node) (keyval(node).p)
# define keybval(node) (keyval(node).b)
# define keygcval(node) (keyval(node).gc)
# define keyisshrstr(node) (keytt(node) == ctb(LUA_TSHRSTR))
# define keystrval(node) (gco2ts(keyval(node).gc))
# define setnilkey(node) (keytt(node) = LUA_TNIL)
# define keyiscollectable(n) (keytt(n) & BIT_ISCOLLECTABLE)
# define gckey(n) (keyval(n).gc)
# define gckeyN(n) (keyiscollectable(n) ? gckey(n) : NULL)
# define setdeadvalue(obj) settt_(obj, LUA_TDEADKEY)
/* }================================================================== */
/** RAVI extension */
typedef enum RaviArrayModifer {
RAVI_ARRAY_SLICE = 1 , /* Array is a slice - implies fixed size */
RAVI_ARRAY_FIXEDSIZE = 2 , /* Fixed size array */
RAVI_ARRAY_ALLOCATED = 4 , /* Array has memory allocated - cannot be true for slices */
RAVI_ARRAY_ISFLOAT = 8 /* A number array */
} RaviArrayModifier ;
enum {
RAVI_ARRAY_MAX_INLINE = 3 /* By default we allow for inline storage of 3 elements */ ,
} ;
/** RAVI extension */
/* Array types look like Userdata from GC point of view, but
* have the same base type as Lua tables .
*/
typedef struct RaviArray {
CommonHeader ;
lu_byte flags ;
unsigned int len ; /* array length, holds real length which is 1+Lua length */
unsigned int size ; /* size of data, in arrays (not slices) if == RAVI_ARRAY_MAX_INLINE then it means we are using inline storage */
union {
lua_Number numarray [ RAVI_ARRAY_MAX_INLINE ] ;
lua_Integer intarray [ RAVI_ARRAY_MAX_INLINE ] ;
struct RaviArray * parent ; /* Only set if this is a slice, parent must be a slice or a fixed length array */
} ;
char * data ; /* Pointer to data. In case of slices points in parent->data. In case of arrays this may point to heap or internal data */
struct Table * metatable ;
} RaviArray ;
# define getsliceunderlying(L,s,o) \
{ TValue * io = ( o ) ; const RaviArray * is = ( s ) ; \
io - > value_ . gc = obj2gco ( is - > parent ) ; settt_ ( io , ctb ( is - > parent - > tt ) ) ; \
checkliveness ( L , io ) ; }
/*
* * ' module ' operation for hashing ( size is always a power of 2 )
@ -876,11 +659,8 @@ LUAI_FUNC void luaO_tostring (lua_State *L, StkId obj);
LUAI_FUNC const char * luaO_pushvfstring ( lua_State * L , const char * fmt ,
va_list argp ) ;
LUAI_FUNC const char * luaO_pushfstring ( lua_State * L , const char * fmt , . . . ) ;
LUAI_FUNC void luaO_chunkid ( char * out , const char * source , size_t srclen ) ;
LUAI_FUNC void luaO_chunkid ( char * out , const char * source , size_t len ) ;
LUAI_FUNC int ravi_checktype ( lua_State * L , StkId input , ravi_type_map type , TString * usertype ) ;
# endif