issue #61 fix bug in compilation

pull/81/head
Dibyendu Majumdar 9 years ago
parent aca5b3ef86
commit c4c8dad5b5

@ -693,7 +693,8 @@ public:
llvm::Value *emit_gep(RaviFunctionDef *def, const char *name, llvm::Value *s,
int arg1, int arg2, int arg3);
llvm::Value *emit_gep(RaviFunctionDef *def, const char *name,
llvm::Value *ptr, llvm::Value *arg1, int arg2, int arg3);
llvm::Value *ptr, llvm::Value *arg1, int arg2,
int arg3);
llvm::Value *emit_gep(RaviFunctionDef *def, const char *name,
llvm::Value *ptr, llvm::Value *arg1, int arg2);
@ -744,21 +745,28 @@ public:
// emit code to load the table value from register
llvm::Instruction *emit_load_reg_h(RaviFunctionDef *def, llvm::Value *ra);
// Gets the size of the hash table
llvm::Value *emit_table_get_hashsize(RaviFunctionDef *def, llvm::Value *table);
// Gets the size of the hash table
llvm::Value *emit_table_get_hashsize(RaviFunctionDef *def,
llvm::Value *table);
// Gets the location of the hash node for given key and table size
llvm::Value *emit_table_get_hashstr(RaviFunctionDef *def, llvm::Value *table, TString *key);
llvm::Value *emit_table_get_hashstr(RaviFunctionDef *def, llvm::Value *table,
TString *key);
llvm::Value *emit_table_get_nodearray(RaviFunctionDef *def, llvm::Value *table);
llvm::Value *emit_table_get_nodearray(RaviFunctionDef *def,
llvm::Value *table);
llvm::Value *emit_table_get_keytype(RaviFunctionDef *def, llvm::Value *node, llvm::Value *index);
llvm::Value *emit_table_get_keytype(RaviFunctionDef *def, llvm::Value *node,
llvm::Value *index);
llvm::Value *emit_table_get_strkey(RaviFunctionDef *def, llvm::Value *node, llvm::Value *index);
llvm::Value *emit_table_get_strkey(RaviFunctionDef *def, llvm::Value *node,
llvm::Value *index);
llvm::Value *emit_table_get_value(RaviFunctionDef *def, llvm::Value *node, llvm::Value *index);
llvm::Value *emit_table_get_value(RaviFunctionDef *def, llvm::Value *node,
llvm::Value *index);
llvm::Value *emit_table_get_arraysize(RaviFunctionDef *def, llvm::Value *table);
llvm::Value *emit_table_get_arraysize(RaviFunctionDef *def,
llvm::Value *table);
llvm::Value *emit_table_get_array(RaviFunctionDef *def, llvm::Value *table);
@ -960,7 +968,7 @@ public:
void emit_TOINT(RaviFunctionDef *def, int A, int pc);
void emit_TOFLT(RaviFunctionDef *def, int A, int pc);
void emit_LEN(RaviFunctionDef *def, int A, int B, int pc);
void emit_SETTABLE(RaviFunctionDef *def, int A, int B, int C, int pc);
@ -1040,7 +1048,7 @@ public:
void emit_MOVEAI(RaviFunctionDef *def, int A, int B, int pc);
void emit_MOVEAF(RaviFunctionDef *def, int A, int B, int pc);
void emit_MOVETAB(RaviFunctionDef *def, int A, int B, int pc);
void emit_TOARRAY(RaviFunctionDef *def, int A, int array_type_expected,

@ -0,0 +1,59 @@
-- Test that compilation of invalid Ravi code fails correctly!
-- All tests are negative tests here
-- =================== start copy from Lua testsuite ===============
local function checkerr (msg, f, ...)
local st, err = pcall(f, ...)
assert(not st and string.find(err, msg))
end
local function doit (s)
local f, msg = load(s)
if f == nil then return msg end
local cond, msg = pcall(f)
return (not cond) and msg
end
local function checkmessage (prog, msg)
local m = doit(prog)
--if (not string.find(m, msg, 1, true)) then
-- print(m)
--end
assert(string.find(m, msg, 1, true))
end
local function checksyntax (prog, extra, token, line)
local msg = doit(prog)
if not string.find(token, "^<%a") and not string.find(token, "^char%(")
then token = "'"..token.."'" end
token = string.gsub(token, "(%p)", "%%%1")
local pt = string.format([[^%%[string ".*"%%]:%d: .- near %s$]],
line, token)
assert(string.find(msg, pt))
assert(string.find(msg, msg, 1, true))
end
-- =================== end copy from Lua testsuite ===============
checkmessage('local t: table = {}; local t2: table = {}; t=t2[1]', 'Invalid assignment: table expected')
checkmessage('local t: table = {}; t=1', 'Invalid assignment: table expected')
checkmessage('local t: table = {}; t=function() end', 'table expected')
checkmessage('local t: table = {}; local t2: number[] = {}; t=t2', 'Invalid assignment: table expected')
checkmessage('local t: table = {}; local t2: table = { data={} }; t=t2.data', 'Invalid assignment: table expected')
checkmessage('local t: table = {}; local f=function() t = 1 end; f()', 'upvalue of table type, cannot be set to non table value')
checkmessage('local t: table = {}; local x=function() return 0 end; local f=function() t = x() end; f()', 'upvalue of table type, cannot be set to non table value')
checkmessage('local t: table = {}; local x=function() t[1] = 1; local f=function() t = 1 end; f(); end; x()', 'upvalue of table type, cannot be set to non table value')
checkmessage('local t: integer[] = {}; local t2: integer[] = {1}; t=t2[1]', 'Invalid assignment: integer[] expected')
checkmessage('local t: integer[] = {}; t=1', 'Invalid assignment: integer[] expected')
checkmessage('local t: integer[] = {}; t=function() end', 'integer[] expected')
checkmessage('local t: integer[] = {}; local t2: number[] = {}; t=t2', 'Invalid assignment: integer[] expected')
checkmessage('local t: integer[] = {}; local t2: table = {}; t=t2', 'Invalid assignment: integer[] expected')
checkmessage('local t: integer[] = {}; local t2: table = {true}; t[1]=t2[1]', 'integer expected')
checkmessage('local t: integer[] = {}; local t2: table = {"hi"}; t[1]=t2[1]', 'integer expected')
checkmessage('local t: integer[] = {}; local t2: table = { data={} }; t=t2.data', 'Invalid assignment: integer[] expected')
checkmessage('local t: integer[] = {}; local f=function() t = 1 end; f()', 'upvalue of integer[] type, cannot be set to non integer[] value')
checkmessage('local t: integer[] = {}; local x=function() return 0 end; local f=function() t = x() end; f()', 'upvalue of integer[] type, cannot be set to non integer[] value')
checkmessage('local t: integer[] = {}; local x=function() t[1] = 1; local f=function() t = 1 end; f(); end; x()', 'upvalue of integer[] type, cannot be set to non integer[] value')
checkmessage('local t: number[] = {}; local t2: number[] = {1.0}; t=t2[1]', 'Invalid assignment: number[] expected')

@ -671,9 +671,7 @@ static void check_valid_store(FuncState *fs, expdesc *var, expdesc *ex) {
fs->ls,
luaO_pushfstring(
fs->ls->L,
"Invalid assignment of type: var type %d, expression type %d",
var->ravi_type,
ex->ravi_type));
"Invalid assignment: number expected"));
}
else if (var->ravi_type == RAVI_TNUMINT) {
if (ex->ravi_type == RAVI_TNUMINT)
@ -684,22 +682,21 @@ static void check_valid_store(FuncState *fs, expdesc *var, expdesc *ex) {
fs->ls,
luaO_pushfstring(
fs->ls->L,
"Invalid assignment of type: var type %d, expression type %d",
"Invalid assignment: integer expected",
var->ravi_type,
ex->ravi_type));
}
else if (var->ravi_type == RAVI_TARRAYFLT ||
var->ravi_type == RAVI_TARRAYINT ||
var->ravi_type == RAVI_TTABLE) {
if (ex->ravi_type == var->ravi_type)
if (ex->ravi_type == var->ravi_type && ex->k != VINDEXED)
return;
luaX_syntaxerror(
fs->ls,
luaO_pushfstring(
fs->ls->L,
"Invalid assignment of type: var type %d, expression type %d",
var->ravi_type,
ex->ravi_type));
"Invalid assignment: %s expected",
var->ravi_type == RAVI_TTABLE ? "table" : (var->ravi_type == RAVI_TARRAYFLT ? "number[]" : "integer[]")));
}
}

@ -58,12 +58,12 @@ void RaviCodeGenerator::emit_LEN(RaviFunctionDef *def, int A, int B, int pc) {
// R(A)[RK(B)] := RK(C)
// This is a more optimized version that calls
// luaH_setint() instead of luaV_settable().
// luaH_setint() instead of luaV_settable().
// This relies on two things:
// a) we know we have a table
// b) we know the key is an integer
void RaviCodeGenerator::emit_SETTABLE_I(RaviFunctionDef *def, int A, int B, int C,
int pc) {
void RaviCodeGenerator::emit_SETTABLE_I(RaviFunctionDef *def, int A, int B,
int C, int pc) {
emit_debug_trace(def, OP_RAVI_SETTABLE_I, pc);
emit_load_base(def);
llvm::Value *ra = emit_gep_register(def, A);
@ -76,7 +76,7 @@ void RaviCodeGenerator::emit_SETTABLE_I(RaviFunctionDef *def, int A, int B, int
// R(A)[RK(B)] := RK(C)
void RaviCodeGenerator::emit_SETTABLE(RaviFunctionDef *def, int A, int B, int C,
int pc) {
int pc) {
// Protect(luaV_settable(L, ra, RKB(i), RKC(i)));
bool traced = emit_debug_trace(def, OP_SETTABLE, pc);
// Below may invoke metamethod so we set savedpc
@ -110,8 +110,8 @@ void RaviCodeGenerator::emit_GETTABLE(RaviFunctionDef *def, int A, int B, int C,
// luaH_getint(). This relies on two things:
// a) we know we have a table
// b) we know the key is an integer
void RaviCodeGenerator::emit_GETTABLE_I(RaviFunctionDef *def, int A, int B, int C,
int pc) {
void RaviCodeGenerator::emit_GETTABLE_I(RaviFunctionDef *def, int A, int B,
int C, int pc) {
emit_debug_trace(def, OP_RAVI_GETTABLE_I, pc);
emit_load_base(def);
llvm::Value *ra = emit_gep_register(def, A);
@ -123,18 +123,18 @@ void RaviCodeGenerator::emit_GETTABLE_I(RaviFunctionDef *def, int A, int B, int
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]);
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);
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::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::Create(def->jitState->context(), "if.not.in.range");
llvm::BasicBlock *end_block =
llvm::BasicBlock::Create(def->jitState->context(), "if.end");
llvm::BasicBlock::Create(def->jitState->context(), "if.end");
def->builder->CreateCondBr(cmp, then_block, else_block);
def->builder->SetInsertPoint(then_block);
@ -145,8 +145,7 @@ void RaviCodeGenerator::emit_GETTABLE_I(RaviFunctionDef *def, int A, int B, int
// 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);
llvm::Value *value2 = CreateCall2(def->builder, def->luaH_getintF, t, key);
def->builder->CreateBr(end_block);
// Merge results from the two branches above
@ -649,13 +648,17 @@ void RaviCodeGenerator::emit_TOARRAY(RaviFunctionDef *def, int A,
OpCode op = OP_RAVI_TOTAB;
switch (array_type_expected) {
case RAVI_TARRAYINT: op = OP_RAVI_TOARRAYI; break;
case RAVI_TARRAYFLT: op = OP_RAVI_TOARRAYF; break;
case RAVI_TTABLE:
default:
break;
case RAVI_TARRAYINT:
op = OP_RAVI_TOARRAYI;
break;
case RAVI_TARRAYFLT:
op = OP_RAVI_TOARRAYF;
break;
case RAVI_TTABLE:
default:
break;
}
emit_debug_trace(def, op, pc);
emit_load_base(def);
llvm::Value *ra = emit_gep_register(def, A);
@ -714,15 +717,13 @@ void RaviCodeGenerator::emit_MOVEAF(RaviFunctionDef *def, int A, int B,
llvm::Value *dest = emit_gep_register(def, A);
emit_assign(def, dest, src);
}
void RaviCodeGenerator::emit_MOVETAB(RaviFunctionDef *def, int A, int B,
int pc) {
emit_debug_trace(def, OP_RAVI_MOVETAB, pc);
emit_TOARRAY(def, B, RAVI_TTABLE, "table expected", pc);
llvm::Value *src = emit_gep_register(def, B);
llvm::Value *dest = emit_gep_register(def, A);
emit_assign(def, dest, src);
}
void RaviCodeGenerator::emit_MOVETAB(RaviFunctionDef *def, int A, int B,
int pc) {
emit_debug_trace(def, OP_RAVI_MOVETAB, pc);
emit_TOARRAY(def, B, RAVI_TTABLE, "table expected", pc);
llvm::Value *src = emit_gep_register(def, B);
llvm::Value *dest = emit_gep_register(def, A);
emit_assign(def, dest, src);
}
}
Loading…
Cancel
Save