issue #99 Use dedicated structure for Ravi array types

arrays
Dibyendu Majumdar 4 years ago
parent eb3d9ca72d
commit 4b34875605

@ -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,52 @@ 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);
LUAI_FUNC int raviH_getn(RaviArray *t);
/* 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);
LUAI_FUNC const RaviArray *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 +179,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 +190,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 +201,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

@ -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 */
@ -782,53 +768,62 @@ int luaH_getn (Table *t) {
}
/* RAVI array specialization */
int raviH_getn(Table *t) {
lua_assert(t->ravi_array.array_type != RAVI_TTABLE);
return t->ravi_array.len - 1;
int raviH_getn(RaviArray *t) {
return t->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 +835,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,106 +858,94 @@ 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);
RaviArray *t = raviH_new(L, (orig->flags & RAVI_ARRAY_ISFLOAT) ? RAVI_TARRAYFLT : RAVI_TARRAYINT, 1);
/* 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);
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))
const RaviArray *raviH_slice_parent(lua_State *L, TValue *slice) {
if (!ttisarray(slice))
luaG_runerror(L, "slice of integer[] or number[] expected");
Table *orig = hvalue(slice);
if (orig->ravi_array.array_modifier != RAVI_ARRAY_SLICE)
RaviArray *orig = arrvalue(slice);
if ((orig->flags & RAVI_ARRAY_SLICE) == 0)
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;
//TODO do a liveness check here
return orig->parent;
}
#if defined(LUA_DEBUG)

@ -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");
}
}
}
}

@ -153,6 +153,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 +178,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 +405,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"
@ -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);

Loading…
Cancel
Save