issue #198 WIP flesh out some more api functions

ravi-compiler
Dibyendu Majumdar 4 years ago
parent 2cab1f104a
commit 98c96c11eb

@ -140,12 +140,17 @@ else ()
endif () endif ()
endif () endif ()
if (RAVICOMP) if (RAVICOMP AND MIR_JIT)
# Need MIR_JIT for the compiler add-on
find_package(RaviComp REQUIRED) find_package(RaviComp REQUIRED)
set(ADDON_SRCS ${RAVICOMP_SRCS}) set(ADDON_SRCS ${RAVICOMP_SRCS})
set_property(SOURCE ${RAVICOMP_SRCS} set_property(SOURCE ${RAVICOMP_SRCS}
APPEND APPEND
PROPERTY INCLUDE_DIRECTORIES ${RAVICOMP_INCLUDE_DIRS}) PROPERTY INCLUDE_DIRECTORIES ${RAVICOMP_INCLUDE_DIRS})
if ($ENV{CLION_IDE})
# CLion seems unable to handle include paths set on sources
include_directories(${RAVICOMP_INCLUDE_DIRS})
endif ()
endif() endif()
# IDE stuff # IDE stuff

@ -10,5 +10,6 @@ find_library(RAVICOMP_LIBRARIES
PATHS PATHS
c:/Software/ravicomp/lib c:/Software/ravicomp/lib
~/Software/ravicomp/lib ~/Software/ravicomp/lib
~/Software/ravicomp/lib64
) )

@ -2,6 +2,8 @@
#define LUA_CORE #define LUA_CORE
#include "ravi_mirjit.h"
#include "lua.h" #include "lua.h"
#include "lapi.h" #include "lapi.h"
#include "lauxlib.h" #include "lauxlib.h"
@ -9,45 +11,50 @@
#include "lmem.h" #include "lmem.h"
#include "lstring.h" #include "lstring.h"
#include "ltable.h" #include "ltable.h"
#include "lvm.h"
#include <string.h>
struct CompilerContext { struct CompilerContext {
lua_State* L; lua_State* L;
Table* h; /* to avoid collection/reuse strings */ ravi_State* jit;
Table* h; /* to avoid collection/reuse strings */
}; };
/* Create a new proto and insert it into parent's list of protos */
static Proto* lua_newProto(void* context, Proto* parent) { static Proto* lua_newProto(void* context, Proto* parent) {
struct CompilerContext* ccontext = (struct CompilerContext*)context; struct CompilerContext* ccontext = (struct CompilerContext*)context;
lua_State* L = ccontext->L; lua_State* L = ccontext->L;
Proto* p = luaF_newproto(L); Proto* p = luaF_newproto(L);
if (parent) { assert(parent);
int old_size = parent->sizep; /* FIXME make this more efficient */
int new_size = parent->sizep + 1; int old_size = parent->sizep;
luaM_growvector(L, parent->p, old_size, new_size, Proto*, MAXARG_Bx, "functions"); int new_size = parent->sizep + 1;
parent->p[parent->sizep++] = p; luaM_growvector(L, parent->p, old_size, new_size, Proto*, MAXARG_Bx, "functions");
// luaC_objbarrier(L, f, clp); parent->p[parent->sizep++] = p;
} luaC_objbarrier(L, parent, p);
return p; return p;
} }
/* /*
* Based off the Lua lexer code. * Based off the Lua lexer code.
*/ */
TString* create_newstring(lua_State* L, Table *h, const char* str, size_t l) { TString* create_newstring(lua_State* L, Table* h, const char* str, size_t l) {
TValue* o; /* entry for 'str' */ TValue* o; /* entry for 'str' */
TString* ts = luaS_newlstr(L, str, l); /* create new string */ TString* ts = luaS_newlstr(L, str, l); /* create new string */
setsvalue2s(L, L->top++, ts); /* temporarily anchor it in stack */ setsvalue2s(L, L->top++, ts); /* temporarily anchor it in stack */
o = luaH_set(L, h, L->top - 1); o = luaH_set(L, h, L->top - 1);
if (ttisnil(o)) { /* not in use yet? */ if (ttisnil(o)) { /* not in use yet? */
/* boolean value does not need GC barrier; /* boolean value does not need GC barrier;
table has no metatable, so it does not need to invalidate cache */ table has no metatable, so it does not need to invalidate cache */
setbvalue(o, 1); /* t[string] = true */ setbvalue(o, 1); /* t[string] = true */
luaC_checkGC(L); luaC_checkGC(L);
} }
else { /* string already present */ else { /* string already present */
ts = tsvalue(keyfromval(o)); /* re-use value previously stored */ ts = tsvalue(keyfromval(o)); /* re-use value previously stored */
} }
L->top--; /* remove string from stack */ L->top--; /* remove string from stack */
return ts; return ts;
} }
/* /*
@ -57,54 +64,53 @@ TString* create_newstring(lua_State* L, Table *h, const char* str, size_t l) {
** as keys (nil cannot be a key, integer keys can collapse with float ** as keys (nil cannot be a key, integer keys can collapse with float
** keys), the caller must provide a useful 'key' for indexing the cache. ** keys), the caller must provide a useful 'key' for indexing the cache.
*/ */
static int addk(lua_State *L, Proto* f, Table* h, TValue* key, TValue* v) { static int addk(lua_State* L, Proto* f, Table* h, TValue* key, TValue* v) {
TValue* idx = luaH_set(L, h, key); /* index scanner table */ TValue* idx = luaH_set(L, h, key); /* index scanner table */
int k, oldsize; int k, oldsize;
if (ttisinteger(idx)) { /* is there an index there? */ if (ttisinteger(idx)) { /* is there an index there? */
k = cast_int(ivalue(idx)); k = cast_int(ivalue(idx));
/* correct value? (warning: must distinguish floats from integers!) */ /* correct value? (warning: must distinguish floats from integers!) */
if (k < f->sizek && ttype(&f->k[k]) == ttype(v) && if (k < f->sizek && ttype(&f->k[k]) == ttype(v) && luaV_rawequalobj(&f->k[k], v))
luaV_rawequalobj(&f->k[k], v)) return k; /* reuse index */
return k; /* reuse index */ }
} /* constant not found; create a new entry */
/* constant not found; create a new entry */ oldsize = f->sizek;
oldsize = f->sizek; k = f->sizek;
k = f->sizek; /* numerical value does not need GC barrier;
/* numerical value does not need GC barrier; table has no metatable, so it does not need to invalidate cache */
table has no metatable, so it does not need to invalidate cache */ setivalue(idx, k);
setivalue(idx, k); luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants");
luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants"); while (oldsize < f->sizek)
while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); setnilvalue(&f->k[oldsize++]);
setobj(L, &f->k[k], v); setobj(L, &f->k[k], v);
f->sizek++; f->sizek++;
luaC_barrier(L, f, v); luaC_barrier(L, f, v);
return k; return k;
} }
/* /*
** Add a string to list of constants and return its index. ** Add a string to list of constants and return its index.
*/ */
static int lua_stringK(lua_State *L, Proto* p, Table *h, TString* s) { static int lua_stringK(lua_State* L, Proto* p, Table* h, TString* s) {
TValue o; TValue o;
setsvalue(L, &o, s); setsvalue(L, &o, s);
return addk(L, p, h, &o, &o); /* use string itself as key */ return addk(L, p, h, &o, &o); /* use string itself as key */
} }
/* Add a string constant to Proto and return its index */ /* Add a string constant to Proto and return its index */
static int lua_newStringConstant(void *context, Proto* proto, struct string_object *s) { static int lua_newStringConstant(void* context, Proto* proto, struct string_object* s) {
struct CompilerContext* ccontext = (struct CompilerContext*)context; struct CompilerContext* ccontext = (struct CompilerContext*)context;
lua_State* L = ccontext->L; lua_State* L = ccontext->L;
Table* h = ccontext->h; Table* h = ccontext->h;
TString* ts = NULL; TString* ts = NULL;
if (s->userdata == NULL) { if (s->userdata == NULL) {
ts = create_newstring(L, h, s->str, s->len); ts = create_newstring(L, h, s->str, s->len);
s->userdata = ts; s->userdata = ts;
} }
else { else {
ts = (TString *) s->userdata; ts = (TString*)s->userdata;
} }
return lua_stringK(L, proto, h, ts); return lua_stringK(L, proto, h, ts);
} }
static void init_C_compiler(void* context) { static void init_C_compiler(void* context) {
@ -128,41 +134,41 @@ static lua_CFunction get_compiled_function(void* context, void* module, const ch
static void lua_setProtoFunction(void* context, Proto* p, lua_CFunction func) { p->ravi_jit.jit_function = func; } static void lua_setProtoFunction(void* context, Proto* p, lua_CFunction func) { p->ravi_jit.jit_function = func; }
static int load_and_compile(lua_State* L) { static int load_and_compile(lua_State* L) {
const char* s = luaL_checkstring(L, 1); const char* s = luaL_checkstring(L, 1);
struct CompilerContext ccontext = { .L = L }; struct CompilerContext ccontext = {.L = L, .jit = G(L)->ravi_state};
LClosure* cl = luaF_newLclosure(L, 1); /* create main closure */ LClosure* cl = luaF_newLclosure(L, 1); /* create main closure */
setclLvalue(L, L->top, cl); /* anchor it (to avoid being collected) */ setclLvalue(L, L->top, cl); /* anchor it (to avoid being collected) */
luaD_inctop(L); luaD_inctop(L);
ccontext.h = luaH_new(L); /* create table for string constants */ ccontext.h = luaH_new(L); /* create table for string constants */
sethvalue(L, L->top, ccontext.h); /* anchor it */ sethvalue(L, L->top, ccontext.h); /* anchor it */
luaD_inctop(L); luaD_inctop(L);
Proto *main_proto = cl->p = luaF_newproto(L); Proto* main_proto = cl->p = luaF_newproto(L);
luaC_objbarrier(L, cl, cl->p); luaC_objbarrier(L, cl, cl->p);
struct Ravi_CompilerInterface ravicomp_interface = { struct Ravi_CompilerInterface ravicomp_interface = {.source = s,
.source = s, .source_len = strlen(s),
.source_len = strlen(s), .source_name = "input",
.source_name = "input", .main_proto = main_proto,
.lua_newProto = lua_newProto, .context = &ccontext,
.lua_newStringConstant = lua_newStringConstant, .lua_newProto = lua_newProto,
.main_proto = main_proto, .lua_newStringConstant = lua_newStringConstant,
.context = &ccontext .init_C_compiler = init_C_compiler,
}; .compile_C = compile_C,
.finish_C_compiler = finish_C_compiler,
int rc = raviX_compile(&ravicomp_interface); .get_compiled_function = get_compiled_function,
L->top--; /* remove table */ .lua_setProtoFunction = lua_setProtoFunction};
lua_assert(cl->nupvalues == cl->p->sizeupvalues); int rc = raviX_compile(&ravicomp_interface);
luaF_initupvals(L, cl); L->top--; /* remove table */
lua_assert(cl->nupvalues == cl->p->sizeupvalues);
luaF_initupvals(L, cl);
} }
static const luaL_Reg ravilib[] = { static const luaL_Reg ravilib[] = {{NULL, NULL}};
{NULL, NULL} };
int (raviopen_compiler)(lua_State *L) { int(raviopen_compiler)(lua_State* L) {
luaL_newlib(L, ravilib); luaL_newlib(L, ravilib);
return 1; return 1;
} }
Loading…
Cancel
Save