change GETTABLE_I to work on objects that may not be tables

gccjit-ravi534
Dibyendu Majumdar 7 years ago
parent f93cefb33c
commit 03485223ed

@ -153,5 +153,7 @@ LUAI_FUNC void raviV_op_band(lua_State *L, TValue *ra, TValue *rb, TValue *rc);
LUAI_FUNC void raviV_op_bnot(lua_State *L, TValue *ra, TValue *rb);
LUAI_FUNC void raviV_gettable_sskey(lua_State *L, const TValue *t, TValue *key, StkId val);
LUAI_FUNC void raviV_settable_sskey(lua_State *L, const TValue *t, TValue *key, StkId val);
LUAI_FUNC void raviV_gettable_i(lua_State *L, const TValue *t, TValue *key, StkId val);
LUAI_FUNC void raviV_settable_i(lua_State *L, const TValue *t, TValue *key, StkId val);
#endif

@ -282,6 +282,8 @@ struct LuaLLVMTypes {
llvm::FunctionType *raviV_op_setupvaltT;
llvm::FunctionType *raviV_gettable_sskeyT;
llvm::FunctionType *raviV_settable_sskeyT;
llvm::FunctionType *raviV_gettable_iT;
llvm::FunctionType *raviV_settable_iT;
llvm::FunctionType *raviH_set_intT;
llvm::FunctionType *raviH_set_floatT;
@ -677,6 +679,8 @@ struct RaviFunctionDef {
llvm::Function *raviV_op_setupvaltF;
llvm::Function *raviV_gettable_sskeyF;
llvm::Function *raviV_settable_sskeyF;
llvm::Function *raviV_gettable_iF;
llvm::Function *raviV_settable_iF;
// array setters
llvm::Function *raviH_set_intF;

@ -44,7 +44,7 @@ function check (f, ...)
local arg = {...}
local c = T.listcode(f)
for i=1, #arg do
-- print(arg[i], c[i])
--print(arg[i], c[i])
assert(string.find(c[i], '- '..arg[i]..' *%d'))
end
assert(c[#arg+2] == nil)
@ -65,7 +65,7 @@ end
-- some basic instructions
check(function ()
(function () end){f()}
end, 'CLOSURE', 'NEWTABLE', 'GETTABUP', 'CALL', 'SETLIST', 'CALL', 'RETURN')
end, 'CLOSURE', 'NEWTABLE', 'GETTABUP_SK', 'CALL', 'SETLIST', 'CALL', 'RETURN')
-- sequence of LOADNILs
@ -121,8 +121,8 @@ check(function ()
end,
'LOADNIL',
'MUL',
'DIV', 'ADD', 'GETTABLE', 'SUB', 'GETTABLE', 'POW',
'UNM', 'SETTABLE', 'SETTABLE', 'RETURN')
'DIV', 'ADD', 'GETTABLE', 'SUB', 'GETTABLE_SK', 'POW',
'UNM', 'SETTABLE', 'SETTABLE_I', 'RETURN')
-- direct access to constants
@ -132,7 +132,7 @@ check(function ()
a.x = b
a[b] = 'x'
end,
'LOADNIL', 'SETTABLE', 'SETTABLE', 'SETTABLE', 'RETURN')
'LOADNIL', 'SETTABLE_SK', 'SETTABLE_SK', 'SETTABLE', 'RETURN')
check(function ()
local a,b
@ -202,7 +202,7 @@ checkequal(function () if (a==nil) then a=1 end; if a~=nil then a=1 end end,
function () if (a==9) then a=1 end; if a~=9 then a=1 end end)
check(function () if a==nil then a='a' end end,
'GETTABUP', 'EQ', 'JMP', 'SETTABUP', 'RETURN')
'GETTABUP_SK', 'EQ', 'JMP', 'SETTABUP', 'RETURN')
-- de morgan
checkequal(function () local a; if not (a or b) then b=a end end,

@ -11,8 +11,10 @@ opcodes_coverage.LOADBOOL = 0
opcodes_coverage.LOADNIL = 0
opcodes_coverage.GETUPVAL = 0
opcodes_coverage.GETTABUP = 0
opcodes_coverage.GETTABUP_SK = 0
opcodes_coverage.GETTABLE = 0
opcodes_coverage.SETTABUP = 0
opcodes_coverage.SETTABUP_SK = 0
opcodes_coverage.SETUPVAL = 0
opcodes_coverage.SETTABLE = 0
opcodes_coverage.NEWTABLE = 0
@ -109,6 +111,8 @@ opcodes_coverage.GETTABLE_I = 0
opcodes_coverage.GETTABLE_S = 0
opcodes_coverage.SETTABLE_I = 0
opcodes_coverage.SETTABLE_S = 0
opcodes_coverage.SETTABLE_SK = 0
opcodes_coverage.GETTABLE_SK = 0
opcodes_coverage.TOTAB = 0
opcodes_coverage.MOVETAB = 0
opcodes_coverage.SETUPVALT = 0
@ -154,7 +158,7 @@ end
-- some basic instructions
check(function ()
(function () end){f()}
end, 'CLOSURE', 'NEWTABLE', 'GETTABUP', 'CALL', 'SETLIST', 'CALL', 'RETURN')
end, 'CLOSURE', 'NEWTABLE', 'GETTABUP_SK', 'CALL', 'SETLIST', 'CALL', 'RETURN')
-- sequence of LOADNILs
check(function ()
@ -208,8 +212,8 @@ check(function ()
end,
'LOADNIL',
'MUL',
'DIV', 'ADD', 'GETTABLE', 'SUB', 'GETTABLE', 'POW',
'UNM', 'SETTABLE', 'SETTABLE', 'RETURN')
'DIV', 'ADD', 'GETTABLE', 'SUB', 'GETTABLE_SK', 'POW',
'UNM', 'SETTABLE', 'SETTABLE_I', 'RETURN')
-- direct access to constants
check(function ()
@ -223,7 +227,7 @@ check(function ()
a[true] = false
end,
'LOADNIL',
'SETTABLE', 'SETTABLE', 'SETTABLE', 'SUB', 'DIV', 'LOADK',
'SETTABLE_SK', 'SETTABLE_SK', 'SETTABLE', 'SUB', 'DIV', 'LOADK',
'SETTABLE', 'RETURN')
@ -256,7 +260,7 @@ checkequal(function () if (a==nil) then a=1 end; if a~=nil then a=1 end end,
function () if (a==9) then a=1 end; if a~=9 then a=1 end end)
check(function () if a==nil then a=1 end end,
'GETTABUP', 'EQ', 'JMP', 'SETTABUP', 'RETURN')
'GETTABUP_SK', 'EQ', 'JMP', 'SETTABUP', 'RETURN')
-- de morgan
checkequal(function () local a; if not (a or b) then b=a end end,
@ -458,9 +462,9 @@ x = function()
assert(i+j == 11)
end
compile(x)
check(x, 'CLOSURE', 'GETTABUP', 'GETUPVAL',
check(x, 'CLOSURE', 'GETTABUP_SK', 'GETUPVAL',
'MOVE', 'CALL', 'CALL', 'MOVE', 'CALL', 'TOINT', 'TOINT',
'GETTABUP', 'ADDII', 'EQ_II', 'JMP', 'LOADBOOL', 'LOADBOOL',
'GETTABUP_SK', 'ADDII', 'EQ_II', 'JMP', 'LOADBOOL', 'LOADBOOL',
'CALL', 'RETURN')
x()
print("test 10 OK")
@ -557,7 +561,7 @@ function tabtest(x)
return x[1]
end
assert(tabtest({}) == 5)
check(tabtest, 'SETTABLE', 'GETTABLE', 'RETURN', 'RETURN')
check(tabtest, 'SETTABLE_I', 'GETTABLE_I', 'RETURN', 'RETURN')
compile(tabtest)
assert(tabtest({}) == 5)
print("test 16 OK")
@ -631,8 +635,8 @@ z = function()
assert(#y == 1)
end
check(z, 'CLOSURE', 'GETUPVAL', 'MOVE', 'CALL',
'MOVE', 'CALL', 'SETUPVAL', 'SETTABUP', 'GETTABUP', 'GETTABUP',
'LOADK', 'CALL', 'GETTABUP', 'GETUPVAL', 'LEN', 'EQ_II',
'MOVE', 'CALL', 'SETUPVAL', 'SETTABUP', 'GETTABUP_SK', 'GETTABUP',
'LOADK', 'CALL', 'GETTABUP_SK', 'GETUPVAL', 'LEN', 'EQ_II',
'JMP', 'LOADBOOL', 'LOADBOOL', 'CALL', 'RETURN')
z()
compile(z)
@ -658,12 +662,12 @@ z = function()
assert(x() == "SundayMondayTuesdayWednesdayThursdayFridaySaturday")
end
check(z, 'NEWTABLE', 'LOADK', 'LOADK', 'LOADK', 'LOADK',
'LOADK', 'LOADK', 'LOADK', 'SETLIST', 'GETTABUP', 'GETTABLE_I',
'EQ', 'JMP', 'LOADBOOL', 'LOADBOOL', 'CALL', 'GETTABUP', 'LEN',
'EQ_II', 'JMP', 'LOADBOOL', 'LOADBOOL', 'CALL', 'GETTABUP', 'GETTABLE_I',
'LOADK', 'LOADK', 'LOADK', 'SETLIST', 'GETTABUP_SK', 'GETTABLE_I',
'EQ', 'JMP', 'LOADBOOL', 'LOADBOOL', 'CALL', 'GETTABUP_SK', 'LEN',
'EQ_II', 'JMP', 'LOADBOOL', 'LOADBOOL', 'CALL', 'GETTABUP_SK', 'GETTABLE_I',
'EQ', 'JMP', 'LOADBOOL', 'LOADBOOL', 'CALL', 'GETTABLE_I', 'LOADK',
'CONCAT', 'SETTABLE_I', 'CLOSURE', 'SETUPVAL', 'GETTABUP', 'GETUPVAL',
'GETUPVAL', 'CALL', 'CALL', 'GETTABUP', 'GETUPVAL', 'CALL', 'EQ',
'CONCAT', 'SETTABLE_I', 'CLOSURE', 'SETUPVAL', 'GETTABUP_SK', 'GETUPVAL',
'GETUPVAL', 'CALL', 'CALL', 'GETTABUP_SK', 'GETUPVAL', 'CALL', 'EQ',
'JMP', 'LOADBOOL', 'LOADBOOL', 'CALL', 'RETURN')
z()
compile(z)
@ -1105,8 +1109,8 @@ function test_tableaccess()
return t.name, t.data.city
end
check(f, 'NEWTABLE', 'SETTABLE_S', 'NEWTABLE',
'SETTABLE_S', 'GETTABLE_S', 'SETTABLE',
'GETTABLE_S', 'GETTABLE_S' , 'GETTABLE',
'SETTABLE_S', 'GETTABLE_S', 'SETTABLE_SK',
'GETTABLE_S', 'GETTABLE_S' , 'GETTABLE_SK',
'RETURN', 'RETURN')
local a,b = f()
assert(a == 'dibyendu')
@ -1127,8 +1131,8 @@ function test_tableaccess()
return t[1], t[2][1]
end
check(f, 'NEWTABLE', 'SETTABLE_I', 'NEWTABLE',
'SETTABLE_I', 'GETTABLE_I', 'SETTABLE',
'GETTABLE_I', 'GETTABLE_I' , 'GETTABLE',
'SETTABLE_I', 'GETTABLE_I', 'SETTABLE_I',
'GETTABLE_I', 'GETTABLE_I' , 'GETTABLE_I',
'RETURN', 'RETURN')
local a,b = f()
assert(a == 'dibyendu')
@ -1149,7 +1153,7 @@ function test_self_s()
return t:name()
end
check(test_self_s, 'NEWTABLE', 'SETTABLE_S', 'CLOSURE',
'SETTABLE_S', 'GETTABUP', 'SELF_S', 'CALL', 'CALL', 'SELF_S', 'TAILCALL',
'SETTABLE_S', 'GETTABUP_SK', 'SELF_S', 'CALL', 'CALL', 'SELF_S', 'TAILCALL',
'RETURN')
assert(test_self_s() == 'dibyendu majumdar')
compile(test_self_s)
@ -1250,12 +1254,12 @@ function test_longkey()
assert(t[s] == 4.4)
assert(t.s == nil)
end
check(test_longkey, 'NEWTABLE', 'SETTABLE', 'GETTABUP', 'GETTABLE',
'EQ', 'JMP', 'LOADBOOL', 'LOADBOOL', 'CALL', 'SETTABLE_S', 'GETTABUP',
check(test_longkey, 'NEWTABLE', 'SETTABLE', 'GETTABUP_SK', 'GETTABLE',
'EQ', 'JMP', 'LOADBOOL', 'LOADBOOL', 'CALL', 'SETTABLE_S', 'GETTABUP_SK',
'GETTABLE_S', 'EQ', 'JMP', 'LOADBOOL', 'LOADBOOL', 'CALL', 'SETTABLE_S',
'GETTABUP', 'GETTABLE_S', 'EQ', 'JMP', 'LOADBOOL', 'LOADBOOL', 'CALL',
'LOADK', 'GETTABUP', 'GETTABLE', 'EQ', 'JMP', 'LOADBOOL', 'LOADBOOL', 'CALL',
'GETTABUP', 'GETTABLE_S', 'EQ', 'JMP', 'LOADBOOL', 'LOADBOOL', 'CALL',
'GETTABUP_SK', 'GETTABLE_S', 'EQ', 'JMP', 'LOADBOOL', 'LOADBOOL', 'CALL',
'LOADK', 'GETTABUP_SK', 'GETTABLE', 'EQ', 'JMP', 'LOADBOOL', 'LOADBOOL', 'CALL',
'GETTABUP_SK', 'GETTABLE_S', 'EQ', 'JMP', 'LOADBOOL', 'LOADBOOL', 'CALL',
'RETURN')
assert(pcall(test_longkey));
compile(test_longkey);

@ -13,8 +13,10 @@ opcodes_coverage.LOADBOOL = 0
opcodes_coverage.LOADNIL = 0
opcodes_coverage.GETUPVAL = 0
opcodes_coverage.GETTABUP = 0
opcodes_coverage.GETTABUP_SK = 0
opcodes_coverage.GETTABLE = 0
opcodes_coverage.SETTABUP = 0
opcodes_coverage.SETTABUP_SK = 0
opcodes_coverage.SETUPVAL = 0
opcodes_coverage.SETTABLE = 0
opcodes_coverage.NEWTABLE = 0
@ -111,6 +113,8 @@ opcodes_coverage.GETTABLE_I = 0
opcodes_coverage.GETTABLE_S = 0
opcodes_coverage.SETTABLE_I = 0
opcodes_coverage.SETTABLE_S = 0
opcodes_coverage.SETTABLE_SK = 0
opcodes_coverage.GETTABLE_SK = 0
opcodes_coverage.TOTAB = 0
opcodes_coverage.MOVETAB = 0
opcodes_coverage.SETUPVALT = 0
@ -164,13 +168,13 @@ x = function()
assert(i == 2)
assert(n == 4.2)
end
check(x, {'LOADK', 'LOADK', 'GETTABUP', 'EQ_II',
check(x, {'LOADK', 'LOADK', 'GETTABUP_SK', 'EQ_II',
'JMP', 'EQ_FF', 'JMP', 'LOADBOOL', 'LOADBOOL',
'CALL', 'NEWTABLE', 'LOADK', 'LOADK', 'LOADK',
'LOADK', 'LOADK', 'SETLIST', 'GETTABLE', 'TOINT',
'MOVEI', 'GETTABLE', 'TOFLT', 'MOVEF', 'GETTABUP',
'LOADK', 'LOADK', 'SETLIST', 'GETTABLE_I', 'TOINT',
'MOVEI', 'GETTABLE_I', 'TOFLT', 'MOVEF', 'GETTABUP_SK',
'EQ_II', 'JMP', 'LOADBOOL', 'LOADBOOL', 'CALL',
'GETTABUP', 'EQ_FF', 'JMP', 'LOADBOOL', 'LOADBOOL',
'GETTABUP_SK', 'EQ_FF', 'JMP', 'LOADBOOL', 'LOADBOOL',
'CALL', 'RETURN'})
x()
compile(x)
@ -182,7 +186,7 @@ function x()
assert(c == a and b == d)
end
check(x, {'LOADK', 'LOADK', 'TOINT', 'MOVE',
'TOINT', 'MOVE', 'GETTABUP', 'EQ', 'JMP',
'TOINT', 'MOVE', 'GETTABUP_SK', 'EQ', 'JMP',
'EQ', 'JMP', 'LOADBOOL', 'LOADBOOL', 'CALL',
'RETURN'})
x()
@ -205,9 +209,9 @@ assert(y == 61 and math.abs(z - 19.9) < 1e-5)
compile(x)
y,z = x()
assert(y == 61 and math.abs(z - 19.9) < 1e-10)
check(x, {'LOADK', 'LOADK', 'LOADK', 'GETTABUP',
'GETTABLE', 'TOINT', 'GETTABUP', 'TOINT', 'TOINT',
'MULII', 'ADDII', 'LOADK', 'GETTABUP', 'GETTABLE',
check(x, {'LOADK', 'LOADK', 'LOADK', 'GETTABUP_SK',
'GETTABLE_I', 'TOINT', 'GETTABUP', 'TOINT', 'TOINT',
'MULII', 'ADDII', 'LOADK', 'GETTABUP_SK', 'GETTABLE_I',
'TOFLT', 'GETTABUP', 'TOFLT', 'MULFF', 'TOFLT',
'SUBFF', 'MOVE', 'MOVE', 'RETURN', 'RETURN'})

@ -607,7 +607,7 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) {
/* Check that we have a short string constant */
else if (e->ravi_type == RAVI_TTABLE && e->u.ind.key_type == RAVI_TSTRING && isshortstr(fs, e->u.ind.idx))
op = OP_RAVI_GETTABLE_S;
else if (e->ravi_type == RAVI_TTABLE && e->u.ind.key_type == RAVI_TNUMINT)
else if (/* e->ravi_type == RAVI_TTABLE &&*/ e->u.ind.key_type == RAVI_TNUMINT)
op = OP_RAVI_GETTABLE_I;
else if (e->u.ind.key_type == RAVI_TSTRING && isshortstr(fs, e->u.ind.idx))
op = OP_RAVI_GETTABLE_SK;
@ -961,7 +961,7 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
else
/* input value is known to be integer */
op = OP_RAVI_SETTABLE_AII;
} else if (var->ravi_type == RAVI_TTABLE && var->u.ind.key_type == RAVI_TNUMINT) {
} else if (/* var->ravi_type == RAVI_TTABLE &&*/ var->u.ind.key_type == RAVI_TNUMINT) {
/* table with integer key */
op = OP_RAVI_SETTABLE_I;
} else if (var->ravi_type == RAVI_TTABLE && var->u.ind.key_type == RAVI_TSTRING && isshortstr(fs, var->u.ind.idx)) {

@ -548,10 +548,10 @@ static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
/* all other instructions can call only through metamethods */
/* Ravi: added GETTABLE_SK and SELF_SK because the call may be through metamethod rather than table */
case OP_SELF: case OP_GETTABUP: case OP_GETTABLE:
case OP_RAVI_SELF_SK: case OP_RAVI_GETTABUP_SK: case OP_RAVI_GETTABLE_SK:
case OP_RAVI_SELF_SK: case OP_RAVI_GETTABUP_SK: case OP_RAVI_GETTABLE_SK: case OP_RAVI_GETTABLE_I:
tm = TM_INDEX;
break;
case OP_SETTABUP: case OP_SETTABLE: case OP_RAVI_SETTABLE_SK:
case OP_SETTABUP: case OP_SETTABLE: case OP_RAVI_SETTABLE_SK: case OP_RAVI_SETTABLE_I:
tm = TM_NEWINDEX;
break;
case OP_ADD: case OP_SUB: case OP_MUL: case OP_MOD:

@ -632,19 +632,7 @@ static char *buildop2(Proto *p, int pc, char *buff, size_t len) {
int line = getfuncline(p, pc);
char tbuf[100];
raviP_instruction_to_str(tbuf, sizeof tbuf, p->code[pc]);
/* This is a temporary hack to output old opcode names to prevent tests from breaking */
if (strncmp(tbuf, luaP_opnames[OP_RAVI_GETTABLE_SK], strlen(luaP_opnames[OP_RAVI_GETTABLE_SK])) == 0 ||
strncmp(tbuf, luaP_opnames[OP_RAVI_SELF_SK], strlen(luaP_opnames[OP_RAVI_SELF_SK])) == 0 ||
strncmp(tbuf, luaP_opnames[OP_RAVI_GETTABUP_SK], strlen(luaP_opnames[OP_RAVI_GETTABUP_SK])) == 0 ||
strncmp(tbuf, luaP_opnames[OP_RAVI_SETTABLE_SK], strlen(luaP_opnames[OP_RAVI_SETTABLE_SK])) == 0) {
char *cp = strstr(tbuf, "_SK ");
if (cp != NULL) {
cp[0] = ' ';
cp[1] = ' ';
cp[2] = ' ';
}
}
snprintf(buff, len, "(%4d) %4d - %s", line, pc, tbuf);
snprintf(buff, len, "(%4d) %4d - %s", line, pc, tbuf);
return buff;
}

@ -468,12 +468,6 @@ static char *buildop (Proto *p, int pc, char *buff) {
Instruction i = p->code[pc];
OpCode o = GET_OPCODE(i);
const char *name = luaP_opnames[o];
/* FIXME Temp hack to output old opcodes so that the tests
do not break */
if (strcmp(name, "GETTABLE_SK") == 0) name = "GETTABLE";
else if (strcmp(name, "SELF_SK") == 0) name = "SELF";
else if (strcmp(name, "SETTABLE_SK") == 0) name = "SETTABLE";
else if (strcmp(name, "GETTABUP_SK") == 0) name = "GETTABUP";
int line = getfuncline(p, pc);
sprintf(buff, "(%4d) %4d - ", line, pc);
switch (getOpMode(o)) {

@ -274,6 +274,36 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
#define GETTABLE_INLINE(L, t, key, val) GETTABLE_INLINE_(L, t, key, val, Unprotect)
#define GETTABLE_INLINE_PROTECTED(L, t, key, val) GETTABLE_INLINE_(L, t, key, val, Protect)
#define GETTABLE_INLINE_I_(L, t, key, val, protect) \
if (RAVI_LIKELY(ttisLtable(t))) { \
lua_Integer idx = ivalue(key); \
Table *h = hvalue(t); \
const TValue *v; \
if (RAVI_LIKELY(l_castS2U(idx - 1) < h->sizearray)) \
v = &h->array[idx - 1]; \
else \
v = luaH_getint(h, idx); \
if (RAVI_LIKELY(!ttisnil(v))) { \
setobj2s(L, val, v); \
} \
else \
protect(luaV_finishget(L, t, key, val, v)); \
} \
else if (ttisfarray(t)) { \
Table *h = hvalue(t); \
raviH_get_float_inline(L, h, ivalue(key), val); \
} \
else if (ttisiarray(t)) { \
Table *h = hvalue(t); \
raviH_get_int_inline(L, h, ivalue(key), val); \
} \
else { \
protect(luaV_finishget(L, t, key, val, NULL)); \
}
#define GETTABLE_INLINE_I(L, t, key, val) GETTABLE_INLINE_I_(L, t, key, val, Unprotect)
#define GETTABLE_INLINE_PROTECTED_I(L, t, key, val) GETTABLE_INLINE_I_(L, t, key, val, Protect)
#define GETTABLE_INLINE_SSKEY_(L, t, key, val, protect) \
if (RAVI_LIKELY(ttisLtable(t))) { \
const TValue *aux = luaH_getshortstr(hvalue(t), tsvalue(key)); \
@ -342,6 +372,62 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
#define SETTABLE_INLINE_PROTECTED(L, t, key, val) SETTABLE_INLINE_(L, t, key, val, Protect)
#define SETTABLE_INLINE(L, t, key, val) SETTABLE_INLINE_(L, t, key, val, Unprotect)
#define SETTABLE_INLINE_I_(L, t, key, val, protect) \
if (RAVI_LIKELY(ttisLtable(t))) { \
lua_Integer idx = ivalue(key); \
Table *h = hvalue(t); \
const TValue *slot; \
if (RAVI_LIKELY(l_castS2U(idx - 1) < h->sizearray)) \
slot = &h->array[idx - 1]; \
else \
slot = luaH_getint(h, idx); \
if (!ttisnil(slot)) { \
luaC_barrierback(L, h, val); \
setobj2t(L, cast(TValue *, slot), val); \
} \
else { \
protect(luaV_finishset(L, t, key, val, slot)); \
} \
} \
else if (ttisfarray(t)) { \
Table *h = hvalue(t); \
if (ttisfloat(val)) { \
raviH_set_float_inline(L, h, ivalue(key), fltvalue(val)); \
} \
else if (ttisinteger(val)) { \
raviH_set_float_inline(L, h, ivalue(key), (lua_Number)(ivalue(val))); \
} \
else { \
lua_Number d = 0.0; \
if (luaV_tonumber_(val, &d)) { \
raviH_set_float_inline(L, h, ivalue(key), d); \
} \
else \
luaG_runerror(L, "value cannot be converted to number"); \
} \
} \
else if (ttisiarray(t)) { \
Table *h = hvalue(t); \
if (ttisinteger(val)) { \
raviH_set_int_inline(L, h, ivalue(key), ivalue(val)); \
} \
else { \
lua_Integer i = 0; \
if (luaV_tointeger_(val, &i)) { \
raviH_set_int_inline(L, h, ivalue(key), i); \
} \
else \
luaG_runerror(L, "value cannot be converted to integer"); \
} \
} \
else { \
protect(luaV_finishset(L, t, key, val, NULL)); \
}
#define SETTABLE_INLINE_PROTECTED_I(L, t, key, val) SETTABLE_INLINE_I_(L, t, key, val, Protect)
#define SETTABLE_INLINE_I(L, t, key, val) SETTABLE_INLINE_I_(L, t, key, val, Unprotect)
#define SETTABLE_INLINE_SSKEY_(L, t, key, val, protect) \
if (RAVI_LIKELY(ttisLtable(t))) { \
const TValue *slot = luaH_getshortstr(hvalue(t), tsvalue(key)); \
@ -1054,13 +1140,18 @@ int luaV_execute (lua_State *L) {
luaC_upvalbarrier(L, uv);
vmbreak;
}
vmcase(OP_RAVI_SETTABLE_I)
vmcase(OP_SETTABLE) {
TValue *rb = RKB(i);
TValue *rc = RKC(i);
SETTABLE_INLINE_PROTECTED(L, ra, rb, rc);
vmbreak;
}
vmcase(OP_RAVI_SETTABLE_I) {
TValue *rb = RKB(i);
TValue *rc = RKC(i);
SETTABLE_INLINE_PROTECTED_I(L, ra, rb, rc);
vmbreak;
}
vmcase(OP_RAVI_SETTABLE_SK)
vmcase(OP_RAVI_SETTABLE_S) {
TValue *rb = RKB(i);
@ -1759,20 +1850,8 @@ int luaV_execute (lua_State *L) {
vmcase(OP_RAVI_GETTABLE_I) {
TValue *rb = RB(i);
TValue *rc = RKC(i);
lua_Integer idx = ivalue(rc);
Table *t = hvalue(rb);
const TValue *v;
if (RAVI_LIKELY(l_castS2U(idx - 1) < t->sizearray))
v = &t->array[idx - 1];
else
v = luaH_getint(t, idx);
if (RAVI_LIKELY(!ttisnil(v))) {
setobj2s(L, ra, v);
}
else {
Protect(luaV_finishget(L, rb, rc, ra, v));
}
vmbreak;
GETTABLE_INLINE_PROTECTED_I(L, rb, rc, ra);
vmbreak;
}
/* This opcode is used when the key is known to be
short string but the variable may or may not be
@ -2604,6 +2683,26 @@ void raviV_settable_sskey(lua_State *L, const TValue *t, TValue *key, StkId val)
SETTABLE_INLINE_SSKEY(L, t, key, val);
}
/*
** Main function for table access (invoking metamethods if needed).
** Compute 'val = t[key]'
** In Lua 5.3.2 this function is a macro but we need it to be a function
** so that JIT code can invoke it
*/
void raviV_gettable_i(lua_State *L, const TValue *t, TValue *key, StkId val) {
GETTABLE_INLINE_I(L, t, key, val);
}
/*
** Main function for table assignment (invoking metamethods if needed).
** Compute 't[key] = val'
** In Lua 5.3.2 this function is a macro but we need it to be a function
** so that JIT code can invoke it
*/
void raviV_settable_i(lua_State *L, const TValue *t, TValue *key, StkId val) {
SETTABLE_INLINE_I(L, t, key, val);
}
/* }================================================================== */

@ -1156,6 +1156,12 @@ void RaviCodeGenerator::emit_extern_declarations(RaviFunctionDef *def) {
def->raviV_gettable_sskeyF = def->raviF->addExternFunction(
def->types->raviV_gettable_sskeyT,
reinterpret_cast<void *>(&raviV_gettable_sskey), "raviV_gettable_sskey");
def->raviV_settable_iF = def->raviF->addExternFunction(
def->types->raviV_settable_iT,
reinterpret_cast<void *>(&raviV_settable_i), "raviV_settable_i");
def->raviV_gettable_iF = def->raviF->addExternFunction(
def->types->raviV_gettable_iT,
reinterpret_cast<void *>(&raviV_gettable_i), "raviV_gettable_i");
def->ravi_dump_valueF = def->raviF->addExternFunction(
def->types->ravi_dump_valueT, reinterpret_cast<void *>(&ravi_dump_value),
@ -1624,8 +1630,11 @@ bool RaviCodeGenerator::compile(lua_State *L, Proto *p,
int C = GETARG_C(i);
emit_SETTABLE_SK(def, A, B, C, pc);
} break;
case OP_RAVI_SETTABLE_I:
case OP_RAVI_SETTABLE_I: {
int B = GETARG_B(i);
int C = GETARG_C(i);
emit_SETTABLE_I(def, A, B, C, pc);
} break;
case OP_SETTABLE: {
int B = GETARG_B(i);
int C = GETARG_C(i);

@ -97,18 +97,13 @@ void RaviCodeGenerator::emit_LEN(RaviFunctionDef *def, int A, int B, int pc) {
// b) we know the key is an integer
void RaviCodeGenerator::emit_SETTABLE_I(RaviFunctionDef *def, int A, int B,
int C, int pc) {
// This is broken as we need to handle meta methods etc.
lua_assert(false);
#if 0
emit_debug_trace(def, OP_RAVI_SETTABLE_I, pc);
bool traced = emit_debug_trace(def, OP_RAVI_SETTABLE_I, pc);
if (!traced) emit_update_savedpc(def, pc);
emit_load_base(def);
llvm::Value *ra = emit_gep_register(def, A);
llvm::Value *rb = emit_gep_register_or_constant(def, B);
llvm::Value *rc = emit_gep_register_or_constant(def, C);
llvm::Instruction *t = emit_load_reg_h(def, ra);
llvm::Instruction *key = emit_load_reg_i(def, rb);
CreateCall4(def->builder, def->luaH_setintF, def->L, t, key, rc);
#endif
CreateCall4(def->builder, def->raviV_settable_iF, def->L, ra, rb, rc);
}
// R(A)[RK(B)] := RK(C)
@ -208,6 +203,17 @@ void RaviCodeGenerator::emit_GETTABLE_SK(RaviFunctionDef *def, int A, int B,
// b) we know the key is an integer
void RaviCodeGenerator::emit_GETTABLE_I(RaviFunctionDef *def, int A, int B,
int C, int pc) {
// changed to that target may not be a table
bool traced = emit_debug_trace(def, OP_RAVI_GETTABLE_I, pc);
if (!traced) emit_update_savedpc(def, pc);
emit_load_base(def);
llvm::Value *ra = emit_gep_register(def, A);
llvm::Value *rb = emit_gep_register(def, B);
llvm::Value *rc = emit_gep_register_or_constant(def, C);
CreateCall4(def->builder, def->raviV_gettable_iF, def->L, rb, rc, ra);
// FIXME following is no longer valid as RB may not be a table
// TValue *rb = RB(i);
// TValue *rc = RKC(i);
// lua_Integer idx = ivalue(rc);
@ -224,49 +230,49 @@ void RaviCodeGenerator::emit_GETTABLE_I(RaviFunctionDef *def, int A, int B,
// Protect(luaV_finishget(L, rb, rc, ra, v));
//}
emit_debug_trace(def, OP_RAVI_GETTABLE_I, pc);
emit_load_base(def);
llvm::Value *ra = emit_gep_register(def, A);
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::Value *data = emit_table_get_array(def, t);
llvm::Value *len = emit_table_get_arraysize(def, t);
// As Lua arrays are 1 based we need to subtract by 1
llvm::Value *key_minus_1 =
def->builder->CreateSub(key, def->types->kluaInteger[1]);
// As len is unsigned int we need to truncate
llvm::Value *ukey =
def->builder->CreateTrunc(key_minus_1, def->types->C_intT);
// Do an unsigned comparison with length
llvm::Value *cmp = def->builder->CreateICmpULT(ukey, len);
llvm::BasicBlock *then_block =
llvm::BasicBlock::Create(def->jitState->context(), "if.in.range", def->f);
llvm::BasicBlock *else_block =
llvm::BasicBlock::Create(def->jitState->context(), "if.not.in.range");
llvm::BasicBlock *end_block =
llvm::BasicBlock::Create(def->jitState->context(), "if.end");
def->builder->CreateCondBr(cmp, then_block, else_block);
def->builder->SetInsertPoint(then_block);
// Key is in range so array access possible
llvm::Value *value1 = def->builder->CreateGEP(data, ukey);
def->builder->CreateBr(end_block);
// Out of range so fall back to luaH_getint()
def->f->getBasicBlockList().push_back(else_block);
def->builder->SetInsertPoint(else_block);
llvm::Value *value2 = CreateCall2(def->builder, def->luaH_getintF, t, key);
def->builder->CreateBr(end_block);
// Merge results from the two branches above
def->f->getBasicBlockList().push_back(end_block);
def->builder->SetInsertPoint(end_block);
llvm::PHINode *phi = def->builder->CreatePHI(def->types->pTValueT, 2);
phi->addIncoming(value1, then_block);
phi->addIncoming(value2, else_block);
emit_finish_GETTABLE(def, phi, t, ra, rb, rc);
//emit_debug_trace(def, OP_RAVI_GETTABLE_I, pc);
//emit_load_base(def);
//llvm::Value *ra = emit_gep_register(def, A);
//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::Value *data = emit_table_get_array(def, t);
//llvm::Value *len = emit_table_get_arraysize(def, t);
//// As Lua arrays are 1 based we need to subtract by 1
//llvm::Value *key_minus_1 =
// def->builder->CreateSub(key, def->types->kluaInteger[1]);
//// As len is unsigned int we need to truncate
//llvm::Value *ukey =
// def->builder->CreateTrunc(key_minus_1, def->types->C_intT);
//// Do an unsigned comparison with length
//llvm::Value *cmp = def->builder->CreateICmpULT(ukey, len);
//llvm::BasicBlock *then_block =
// llvm::BasicBlock::Create(def->jitState->context(), "if.in.range", def->f);
//llvm::BasicBlock *else_block =
// llvm::BasicBlock::Create(def->jitState->context(), "if.not.in.range");
//llvm::BasicBlock *end_block =
// llvm::BasicBlock::Create(def->jitState->context(), "if.end");
//def->builder->CreateCondBr(cmp, then_block, else_block);
//def->builder->SetInsertPoint(then_block);
//// Key is in range so array access possible
//llvm::Value *value1 = def->builder->CreateGEP(data, ukey);
//def->builder->CreateBr(end_block);
//// Out of range so fall back to luaH_getint()
//def->f->getBasicBlockList().push_back(else_block);
//def->builder->SetInsertPoint(else_block);
//llvm::Value *value2 = CreateCall2(def->builder, def->luaH_getintF, t, key);
//def->builder->CreateBr(end_block);
//// Merge results from the two branches above
//def->f->getBasicBlockList().push_back(end_block);
//def->builder->SetInsertPoint(end_block);
//llvm::PHINode *phi = def->builder->CreatePHI(def->types->pTValueT, 2);
//phi->addIncoming(value1, then_block);
//phi->addIncoming(value2, else_block);
//emit_finish_GETTABLE(def, phi, t, ra, rb, rc);
}
void RaviCodeGenerator::emit_finish_GETTABLE(RaviFunctionDef *def,

@ -808,6 +808,10 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false);
raviV_settable_sskeyT =
llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false);
raviV_gettable_iT =
llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false);
raviV_settable_iT =
llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false);
// void luaV_finishget (lua_State *L, const TValue *t, TValue *key,
// StkId val, const TValue *slot);

Loading…
Cancel
Save