gccjit-ravi534
Dibyendu Majumdar 7 years ago
parent 92d4d5d186
commit d3f821c59a

@ -69,7 +69,7 @@ PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
SortIncludes: true
SortIncludes: false
PointerAlignment: Left
SpaceAfterCStyleCast: false
SpaceBeforeAssignmentOperators: true

@ -155,5 +155,6 @@ LUAI_FUNC void raviV_gettable_sskey(lua_State *L, const TValue *t, TValue *key,
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);
LUAI_FUNC void raviV_op_totype(lua_State *L, TValue *ra, TValue *rb);
#endif

@ -284,6 +284,7 @@ struct LuaLLVMTypes {
llvm::FunctionType *raviV_settable_sskeyT;
llvm::FunctionType *raviV_gettable_iT;
llvm::FunctionType *raviV_settable_iT;
llvm::FunctionType *raviV_op_totypeT;
llvm::FunctionType *raviH_set_intT;
llvm::FunctionType *raviH_set_floatT;
@ -756,6 +757,7 @@ struct RaviFunctionDef {
llvm::Function *raviV_settable_sskeyF;
llvm::Function *raviV_gettable_iF;
llvm::Function *raviV_settable_iF;
llvm::Function *raviV_op_totypeF;
// array setters
llvm::Function *raviH_set_intF;
@ -895,7 +897,7 @@ class RaviCodeGenerator {
// The return value is a boolean type as a result of
// integer comparison result which is i1 in LLVM
llvm::Value *emit_is_not_value_of_type_class(
RaviFunctionDef *def, llvm::Value *value_type, LuaTypeCode lua_typecode,
RaviFunctionDef *def, llvm::Value *value_type, int lua_typecode,
const char *varname = "value.not.typeof");
// emit code for LClosure *cl = clLvalue(ci->func)
@ -1222,6 +1224,12 @@ class RaviCodeGenerator {
void emit_TOFLT(RaviFunctionDef *def, int A, int pc);
void emit_TOSTRING(RaviFunctionDef *def, int A, int pc);
void emit_TOCLOSURE(RaviFunctionDef *def, int A, int pc);
void emit_TOTYPE(RaviFunctionDef *def, int A, int Bx, 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);

@ -96,5 +96,12 @@ checkmessage('local mt: number[] = {}; local t: table = {}; setmetatable(t, mt)'
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')
checkmessage('local x: number[] = {1,2}; x:try()', 'attempt to incorrectly index a table value')
checkmessage('@integer ""', 'unexpected symbol near @integer') -- FIXME bad error message
checkmessage('@string 1', 'unexpected symbol near @string') -- FIXME bad error message
checkmessage('@MyType 1', "unexpected symbol near '@'") -- FIXME bad error message
checkmessage('local function x(y: MyType) end x(1)', 'type mismatch: expected MyType')
checkmessage('local function x(y: string) end x(1)', 'string expected')
checkmessage('local function x(y: closure) end x(1)', 'closure expected')
print 'Ok'

@ -117,7 +117,9 @@ opcodes_coverage.TOTAB = 0
opcodes_coverage.MOVETAB = 0
opcodes_coverage.SETUPVALT = 0
opcodes_coverage.SELF_S = 0
opcodes_coverage.TOTYPE = 0
opcodes_coverage.TOSTRING = 0
opcodes_coverage.TOCLOSURE = 0
local compile = function(f)
if ravi.jit() then
@ -425,7 +427,7 @@ assert(x(5.1) == 2.0)
assert(x(4.0) == 3.0)
print("test 8 OK")
-- test 10
-- test 9
x = function (y: integer, z)
if y == 1 then
if z == 1 then
@ -451,7 +453,7 @@ assert(x(5) == 2.0)
assert(x(4) == 3.0)
print("test 9 OK")
-- test 11
-- test 10
x = function()
local function tryme()
local i,j = 5,6
@ -469,7 +471,7 @@ check(x, 'CLOSURE', 'GETTABUP_SK', 'GETUPVAL',
x()
print("test 10 OK")
-- test 12
-- test 11
function x()
local a : number[], j:number = {}
for i=1,10 do
@ -487,7 +489,7 @@ compile(x)
assert(x() == 55.0)
print("test 11 OK")
-- test 13
-- test 12
function pisum()
local sum : number
for j = 1,500 do
@ -508,7 +510,7 @@ assert(compile(pisum))
assert(math.abs(pisum()-1.644834071848065) < 1e-12)
print("test 12 OK")
-- test 15
-- test 13
function y()
local i,j = 5.1,"6.2"
return i,j
@ -525,7 +527,7 @@ assert(compile(x))
assert(math.abs(x(y) - 11.3) < 0.0001)
print("test 13 OK")
-- test 16
-- test 14
function tryme(x,y)
if x < y then
return 1
@ -543,7 +545,7 @@ assert(tryme(1,2) == 1)
assert(tryme(2,1) == 0)
print("test 14 OK")
-- test 17
-- test 15
function tryme(x,y)
return x < y
end
@ -555,7 +557,7 @@ assert(tryme(1,2))
assert(not tryme(2,1))
print("test 15 OK")
-- test 18
-- test 16
function tabtest(x)
x[1] = 5
return x[1]
@ -566,7 +568,7 @@ compile(tabtest)
assert(tabtest({}) == 5)
print("test 16 OK")
-- test 19
-- test 17
function optest()
local a,b,c = 1, 5
c = a and b
@ -579,7 +581,7 @@ compile(optest)
assert(optest() == 5)
print("test 17 OK")
-- test 20
-- test 18
function optest()
local a,b,c = 1, 5
c = a or b
@ -592,7 +594,7 @@ compile(optest)
assert(optest() == 1)
print("test 18 OK")
-- test 21
-- test 19
function optest()
local a,b = 1, 5
if a and b then
@ -607,7 +609,7 @@ compile(optest)
assert(optest() == 5)
print("test 19 OK")
-- test 22
-- test 20
function optest()
local a,b = nil, 5
if a or b then
@ -622,7 +624,7 @@ compile(optest)
assert(optest() == 5)
print("test 20 OK")
-- test 29
-- test 21
z = function()
local x=function()
local j:number[] = {}
@ -643,7 +645,7 @@ compile(z)
z()
print("test 21 OK")
-- test 30
-- test 22
z = function()
local days: table = {"Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturda"}
@ -674,7 +676,7 @@ compile(z)
z()
print("test 22 OK")
-- test 31
-- test 23
x = function(a)
return not a
end
@ -688,7 +690,7 @@ assert(y(x(false)))
assert(not y(x(true)))
print("test 23 OK")
-- test 36
-- test 24
t = { name_ = "ravi" }
function t:name()
return self.name_
@ -699,9 +701,9 @@ end
assert(compile(t.name))
assert(compile(z))
assert(z(t) == "ravi")
print("test 25 OK")
print("test 24 OK")
-- test 38
-- test 25
-- test ravi integer array
function f()
local x: integer[] = { 1, 5 }
@ -714,9 +716,9 @@ function f()
end
assert(compile(f))
assert(f() == 6)
print("test 26 OK")
print("test 25 OK")
-- test 39
-- test 26
function f()
local x: number[] = { 5.0, 6.1 }
x[3] = x[1] + x[2]
@ -725,9 +727,9 @@ end
--ravi.dumplua(f)
assert(compile(f))
assert(math.abs(f()-11.1) < 1e-12)
print("test 27 OK")
print("test 26 OK")
-- test 41
-- test 27
-- Ravi arrays support for ipairs()
-- Plus special slot at [0]
x = function()
@ -743,9 +745,9 @@ x = function()
end
assert(compile(x))
assert(x() == 28)
print("test 28 OK")
print("test 27 OK")
-- test 42
-- test 28
-- Ravi arrays support for pairs()
-- Plus special slot at [0]
x = function()
@ -761,9 +763,9 @@ x = function()
end
assert(compile(x))
assert(x() == 28)
print("test 29 OK")
print("test 28 OK")
-- test 43
-- test 29
-- test creation of arrays and slice
x = function()
local zeros: integer[] = table.intarray(10, 0)
@ -785,9 +787,9 @@ x = function()
end
assert(compile(x))
assert(x() == true)
print("test 30 OK")
print("test 29 OK")
-- test 44
-- test 30
matrix = {}
matrix.new = function (m, n)
local t = {m, n, table.numarray(m*n, 0)}
@ -833,9 +835,9 @@ assert(compile(matrix.getcol))
assert(compile(matrix.getdata))
assert(compile(x))
assert(x() == 65)
print("test 31 OK")
print("test 30 OK")
-- test 23
-- test 31
function testadd(a,b)
return a+b
end
@ -844,9 +846,9 @@ assert(testadd(1,1) == 2)
assert(testadd(1.5,1.6) == 3.1)
assert(testadd("1.5",1.6) == 3.1)
assert(testadd("1.5","1.6") == 3.1)
print("test 32 OK")
print("test 31 OK")
-- test 24
-- test 32
function testsub(a,b)
return a-b
end
@ -855,9 +857,9 @@ assert(testsub(1,1) == 0)
assert(math.abs(testsub(1.5,1.6)-(-0.1)) < 1e-6)
assert(math.abs(testsub("1.5",1.6)-(-0.1)) < 1e-6)
assert(math.abs(testsub("1.5","1.6")-(-0.1)) < 1e-6)
print("test 33 OK")
print("test 32 OK")
-- test 25
-- test 33
function testmul(a,b)
return a*b
end
@ -866,10 +868,10 @@ assert(testmul(2,2) == 4)
assert(math.abs(testmul(1.5,1.6)-2.4) < 1e-12)
assert(math.abs(testmul("1.5",1.6)-2.4) < 1e-12)
assert(math.abs(testmul("1.5","1.6")-2.4) < 1e-12)
print("test 34 OK")
print("test 33 OK")
-- test 26
-- test 34
function testdiv(a,b)
return a/b
end
@ -878,10 +880,10 @@ assert(testdiv(2,2) == 1.0)
assert(math.abs(testdiv(1.5,1.6)-0.9375) < 1e-12)
assert(math.abs(testdiv("1.5",1.6)-0.9375) < 1e-12)
assert(math.abs(testdiv("1.5","1.6")-0.9375) < 1e-12)
print("test 35 OK")
print("test 34 OK")
-- test 37
-- test 35
-- this tests that within the for loop
-- the locals get mapped correctly to upvalues
function f()
@ -904,11 +906,9 @@ assert(t[1]() == 10)
assert(t[2]() == 10)
assert(t[1]() == 20)
assert(t[2]() == 20)
print("test 36 OK")
print("test 35 OK")
-- test 27
-- test 36
-- upvalues
local x = 1
local y=function()
@ -923,9 +923,9 @@ local f = y()
assert(f() == 1)
x=5
assert(f() == 5)
print("test 37 OK")
print("test 36 OK")
-- test 28
-- test 37
-- upvalues
x1 = 3
local y=function()
@ -944,9 +944,9 @@ local f = y()
assert(f() == 3)
x1=5
assert(f() == 5)
print("test 38 OK")
print("test 37 OK")
-- test 35
-- test 38
function x()
local x = 1
local f = function()
@ -959,7 +959,7 @@ f=x()
assert(compile(f))
assert(f() == 2)
assert(f() == 3)
print("test 39 OK")
print("test 38 OK")
-- test setupval, getupval
function x()
@ -973,9 +973,9 @@ compile(y)
assert(y(2) == 2)
assert(y(2) == 4)
assert(y(3) == 7)
print('test 40 Ok')
print('test 39 OK')
-- test 32
-- test 40
x=function(a,b)
return a%b
end
@ -984,9 +984,9 @@ assert(compile(x))
-- if ravi.jit() then ravi.compile(x) end
assert(x(5,2) == 1)
assert(math.abs(x(5.1,2.1)-0.9) < 1e-6)
print("test 41 OK")
print("test 40 OK")
-- test 33
-- test 41
x=function(a,b)
return a//b
end
@ -995,9 +995,9 @@ assert(compile(x))
-- if ravi.jit() then ravi.compile(x) end
assert(x(5,2) == 2)
assert(math.abs(x(5.5,2.1)-2.0) < 1e-6)
print("test 42 OK")
print("test 41 OK")
-- test 6
-- test 42
x = function ()
local j = 0
for i=2.0,6.0,3.1 do
@ -1007,10 +1007,10 @@ x = function ()
end
if (not compile(x)) then
print("test 6 FAILED to compile")
print("test FAILED to compile")
end
assert(x() == 5.1)
print("test 43 OK")
print("test 42 OK")
-- test parameter types
x = function (a: integer, b: number)
@ -1022,7 +1022,7 @@ end
assert(x(1,5.5) == 6.5)
compile(x)
assert(x(1,5.5) == 6.5)
print'test 44 OK'
print'test 43 OK'
x=function (a:number[], b:integer)
local j: number = a[b]
@ -1037,9 +1037,9 @@ assert(y() == 4.2)
compile(x)
compile(y)
assert(y() == 4.2)
print'test 45 OK'
print'test 44 OK'
-- test 40
-- test 45
function x(t) return t; end
function f()
local tt: integer[] = {1}
@ -1055,23 +1055,19 @@ function f()
tt = x({})
end
--ravi.dumplua(f)
print'+'
assert(compile(f))
assert(not pcall(f))
print'+'
function f()
local tt: integer[] = {1}
local ss: number[] = { 55.5 }
ss = x(tt)
end
print'+'
assert(compile(f))
assert(not pcall(f))
print("test 46 OK")
print("test 45 OK")
-- test 41
-- test 47
function test_idiv()
local t = {}
t.__idiv = function(...) return 'idiv' end
@ -1149,7 +1145,7 @@ function test_self_s()
local t : table = {}
t.name_ = 'dibyendu majumdar'
t.name = function (t:table) return t.name_ end
print(t:name())
assert(t:name())
return t:name()
end
check(test_self_s, 'NEWTABLE', 'SETTABLE_S', 'CLOSURE',
@ -1160,7 +1156,7 @@ compile(test_self_s)
assert(test_self_s() == 'dibyendu majumdar')
print 'Test 49 OK'
-- issue #73
-- issue #73
function bug_index_event()
local t1 = { name='dibyendu' }
local t2 = { surname='majumdar' }
@ -1264,11 +1260,11 @@ check(test_longkey, 'NEWTABLE', 'SETTABLE', 'GETTABUP_SK', 'GETTABLE',
assert(pcall(test_longkey));
compile(test_longkey);
assert(pcall(test_longkey));
print 'Test 53 OK'
print 'Test 54 OK'
function test_yields_in_metamethods()
print"testing yields inside metamethods"
--print"testing yields inside metamethods"
local mt = {
__eq = function(a:table,b:table) coroutine.yield(nil, "eq"); return a.x == b.x end,
__lt = function(a:table,b:table) coroutine.yield(nil, "lt"); return a.x < b.x end,
@ -1396,7 +1392,7 @@ end
assert(pcall(test_yields_in_metamethods));
compile(test_longkey);
assert(pcall(test_yields_in_metamethods));
print 'Test 54 Ok'
print 'Test 55 OK'
function test_upvaluejoin()
local debug = require'debug'
@ -1445,7 +1441,7 @@ end
assert(pcall(test_upvaluejoin));
compile(test_upvaluejoin);
assert(pcall(test_upvaluejoin));
print 'Test 55 Ok'
print 'Test 56 OK'
function test_idiv(y: integer)
local era: integer
@ -1456,7 +1452,7 @@ check(test_idiv, 'TOINT', 'LOADNIL', 'LOADIZ', 'IDIV', 'RETURN', 'RETURN')
assert(test_idiv(1900) == 4)
compile(test_idiv)
assert(test_idiv(1900) == 4)
print 'Test 56 Ok'
print 'Test 57 OK'
function from_dmy1(y: integer, m: integer, d: integer)
if m <= 2 then
@ -1512,7 +1508,48 @@ check(from_dmy1, 'TOINT', 'TOINT', 'TOINT', 'LE_II', 'JMP',
'JMP','LOADK','ADDII','MULII','ADDII','IDIV','ADDII','SUBII',
'MULII','IDIV','ADDII','IDIV','SUBII','ADDII','MULII','ADDII',
'SUBII','RETURN','RETURN')
print 'Test 57 Ok'
print 'Test 58 OK'
function x(s1: string, s2: string)
return @string( s1 .. s2 )
end
check(x, 'TOSTRING', 'TOSTRING', 'MOVE', 'MOVE', 'CONCAT', 'TOSTRING', 'RETURN', 'RETURN')
assert(x('a', 'b') == 'ab')
compile(x)
assert(x('a', 'b') == 'ab')
print 'Test 59 OK'
function x(f: closure)
local g = @closure f
return g()
end
check(x, 'TOCLOSURE', 'MOVE', 'MOVE', 'TAILCALL', 'RETURN', 'RETURN')
local called = 0
function y()
called = called + 1
end
x(y)
assert(called == 1)
compile(x)
compile(y)
x(y)
assert(called == 2)
print 'Test 60 OK'
local mt = { __name='MyType'}
debug.getregistry().MyType = mt
local t = {}
setmetatable(t, mt)
function x(s: MyType)
local assert = assert
assert(@MyType s == @MyType t)
assert(@MyType t == t)
end
x(t)
compile(x)
x(t)
print 'Test 61 OK'
for k,v in pairs(opcodes_coverage)
do
@ -1521,3 +1558,4 @@ end
-- ravi.dumplua(test_yields_in_metamethods)
print 'OK'

@ -119,6 +119,9 @@ opcodes_coverage.TOTAB = 0
opcodes_coverage.MOVETAB = 0
opcodes_coverage.SETUPVALT = 0
opcodes_coverage.SELF_S = 0
opcodes_coverage.TOTYPE = 0
opcodes_coverage.TOSTRING = 0
opcodes_coverage.TOCLOSURE = 0
local compile = function(f)

@ -1417,6 +1417,13 @@ static void code_type_assertion(FuncState *fs, UnOpr op, expdesc *e, TString *ty
}
break;
}
case VK: {
if (op == OPR_TO_STRING) {
if (e->ravi_type == RAVI_TSTRING)
return;
}
break;
}
case VRELOCABLE:
case VNONRELOC: {
discharge2anyreg(fs, e);

@ -1079,7 +1079,7 @@ void luaV_finishOp (lua_State *L) {
Protect(luaV_finishset(L,t,k,v,slot)); }
int raviV_check_usertype(lua_State *L, TString *name, const TValue *o)
int check_usertype(lua_State *L, TString *name, const TValue *o)
{
Table *mt;
switch (ttnov(o)) {
@ -2248,7 +2248,7 @@ int luaV_execute (lua_State *L) {
if (!ttisshrstring(rb))
luaG_runerror(L, "type name must be string");
TString *key = tsvalue(rb);
if (!raviV_check_usertype(L, key, ra))
if (!check_usertype(L, key, ra))
luaG_runerror(L, "type mismatch: expected %s", getstr(key));
vmbreak;
}
@ -2764,5 +2764,16 @@ void raviV_settable_i(lua_State *L, const TValue *t, TValue *key, StkId val) {
SETTABLE_INLINE_I(L, t, key, val);
}
/**
** Opcode TOTYPE validates that the register A contains a
** type whose metatable is registered by name in constant Bx
*/
void raviV_op_totype(lua_State *L, TValue *ra, TValue *rb) {
if (!ttisshrstring(rb)) luaG_runerror(L, "type name must be string");
TString *key = tsvalue(rb);
if (!check_usertype(L, key, ra))
luaG_runerror(L, "type mismatch: expected %s", getstr(key));
}
/* }================================================================== */

@ -1,25 +1,25 @@
/******************************************************************************
* Copyright (C) 2015 Dibyendu Majumdar
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
******************************************************************************/
* Copyright (C) 2015 Dibyendu Majumdar
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
******************************************************************************/
#include <ravijit.h>
#include <ravi_llvmcodegen.h>
#include <ravi_jitshared.h>
@ -114,10 +114,10 @@ void RaviCodeGenerator::attach_branch_weights(RaviFunctionDef *def,
def->jitState->types()->mdbuilder.createBranchWeights(
true_branch, false_branch));
#else
(void)def;
(void)ins;
(void)true_branch;
(void)false_branch;
(void)def;
(void)ins;
(void)true_branch;
(void)false_branch;
#endif
}
@ -561,7 +561,7 @@ llvm::Value *RaviCodeGenerator::emit_is_not_value_of_type(
// Compare without variants i.e. ttnov(value_type) == lua_type
llvm::Value *RaviCodeGenerator::emit_is_not_value_of_type_class(
RaviFunctionDef *def, llvm::Value *value_type, LuaTypeCode lua_type,
RaviFunctionDef *def, llvm::Value *value_type, int lua_type,
const char *varname) {
llvm::Value *novariant_type =
def->builder->CreateAnd(value_type, def->types->kInt[0x0F]);
@ -1056,10 +1056,10 @@ void RaviCodeGenerator::emit_extern_declarations(RaviFunctionDef *def) {
def->types->luaH_getstrT, reinterpret_cast<void *>(&luaH_getstr),
"luaH_getstr");
def->luaH_getstrF->addFnAttr(llvm::Attribute::AttrKind::ReadOnly);
//def->luaH_getstrF->setDoesNotAlias(1);
//def->luaH_getstrF->setDoesNotCapture(1);
//def->luaH_getstrF->setDoesNotAlias(2);
//def->luaH_getstrF->setDoesNotCapture(2);
// def->luaH_getstrF->setDoesNotAlias(1);
// def->luaH_getstrF->setDoesNotCapture(1);
// def->luaH_getstrF->setDoesNotAlias(2);
// def->luaH_getstrF->setDoesNotCapture(2);
def->luaV_finishgetF = def->raviF->addExternFunction(
def->types->luaV_finishgetT, reinterpret_cast<void *>(&luaV_finishget),
"luaV_finishget");
@ -1157,11 +1157,14 @@ void RaviCodeGenerator::emit_extern_declarations(RaviFunctionDef *def) {
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->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->types->raviV_gettable_iT,
reinterpret_cast<void *>(&raviV_gettable_i), "raviV_gettable_i");
def->raviV_op_totypeF = def->raviF->addExternFunction(
def->types->raviV_op_totypeT, reinterpret_cast<void *>(&raviV_op_totype),
"raviV_op_totype");
def->ravi_dump_valueF = def->raviF->addExternFunction(
def->types->ravi_dump_valueT, reinterpret_cast<void *>(&ravi_dump_value),
@ -1296,11 +1299,10 @@ bool RaviCodeGenerator::compile(lua_State *L, Proto *p,
std::shared_ptr<RaviJITModule> module,
ravi_compile_options_t *options) {
if (p->ravi_jit.jit_status == RAVI_JIT_COMPILED) return true;
// Avoid recursive calls
if (module->owner()->get_compiling_flag())
return false;
if (module->owner()->get_compiling_flag()) return false;
bool doVerify = module->owner()->get_validation() != 0;
bool omitArrayGetRangeCheck =
options ? options->omit_array_get_range_check != 0 : 0;
@ -1321,10 +1323,10 @@ bool RaviCodeGenerator::compile(lua_State *L, Proto *p,
p->ravi_jit.jit_status = RAVI_JIT_CANT_COMPILE; // can't compile
return false;
}
// Set flag so we can avoid recursive calls
module->owner()->set_compiling_flag(true);
// The Lua GC doesn't know about memory allocated by the JIT
// compiler; this means that if lots of functions are being compiled
// such as in the test cases, then memory usage can grow very large
@ -1717,11 +1719,19 @@ bool RaviCodeGenerator::compile(lua_State *L, Proto *p,
case OP_RAVI_TOARRAYF: {
emit_TOARRAY(def, A, RAVI_TARRAYFLT, "number[] expected", pc);
} break;
case OP_RAVI_TOSTRING:
case OP_RAVI_TOCLOSURE:
case OP_RAVI_TOTYPE:
// No-op for now
case OP_RAVI_TOSTRING: {
emit_TOSTRING(def, A, pc);
break;
}
case OP_RAVI_TOCLOSURE: {
emit_TOCLOSURE(def, A, pc);
break;
}
case OP_RAVI_TOTYPE: {
int Bx = GETARG_Bx(i);
emit_TOTYPE(def, A, Bx, pc);
break;
}
case OP_RAVI_MOVEAI: {
int B = GETARG_B(i);
emit_MOVEAI(def, A, B, pc);
@ -1930,8 +1940,7 @@ bool RaviCodeGenerator::compile(lua_State *L, Proto *p,
}
}
}
if (doVerify &&
llvm::verifyFunction(*f->function(), &llvm::errs())) {
if (doVerify && llvm::verifyFunction(*f->function(), &llvm::errs())) {
f->dump();
fprintf(stderr, "LLVM Code Verification failed\n");
exit(1);
@ -1941,9 +1950,9 @@ bool RaviCodeGenerator::compile(lua_State *L, Proto *p,
p->ravi_jit.jit_data = reinterpret_cast<void *>(llvm_func);
p->ravi_jit.jit_function = nullptr;
p->ravi_jit.jit_status = RAVI_JIT_COMPILED;
module->owner()->set_compiling_flag(false);
return llvm_func != nullptr;
}
@ -2021,4 +2030,4 @@ void RaviCodeGenerator::scan_jump_targets(RaviFunctionDef *def, Proto *p) {
}
}
}
}
} // namespace ravi

@ -238,6 +238,68 @@ void RaviCodeGenerator::emit_MOVEF(RaviFunctionDef *def, int A, int B, int pc) {
emit_store_reg_n_withtype(def, load_var, dest);
}
void RaviCodeGenerator::emit_TOSTRING(RaviFunctionDef *def, int A, int pc) {
emit_debug_trace(def, OP_RAVI_TOSTRING, pc);
emit_load_base(def);
llvm::Value *ra = emit_gep_register(def, A);
llvm::Instruction *type = emit_load_type(def, ra);
// check if string type
llvm::Value *cmp1 = emit_is_not_value_of_type_class(def, type, LUA_TSTRING,
"OP_RAVI_TOSTRING_is.not.expected.type");
llvm::BasicBlock *raise_error = llvm::BasicBlock::Create(
def->jitState->context(), "OP_RAVI_TOSTRING_if.not.expected_type", def->f);
llvm::BasicBlock *done =
llvm::BasicBlock::Create(def->jitState->context(), "OP_RAVI_TOSTRING_done");
auto brinst1 = def->builder->CreateCondBr(cmp1, raise_error, done);
attach_branch_weights(def, brinst1, 0, 100);
def->builder->SetInsertPoint(raise_error);
// Conversion failed, so raise error
emit_raise_lua_error(def, "string expected");
def->builder->CreateBr(done);
def->f->getBasicBlockList().push_back(done);
def->builder->SetInsertPoint(done);
}
void RaviCodeGenerator::emit_TOCLOSURE(RaviFunctionDef *def, int A, int pc) {
emit_debug_trace(def, OP_RAVI_TOCLOSURE, pc);
emit_load_base(def);
llvm::Value *ra = emit_gep_register(def, A);
llvm::Instruction *type = emit_load_type(def, ra);
// check if function type
llvm::Value *cmp1 = emit_is_not_value_of_type_class(
def, type, LUA_TFUNCTION, "OP_RAVI_TOCLOSURE_is.not.expected.type");
llvm::BasicBlock *raise_error = llvm::BasicBlock::Create(
def->jitState->context(), "OP_RAVI_TOCLOSURE_if.not.expected_type",
def->f);
llvm::BasicBlock *done = llvm::BasicBlock::Create(def->jitState->context(),
"OP_RAVI_TOCLOSURE_done");
auto brinst1 = def->builder->CreateCondBr(cmp1, raise_error, done);
attach_branch_weights(def, brinst1, 0, 100);
def->builder->SetInsertPoint(raise_error);
// Conversion failed, so raise error
emit_raise_lua_error(def, "closure expected");
def->builder->CreateBr(done);
def->f->getBasicBlockList().push_back(done);
def->builder->SetInsertPoint(done);
}
void RaviCodeGenerator::emit_TOTYPE(RaviFunctionDef *def, int A, int Bx,
int pc) {
emit_debug_trace(def, OP_RAVI_TOTYPE, pc);
// Load pointer to base
emit_load_base(def);
llvm::Value *ra = emit_gep_register(def, A);
llvm::Value *rb = emit_gep_constant(def, Bx);
CreateCall3(def->builder, def->raviV_op_totypeF, def->L, ra, rb);
}
void RaviCodeGenerator::emit_TOINT(RaviFunctionDef *def, int A, int pc) {
// case OP_RAVI_TOINT: {
// lua_Integer j;

@ -1,25 +1,25 @@
/******************************************************************************
* Copyright (C) 2015 Dibyendu Majumdar
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
******************************************************************************/
* Copyright (C) 2015 Dibyendu Majumdar
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
******************************************************************************/
#include "ravi_llvmcodegen.h"
namespace ravi {
@ -261,12 +261,14 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
// */
//}Upvaldesc;
UpvaldescT = llvm::StructType::create(context, "struct.Upvaldesc");
//elements.clear();
//elements.push_back(pTStringT); /* name */
//elements.push_back(ravitype_tT); /* type */
//elements.push_back(lu_byteT); /* instack */
//elements.push_back(lu_byteT); /* idx */
//UpvaldescT->setBody(elements);
// FIXME (issue #136) this structure is changing hence better to keep it
// opaque
// elements.clear();
// elements.push_back(pTStringT); /* name */
// elements.push_back(ravitype_tT); /* type */
// elements.push_back(lu_byteT); /* instack */
// elements.push_back(lu_byteT); /* idx */
// UpvaldescT->setBody(elements);
pUpvaldescT = llvm::PointerType::get(UpvaldescT, 0);
///*
@ -281,12 +283,14 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
// */
//} LocVar;
LocVarT = llvm::StructType::create(context, "struct.LocVar");
//elements.clear();
//elements.push_back(pTStringT); /* varname */
//elements.push_back(C_intT); /* startpc */
//elements.push_back(C_intT); /* endpc */
//elements.push_back(ravitype_tT); /* ravi_type */
//LocVarT->setBody(elements);
// FIXME (issue #136) this structure is changing hence better to keep it
// opaque
// elements.clear();
// elements.push_back(pTStringT); /* varname */
// elements.push_back(C_intT); /* startpc */
// elements.push_back(C_intT); /* endpc */
// elements.push_back(ravitype_tT); /* ravi_type */
// LocVarT->setBody(elements);
pLocVarT = llvm::PointerType::get(LocVarT, 0);
LClosureT = llvm::StructType::create(context, "struct.LClosure");
@ -485,7 +489,7 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
elements.push_back(pGCObjectT); /* gclist */
elements.push_back(RaviArrayT); /* RaviArray */
#if RAVI_USE_NEWHASH
elements.push_back(C_intT); /* hmask */
elements.push_back(C_intT); /* hmask */
#endif
TableT->setBody(elements);
@ -573,7 +577,7 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
elements.push_back(pCallInfoT); /* next */
elements.push_back(
CallInfo_lT); /* u.l - as we will typically access the lua call details
*/
*/
elements.push_back(C_ptrdiff_t); /* extra */
elements.push_back(llvm::Type::getInt16Ty(context)); /* nresults */
elements.push_back(C_shortT); /* callstatus */
@ -761,6 +765,10 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
// int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r)
luaV_lessequalT = llvm::FunctionType::get(C_intT, elements, false);
// void raviV_op_totype(lua_State *L, TValue *ra, TValue *rb);
raviV_op_totypeT =
llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false);
// l_noret luaG_runerror (lua_State *L, const char *fmt, ...)
elements.clear();
elements.push_back(plua_StateT);
@ -809,9 +817,9 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
raviV_settable_sskeyT =
llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false);
raviV_gettable_iT =
llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false);
llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false);
raviV_settable_iT =
llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false);
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);
@ -1361,4 +1369,4 @@ void LuaLLVMTypes::dump() {
fputs("\n", stdout);
#endif
}
}
} // namespace ravi
Loading…
Cancel
Save