issue #78 nearly done

pull/81/head
Dibyendu Majumdar 8 years ago
parent 5472c25f2c
commit 1ed019dffd

@ -381,6 +381,9 @@ class RAVI_API RaviJITModule {
// post compilation
std::vector<RaviJITFunction *> functions_;
// Keep track of external symbols added
std::map<std::string, llvm::Function *> external_symbols_;
public:
RaviJITModule(RaviJITState *owner);
~RaviJITModule();

@ -53,6 +53,9 @@ void raviV_close(struct lua_State *L);
/* Compile the given function if possible */
int raviV_compile(struct lua_State *L, struct Proto *p,
ravi_compile_options_t *options);
/* Compile an array of functions */
int raviV_compile_n(struct lua_State *L, struct Proto *p[], int n,
ravi_compile_options_t *options);
int raviV_iscompiled(struct lua_State *L, struct Proto *p);
/* Free the JIT structures associated with the prototype */

@ -913,6 +913,12 @@ static void init_def(ravi_function_def_t *def, ravi_gcc_context_t *ravi,
def->dump_asm = 0;
}
int raviV_compile_n(struct lua_State *L, struct Proto *p[], int n,
ravi_compile_options_t *options) {
// FIXME implement
return 0;
}
// Compile a Lua function
// If JIT is turned off then compilation is skipped
// Compilation occurs if either auto compilation is ON (subject to some

@ -282,6 +282,9 @@ void RaviJITFunction::setFunctionPtr() {
llvm::Function *RaviJITModule::addExternFunction(llvm::FunctionType *type,
void *address,
const std::string &name) {
auto fn = external_symbols_.find(name);
if (fn != external_symbols_.end())
return fn->second;
llvm::Function *f = llvm::Function::Create(
type, llvm::Function::ExternalLinkage, name, module_);
f->setDoesNotThrow();
@ -291,6 +294,7 @@ llvm::Function *RaviJITModule::addExternFunction(llvm::FunctionType *type,
// See bug report http://llvm.org/bugs/show_bug.cgi?id=20656
// following will call DynamicLibrary::AddSymbol
owner_->addGlobalSymbol(name, address);
external_symbols_[name] = f;
return f;
}
@ -373,6 +377,25 @@ int raviV_compile(struct lua_State *L, struct Proto *p,
return p->ravi_jit.jit_function != nullptr;
}
// Compile a bunch of Lua functions
// And put them all in one module
// Returns true if compilation was successful
int raviV_compile_n(struct lua_State *L, struct Proto *p[], int n,
ravi_compile_options_t *options) {
global_State *G = G(L);
int count = 0;
auto module = std::make_shared<ravi::RaviJITModule>(G->ravi_state->jit);
for (int i = 0; i < n; i++) {
if (G->ravi_state->code_generator->compile(L, p[i], module, options))
count++;
}
if (count) {
module->runpasses();
module->finalize(options ? options->dump_level != 0 : 0);
}
return count > 0;
}
// Free the JIT compiled function
// Note that this is called by the garbage collector
void raviV_freeproto(struct lua_State *L, struct Proto *p) {

@ -28,13 +28,13 @@ extern "C" {
#define LUA_CORE
#include "lua.h"
#include "lobject.h"
#include "lstate.h"
#include "lauxlib.h"
#include "lapi.h"
#include "lopcodes.h"
#include "lauxlib.h"
#include "lfunc.h"
#include "lobject.h"
#include "lopcodes.h"
#include "lstate.h"
#include "lua.h"
#include <string.h>
@ -94,6 +94,47 @@ static int ravi_compile(lua_State *L) {
return 1;
}
static int ravi_compile_n(lua_State *L) {
enum { MAX_COMPILES = 100 };
Proto *functions[MAX_COMPILES];
int n = 0;
if (lua_istable(L, 1)) {
lua_pushnil(L); // push first key
while (lua_next(L, 1)) {
if (n < MAX_COMPILES && lua_isfunction(L, -1) &&
!lua_iscfunction(L, -1)) {
void *p = (void *)lua_topointer(L, -1);
LClosure *l = reinterpret_cast<LClosure *>(p);
if (!l->p->ravi_jit.jit_function) functions[n++] = l->p;
}
lua_pop(L, 1); // pop value, but keep key
}
}
else {
luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1,
"argument must be a Lua function");
void *p = (void *)lua_topointer(L, 1);
LClosure *l = reinterpret_cast<LClosure *>(p);
functions[n++] = l->p;
}
ravi_compile_options_t options = {0};
options.manual_request = 1;
if (lua_istable(L, 2)) {
lua_Integer do_dump, do_verify, omit_arrayget_rangecheck;
l_table_get_integer(L, 2, "dump", &do_dump, 0);
l_table_get_integer(L, 2, "verify", &do_verify, 0);
l_table_get_integer(L, 2, "omitArrayGetRangeCheck",
&omit_arrayget_rangecheck, 0);
options.omit_array_get_range_check = (int)omit_arrayget_rangecheck;
options.dump_level = (int)do_dump;
options.verification_level = (int)do_verify;
}
int result = 0;
if (n > 0) { result = raviV_compile_n(L, functions, n, &options); }
lua_pushboolean(L, result);
return 1;
}
// Dump Lua bytecode of the supplied function
static int ravi_dump_luacode(lua_State *L) {
int n = lua_gettop(L);
@ -136,14 +177,11 @@ static int ravi_auto(lua_State *L) {
lua_pushboolean(L, raviV_getauto(L));
lua_pushinteger(L, raviV_getmincodesize(L));
lua_pushinteger(L, raviV_getminexeccount(L));
if (n >= 1)
raviV_setauto(L, lua_toboolean(L, 1));
if (n >= 1) raviV_setauto(L, lua_toboolean(L, 1));
int min_code_size = (n >= 2) ? (int)(lua_tointeger(L, 2)) : -1;
int min_exec_count = (n == 3) ? (int)(lua_tointeger(L, 3)) : -1;
if (min_code_size >= 1)
raviV_setmincodesize(L, min_code_size);
if (min_exec_count >= 1)
raviV_setminexeccount(L, min_exec_count);
if (min_code_size >= 1) raviV_setmincodesize(L, min_code_size);
if (min_exec_count >= 1) raviV_setminexeccount(L, min_exec_count);
return 3;
}
@ -208,13 +246,14 @@ static int ravi_traceenable(lua_State *L) {
}
static int ravi_listcode(lua_State *L) {
luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
1, "Lua function expected");
luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1,
"Lua function expected");
return ravi_list_code(L);
}
static const luaL_Reg ravilib[] = {{"iscompiled", ravi_is_compiled},
{"compile", ravi_compile},
{"compilen", ravi_compile_n},
{"dumplua", ravi_dump_luacode},
{"dumpllvm", ravi_dump_ir},
{"dumpir", ravi_dump_ir},

Loading…
Cancel
Save