setupval type specialized opcodes should not cause JIT failure

pull/81/head
Dibyendu Majumdar 9 years ago
parent 6e6f31835e
commit a11f7bbd27

@ -78,8 +78,13 @@ LUAI_FUNC void raviV_op_setlist(lua_State *L, CallInfo *ci, TValue *ra, int b, i
LUAI_FUNC void raviV_op_concat(lua_State *L, CallInfo *ci, int a, int b, int c);
LUAI_FUNC void raviV_op_closure(lua_State *L, CallInfo *ci, LClosure *cl, int a, int Bx);
LUAI_FUNC void raviV_op_vararg(lua_State *L, CallInfo *ci, LClosure *cl, int a, int b);
LUAI_FUNC void raviV_op_setupval(lua_State *L, LClosure *cl, TValue *ra, int b);
LUAI_FUNC void raviV_op_setupvali(lua_State *L, LClosure *cl, TValue *ra, int b);
LUAI_FUNC void raviV_op_setupvalf(lua_State *L, LClosure *cl, TValue *ra, int b);
LUAI_FUNC void raviV_op_setupvalai(lua_State *L, LClosure *cl, TValue *ra, int b);
LUAI_FUNC void raviV_op_setupvalaf(lua_State *L, LClosure *cl, TValue *ra, int b);
LUAI_FUNC void raviV_op_setupvalt(lua_State *L, LClosure *cl, TValue *ra, int b);
LUAI_FUNC void raviV_op_shl(lua_State *L, TValue *ra, TValue *rb, TValue *rc);
LUAI_FUNC void raviV_op_shr(lua_State *L, TValue *ra, TValue *rb, TValue *rc);
#endif

@ -259,6 +259,11 @@ struct LuaLLVMTypes {
llvm::FunctionType *raviV_op_varargT;
llvm::FunctionType *raviV_op_shrT;
llvm::FunctionType *raviV_op_shlT;
llvm::FunctionType *raviV_op_setupvaliT;
llvm::FunctionType *raviV_op_setupvalfT;
llvm::FunctionType *raviV_op_setupvalaiT;
llvm::FunctionType *raviV_op_setupvalafT;
llvm::FunctionType *raviV_op_setupvaltT;
llvm::FunctionType *raviH_set_intT;
llvm::FunctionType *raviH_set_floatT;
@ -556,6 +561,11 @@ struct RaviFunctionDef {
llvm::Function *raviV_op_varargF;
llvm::Function *raviV_op_shrF;
llvm::Function *raviV_op_shlF;
llvm::Function *raviV_op_setupvaliF;
llvm::Function *raviV_op_setupvalfF;
llvm::Function *raviV_op_setupvalaiF;
llvm::Function *raviV_op_setupvalafF;
llvm::Function *raviV_op_setupvaltF;
// array setters
llvm::Function *raviH_set_intF;
@ -988,6 +998,8 @@ public:
void emit_SETUPVAL(RaviFunctionDef *def, int A, int B, int pc);
void emit_SETUPVAL_Specific(RaviFunctionDef *def, int A, int B, int pc, OpCode op, llvm::Function *f);
void emit_GETTABUP(RaviFunctionDef *def, int A, int B, int C, int pc);
void emit_SETTABUP(RaviFunctionDef *def, int A, int B, int C, int pc);

@ -62,7 +62,8 @@ checkmessage('local t: integer = function() return "hell" end', 'Invalid local a
checkmessage('local function j() return "hell" end; local t: integer = j()', 'integer expected')
checkmessage('local t: integer = 5; local x=function() return "string" end; local f=function() t = x() end; f()', 'upvalue of integer type, cannot be set to non integer value')
checkmessage('local t: integer = 5.5', 'Invalid local assignment')
checkmessage('local function f() local t: number[] = {}; t[1] = 4.2; t[5] = 2.4; end; f()', 'array out of bounds')
checkmessage('local function f() local t: integer[] = {}; t[1] = 4; t[5] = 2; end; f()', 'array out of bounds')
checkmessage('local function f() local t: integer[] = {}; t[1] = 4; t[-5] = 2; end; f()', 'array out of bounds')
checkmessage('local t: number[] = {}; local t2: number[] = {1.0}; t=t2[1]', 'Invalid assignment: number[] expected')
checkmessage('local t: number[] = {}; t=1', 'Invalid assignment: number[] expected')
@ -84,6 +85,8 @@ checkmessage('local t: number = function() return "hell" end', 'Invalid local as
checkmessage('local function j() return "hell" end; local t: number = j()', 'number expected')
checkmessage('local t: number = 5.5; local x=function() return "string" end; local f=function() t = x() end; f()', 'upvalue of number type, cannot be set to non number value')
checkmessage('local t: number = 5', 'Invalid local assignment')
checkmessage('local function f() local t: number[] = {}; t[1] = 4.2; t[5] = 2.4; end; f()', 'array out of bounds')
checkmessage('local function f() local t: number[] = {}; t[1] = 4.2; t[-5] = 2.4; end; f()', 'array out of bounds')
checkmessage('for i=1,10 do i="a" end', 'Invalid assignment: integer expected')
checkmessage('for i=1,10 do local f = function() i="a" end; f(); end', 'upvalue of integer type, cannot be set to non integer value')

@ -104,9 +104,9 @@ Note that if a Lua functions contains a bytecode that cannot be be JITed then th
+-------------------------+----------+--------------------------------------------------+
| OP_BXOR | NO | R(A) := RK(B) ~ RK(C) |
+-------------------------+----------+--------------------------------------------------+
| OP_SHL | NO | R(A) := RK(B) << RK(C) |
| OP_SHL | YES | R(A) := RK(B) << RK(C) |
+-------------------------+----------+--------------------------------------------------+
| OP_SHR | NO | R(A) := RK(B) >> RK(C) |
| OP_SHR | YES | R(A) := RK(B) >> RK(C) |
+-------------------------+----------+--------------------------------------------------+
| OP_UNM | YES | R(A) := -R(B) |
+-------------------------+----------+--------------------------------------------------+
@ -272,7 +272,20 @@ Note that if a Lua functions contains a bytecode that cannot be be JITed then th
+-------------------------+----------+--------------------------------------------------+
| OP_RAVI_LE_FF | YES | if ((RK(B) <= RK(C)) ~= A) then pc++ |
+-------------------------+----------+--------------------------------------------------+
| OP_RAVI_GETTABLE_I | YES | R(A) := R(B)[RK(C)], integer key |
+-------------------------+----------+--------------------------------------------------+
| OP_RAVI_GETTABLE_S | YES | R(A) := R(B)[RK(C)], string key |
+-------------------------+----------+--------------------------------------------------+
| OP_RAVI_SETTABLE_I | YES | R(A)[RK(B)] := RK(C), integer key |
+-------------------------+----------+--------------------------------------------------+
| OP_RAVI_SETTABLE_S | YES | R(A)[RK(B)] := RK(C), string key |
+-------------------------+----------+--------------------------------------------------+
| OP_RAVI_TOTAB | YES | R(A) := to_table(R(A)) |
+-------------------------+----------+--------------------------------------------------+
| OP_RAVI_MOVETAB | YES | R(A) := R(B), check R(B) is a table |
+-------------------------+----------+--------------------------------------------------+
| OP_RAVI_SETUPVALT | NO | UpValue[B] := to_table(R(A)) |
+-------------------------+----------+--------------------------------------------------+
Ravi's LLVM JIT compiler source
-------------------------------
@ -281,8 +294,9 @@ The LLVM JIT implementation is in following sources:
* ravillvm.h - includes LLVM headers and defines the generic JIT State and Function interfaces
* ravijit.h - defines the JIT API
* ravi_llvmcodegen.h - defines the types used by the code generator
* ravijit.cpp - Non implementation specific JIT API functions
* ravijit.cpp - basic LLVM infrastructure and Ravi API definition
* ravi_llvmjit.cpp - basic LLVM infrastructure and Ravi API definition
* ravi_llvmtypes.cpp - contains LLVM type definitions for Lua objects
* ravi_llvmcodegen.cpp - LLVM JIT compiler - main driver for compiling Lua bytecodes into LLVM IR
* ravi_llvmload.cpp - implements OP_LOADK and OP_MOVE, and related operations, also OP_LOADBOOL

@ -2106,8 +2106,49 @@ void raviV_op_loadnil(CallInfo *ci, int a, int b) {
} while (b--);
}
void raviV_op_setupvali(lua_State *L, LClosure *cl, TValue *ra, int b) {
lua_Integer ia;
if (tointeger(ra, &ia)) {
UpVal *uv = cl->upvals[b];
setivalue(uv->v, ia);
luaC_upvalbarrier(L, uv);
} else
luaG_runerror(
L, "upvalue of integer type, cannot be set to non integer value");
}
void raviV_op_setupvalf(lua_State *L, LClosure *cl, TValue *ra, int b) {
lua_Number na;
if (tonumber(ra, &na)) {
UpVal *uv = cl->upvals[b];
setfltvalue(uv->v, na);
luaC_upvalbarrier(L, uv);
} else
luaG_runerror(L,
"upvalue of number type, cannot be set to non number value");
}
void raviV_op_setupvalai(lua_State *L, LClosure *cl, TValue *ra, int b) {
if (!ttistable(ra) || hvalue(ra)->ravi_array.array_type != RAVI_TARRAYINT)
luaG_runerror(
L, "upvalue of integer[] type, cannot be set to non integer[] value");
UpVal *uv = cl->upvals[b];
setobj(L, uv->v, ra);
luaC_upvalbarrier(L, uv);
}
void raviV_op_setupvalaf(lua_State *L, LClosure *cl, TValue *ra, int b) {
if (!ttistable(ra) || hvalue(ra)->ravi_array.array_type != RAVI_TARRAYFLT)
luaG_runerror(
L, "upvalue of number[] type, cannot be set to non number[] value");
UpVal *uv = cl->upvals[b];
setobj(L, uv->v, ra);
luaC_upvalbarrier(L, uv);
}
void raviV_op_setupval(lua_State *L, LClosure *cl, TValue *ra, int b) {
void raviV_op_setupvalt(lua_State *L, LClosure *cl, TValue *ra, int b) {
if (!ttistable(ra) || hvalue(ra)->ravi_array.array_type != RAVI_TTABLE)
luaG_runerror(L, "upvalue of table type, cannot be set to non table value");
UpVal *uv = cl->upvals[b];
setobj(L, uv->v, ra);
luaC_upvalbarrier(L, uv);

@ -877,6 +877,11 @@ bool RaviCodeGenerator::canCompile(Proto *p) {
case OP_RAVI_SETTABLE_S:
case OP_RAVI_TOTAB:
case OP_RAVI_MOVETAB:
case OP_RAVI_SETUPVALI:
case OP_RAVI_SETUPVALF:
case OP_RAVI_SETUPVALAI:
case OP_RAVI_SETUPVALAF:
case OP_RAVI_SETUPVALT:
break;
default:
return false;
@ -1086,6 +1091,21 @@ void RaviCodeGenerator::emit_extern_declarations(RaviFunctionDef *def) {
def->raviV_op_shrF = def->raviF->addExternFunction(
def->types->raviV_op_shrT, reinterpret_cast<void *>(&raviV_op_shr),
"raviV_op_shr");
def->raviV_op_setupvaliF = def->raviF->addExternFunction(
def->types->raviV_op_setupvaliT,
reinterpret_cast<void *>(&raviV_op_setupvali), "raviV_op_setupvali");
def->raviV_op_setupvalfF = def->raviF->addExternFunction(
def->types->raviV_op_setupvalfT,
reinterpret_cast<void *>(&raviV_op_setupvalf), "raviV_op_setupvalf");
def->raviV_op_setupvalaiF = def->raviF->addExternFunction(
def->types->raviV_op_setupvalaiT,
reinterpret_cast<void *>(&raviV_op_setupvalai), "raviV_op_setupvalai");
def->raviV_op_setupvalafF = def->raviF->addExternFunction(
def->types->raviV_op_setupvalafT,
reinterpret_cast<void *>(&raviV_op_setupvalaf), "raviV_op_setupvalaf");
def->raviV_op_setupvaltF = def->raviF->addExternFunction(
def->types->raviV_op_setupvaltT,
reinterpret_cast<void *>(&raviV_op_setupvalt), "raviV_op_setupvalt");
def->ravi_dump_valueF = def->raviF->addExternFunction(
def->types->ravi_dump_valueT, reinterpret_cast<void *>(&ravi_dump_value),
@ -1629,6 +1649,32 @@ void RaviCodeGenerator::compile(lua_State *L, Proto *p,
emit_SETUPVAL(def, A, B, pc);
} break;
case OP_RAVI_SETUPVALI: {
int B = GETARG_B(i);
emit_SETUPVAL_Specific(def, A, B, pc, OP_RAVI_SETUPVALI,
def->raviV_op_setupvaliF);
} break;
case OP_RAVI_SETUPVALF: {
int B = GETARG_B(i);
emit_SETUPVAL_Specific(def, A, B, pc, OP_RAVI_SETUPVALF,
def->raviV_op_setupvalfF);
} break;
case OP_RAVI_SETUPVALAI: {
int B = GETARG_B(i);
emit_SETUPVAL_Specific(def, A, B, pc, OP_RAVI_SETUPVALAI,
def->raviV_op_setupvalaiF);
} break;
case OP_RAVI_SETUPVALAF: {
int B = GETARG_B(i);
emit_SETUPVAL_Specific(def, A, B, pc, OP_RAVI_SETUPVALAF,
def->raviV_op_setupvalafF);
} break;
case OP_RAVI_SETUPVALT: {
int B = GETARG_B(i);
emit_SETUPVAL_Specific(def, A, B, pc, OP_RAVI_SETUPVALT,
def->raviV_op_setupvaltF);
} break;
case OP_RAVI_BXOR_II:
case OP_RAVI_BOR_II:
case OP_RAVI_BAND_II: {

@ -516,6 +516,17 @@ void RaviCodeGenerator::emit_GETUPVAL(RaviFunctionDef *def, int A, int B,
emit_assign(def, ra, v);
}
// UpValue[B] := R(A)
void RaviCodeGenerator::emit_SETUPVAL_Specific(RaviFunctionDef *def, int A,
int B, int pc, OpCode op,
llvm::Function *f) {
emit_debug_trace(def, op, pc);
emit_load_base(def);
llvm::Value *ra = emit_gep_register(def, A);
CreateCall4(def->builder, f, def->L, def->p_LClosure, ra,
llvm::ConstantInt::get(def->types->C_intT, B));
}
// UpValue[B] := R(A)
void RaviCodeGenerator::emit_SETUPVAL(RaviFunctionDef *def, int A, int B,
int pc) {

@ -856,6 +856,29 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
raviV_op_varargT =
llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false);
// void raviV_op_setupvali(lua_State *L, LClosure *cl, TValue *ra, int b);
// void raviV_op_setupvalf(lua_State *L, LClosure *cl, TValue *ra, int b);
// void raviV_op_setupvalai(lua_State *L, LClosure *cl, TValue *ra, int b);
// void raviV_op_setupvalaf(lua_State *L, LClosure *cl, TValue *ra, int b);
// void raviV_op_setupvalt(lua_State *L, LClosure *cl, TValue *ra, int b);
elements.clear();
elements.push_back(plua_StateT);
elements.push_back(pLClosureT);
elements.push_back(pTValueT);
elements.push_back(C_intT);
raviV_op_setupvaliT =
llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false);
raviV_op_setupvalfT =
llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false);
raviV_op_setupvalaiT =
llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false);
raviV_op_setupvalafT =
llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false);
raviV_op_setupvaltT =
llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false);
// void raviV_op_shl(lua_State *L, TValue *ra, TValue *rb, TValue *rc);
// void raviV_op_shr(lua_State *L, TValue *ra, TValue *rb, TValue *rc);
elements.clear();
elements.push_back(plua_StateT);
elements.push_back(pTValueT);

@ -42,7 +42,7 @@ int test1() {
llvm::Module *module = theModule.get();
llvm::IRBuilder<> builder(context);
#ifdef _WIN32
#if defined(_WIN32) && (!defined(_WIN64) || LLVM_VERSION_MINOR < 7)
// On Windows we get error saying incompatible object format
// Reading posts on mailining lists I found that the issue is that COEFF
// format is not supported and therefore we need to set -elf as the object

Loading…
Cancel
Save