issue #99 Merge splitting out of the RaviArray structure from Table

lua54-randomgen
Dibyendu Majumdar 4 years ago
commit 76f9bbdffb

@ -175,6 +175,7 @@ typedef struct lua_TValue {
#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 ttisfunction(o) checktype(o, LUA_TFUNCTION)
#define ttisclosure(o) ((rttype(o) & 0x1F) == LUA_TFUNCTION)
@ -201,7 +202,8 @@ typedef struct lua_TValue {
#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 hvalue(o) check_exp(ttisLtable(o), gco2t(val_(o).gc))
#define arrvalue(o) check_exp(ttisarray(o), gco2array(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 */
@ -295,13 +297,13 @@ typedef struct lua_TValue {
/** RAVI extension **/
#define setiarrayvalue(L,obj,x) \
{ TValue *io = (obj); Table *x_ = (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); Table *x_ = (x); \
{ TValue *io = (obj); RaviArray *x_ = (x); \
val_(io).gc = obj2gco(x_); settt_(io, ctb(RAVI_TFARRAY)); \
checkliveness(L,io); }
@ -593,17 +595,32 @@ typedef struct Node {
/** RAVI extension */
typedef enum RaviArrayModifer {
RAVI_ARRAY_SLICE = 1,
RAVI_ARRAY_FIXEDSIZE = 2
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 {
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 */
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;
typedef struct Table {
@ -616,8 +633,6 @@ 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 */

@ -240,6 +240,7 @@ union GCUnion {
struct Udata u;
union Closure cl;
struct Table h;
struct RaviArray arr;
struct Proto p;
struct lua_State th; /* thread */
};
@ -256,7 +257,8 @@ union GCUnion {
#define gco2cl(o) \
check_exp(novariant((o)->tt) == LUA_TFUNCTION, &((cast_u(o))->cl))
/** RAVI change - we have table sub types in RAVI **/
#define gco2t(o) check_exp(novariant((o)->tt) == LUA_TTABLE, &((cast_u(o))->h))
#define gco2t(o) check_exp((o)->tt == LUA_TTABLE, &((cast_u(o))->h))
#define gco2array(o) check_exp(((o)->tt == RAVI_TIARRAY || (o)->tt == RAVI_TFARRAY), &((cast_u(o))->arr))
#define gco2p(o) check_exp((o)->tt == LUA_TPROTO, &((cast_u(o))->p))
#define gco2th(o) check_exp((o)->tt == LUA_TTHREAD, &((cast_u(o))->th))

@ -124,49 +124,49 @@ LUAI_FUNC int luaH_getn (Table *t);
/* Creates a specialized version of Lua Table to support Ravi's
* integer[] and number[] arrays.
*/
LUAI_FUNC Table *raviH_new(lua_State *L, ravitype_t array_type, int is_slice);
LUAI_FUNC RaviArray *raviH_new(lua_State *L, ravitype_t array_type, int is_slice);
LUAI_FUNC void raviH_free(lua_State* L, RaviArray* t);
LUAI_FUNC int raviH_next(lua_State* L, RaviArray* t, StkId key);
LUAI_FUNC Table *raviH_new_integer_array(lua_State *L, unsigned int len,
LUAI_FUNC RaviArray *raviH_new_integer_array(lua_State *L, unsigned int len,
lua_Integer init_value);
LUAI_FUNC Table *raviH_new_number_array(lua_State *L, unsigned int len,
LUAI_FUNC RaviArray *raviH_new_number_array(lua_State *L, unsigned int len,
lua_Number init_value);
/* Returns the array length - note that this function will
* ignore any elements outside of the Ravi Array structure
*/
LUAI_FUNC int raviH_getn(Table *t);
#define raviH_getn(t) ((t)->len - 1)
/* Type specific array set operation */
LUAI_FUNC void raviH_set_int(lua_State *L, Table *t, lua_Unsigned key,
LUAI_FUNC void raviH_set_int(lua_State *L, RaviArray *t, lua_Unsigned key,
lua_Integer value);
/* Type specific array set operation */
LUAI_FUNC void raviH_set_float(lua_State *L, Table *t, lua_Unsigned key,
LUAI_FUNC void raviH_set_float(lua_State *L, RaviArray *t, lua_Unsigned key,
lua_Number value);
/* Create a slice of an existing array
* The original table containing the array is inserted into the
* the slice as a value against special key pointer('key_orig_table') so that
* the parent table is not garbage collected while this array contains a
* reference to it
/*
* Create a slice of an existing array
* The original array is inserted into the
* the slice as a paren so that
* the parent array is not garbage collected while this array contains a
* reference to it. This is enforced in the GC.
* The array slice starts at start but start-1 is also accessible because of the
* implementation having array values starting at 0.
* A slice must not attempt to release the data array as this is not owned by it,
* and in fact may point to garbage from a memory allocater's point of view.
*/
LUAI_FUNC Table *raviH_new_slice(lua_State *L, TValue *parent,
LUAI_FUNC RaviArray *raviH_new_slice(lua_State *L, TValue *parent,
unsigned int start, unsigned int len);
/* Obtain parent array of the slice */
LUAI_FUNC const TValue *raviH_slice_parent(lua_State *L, TValue *slice);
/* Type specific array get operation */
#define raviH_get_int_inline(L, t, key, v) \
{ \
unsigned int ukey = (unsigned int)((key)); \
lua_Integer *data = (lua_Integer *)t->ravi_array.data; \
if (ukey < t->ravi_array.len) { \
lua_Integer *data = (lua_Integer *)t->data; \
if (ukey < t->len) { \
setivalue(v, data[ukey]); \
} else \
luaG_runerror(L, "array out of bounds"); \
@ -176,8 +176,8 @@ LUAI_FUNC const TValue *raviH_slice_parent(lua_State *L, TValue *slice);
#define raviH_get_float_inline(L, t, key, v) \
{ \
unsigned int ukey = (unsigned int)((key)); \
lua_Number *data = (lua_Number *)t->ravi_array.data; \
if (ukey < t->ravi_array.len) { \
lua_Number *data = (lua_Number *)t->data; \
if (ukey < t->len) { \
setfltvalue(v, data[ukey]); \
} else \
luaG_runerror(L, "array out of bounds"); \
@ -187,8 +187,8 @@ LUAI_FUNC const TValue *raviH_slice_parent(lua_State *L, TValue *slice);
#define raviH_set_int_inline(L, t, key, value) \
{ \
unsigned int ukey = (unsigned int)((key)); \
lua_Integer *data = (lua_Integer *)t->ravi_array.data; \
if (ukey < t->ravi_array.len) { \
lua_Integer *data = (lua_Integer *)t->data; \
if (ukey < t->len) { \
data[ukey] = (value); \
} else \
raviH_set_int(L, t, ukey, (value)); \
@ -198,15 +198,15 @@ LUAI_FUNC const TValue *raviH_slice_parent(lua_State *L, TValue *slice);
#define raviH_set_float_inline(L, t, key, value) \
{ \
unsigned int ukey = (unsigned int)((key)); \
lua_Number *data = (lua_Number *)t->ravi_array.data; \
if (ukey < t->ravi_array.len) { \
lua_Number *data = (lua_Number *)t->data; \
if (ukey < t->len) { \
data[ukey] = (value); \
} else \
raviH_set_float(L, t, ukey, (value)); \
}
LUAI_FUNC void raviH_get_number_array_rawdata(lua_State *L, Table *t, Ravi_NumberArray *data);
LUAI_FUNC void raviH_get_integer_array_rawdata(lua_State *L, Table *t, Ravi_IntegerArray *data);
LUAI_FUNC void raviH_get_number_array_rawdata(lua_State *L, RaviArray *t, Ravi_NumberArray *data);
LUAI_FUNC void raviH_get_integer_array_rawdata(lua_State *L, RaviArray *t, Ravi_IntegerArray *data);
#if defined(LUA_DEBUG)
LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key);

@ -813,7 +813,7 @@
#endif
#if defined(_MSC_VER)
#if defined(_MSC_VER) && !defined(__clang__)
#define RAVI_NORETURN __declspec(noreturn)
#define RAVI_INLINE __inline

@ -179,6 +179,8 @@ struct LuaLLVMTypes {
llvm::StructType *UdataT;
llvm::StructType *RaviArrayT;
llvm::PointerType* pRaviArrayT;
llvm::PointerType* ppRaviArrayT;
llvm::StructType *TableT;
llvm::PointerType *pTableT;
llvm::PointerType *ppTableT;
@ -1036,6 +1038,9 @@ class RaviCodeGenerator {
// emit code to load the table value from register
llvm::Instruction *emit_load_reg_h(RaviFunctionDef *def, llvm::Value *ra);
// emit code to load the RaviArray value from register
llvm::Instruction* emit_load_reg_arr(RaviFunctionDef* def, llvm::Value* ra);
// Gets the size of the hash table
// This is the sizenode() macro in lobject.h
llvm::Value *emit_table_get_hashsize(RaviFunctionDef *def, llvm::Value *table);
@ -1097,7 +1102,8 @@ class RaviCodeGenerator {
llvm::Instruction *emit_load_type(RaviFunctionDef *def, llvm::Value *value);
// emit code to load the array type
llvm::Instruction *emit_load_ravi_arraytype(RaviFunctionDef *def, llvm::Value *value);
// Disabled as it is now broken
//llvm::Instruction *emit_load_ravi_arraytype(RaviFunctionDef *def, llvm::Value *value);
// emit code to load the array length
llvm::Instruction *emit_load_ravi_arraylength(RaviFunctionDef *def, llvm::Value *value);

@ -333,6 +333,20 @@ static void checkobject (global_State *g, GCObject *o, int maybedead) {
checkvalref(g, o, &uservalue);
break;
}
case RAVI_TFARRAY:
case RAVI_TIARRAY: {
Table *mt = gco2array(o)->metatable;
checkobjref(g, o, mt);
// TODO use macro for below - see lgc too
if (arrvalue(o)->flags & RAVI_ARRAY_SLICE) {
TValue parent;
lua_assert(arrvalue(o)->parent);
parent.tt_ = ctb(arrvalue(o)->parent->tt);
parent.value_.gc = obj2gco(arrvalue(o)->parent);
checkvalref(g, o, &parent);
}
break;
}
case LUA_TTABLE: {
checktable(g, gco2t(o));
break;

@ -427,7 +427,7 @@ LUA_API size_t lua_rawlen (lua_State *L, int idx) {
case LUA_TUSERDATA: return uvalue(o)->len;
case RAVI_TIARRAY:
case RAVI_TFARRAY: {
Table *h = hvalue(o);
RaviArray *h = arrvalue(o);
return raviH_getn(h);
}
case LUA_TTABLE: {
@ -468,7 +468,7 @@ LUA_API const void *lua_topointer(lua_State *L, int idx) {
StkId o = index2addr(L, idx);
switch (ttype(o)) {
case RAVI_TIARRAY:
case RAVI_TFARRAY:
case RAVI_TFARRAY: return arrvalue(o);
case LUA_TTABLE: return hvalue(o);
case LUA_TLCL: return clLvalue(o);
case LUA_TCCL: return clCvalue(o);
@ -691,7 +691,7 @@ LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) {
}
}
else {
Table *h = hvalue(t);
RaviArray *h = arrvalue(t);
if (ttisfarray(t)) {
if (n <= raviH_getn(h)) { raviH_get_float_inline(L, h, n, L->top); }
else {
@ -712,15 +712,15 @@ LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) {
LUA_API int lua_rawget(lua_State *L, int idx) {
StkId t;
Table *h;
lua_lock(L);
t = index2addr(L, idx);
api_check(L, ttistable(t), "table expected");
h = hvalue(t);
if (ttisLtable(t)) {
setobj2s(L, L->top - 1, luaH_get(h, L->top - 1));
Table* h = hvalue(t);
setobj2s(L, L->top - 1, luaH_get(h, L->top - 1));
}
else if (ttisfarray(t)) {
RaviArray* h = arrvalue(t);
TValue *key = L->top - 1;
api_check(L, ttisinteger(key), "key must be integer");
if (ttisinteger(key)) {
@ -735,6 +735,7 @@ LUA_API int lua_rawget(lua_State *L, int idx) {
}
}
else {
RaviArray* h = arrvalue(t);
TValue *key = L->top - 1;
api_check(L, ttisinteger(key), "key must be integer");
if (ttisinteger(key)) {
@ -755,21 +756,22 @@ LUA_API int lua_rawget(lua_State *L, int idx) {
LUA_API int lua_rawgeti (lua_State *L, int idx, lua_Integer n) {
StkId t;
Table *h;
lua_lock(L);
t = index2addr(L, idx);
api_check(L, ttistable(t), "table expected");
h = hvalue(t);
if (ttisLtable(t)) {
Table *h = hvalue(t);
setobj2s(L, L->top, luaH_getint(h, n));
}
else if (ttisfarray(t)) {
RaviArray *h = arrvalue(t);
if (n <= raviH_getn(h)) { raviH_get_float_inline(L, h, n, L->top); }
else {
setnilvalue(L->top);
}
}
else {
RaviArray *h = arrvalue(t);
if (n <= raviH_getn(h)) { raviH_get_int_inline(L, h, n, L->top); }
else {
setnilvalue(L->top);
@ -812,7 +814,7 @@ LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
*/
LUA_API void ravi_create_integer_array(lua_State *L, int narray,
lua_Integer initial_value) {
Table *t;
RaviArray *t;
lua_lock(L);
t = raviH_new_integer_array(L, (unsigned int)narray, initial_value);
setiarrayvalue(L, L->top, t);
@ -826,7 +828,7 @@ LUA_API void ravi_create_integer_array(lua_State *L, int narray,
*/
LUA_API void ravi_create_number_array(lua_State *L, int narray,
lua_Number initial_value) {
Table *t;
RaviArray *t;
lua_lock(L);
t = raviH_new_number_array(L, (unsigned int)narray, initial_value);
setfarrayvalue(L, L->top, t);
@ -857,7 +859,7 @@ LUA_API void ravi_get_number_array_rawdata(lua_State *L, int idx, Ravi_NumberArr
StkId o = index2addr(L, idx);
if (!ttisfarray(o))
luaG_runerror(L, "number[] required");
raviH_get_number_array_rawdata(L, hvalue(o), data);
raviH_get_number_array_rawdata(L, arrvalue(o), data);
}
/* Get the raw data associated with the number array at idx.
@ -868,7 +870,7 @@ LUA_API void ravi_get_integer_array_rawdata(lua_State *L, int idx, Ravi_IntegerA
StkId o = index2addr(L, idx);
if (!ttisiarray(o))
luaG_runerror(L, "integer[] required");
raviH_get_integer_array_rawdata(L, hvalue(o), data);
raviH_get_integer_array_rawdata(L, arrvalue(o), data);
}
/* Create a slice of an existing array
@ -885,7 +887,7 @@ LUA_API void ravi_get_integer_array_rawdata(lua_State *L, int idx, Ravi_IntegerA
LUA_API void ravi_create_slice(lua_State *L, int idx, unsigned int start,
unsigned int len) {
TValue *parent;
Table *slice;
RaviArray *slice;
const char *errmsg = NULL;
lua_lock(L);
/* The do-while loop here is just for error handling */
@ -898,8 +900,8 @@ LUA_API void ravi_create_slice(lua_State *L, int idx, unsigned int start,
errmsg = "cannot create a slice of a table, integer[] or number[] expected";
goto done;
}
Table *orig = hvalue(parent);
if (start < 1 || start + len > orig->ravi_array.len) {
RaviArray *orig = arrvalue(parent);
if (start < 1 || start + len > orig->len) {
errmsg = "cannot create a slice of given bounds";
goto done;
}
@ -924,7 +926,11 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) {
int res = 0;
lua_lock(L);
obj = index2addr(L, objindex);
switch (ttnov(obj)) {
switch (ttype(obj)) {
case RAVI_TIARRAY:
case RAVI_TFARRAY:
mt = arrvalue(obj)->metatable;
break;
case LUA_TTABLE:
mt = hvalue(obj)->metatable;
break;
@ -1025,7 +1031,7 @@ LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) {
}
}
else {
Table *h = hvalue(t);
RaviArray *h = arrvalue(t);
if (ttisfarray(t)) {
TValue *val = L->top - 1;
if (ttisfloat(val)) { raviH_set_float_inline(L, h, n, fltvalue(val)); }
@ -1069,7 +1075,7 @@ LUA_API void lua_rawset (lua_State *L, int idx) {
luaC_barrierback(L, hvalue(o), L->top - 1);
}
else if (ttisfarray(o)) {
Table *t = hvalue(o);
RaviArray *t = arrvalue(o);
TValue *key = L->top - 2;
TValue *val = L->top - 1;
if (!ttisinteger(key)) luaG_typeerror(L, key, "index");
@ -1089,7 +1095,7 @@ LUA_API void lua_rawset (lua_State *L, int idx) {
}
}
else {
Table *t = hvalue(o);
RaviArray *t = arrvalue(o);
TValue *key = L->top - 2;
TValue *val = L->top - 1;
if (!ttisinteger(key)) luaG_typeerror(L, key, "index");
@ -1121,7 +1127,7 @@ LUA_API void lua_rawseti (lua_State *L, int idx, lua_Integer n) {
luaC_barrierback(L, hvalue(o), L->top - 1);
}
else if (ttisfarray(o)) {
Table *t = hvalue(o);
RaviArray *t = arrvalue(o);
TValue *val = L->top - 1;
if (ttisfloat(val)) { raviH_set_float_inline(L, t, n, fltvalue(val)); }
else if (ttisinteger(val)) {
@ -1135,7 +1141,7 @@ LUA_API void lua_rawseti (lua_State *L, int idx, lua_Integer n) {
}
}
else {
Table *t = hvalue(o);
RaviArray *t = arrvalue(o);
TValue *val = L->top - 1;
if (ttisinteger(val)) { raviH_set_int_inline(L, t, n, ivalue(val)); }
else {
@ -1180,7 +1186,16 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) {
luaG_runerror(L, "Lua table expected");
mt = hvalue(L->top - 1);
}
switch (ttnov(obj)) {
switch (ttype(obj)) {
case RAVI_TIARRAY:
case RAVI_TFARRAY: {
arrvalue(obj)->metatable = mt;
if (mt) {
luaC_objbarrier(L, gcvalue(obj), mt);
luaC_checkfinalizer(L, gcvalue(obj), mt);
}
break;
}
case LUA_TTABLE: {
hvalue(obj)->metatable = mt;
if (mt) {
@ -1451,7 +1466,7 @@ LUA_API int lua_next (lua_State *L, int idx) {
lua_lock(L);
t = index2addr(L, idx);
api_check(L, ttistable(t), "table expected");
more = luaH_next(L, hvalue(t), L->top - 1);
more = ttisLtable(t) ? luaH_next(L, hvalue(t), L->top - 1) : raviH_next(L, arrvalue(t), L->top - 1);
if (more) {
api_incr_top(L);
}

@ -519,7 +519,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults, int op_call) {
return 0;
}
case RAVI_TFCF: {
int nargs = L->top - func - 1;
int nargs = (int)(L->top - func - 1);
int tt = rttype(func);
int sig = getfcf_tag(tt); /* Extract the function signature */
switch (sig) {

@ -338,9 +338,22 @@ static void reallymarkobject (global_State *g, GCObject *o) {
linkgclist(gco2ccl(o), g->gray);
break;
}
/* RAVI changes */
/* arrays are treated like userdata. */
case RAVI_TIARRAY:
case RAVI_TFARRAY:
case RAVI_TFARRAY: {
RaviArray *slice = gco2array(o);
markobjectN(g, gco2array(o)->metatable); /* mark its metatable */
gray2black(o);
if (slice->flags & RAVI_ARRAY_SLICE) {
lua_assert(slice->parent);
TValue pvalue = {.tt_ = ctb(slice->parent->tt), .value_.gc = obj2gco(slice->parent)}; // FIX we should use appropriate macro
if (valiswhite(&pvalue)) {
o = gcvalue(&pvalue);
goto reentry;
}
}
break;
}
case LUA_TTABLE: {
linkgclist(gco2t(o), g->gray);
break;
@ -641,9 +654,6 @@ static void propagatemark (global_State *g) {
lua_assert(isgray(o));
gray2black(o);
switch (o->tt) {
/* RAVI changes */
case RAVI_TIARRAY:
case RAVI_TFARRAY:
case LUA_TTABLE: {
Table *h = gco2t(o);
g->gray = h->gclist; /* remove from 'gray' list */
@ -789,7 +799,7 @@ static void freeobj (lua_State *L, GCObject *o) {
}
/* RAVI changes */
case RAVI_TFARRAY:
case RAVI_TIARRAY:
case RAVI_TIARRAY: raviH_free(L, gco2array(o)); break;
case LUA_TTABLE: luaH_free(L, gco2t(o)); break;
case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break;
case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break;

@ -175,7 +175,7 @@ static unsigned int findindex (lua_State *L, Table *t, StkId key) {
* set value to key+1
* increment *key
*/
int raviH_next(lua_State *L, Table *t, StkId key) {
int raviH_next(lua_State *L, RaviArray *t, StkId key) {
lua_Integer i;
if (ttisnil(key))
/* Lua keys start at 1 so this is just before that
@ -187,11 +187,11 @@ int raviH_next(lua_State *L, Table *t, StkId key) {
return 0;
}
i = i + 1;
if (i >= t->ravi_array.len)
if (i >= t->len)
/* no more keys */
return 0;
setivalue(key, i);
if (t->ravi_array.array_type == RAVI_TARRAYFLT) {
if (t->flags & RAVI_ARRAY_ISFLOAT) {
raviH_get_float_inline(L, t, i, (key + 1));
}
else {
@ -200,27 +200,23 @@ int raviH_next(lua_State *L, Table *t, StkId key) {
return 1;
}
int luaH_next (lua_State *L, Table *t, StkId key) {
if (t->ravi_array.array_type != RAVI_TTABLE)
return raviH_next(L, t, key);
else {
unsigned int i = findindex(L, t, key); /* find original element */
for (; i < t->sizearray; i++) { /* try first array part */
if (!ttisnil(&t->array[i])) { /* a non-nil value? */
setivalue(key, i + 1);
setobj2s(L, key + 1, &t->array[i]);
return 1;
}
int luaH_next(lua_State *L, Table *t, StkId key) {
unsigned int i = findindex(L, t, key); /* find original element */
for (; i < t->sizearray; i++) { /* try first array part */
if (!ttisnil(&t->array[i])) { /* a non-nil value? */
setivalue(key, i + 1);
setobj2s(L, key + 1, &t->array[i]);
return 1;
}
for (i -= t->sizearray; cast_int(i) < sizenode(t); i++) { /* hash part */
if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */
setobj2s(L, key, gkey(gnode(t, i)));
setobj2s(L, key + 1, gval(gnode(t, i)));
return 1;
}
}
for (i -= t->sizearray; cast_int(i) < sizenode(t); i++) { /* hash part */
if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */
setobj2s(L, key, gkey(gnode(t, i)));
setobj2s(L, key + 1, gval(gnode(t, i)));
return 1;
}
return 0; /* no more elements */
}
return 0; /* no more elements */
}
/*
@ -451,30 +447,22 @@ Table *luaH_new (lua_State *L) {
t->flags = cast_byte(~0);
t->array = NULL;
t->sizearray = 0;
t->ravi_array.len = 0; /* RAVI */
t->ravi_array.array_type = RAVI_TTABLE; /* default is a Lua table */
t->ravi_array.array_modifier = 0;
t->ravi_array.data = NULL; /* data */
t->ravi_array.size = 0;
setnodevector(L, t, 0);
return t;
}
Table *raviH_new(lua_State *L, ravitype_t tt, int is_slice) {
RaviArray *raviH_new(lua_State *L, ravitype_t tt, int is_slice) {
lua_assert(tt == RAVI_TARRAYFLT || tt == RAVI_TARRAYINT);
GCObject *o = luaC_newobj(L, tt == RAVI_TARRAYFLT ? RAVI_TFARRAY : RAVI_TIARRAY, sizeof(Table));
Table *t = gco2t(o);
GCObject *o = luaC_newobj(L, tt == RAVI_TARRAYFLT ? RAVI_TFARRAY : RAVI_TIARRAY, sizeof(RaviArray));
RaviArray *t = gco2array(o);
t->len = 0;
t->size = RAVI_ARRAY_MAX_INLINE; /* Initially we use inline storage */
t->flags = (tt == RAVI_TARRAYFLT) ? RAVI_ARRAY_ISFLOAT : 0;
t->data = (tt == RAVI_TARRAYFLT) ? (char *) &t->numarray : (char *) &t->intarray; /* data */
t->parent = NULL;
t->metatable = NULL;
t->flags = cast_byte(~0);
t->array = NULL;
t->sizearray = 0;
t->ravi_array.len = 0; /* RAVI */
t->ravi_array.array_modifier = 0;
t->ravi_array.data = NULL; /* data */
t->ravi_array.size = 0;
setnodevector(L, t, 0);
t->ravi_array.array_type = tt;
if (!is_slice) {
/* Note following will set len to 1 */
if (tt == RAVI_TARRAYFLT) {
raviH_set_float_inline(L, t, 0, 0.0);
}
@ -482,27 +470,31 @@ Table *raviH_new(lua_State *L, ravitype_t tt, int is_slice) {
raviH_set_int_inline(L, t, 0, 0);
}
}
else {
t->flags |= (RAVI_ARRAY_FIXEDSIZE|RAVI_ARRAY_SLICE);
}
return t;
}
void luaH_free (lua_State *L, Table *t) {
if (t->ravi_array.array_modifier != RAVI_ARRAY_SLICE && t->ravi_array.data) {
if (t->ravi_array.array_type == RAVI_TARRAYFLT)
luaM_freemem(L, t->ravi_array.data, (t->ravi_array.size*sizeof(lua_Number)));
else {
lua_assert(t->ravi_array.array_type == RAVI_TARRAYINT);
luaM_freemem(L, t->ravi_array.data, (t->ravi_array.size*sizeof(lua_Integer)));
}
}
if (!isdummy(t))
luaM_freearray(L, t->node, cast(size_t, sizenode(t)));
luaM_freearray(L, t->array, t->sizearray);
luaM_free(L, t);
}
void raviH_free(lua_State *L, RaviArray *t) {
if (t->flags & RAVI_ARRAY_ALLOCATED) {
// slices will never have allocated flag set
lua_assert((t->flags & RAVI_ARRAY_SLICE) == 0);
if (t->flags & RAVI_ARRAY_ISFLOAT)
luaM_freemem(L, t->data, (t->size * sizeof(lua_Number)));
else {
luaM_freemem(L, t->data, (t->size * sizeof(lua_Integer)));
}
}
luaM_free(L, t);
}
static Node *getfreepos (Table *t) {
if (!isdummy(t)) {
@ -758,12 +750,6 @@ static lua_Unsigned unbound_search (Table *t, lua_Unsigned j) {
*/
int luaH_getn (Table *t) {
unsigned int j;
/* if this is a RAVI array then use specialized function */
if (t->ravi_array.array_type != RAVI_TTABLE) {
lua_assert(t->ravi_array.array_type == RAVI_TARRAYFLT ||
t->ravi_array.array_type == RAVI_TARRAYINT);
return t->ravi_array.len;
}
j = t->sizearray;
if (j > 0 && ttisnil(&t->array[j - 1])) {
/* there is a boundary in the array part: (binary) search for it */
@ -781,54 +767,58 @@ int luaH_getn (Table *t) {
else return unbound_search(t, j);
}
/* RAVI array specialization */
int raviH_getn(Table *t) {
lua_assert(t->ravi_array.array_type != RAVI_TTABLE);
return t->ravi_array.len - 1;
}
/* resize array and initialize new elements if requested */
static int ravi_resize_array(lua_State *L, Table *t, unsigned int new_size,
int initialize) {
if (t->ravi_array.array_modifier) {
static int ravi_resize_array(lua_State *L, RaviArray *t, unsigned int new_size, int initialize) {
if (t->flags & RAVI_ARRAY_FIXEDSIZE || t->flags & RAVI_ARRAY_SLICE) {
/* cannot resize */
return 0;
}
int number_array = RAVI_TARRAYFLT == t->ravi_array.array_type;
unsigned int size =
new_size < t->ravi_array.size + 10 ? t->ravi_array.size + 10 : new_size;
/*
Array could initially be pointing to inline storage so we
need to be careful when reallocating. Also we allow for lua_Number and
lua_Integer to be different sizes
*/
int number_array = t->flags & RAVI_ARRAY_ISFLOAT;
unsigned int size = new_size < t->size + 10 ? t->size + 10 : new_size;
int was_allocated = t->flags & RAVI_ARRAY_ALLOCATED;
lua_assert(!was_allocated ? t->size == RAVI_ARRAY_MAX_INLINE : 1);
lua_assert(!was_allocated ? (t->data == &t->numarray || t->data == &t->intarray) : 1);
char *olddata = was_allocated ? t->data : NULL; // Not allocated
if (number_array) {
t->ravi_array.data = (char *)luaM_reallocv(
L, t->ravi_array.data, t->ravi_array.size, size, sizeof(lua_Number));
t->data = (char *)luaM_reallocv(L, olddata, t->size, size, sizeof(lua_Number));
if (!was_allocated)
memcpy(t->data, t->numarray, sizeof(lua_Number) * t->size);
if (initialize) {
lua_Number *data = (lua_Number *)t->ravi_array.data;
memset(&data[t->ravi_array.len], 0, (size - t->ravi_array.size) * sizeof(lua_Number));
lua_Number *ndata = (lua_Number *)t->data;
memset(&ndata[t->len], 0, (size - t->size) * sizeof(lua_Number));
}
}
else {
t->ravi_array.data = (char *)luaM_reallocv(
L, t->ravi_array.data, t->ravi_array.size, size, sizeof(lua_Integer));
t->data = (char *)luaM_reallocv(L, olddata, t->size, size, sizeof(lua_Integer));
if (!was_allocated)
memcpy(t->data, t->intarray, sizeof(lua_Integer) * t->size);
if (initialize) {
lua_Integer *data = (lua_Integer *)t->ravi_array.data;
memset(&data[t->ravi_array.len], 0, (size - t->ravi_array.size) * sizeof(lua_Integer));
lua_Integer *idata = (lua_Integer *)t->data;
memset(&idata[t->len], 0, (size - t->size) * sizeof(lua_Integer));
}
}
t->ravi_array.size = size;
t->size = size;
t->flags |= RAVI_ARRAY_ALLOCATED;
return 1;
}
void raviH_set_int(lua_State *L, Table *t, lua_Unsigned u1, lua_Integer value) {
void raviH_set_int(lua_State *L, RaviArray *t, lua_Unsigned u1, lua_Integer value) {
unsigned int u = (unsigned int)u1;
lua_assert(t->ravi_array.array_type == RAVI_TARRAYINT);
lua_assert((t->flags & RAVI_ARRAY_ISFLOAT) == 0);
lua_Integer *data;
if (u < t->ravi_array.len) {
if (u < t->len) {
setval2:
data = (lua_Integer *)t->ravi_array.data;
data = (lua_Integer *)t->data;
data[u] = value;
} else if (u == t->ravi_array.len) {
if (u < t->ravi_array.size) {
} else if (u == t->len) {
if (u < t->size) {
setval:
t->ravi_array.len++;
t->len++;
goto setval2;
} else {
if (ravi_resize_array(L, t, 0, 1))
@ -840,18 +830,18 @@ void raviH_set_int(lua_State *L, Table *t, lua_Unsigned u1, lua_Integer value) {
luaG_runerror(L, "array out of bounds");
}
void raviH_set_float(lua_State *L, Table *t, lua_Unsigned u1, lua_Number value) {
void raviH_set_float(lua_State *L, RaviArray *t, lua_Unsigned u1, lua_Number value) {
unsigned int u = (unsigned int)u1;
lua_assert(t->ravi_array.array_type == RAVI_TARRAYFLT);
lua_assert(t->flags & RAVI_ARRAY_ISFLOAT);
lua_Number *data;
if (u < t->ravi_array.len) {
if (u < t->len) {
setval2:
data = (lua_Number *)t->ravi_array.data;
data = (lua_Number *)t->data;
data[u] = value;
} else if (u == t->ravi_array.len) {
if (u < t->ravi_array.size) {
} else if (u == t->len) {
if (u < t->size) {
setval:
t->ravi_array.len++;
t->len++;
goto setval2;
} else {
if (ravi_resize_array(L, t, 0, 1))
@ -863,108 +853,85 @@ void raviH_set_float(lua_State *L, Table *t, lua_Unsigned u1, lua_Number value)
luaG_runerror(L, "array out of bounds");
}
Table *raviH_new_integer_array(lua_State *L, unsigned int len,
RaviArray *raviH_new_integer_array(lua_State *L, unsigned int len,
lua_Integer init_value) {
Table *t = raviH_new(L, RAVI_TARRAYINT, 0);
RaviArray *t = raviH_new(L, RAVI_TARRAYINT, 0);
ravi_resize_array(L, t, len + 1, 0);
lua_Integer *data = (lua_Integer *)t->ravi_array.data;
lua_Integer *data = (lua_Integer *)t->data;
data[0] = 0;
for (unsigned int i = 1; i <= len; i++) {
data[i] = init_value;
}
t->ravi_array.len = len + 1;
t->ravi_array.array_modifier = RAVI_ARRAY_FIXEDSIZE;
t->len = len + 1;
t->flags |= RAVI_ARRAY_FIXEDSIZE;
return t;
}
Table *raviH_new_number_array(lua_State *L, unsigned int len,
RaviArray *raviH_new_number_array(lua_State *L, unsigned int len,
lua_Number init_value) {
Table *t = raviH_new(L, RAVI_TARRAYFLT, 0);
RaviArray *t = raviH_new(L, RAVI_TARRAYFLT, 0);
ravi_resize_array(L, t, len + 1, 0);
lua_Number *data = (lua_Number *)t->ravi_array.data;
lua_Number *data = (lua_Number *)t->data;
data[0] = 0;
for (unsigned int i = 1; i <= len; i++) {
data[i] = init_value;
}
t->ravi_array.len = len + 1;
t->ravi_array.array_modifier = RAVI_ARRAY_FIXEDSIZE;
t->len = len + 1;
t->flags |= RAVI_ARRAY_FIXEDSIZE;
return t;
}
void raviH_get_number_array_rawdata(lua_State *L, Table *t, Ravi_NumberArray *data) {
void raviH_get_number_array_rawdata(lua_State *L, RaviArray *t, Ravi_NumberArray *data) {
(void)L;
lua_assert(t->ravi_array.array_type == RAVI_TARRAYFLT);
data->data = (lua_Number *)t->ravi_array.data;
data->length = t->ravi_array.len;
lua_assert(t->flags & RAVI_ARRAY_ISFLOAT);
data->data = (lua_Number *)t->data;
data->length = t->len;
}
void raviH_get_integer_array_rawdata(lua_State *L, Table *t, Ravi_IntegerArray *data) {
void raviH_get_integer_array_rawdata(lua_State *L, RaviArray *t, Ravi_IntegerArray *data) {
(void)L;
lua_assert(t->ravi_array.array_type == RAVI_TARRAYINT);
data->data = (lua_Integer *)t->ravi_array.data;
data->length = t->ravi_array.len;
lua_assert((t->flags & RAVI_ARRAY_ISFLOAT) == 0);
data->data = (lua_Integer *)t->data;
data->length = t->len;
}
static const char *key_orig_table = "Originaltable";
/* Create a slice of an existing array
* The original table containing the array is inserted into the
* the slice as a value against special key pointer('key_orig_table') so that
* the parent table is not garbage collected while this array contains a
* reference to it
/* Create a slice of an existing array, array must be fixed size.
* The original array is set as the parent of the slice.
* The parent will not be garbage collected while the slice contains a
* reference to it.
* The array slice starts at start but start-1 is also accessible because of the
* implementation having array values starting at 0.
* A slice must not attempt to release the data array as this is not owned by
* it,
* and in fact may point to garbage from a memory allocater's point of view.
*/
Table *raviH_new_slice(lua_State *L, TValue *parent, unsigned int start,
RaviArray *raviH_new_slice(lua_State *L, TValue *parent, unsigned int start,
unsigned int len) {
if (!ttistable(parent) || ttisLtable(parent))
if (!ttisarray(parent))
luaG_runerror(L, "integer[] or number[] expected");
Table *orig = hvalue(parent);
if (!orig->ravi_array.array_modifier)
RaviArray *orig = arrvalue(parent);
if ((orig->flags & RAVI_ARRAY_FIXEDSIZE) == 0)
luaG_runerror(
L, "cannot create slice from dynamic integer[] or number[] array");
/* Create the slice table */
Table *t = raviH_new(L, orig->ravi_array.array_type, 1);
lua_assert(t->ravi_array.data == NULL);
/* Add a reference to the parent table */
TValue k;
setpvalue(&k, (void *)key_orig_table);
TValue *cell = luaH_newkey(L, t, &k);
setobj2t(L, cell, parent);
RaviArray *t = raviH_new(L, (orig->flags & RAVI_ARRAY_ISFLOAT) ? RAVI_TARRAYFLT : RAVI_TARRAYINT, 1);
/* Add a reference to the parent table. From GC perspective the slice is a white object
so we do not need a write barrier */
t->parent = orig;
/* Initialize */
t->ravi_array.array_type = orig->ravi_array.array_type;
t->ravi_array.array_modifier = RAVI_ARRAY_SLICE;
if (ttisfarray(parent)) {
lua_Number *data = (lua_Number *)orig->ravi_array.data;
t->ravi_array.data = (char *)(data + start - 1);
if (orig->flags & RAVI_ARRAY_ISFLOAT) {
lua_Number *data = (lua_Number *)orig->data;
t->data = (char *)(data + start - 1);
}
else {
lua_Integer *data = (lua_Integer *)orig->ravi_array.data;
t->ravi_array.data = (char *)(data + start - 1);
lua_Integer *data = (lua_Integer *)orig->data;
t->data = (char *)(data + start - 1);
}
t->ravi_array.len = len + 1;
t->ravi_array.size = len + 1;
t->len = len + 1;
t->size = len + 1;
return t;
}
/* Obtain parent array of the slice */
const TValue *raviH_slice_parent(lua_State *L, TValue *slice) {
if (!ttistable(slice) || ttisLtable(slice))
luaG_runerror(L, "slice of integer[] or number[] expected");
Table *orig = hvalue(slice);
if (orig->ravi_array.array_modifier != RAVI_ARRAY_SLICE)
luaG_runerror(L, "slice of integer[] or number[] expected");
/* Get reference to the parent table */
TValue k;
setpvalue(&k, (void *)key_orig_table);
const TValue *cell = luaH_get(orig, &k);
lua_assert(ttistable(cell));
return cell;
}
#if defined(LUA_DEBUG)
Node *luaH_mainposition (const Table *t, const TValue *key) {

@ -69,7 +69,11 @@ const TValue *luaT_gettm (Table *events, TMS event, TString *ename) {
const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
Table *mt;
switch (ttnov(o)) {
switch (ttype(o)) {
case RAVI_TIARRAY:
case RAVI_TFARRAY:
mt = arrvalue(o)->metatable;
break;
case LUA_TTABLE:
mt = hvalue(o)->metatable;
break;
@ -89,8 +93,9 @@ const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
*/
const char *luaT_objtypename (lua_State *L, const TValue *o) {
Table *mt;
if ((ttistable(o) && (mt = hvalue(o)->metatable) != NULL) ||
(ttisfulluserdata(o) && (mt = uvalue(o)->metatable) != NULL)) {
if ((ttisLtable(o) && (mt = hvalue(o)->metatable) != NULL) ||
(ttisfulluserdata(o) && (mt = uvalue(o)->metatable) != NULL) ||
(ttisarray(o) && (mt = arrvalue(o)->metatable) != NULL)) {
const TValue *name = luaH_getshortstr(mt, luaS_new(L, "__name"));
if (ttisstring(name)) /* is '__name' a string? */
return getstr(tsvalue(name)); /* use it as type name */
@ -104,8 +109,9 @@ const char *luaT_objtypename (lua_State *L, const TValue *o) {
*/
const char *raviT_objtypename(lua_State *L, const TValue *o) {
Table *mt;
if ((ttistable(o) && (mt = hvalue(o)->metatable) != NULL) ||
(ttisfulluserdata(o) && (mt = uvalue(o)->metatable) != NULL)) {
if ((ttisLtable(o) && (mt = hvalue(o)->metatable) != NULL) ||
(ttisfulluserdata(o) && (mt = uvalue(o)->metatable) != NULL) ||
(ttisarray(o) && (mt = arrvalue(o)->metatable) != NULL)) {
const TValue *name = luaH_getshortstr(mt, luaS_new(L, "__name"));
if (ttisstring(name)) /* is '__name' a string? */
return getstr(tsvalue(name)); /* use it as type name */

@ -281,12 +281,12 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
} \
else if (ttisfarray(t)) { \
if (!ttisinteger(key)) luaG_typeerror(L, key, "index"); \
Table *h = hvalue(t); \
RaviArray *h = arrvalue(t); \
raviH_get_float_inline(L, h, ivalue(key), val); \
} \
else if (ttisiarray(t)) { \
if (!ttisinteger(key)) luaG_typeerror(L, key, "index"); \
Table *h = hvalue(t); \
RaviArray *h = arrvalue(t); \
raviH_get_int_inline(L, h, ivalue(key), val); \
} \
else { \
@ -312,11 +312,11 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
protect(luaV_finishget(L, t, key, val, v)); \
} \
else if (ttisfarray(t)) { \
Table *h = hvalue(t); \
RaviArray *h = arrvalue(t); \
raviH_get_float_inline(L, h, ivalue(key), val); \
} \
else if (ttisiarray(t)) { \
Table *h = hvalue(t); \
RaviArray *h = arrvalue(t); \
raviH_get_int_inline(L, h, ivalue(key), val); \
} \
else { \
@ -365,7 +365,7 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
} \
} \
else if (ttisfarray(t)) { \
Table *h = hvalue(t); \
RaviArray *h = arrvalue(t); \
if (!ttisinteger(key)) luaG_typeerror(L, key, "index"); \
if (ttisfloat(val)) { \
raviH_set_float_inline(L, h, ivalue(key), fltvalue(val)); \
@ -383,7 +383,7 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
} \
} \
else if (ttisiarray(t)) { \
Table *h = hvalue(t); \
RaviArray *h = arrvalue(t); \
if (!ttisinteger(key)) luaG_typeerror(L, key, "index"); \
if (ttisinteger(val)) { \
raviH_set_int_inline(L, h, ivalue(key), ivalue(val)); \
@ -422,7 +422,7 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
} \
} \
else if (ttisfarray(t)) { \
Table *h = hvalue(t); \
RaviArray *h = arrvalue(t); \
if (ttisfloat(val)) { \
raviH_set_float_inline(L, h, ivalue(key), fltvalue(val)); \
} \
@ -439,7 +439,7 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
} \
} \
else if (ttisiarray(t)) { \
Table *h = hvalue(t); \
RaviArray *h = arrvalue(t); \
if (ttisinteger(val)) { \
raviH_set_int_inline(L, h, ivalue(key), ivalue(val)); \
} \
@ -705,7 +705,7 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) {
}
case RAVI_TIARRAY:
case RAVI_TFARRAY: {
if (hvalue(t1) == hvalue(t2)) return 1;
if (arrvalue(t1) == arrvalue(t2)) return 1;
else return 0;
}
case LUA_TTABLE: {
@ -795,7 +795,7 @@ void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
switch (ttype(rb)) {
case RAVI_TIARRAY:
case RAVI_TFARRAY: {
Table *h = hvalue(rb);
RaviArray *h = arrvalue(rb);
setivalue(ra, raviH_getn(h));
return;
}
@ -1143,7 +1143,11 @@ void luaV_finishOp (lua_State *L) {
int raviV_check_usertype(lua_State *L, TString *name, const TValue *o)
{
Table *mt;
switch (ttnov(o)) {
switch (ttype(o)) {
case RAVI_TIARRAY:
case RAVI_TFARRAY:
mt = arrvalue(o)->metatable;
break;
case LUA_TTABLE:
mt = hvalue(o)->metatable;
break;
@ -1863,7 +1867,7 @@ int luaV_execute (lua_State *L) {
vmcase(OP_SETLIST) {
int n = GETARG_B(i);
int c = GETARG_C(i);
#if 1
#if 0
if (c == 0) {
lua_assert(GET_OPCODE(*pc) == OP_EXTRAARG);
c = GETARG_Ax(*pc++);
@ -1872,16 +1876,15 @@ int luaV_execute (lua_State *L) {
raviV_op_setlist(L, ci, ra, n, c);
#else
unsigned int last;
Table *h;
if (n == 0) n = cast_int(L->top - ra) - 1;
if (c == 0) {
lua_assert(GET_OPCODE(*pc) == OP_EXTRAARG);
c = GETARG_Ax(*pc++);
}
h = hvalue(ra);
last = ((c-1)*LFIELDS_PER_FLUSH) + n;
savepc(L); /* in case of allocation errors */
if (h->ravi_array.array_type == RAVI_TTABLE) {
if (ttisLtable(ra)) {
Table* h = hvalue(ra);
if (last > h->sizearray) /* needs more space? */
luaH_resizearray(L, h, last); /* pre-allocate it at once */
for (; n > 0; n--) {
@ -1891,41 +1894,39 @@ int luaV_execute (lua_State *L) {
}
}
else {
RaviArray *h = arrvalue(ra);
int i = last - n + 1;
for (; i <= (int)last; i++) {
TValue *val = ra + i;
unsigned int u = (unsigned int)(i);
switch (h->ravi_array.array_type) {
case RAVI_TARRAYINT: {
if (ttisinteger(val)) {
raviH_set_int_inline(L, h, u, ivalue(val));
if ((h->flags & RAVI_ARRAY_ISFLOAT) == 0) {
if (ttisinteger(val)) {
raviH_set_int_inline(L, h, u, ivalue(val));
}
else {
lua_Integer i = 0;
if (luaV_tointeger_(val, &i)) {
raviH_set_int_inline(L, h, u, i);
}
else {
lua_Integer i = 0;
if (luaV_tointeger_(val, &i)) {
raviH_set_int_inline(L, h, u, i);
}
else
luaG_runerror(L, "value cannot be converted to integer");
}
} break;
case RAVI_TARRAYFLT: {
if (ttisfloat(val)) {
raviH_set_float_inline(L, h, u, fltvalue(val));
}
else if (ttisinteger(val)) {
raviH_set_float_inline(L, h, u, (lua_Number)(ivalue(val)));
}
else {
lua_Number d = 0.0;
if (luaV_tonumber_(val, &d)) {
raviH_set_float_inline(L, h, u, d);
}
else
luaG_runerror(L, "value cannot be converted to number");
else
luaG_runerror(L, "value cannot be converted to integer");
}
}
else {
if (ttisfloat(val)) {
raviH_set_float_inline(L, h, u, fltvalue(val));
}
else if (ttisinteger(val)) {
raviH_set_float_inline(L, h, u, (lua_Number)(ivalue(val)));
}
else {
lua_Number d = 0.0;
if (luaV_tonumber_(val, &d)) {
raviH_set_float_inline(L, h, u, d);
}
} break;
default: lua_assert(0);
else
luaG_runerror(L, "value cannot be converted to number");
}
}
}
}
@ -2110,7 +2111,7 @@ int luaV_execute (lua_State *L) {
vmbreak;
}
vmcase(OP_RAVI_NEW_IARRAY) {
Table *t;
RaviArray *t;
savepc(L); /* in case of allocation errors */
t = raviH_new(L, RAVI_TARRAYINT, 0);
setiarrayvalue(L, ra, t);
@ -2118,7 +2119,7 @@ int luaV_execute (lua_State *L) {
vmbreak;
}
vmcase(OP_RAVI_NEW_FARRAY) {
Table *t;
RaviArray *t;
savepc(L); /* in case of allocation errors */
t = raviH_new(L, RAVI_TARRAYFLT, 0);
setfarrayvalue(L, ra, t);
@ -2199,7 +2200,7 @@ int luaV_execute (lua_State *L) {
TValue *rb = RB(i);
TValue *rc = RKC(i);
lua_Integer idx = ivalue(rc);
Table *t = hvalue(rb);
RaviArray *t = arrvalue(rb);
raviH_get_int_inline(L, t, idx, ra);
vmbreak;
}
@ -2207,12 +2208,12 @@ int luaV_execute (lua_State *L) {
TValue *rb = RB(i);
TValue *rc = RKC(i);
lua_Integer idx = ivalue(rc);
Table *t = hvalue(rb);
RaviArray *t = arrvalue(rb);
raviH_get_float_inline(L, t, idx, ra);
vmbreak;
}
vmcase(OP_RAVI_IARRAY_SET) {
Table *t = hvalue(ra);
RaviArray *t = arrvalue(ra);
TValue *rb = RKB(i);
TValue *rc = RKC(i);
lua_Integer idx = ivalue(rb);
@ -2229,7 +2230,7 @@ int luaV_execute (lua_State *L) {
vmbreak;
}
vmcase(OP_RAVI_IARRAY_SETI) {
Table *t = hvalue(ra);
RaviArray *t = arrvalue(ra);
TValue *rb = RKB(i);
TValue *rc = RKC(i);
lua_Integer idx = ivalue(rb);
@ -2237,7 +2238,7 @@ int luaV_execute (lua_State *L) {
vmbreak;
}
vmcase(OP_RAVI_FARRAY_SET) {
Table *t = hvalue(ra);
RaviArray *t = arrvalue(ra);
TValue *rb = RKB(i);
TValue *rc = RKC(i);
lua_Integer idx = ivalue(rb);
@ -2254,7 +2255,7 @@ int luaV_execute (lua_State *L) {
vmbreak;
}
vmcase(OP_RAVI_FARRAY_SETF) {
Table *t = hvalue(ra);
RaviArray *t = arrvalue(ra);
TValue *rb = RKB(i);
TValue *rc = RKC(i);
lua_Integer idx = ivalue(rb);
@ -2692,13 +2693,13 @@ void raviV_debug_trace(lua_State *L, int opCode, int pc) {
}
void raviV_op_newarrayint(lua_State *L, CallInfo *ci, TValue *ra) {
Table *t = raviH_new(L, RAVI_TARRAYINT, 0);
RaviArray *t = raviH_new(L, RAVI_TARRAYINT, 0);
setiarrayvalue(L, ra, t);
checkGC_(L, ra + 1);
}
void raviV_op_newarrayfloat(lua_State *L, CallInfo *ci, TValue *ra) {
Table *t = raviH_new(L, RAVI_TARRAYFLT, 0);
RaviArray *t = raviH_new(L, RAVI_TARRAYFLT, 0);
setfarrayvalue(L, ra, t);
checkGC_(L, ra + 1);
}
@ -2713,11 +2714,11 @@ void raviV_op_newtable(lua_State *L, CallInfo *ci, TValue *ra, int b, int c) {
void raviV_op_setlist(lua_State *L, CallInfo *ci, TValue *ra, int b, int c) {
int n = b;
unsigned int last;
Table *h;
if (n == 0) n = cast_int(L->top - ra) - 1;
h = hvalue(ra);
if (n == 0)
n = cast_int(L->top - ra) - 1;
last = ((c - 1) * LFIELDS_PER_FLUSH) + n;
if (h->ravi_array.array_type == RAVI_TTABLE) {
if (ttisLtable(ra)) {
Table *h = hvalue(ra);
if (last > h->sizearray) /* needs more space? */
luaH_resizearray(L, h, last); /* pre-allocate it at once */
for (; n > 0; n--) {
@ -2727,35 +2728,39 @@ void raviV_op_setlist(lua_State *L, CallInfo *ci, TValue *ra, int b, int c) {
}
}
else {
RaviArray *h = arrvalue(ra);
int i = last - n + 1;
for (; i <= (int)last; i++) {
TValue *val = ra + i;
unsigned int u = (unsigned int)(i);
switch (h->ravi_array.array_type) {
case RAVI_TARRAYINT: {
if (ttisinteger(val)) { raviH_set_int_inline(L, h, u, ivalue(val)); }
else {
lua_Integer i = 0;
if (luaV_tointeger_(val, &i)) { raviH_set_int_inline(L, h, u, i); }
else
luaG_runerror(L, "value cannot be converted to integer");
}
} break;
case RAVI_TARRAYFLT: {
if (ttisfloat(val)) {
raviH_set_float_inline(L, h, u, fltvalue(val));
}
else if (ttisinteger(val)) {
raviH_set_float_inline(L, h, u, (lua_Number)(ivalue(val)));
if ((h->flags & RAVI_ARRAY_ISFLOAT) == 0) {
if (ttisinteger(val)) {
raviH_set_int_inline(L, h, u, ivalue(val));
}
else {
lua_Integer i = 0;
if (luaV_tointeger_(val, &i)) {
raviH_set_int_inline(L, h, u, i);
}
else {
lua_Number d = 0.0;
if (luaV_tonumber_(val, &d)) { raviH_set_float_inline(L, h, u, d); }
else
luaG_runerror(L, "value cannot be converted to number");
else
luaG_runerror(L, "value cannot be converted to integer");
}
}
else {
if (ttisfloat(val)) {
raviH_set_float_inline(L, h, u, fltvalue(val));
}
else if (ttisinteger(val)) {
raviH_set_float_inline(L, h, u, (lua_Number)(ivalue(val)));
}
else {
lua_Number d = 0.0;
if (luaV_tonumber_(val, &d)) {
raviH_set_float_inline(L, h, u, d);
}
} break;
default: lua_assert(0);
else
luaG_runerror(L, "value cannot be converted to number");
}
}
}
}

@ -34,7 +34,6 @@
*/
static const char Lua_header[] =
""
//"#ifndef __SIZE_TYPE__\n"
//"#define __SIZE_TYPE__ long long\n"
//"#endif\n"
@ -153,6 +152,7 @@ static const char Lua_header[] =
"#define ttistable(o) checktype((o), LUA_TTABLE)\n"
"#define ttisiarray(o) checktag((o), ctb(RAVI_TIARRAY))\n"
"#define ttisfarray(o) checktag((o), ctb(RAVI_TFARRAY))\n"
"#define ttisarray(o) (ttisiarray(o) || ttisfarray(o))\n"
"#define ttisLtable(o) checktag((o), ctb(LUA_TTABLE))\n"
"#define ttisfunction(o) checktype(o, LUA_TFUNCTION)\n"
"#define ttisclosure(o) ((rttype(o) & 0x1F) == LUA_TFUNCTION)\n"
@ -177,6 +177,8 @@ static const char Lua_header[] =
"#define fvalue(o) check_exp(ttislcf(o), val_(o).f)\n"
"#define fcfvalue(o) check_exp(ttisfcf(o), val_(o).p)\n"
"#define hvalue(o) check_exp(ttistable(o), gco2t(val_(o).gc))\n"
"#define arrvalue(o) check_exp(ttisarray(o), gco2array(val_(o).gc))\n"
"#define arrvalue(o) check_exp(ttisarray(o), gco2array(val_(o).gc))\n"
"#define bvalue(o) check_exp(ttisboolean(o), val_(o).b)\n"
"#define thvalue(o) check_exp(ttisthread(o), gco2th(val_(o).gc))\n"
"#define deadvalue(o) check_exp(ttisdeadkey(o), cast(void *, val_(o).gc))\n"
@ -402,30 +404,38 @@ static const char Lua_header[] =
" TKey i_key;\n"
"} Node;\n"
"typedef enum RaviArrayModifer {\n"
" RAVI_ARRAY_SLICE = 1,\n"
" RAVI_ARRAY_FIXEDSIZE = 2\n"
" RAVI_ARRAY_SLICE = 1,\n"
" RAVI_ARRAY_FIXEDSIZE = 2,\n"
" RAVI_ARRAY_ALLOCATED = 4,\n"
" RAVI_ARRAY_ISFLOAT = 8\n"
"} RaviArrayModifier;\n"
"enum {\n"
" RAVI_ARRAY_MAX_INLINE = 3,\n"
"};\n"
"typedef struct RaviArray {\n"
" char *data;\n"
" unsigned int len;\n"
" unsigned int size;\n"
" lu_byte array_type;\n"
" lu_byte array_modifier;\n"
" CommonHeader;\n"
" lu_byte flags;\n"
" unsigned int len;\n"
" unsigned int size;\n"
" union {\n"
" lua_Number numarray[RAVI_ARRAY_MAX_INLINE];\n"
" lua_Integer intarray[RAVI_ARRAY_MAX_INLINE];\n"
" struct RaviArray* parent;\n"
" };\n"
" char *data;\n"
" struct Table *metatable;\n"
"} RaviArray;\n"
"typedef struct Table {\n"
" CommonHeader;\n"
" lu_byte flags;\n"
" lu_byte lsizenode;\n"
" unsigned int sizearray;\n"
" TValue *array;\n"
" Node *node;\n"
" Node *lastfree;\n"
" struct Table *metatable;\n"
" GCObject *gclist;\n"
" RaviArray ravi_array;\n"
#if RAVI_USE_NEWHASH
" unsigned int hmask;\n"
#endif
" CommonHeader;\n"
" lu_byte flags;\n"
" lu_byte lsizenode;\n"
" unsigned int sizearray;\n"
" TValue *array;\n"
" Node *node;\n"
" Node *lastfree;\n"
" struct Table *metatable;\n"
" GCObject *gclist;\n"
" unsigned int hmask;\n"
"} Table;\n"
"typedef struct Mbuffer {\n"
" char *buffer;\n"
@ -512,6 +522,7 @@ static const char Lua_header[] =
" struct Udata u;\n"
" union Closure cl;\n"
" struct Table h;\n"
" struct RaviArray arr;\n"
" struct Proto p;\n"
" struct lua_State th;\n"
"};\n"
@ -539,7 +550,8 @@ static const char Lua_header[] =
"#define gco2ccl(o) check_exp((o)->tt == LUA_TCCL, &((cast_u(o))->cl.c))\n"
"#define gco2cl(o) \\\n"
" check_exp(novariant((o)->tt) == LUA_TFUNCTION, &((cast_u(o))->cl))\n"
"#define gco2t(o) check_exp(novariant((o)->tt) == LUA_TTABLE, &((cast_u(o))->h))\n"
"#define gco2t(o) check_exp((o)->tt == LUA_TTABLE, &((cast_u(o))->h))\n"
"#define gco2array(o) check_exp(((o)->tt == RAVI_TIARRAY || (o)->tt == RAVI_TFARRAY), &((cast_u(o))->arr))\n"
"#define gco2p(o) check_exp((o)->tt == LUA_TPROTO, &((cast_u(o))->p))\n"
"#define gco2th(o) check_exp((o)->tt == LUA_TTHREAD, &((cast_u(o))->th))\n"
"#define obj2gco(v) \\\n"
@ -583,8 +595,8 @@ static const char Lua_header[] =
"extern void raise_error(lua_State *L, int errorcode);\n"
"extern void raise_error_with_info(lua_State *L, int errorcode, const char *info);\n"
"extern void luaD_call (lua_State *L, StkId func, int nResults);\n"
"extern void raviH_set_int(lua_State *L, Table *t, lua_Unsigned key, lua_Integer value);\n"
"extern void raviH_set_float(lua_State *L, Table *t, lua_Unsigned key, lua_Number value);\n"
"extern void raviH_set_int(lua_State *L, RaviArray *t, lua_Unsigned key, lua_Integer value);\n"
"extern void raviH_set_float(lua_State *L, RaviArray *t, lua_Unsigned key, lua_Number value);\n"
"extern int raviV_check_usertype(lua_State *L, TString *name, const TValue *o);\n"
"extern void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, TValue *res, TMS event);\n"
"extern void raviV_gettable_sskey(lua_State *L, const TValue *t, TValue *key, TValue *val);\n"
@ -699,10 +711,10 @@ static void emit_IARRAY_GET(struct function *fn, int A, int B, int C, bool omitA
emit_reg(fn, "rb", B);
emit_reg_or_k(fn, "rc", C);
membuff_add_string(&fn->body, "ukey = (lua_Unsigned)(ivalue(rc));\n");
membuff_add_string(&fn->body, "t = hvalue(rb);");
membuff_add_string(&fn->body, "iptr = (lua_Integer *)t->ravi_array.data;\n");
membuff_add_string(&fn->body, "t = arrvalue(rb);");
membuff_add_string(&fn->body, "iptr = (lua_Integer *)t->data;\n");
if (!omitArrayGetRangeCheck) {
membuff_add_string(&fn->body, "if (ukey < (lua_Unsigned)(t->ravi_array.len)) {\n");
membuff_add_string(&fn->body, "if (ukey < (lua_Unsigned)(t->len)) {\n");
}
membuff_add_string(&fn->body, " setivalue(ra, iptr[ukey]);\n");
if (!omitArrayGetRangeCheck) {
@ -723,10 +735,10 @@ static void emit_FARRAY_GET(struct function *fn, int A, int B, int C, bool omitA
emit_reg(fn, "rb", B);
emit_reg_or_k(fn, "rc", C);
membuff_add_string(&fn->body, "ukey = (lua_Unsigned)(ivalue(rc));\n");
membuff_add_string(&fn->body, "t = hvalue(rb);");
membuff_add_string(&fn->body, "nptr = (lua_Number *)t->ravi_array.data;\n");
membuff_add_string(&fn->body, "t = arrvalue(rb);");
membuff_add_string(&fn->body, "nptr = (lua_Number *)t->data;\n");
if (!omitArrayGetRangeCheck) {
membuff_add_string(&fn->body, "if (ukey < (lua_Unsigned)(t->ravi_array.len)) {\n");
membuff_add_string(&fn->body, "if (ukey < (lua_Unsigned)(t->len)) {\n");
}
membuff_add_string(&fn->body, " setfltvalue(ra, nptr[ukey]);\n");
if (!omitArrayGetRangeCheck) {
@ -747,10 +759,10 @@ static void emit_IARRAY_SETI(struct function *fn, int A, int B, int C, bool know
emit_reg(fn, "ra", A);
emit_reg_or_k(fn, "rb", B);
emit_reg_or_k(fn, "rc", C);
membuff_add_string(&fn->body, "t = hvalue(ra);\n");
membuff_add_string(&fn->body, "t = arrvalue(ra);\n");
membuff_add_string(&fn->body, "ukey = (lua_Unsigned)(ivalue(rb));\n");
membuff_add_string(&fn->body, "iptr = (lua_Integer *)t->ravi_array.data;\n");
membuff_add_string(&fn->body, "if (ukey < (lua_Unsigned)(t->ravi_array.len)) {\n");
membuff_add_string(&fn->body, "iptr = (lua_Integer *)t->data;\n");
membuff_add_string(&fn->body, "if (ukey < (lua_Unsigned)(t->len)) {\n");
membuff_add_string(&fn->body, " iptr[ukey] = ivalue(rc);\n");
membuff_add_string(&fn->body, "} else {\n");
membuff_add_fstring(&fn->body, " raviH_set_int(L, t, ukey, ivalue(rc));\n");
@ -763,9 +775,9 @@ static void emit_IARRAY_SET(struct function *fn, int A, int B, int C, bool known
emit_reg(fn, "ra", A);
emit_reg_or_k(fn, "rb", B);
emit_reg_or_k(fn, "rc", C);
membuff_add_string(&fn->body, "t = hvalue(ra);\n");
membuff_add_string(&fn->body, "t = arrvalue(ra);\n");
membuff_add_string(&fn->body, "ukey = (lua_Unsigned)(ivalue(rb));\n");
membuff_add_string(&fn->body, "iptr = (lua_Integer *)t->ravi_array.data;\n");
membuff_add_string(&fn->body, "iptr = (lua_Integer *)t->data;\n");
membuff_add_string(&fn->body, "if (!ttisinteger(rc)) {\n");
#if GOTO_ON_ERROR
membuff_add_fstring(&fn->body, " error_code = %d;\n", Error_integer_expected);
@ -775,7 +787,7 @@ static void emit_IARRAY_SET(struct function *fn, int A, int B, int C, bool known
#endif
membuff_add_string(&fn->body, "}\n");
membuff_add_string(&fn->body, "i = ivalue(rc);\n");
membuff_add_string(&fn->body, "if (ukey < (lua_Unsigned)(t->ravi_array.len)) {\n");
membuff_add_string(&fn->body, "if (ukey < (lua_Unsigned)(t->len)) {\n");
membuff_add_string(&fn->body, " iptr[ukey] = i;\n");
membuff_add_string(&fn->body, "} else {\n");
membuff_add_fstring(&fn->body, " raviH_set_int(L, t, ukey, i);\n");
@ -788,10 +800,10 @@ static void emit_FARRAY_SETF(struct function *fn, int A, int B, int C, bool know
emit_reg(fn, "ra", A);
emit_reg_or_k(fn, "rb", B);
emit_reg_or_k(fn, "rc", C);
membuff_add_string(&fn->body, "t = hvalue(ra);\n");
membuff_add_string(&fn->body, "t = arrvalue(ra);\n");
membuff_add_string(&fn->body, "ukey = (lua_Unsigned)(ivalue(rb));\n");
membuff_add_string(&fn->body, "nptr = (lua_Number *)t->ravi_array.data;\n");
membuff_add_string(&fn->body, "if (ukey < (lua_Unsigned)(t->ravi_array.len)) {\n");
membuff_add_string(&fn->body, "nptr = (lua_Number *)t->data;\n");
membuff_add_string(&fn->body, "if (ukey < (lua_Unsigned)(t->len)) {\n");
membuff_add_string(&fn->body, " nptr[ukey] = fltvalue(rc);\n");
membuff_add_string(&fn->body, "} else {\n");
membuff_add_fstring(&fn->body, " raviH_set_float(L, t, ukey, fltvalue(rc));\n");
@ -804,9 +816,9 @@ static void emit_FARRAY_SET(struct function *fn, int A, int B, int C, bool known
emit_reg(fn, "ra", A);
emit_reg_or_k(fn, "rb", B);
emit_reg_or_k(fn, "rc", C);
membuff_add_string(&fn->body, "t = hvalue(ra);\n");
membuff_add_string(&fn->body, "t = arrvalue(ra);\n");
membuff_add_string(&fn->body, "ukey = (lua_Unsigned)(ivalue(rb));\n");
membuff_add_string(&fn->body, "nptr = (lua_Number *)t->ravi_array.data;\n");
membuff_add_string(&fn->body, "nptr = (lua_Number *)t->data;\n");
membuff_add_string(&fn->body, "if (!ttisnumber(rc)) {\n");
#if GOTO_ON_ERROR
membuff_add_fstring(&fn->body, " error_code = %d;\n", Error_number_expected);
@ -816,7 +828,7 @@ static void emit_FARRAY_SET(struct function *fn, int A, int B, int C, bool known
#endif
membuff_add_string(&fn->body, "}\n");
membuff_add_string(&fn->body, "n = (ttisinteger(rc) ? (double)ivalue(rc) : fltvalue(rc));\n");
membuff_add_string(&fn->body, "if (ukey < (lua_Unsigned)(t->ravi_array.len)) {\n");
membuff_add_string(&fn->body, "if (ukey < (lua_Unsigned)(t->len)) {\n");
membuff_add_string(&fn->body, " nptr[ukey] = n;\n");
membuff_add_string(&fn->body, "} else {\n");
membuff_add_fstring(&fn->body, " raviH_set_float(L, t, ukey, n);\n");
@ -1191,7 +1203,7 @@ static void initfn(struct function *fn, struct lua_State *L, struct Proto *p, co
membuff_add_string(&fn->prologue, "lua_Unsigned ukey = 0;\n");
membuff_add_string(&fn->prologue, "lua_Integer *iptr = NULL;\n");
membuff_add_string(&fn->prologue, "lua_Number *nptr = NULL;\n");
membuff_add_string(&fn->prologue, "Table *t = NULL;\n");
membuff_add_string(&fn->prologue, "RaviArray *t = NULL;\n");
// TODO we never set this???
// ci->callstatus |= CIST_FRESH; /* fresh invocation of 'luaV_execute" */
// lua_assert(ci == L->ci);

@ -345,6 +345,15 @@ llvm::Instruction *RaviCodeGenerator::emit_load_reg_h(RaviFunctionDef *def,
return h;
}
// emit code to load the RaviArray value from register (TValue)
llvm::Instruction* RaviCodeGenerator::emit_load_reg_arr(RaviFunctionDef* def,
llvm::Value* rb) {
llvm::Value* rb_h = def->builder->CreateBitCast(rb, def->types->ppRaviArrayT);
llvm::Instruction* h = def->builder->CreateLoad(rb_h);
h->setMetadata(llvm::LLVMContext::MD_tbaa, def->types->tbaa_TValue_hT);
return h;
}
// Gets the size of the hash table
// This is the sizenode() macro in lobject.h
llvm::Value *RaviCodeGenerator::emit_table_get_hashsize(RaviFunctionDef *def,
@ -370,7 +379,7 @@ llvm::Value *RaviCodeGenerator::emit_table_get_hashstr(RaviFunctionDef *def,
TString *key) {
#if RAVI_USE_NEWHASH
unsigned int hash = key->hash;
llvm::Value *hmask_ptr = emit_gep(def, "hmask", table, 0, 12);
llvm::Value *hmask_ptr = emit_gep(def, "hmask", table, 0, 11);
llvm::Instruction *hmask = def->builder->CreateLoad(hmask_ptr);
hmask->setMetadata(llvm::LLVMContext::MD_tbaa, def->types->tbaa_Table_hmask);
llvm::Value *offset = def->builder->CreateAnd(
@ -462,9 +471,10 @@ llvm::Instruction *RaviCodeGenerator::emit_load_reg_s(RaviFunctionDef *def,
return s;
}
/* Loads the data pointer as lua_Number[] from a RaviArray object */
llvm::Instruction *RaviCodeGenerator::emit_load_reg_h_floatarray(
RaviFunctionDef *def, llvm::Instruction *h) {
llvm::Value *data_ptr = emit_gep(def, "data_ptr", h, 0, 11, 0);
llvm::Value *data_ptr = emit_gep(def, "data_ptr", h, 0, 7);
llvm::Value *darray_ptr =
def->builder->CreateBitCast(data_ptr, def->types->pplua_NumberT);
llvm::Instruction *darray = def->builder->CreateLoad(darray_ptr);
@ -473,9 +483,10 @@ llvm::Instruction *RaviCodeGenerator::emit_load_reg_h_floatarray(
return darray;
}
/* Loads the data pointer as lua_Integer[] from a RaviArray object */
llvm::Instruction *RaviCodeGenerator::emit_load_reg_h_intarray(
RaviFunctionDef *def, llvm::Instruction *h) {
llvm::Value *data_ptr = emit_gep(def, "data_ptr", h, 0, 11, 0);
llvm::Value *data_ptr = emit_gep(def, "data_ptr", h, 0, 7);
llvm::Value *darray_ptr =
def->builder->CreateBitCast(data_ptr, def->types->pplua_IntegerT);
llvm::Instruction *darray = def->builder->CreateLoad(darray_ptr);
@ -580,17 +591,21 @@ llvm::Value *RaviCodeGenerator::emit_is_not_value_of_type_class(
llvm::ConstantInt::get(def->types->lua_LuaTypeT, lua_type), varname);
}
llvm::Instruction *RaviCodeGenerator::emit_load_ravi_arraytype(
RaviFunctionDef *def, llvm::Value *value) {
llvm::Value *tt_ptr = emit_gep(def, "raviarray.type_ptr", value, 0, 11, 3);
llvm::Instruction *tt = def->builder->CreateLoad(tt_ptr, "raviarray.type");
tt->setMetadata(llvm::LLVMContext::MD_tbaa, def->types->tbaa_RaviArray_typeT);
return tt;
}
/* This loads the RaviArray type value from the tt field maintained in the
GC part. However this tt is 8-bit value and needs to be converted to
the 16-bit value used in TValue objects */
//llvm::Instruction *RaviCodeGenerator::emit_load_ravi_arraytype(
// RaviFunctionDef *def, llvm::Value *value) {
// llvm::Value *tt_ptr = emit_gep(def, "raviarray.type_ptr", value, 0, 1);
// llvm::Instruction *tt = def->builder->CreateLoad(tt_ptr, "raviarray.type");
// // FIXME promote to 16 bit and set collectible bit
// tt->setMetadata(llvm::LLVMContext::MD_tbaa, def->types->tbaa_RaviArray_typeT);
// return tt;
//}
llvm::Instruction *RaviCodeGenerator::emit_load_ravi_arraylength(
RaviFunctionDef *def, llvm::Value *value) {
llvm::Value *tt_ptr = emit_gep(def, "raviarray.len_ptr", value, 0, 11, 1);
llvm::Value *tt_ptr = emit_gep(def, "raviarray.len_ptr", value, 0, 4);
llvm::Instruction *tt = def->builder->CreateLoad(tt_ptr, "raviarray.len");
tt->setMetadata(llvm::LLVMContext::MD_tbaa, def->types->tbaa_RaviArray_lenT);
return tt;

@ -477,8 +477,8 @@ void RaviCodeGenerator::emit_FARRAY_GET(RaviFunctionDef *def, int A, int B,
int pc) {
//#define raviH_get_float_inline(L, t, key, v)
//{ unsigned ukey = (unsigned)((key));
// lua_Number *data = (lua_Number *)t->ravi_array.data;
// if (ukey < t->ravi_array.len) {
// lua_Number *data = (lua_Number *)t->data;
// if (ukey < t->len) {
// setfltvalue(v, data[ukey]);
// }else
// luaG_runerror(L, "array out of bounds");
@ -496,7 +496,7 @@ void RaviCodeGenerator::emit_FARRAY_GET(RaviFunctionDef *def, int A, int B,
llvm::Value *rb = emit_gep_register(def, B);
llvm::Value *rc = emit_gep_register_or_constant(def, C);
llvm::Instruction *key = emit_load_reg_i(def, rc);
llvm::Instruction *t = emit_load_reg_h(def, rb);
llvm::Instruction *t = emit_load_reg_arr(def, rb);
llvm::Instruction *data = emit_load_reg_h_floatarray(def, t);
llvm::BasicBlock *then_block = nullptr;
llvm::BasicBlock *else_block = nullptr;
@ -541,8 +541,8 @@ void RaviCodeGenerator::emit_IARRAY_GET(RaviFunctionDef *def, int A, int B,
int pc) {
//#define raviH_get_int_inline(L, t, key, v)
//{ unsigned ukey = (unsigned)((key));
// lua_Integer *data = (lua_Integer *)t->ravi_array.data;
// if (ukey < t->ravi_array.len) {
// lua_Integer *data = (lua_Integer *)t->data;
// if (ukey < t->len) {
// setivalue(v, data[ukey]);
// } else
// luaG_runerror(L, "array out of bounds");
@ -560,7 +560,7 @@ void RaviCodeGenerator::emit_IARRAY_GET(RaviFunctionDef *def, int A, int B,
llvm::Value *rb = emit_gep_register(def, B);
llvm::Value *rc = emit_gep_register_or_constant(def, C);
llvm::Instruction *key = emit_load_reg_i(def, rc);
llvm::Instruction *t = emit_load_reg_h(def, rb);
llvm::Instruction *t = emit_load_reg_arr(def, rb);
llvm::Instruction *data = emit_load_reg_h_intarray(def, t);
llvm::BasicBlock *then_block = nullptr;
@ -605,8 +605,8 @@ void RaviCodeGenerator::emit_IARRAY_SET(RaviFunctionDef *def, int A, int B,
int C, bool known_int, int pc) {
//#define raviH_set_int_inline(L, t, key, value)
//{ unsigned ukey = (unsigned)((key));
// lua_Integer *data = (lua_Integer *)t->ravi_array.data;
// if (ukey < t->ravi_array.len) {
// lua_Integer *data = (lua_Integer *)t->data;
// if (ukey < t->len) {
// data[ukey] = value;
// } else
// raviH_set_int(L, t, ukey, value);
@ -628,7 +628,7 @@ void RaviCodeGenerator::emit_IARRAY_SET(RaviFunctionDef *def, int A, int B,
llvm::Instruction *key = emit_load_reg_i(def, rb);
llvm::Instruction *value =
known_int ? emit_load_reg_i(def, rc) : emit_tointeger(def, rc);
llvm::Instruction *t = emit_load_reg_h(def, ra);
llvm::Instruction *t = emit_load_reg_arr(def, ra);
llvm::Instruction *data = emit_load_reg_h_intarray(def, t);
llvm::Instruction *len = emit_load_ravi_arraylength(def, t);
llvm::Value *ulen =
@ -665,8 +665,8 @@ void RaviCodeGenerator::emit_FARRAY_SET(RaviFunctionDef *def, int A, int B,
int C, bool known_float, int pc) {
//#define raviH_set_float_inline(L, t, key, value)
//{ unsigned ukey = (unsigned)((key));
// lua_Number *data = (lua_Number *)t->ravi_array.data;
// if (ukey < t->ravi_array.len) {
// lua_Number *data = (lua_Number *)t->data;
// if (ukey < t->len) {
// data[ukey] = value;
// } else
// raviH_set_float(L, t, ukey, value);
@ -692,7 +692,7 @@ void RaviCodeGenerator::emit_FARRAY_SET(RaviFunctionDef *def, int A, int B,
llvm::Instruction *key = emit_load_reg_i(def, rb);
llvm::Instruction *value =
known_float ? emit_load_reg_n(def, rc) : emit_tofloat(def, rc);
llvm::Instruction *t = emit_load_reg_h(def, ra);
llvm::Instruction *t = emit_load_reg_arr(def, ra);
llvm::Instruction *data = emit_load_reg_h_floatarray(def, t);
llvm::Instruction *len = emit_load_ravi_arraylength(def, t);
llvm::Value *ulen =

@ -446,22 +446,32 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
NodeT->setBody(elements);
pNodeT = llvm::PointerType::get(NodeT, 0);
// typedef struct RaviArray {
// char *data;
// unsigned int len; /* RAVI len specialization */
// 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;
//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;
//}
RaviArrayT = llvm::StructType::create(context, "struct.RaviArray");
elements.clear();
elements.push_back(C_pcharT);
elements.push_back(C_intT);
elements.push_back(C_intT);
elements.push_back(lu_byteT);
elements.push_back(lu_byteT);
addCommonGCHeader(elements);
elements.push_back(lu_byteT); /* flags */
elements.push_back(C_intT); /* len - 4 */
elements.push_back(C_intT); /* size */
elements.push_back(llvm::ArrayType::get(lua_NumberT, RAVI_ARRAY_MAX_INLINE)); /* numarray: Assumption: lua_Number and lua_Integer have same size */
elements.push_back(C_pcharT); /* data - 7 */
elements.push_back(pTableT); /* metatable*/
RaviArrayT->setBody(elements);
pRaviArrayT = llvm::PointerType::get(RaviArrayT, 0);
ppRaviArrayT = llvm::PointerType::get(pRaviArrayT, 0);
// typedef struct Table {
// CommonHeader;
@ -473,7 +483,6 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
// Node *lastfree; /* any free position is before this position */
// struct Table *metatable;
// GCObject *gclist;
// RaviArray ravi_array;
// unsigned int hmask; /* Hash part mask (size of hash part - 1) */
//} Table;
elements.clear();
@ -486,7 +495,6 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
elements.push_back(pNodeT); /* lastfree */
elements.push_back(pTableT); /* metatable */
elements.push_back(pGCObjectT); /* gclist */
elements.push_back(RaviArrayT); /* RaviArray */
#if RAVI_USE_NEWHASH
elements.push_back(C_intT); /* hmask */
#endif
@ -999,21 +1007,21 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
elements.push_back(pTStringT);
luaH_getstrT = llvm::FunctionType::get(pTValueT, elements, false);
// void raviH_set_int(lua_State *L, Table *t, lua_Unsigned key, lua_Integer
// void raviH_set_int(lua_State *L, RaviArray *t, lua_Unsigned key, lua_Integer
// value);
elements.clear();
elements.push_back(plua_StateT);
elements.push_back(pTableT);
elements.push_back(pRaviArrayT);
elements.push_back(lua_UnsignedT);
elements.push_back(lua_IntegerT);
raviH_set_intT =
llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false);
// void raviH_set_float(lua_State *L, Table *t, lua_Unsigned key, lua_Number
// void raviH_set_float(lua_State *L, RaviArray *t, lua_Unsigned key, lua_Number
// value);
elements.clear();
elements.push_back(plua_StateT);
elements.push_back(pTableT);
elements.push_back(pRaviArrayT);
elements.push_back(lua_UnsignedT);
elements.push_back(lua_NumberT);
raviH_set_floatT =
@ -1295,16 +1303,17 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
mdbuilder.createTBAAStructTagNode(tbaa_UpValT, tbaa_pointerT, 0);
// RaviArray
// !{!"RaviArray", !5, i64 0, !6, i64 4, !6, i64 5, !6, i64 6, !11, i64 8, !11, i64 12, !6, i64 16, !5, i64 40, !5, i64 44}
nodes.clear();
nodes.push_back(
std::pair<llvm::MDNode *, uint64_t>(tbaa_pointerT, 0)); /* data */
nodes.push_back(std::pair<llvm::MDNode *, uint64_t>(tbaa_intT, 4)); /* len */
nodes.push_back(std::pair<llvm::MDNode *, uint64_t>(tbaa_intT, 8)); /* size */
nodes.push_back(
std::pair<llvm::MDNode *, uint64_t>(tbaa_charT, 12)); /* type */
nodes.push_back(
std::pair<llvm::MDNode *, uint64_t>(tbaa_charT, 13)); /* modifiers */
nodes.push_back(std::pair<llvm::MDNode *, uint64_t>(tbaa_pointerT, 0)); /* next */
nodes.push_back(std::pair<llvm::MDNode *, uint64_t>(tbaa_charT, 4)); /* tt */
nodes.push_back(std::pair<llvm::MDNode *, uint64_t>(tbaa_charT, 5)); /* marked */
nodes.push_back(std::pair<llvm::MDNode *, uint64_t>(tbaa_charT, 6)); /* flags */
nodes.push_back(std::pair<llvm::MDNode *, uint64_t>(tbaa_intT, 8)); /* len */
nodes.push_back(std::pair<llvm::MDNode *, uint64_t>(tbaa_intT, 12)); /* size */
nodes.push_back(std::pair<llvm::MDNode *, uint64_t>(tbaa_charT, 16)); /* numarray */
nodes.push_back(std::pair<llvm::MDNode *, uint64_t>(tbaa_pointerT, 40)); /* data */
nodes.push_back(std::pair<llvm::MDNode *, uint64_t>(tbaa_pointerT, 44)); /* metatable */
tbaa_RaviArrayT = mdbuilder.createTBAAStructTypeNode("RaviArray", nodes);
// Table TBAA struct type
@ -1330,11 +1339,9 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
std::pair<llvm::MDNode *, uint64_t>(tbaa_pointerT, 24)); /* metatable */
nodes.push_back(
std::pair<llvm::MDNode *, uint64_t>(tbaa_pointerT, 28)); /* gclist */
nodes.push_back(std::pair<llvm::MDNode *, uint64_t>(tbaa_RaviArrayT,
32)); /* ravi_array */
#if RAVI_USE_NEWHASH
nodes.push_back(
std::pair<llvm::MDNode *, uint64_t>(tbaa_intT, 48)); /* hmask */
std::pair<llvm::MDNode *, uint64_t>(tbaa_intT, 32)); /* hmask */
#endif
tbaa_TableT = mdbuilder.createTBAAStructTypeNode("Table", nodes);
@ -1350,16 +1357,17 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
mdbuilder.createTBAAStructTagNode(tbaa_TableT, tbaa_pointerT, 16);
tbaa_Table_metatable =
mdbuilder.createTBAAStructTagNode(tbaa_TableT, tbaa_pointerT, 24);
tbaa_RaviArray_dataT =
mdbuilder.createTBAAStructTagNode(tbaa_TableT, tbaa_pointerT, 32);
tbaa_RaviArray_lenT =
mdbuilder.createTBAAStructTagNode(tbaa_TableT, tbaa_intT, 36);
tbaa_RaviArray_typeT =
mdbuilder.createTBAAStructTagNode(tbaa_TableT, tbaa_charT, 44);
#if RAVI_USE_NEWHASH
tbaa_Table_hmask =
mdbuilder.createTBAAStructTagNode(tbaa_TableT, tbaa_intT, 48);
mdbuilder.createTBAAStructTagNode(tbaa_TableT, tbaa_intT, 32);
#endif
tbaa_RaviArray_dataT =
mdbuilder.createTBAAStructTagNode(tbaa_RaviArrayT, tbaa_pointerT, 40);
tbaa_RaviArray_lenT =
mdbuilder.createTBAAStructTagNode(tbaa_RaviArrayT, tbaa_intT, 8);
tbaa_RaviArray_typeT =
mdbuilder.createTBAAStructTagNode(tbaa_RaviArrayT, tbaa_charT, 4);
}
void LuaLLVMTypes::dump() {

Loading…
Cancel
Save