[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Tinycc-devel] tcc_relocate() and tcc_relocate_ex()
From: |
Sean Conner |
Subject: |
Re: [Tinycc-devel] tcc_relocate() and tcc_relocate_ex() |
Date: |
Tue, 28 Aug 2012 14:04:10 -0400 |
User-agent: |
Mutt/1.4.1i |
It was thus said that the Great grischka once stated:
> Sean Conner wrote:
> > Can you at least commit the change that makes tcc_relocate_ex() global?
>
> Yes, perhaps at least. You wrote:
> >... but fixing my code to match the current definition
> >of tcc_relocate() was out of the question (the surrounding code manages the
> >lifetime of both the TCCState and the resulting executable code compiled
> >into memory).
>
> I'd actually like to know some details why you can't just use
> tcc_relocate()?
> Admittedly we know little about how people actually use the libtcc API.
I have three use cases right now in using libtcc.
Case 1: Synthesis OS (http://valerieaurora.org/synthesis/SynthesisOS/)
Synthesis OS was an experiment operating system from 1992 written for a
Ph. D. dissertation. Dispite it being written in assembly language
(MC68030) it basically would "recompile" system calls on the fly (the whole
thing is mind blowing and its worth reading the dissertation)---think of a
"just-in-time" compiler but one that recompiles the kernel as needed. This
is a technique I'm interested in (on my own time).
I have a "wow---it can work!" type of prototype using libtcc (nothing even
close to a kernel, just some simple code). I have a custom "open()"
function that will compile a custom "read()" routine based upon the
paramteres given it---if I open a file read-only for character-by-character
access, and if the file can be mmap()'ed into memory, then you get a
specialized version of read() that returns successive characters from an
mmap()'ed file; if the file can't be mmap()'ed, you get a more traditional
read() function. This re-compilation happens on a file-by-file basis (each
file returned from my custom open() will have a custom read() function
compiled that deals only with the given file).
The issue here with tcc_relocate() is that once the compilation phase is
done, I don't need (or want) the symbol table, section definitions, buffers,
or anything else of the TCCState *except for the code just compiled*, and
the memory for that (the compiled code) is reclaimed on the call to a custom
close() function.
Yes, I could skip the compilation step and load pre-written functions (as
a shared object) but the ability to compile a custom version, quickly (one
of the strengths of TCC) in memory and use it immediately, is not something
I want to give up here.
Case 2: Lua (http://www.lua.org/)
Just to recap Lua---it's a small scripting language intended to be
embedded in a larger application to give said application scripting
abilities. You can also load additional modules either written in Lua or
written in C (as shared objects, either .so for Unix or .dll for Windows).
Anyway, I wrote Lua bindings for libtcc [1], so from within a Lua script,
I can include C code, compile it and then call the newly compiled C code
from Lua (you can see an example of this starting with line 112 of [2]).
Just as with case 1, once the code is compiled, I don't care about the rest
of the TCCState---just the compiled code.
In fact, I use the libtcc bindings to extend Lua's require() function to
compile a Lua module upon loading it, and have Lua manage the memory for the
resulting code automatically (Lua is a garbage collected language).
[1] https://github.com/spc476/lua-conmanorg/blob/master/src/tcc.c
[2] https://github.com/spc476/lua-conmanorg/blob/master/lua/cc.lua
Case 3: Closures in C (or, a mixture of case 1 and case 2)
Why this exists doesn't matter, but I have written Lua bindings to Xlib
(the lowest level of X programming without talking the protocol directly).
Xlib, however, reports some errors via a callback function you register
using XSetErrorHandler():
int (*XSetErrorHandler(int (*handler)(Display *, XErrorEvent *)))();
I would like to push the error into Lua, but the issue I have is---I need
a global variable pointing to the current Lua state, which is something I
don't particularly want (the global variable), because the following:
int foo(lua_State *L)
{
XSetErrorHandler(int (Display *display,XEerrorEvent *event)
{
lua_pushlightuserdata(L,display);
lua_gettable(L,LUA_REGISTRYINDEX);
lua_getfield(L,-1,"error_handler");
mylua_pushevent(L,event);
lua_call(L,1,0);
return 0;
}
)
return 0;
}
is not legal C. However, using libtcc, I can fake a closure with C:
#include <stdlib.h>
#include <X11/Xlib.h>
#include <syslog.h>
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
lua_State *L;
int Xcallback_function(Display *display,XErrorEvent *event)
{
lua_pushlightuserdata(...);
/* ... */
}
and compile it with (excluding error checking for clarity):
lua_State *L; /* assume it's set properly */
TCCState *s;
int size;
void *mem;
lua_State **pL;
int (*cb)(Display *,XErrorEvent *);
s = tcc_new();
tcc_set_output_type(s,TCC_OUT_MEMORY);
tcc_add_file(s,"xcallback.c");
size = tcc_relocate_ex(s,NULL);
mem = lua_newuserdata(L,size);
tcc_relocate_ex(s,mem);
pL = tcc_get_symbol(s,"L");
cb = tcc_get_symbol(s,"Xcallback_function");
*pL = L;
XSetErrorHandler(cb);
/*----------------------------------------
; I don't need the compiler info any more
;----------------------------------------*/
tcc_delete(s);
Yes, it's a bit of a ways to go to get closures under C, but it works.
And in all cases, once the code is compiled, I have no need for the
compiler specific stuff (symbols, section definitions, etc), but I want the
code. In order to get that, I need tcc_relocate_ex()---tcc_relocate() does
a bit *too* much for me, and leaves around a ton of stuff I don't care about
after compiling the code.
In a way, I'm embedding libtcc into an application to allow me to extend
the application with C (much like you can do with Lua).
-spc (So, I hope that answers your question ... )
- Re: [Tinycc-devel] tcc_relocate() and tcc_relocate_ex(), (continued)
- Re: [Tinycc-devel] tcc_relocate() and tcc_relocate_ex(), grischka, 2012/08/13
- Re: [Tinycc-devel] tcc_relocate() and tcc_relocate_ex(), Sean Conner, 2012/08/13
- Re: [Tinycc-devel] tcc_relocate() and tcc_relocate_ex(), Sean Conner, 2012/08/13
- Re: [Tinycc-devel] tcc_relocate() and tcc_relocate_ex(), grischka, 2012/08/14
- Re: [Tinycc-devel] tcc_relocate() and tcc_relocate_ex(), Sean Conner, 2012/08/22
- Re: [Tinycc-devel] tcc_relocate() and tcc_relocate_ex(), grischka, 2012/08/23
- Re: [Tinycc-devel] tcc_relocate() and tcc_relocate_ex(), Sean Conner, 2012/08/23
- Re: [Tinycc-devel] tcc_relocate() and tcc_relocate_ex(), grischka, 2012/08/24
- Re: [Tinycc-devel] tcc_relocate() and tcc_relocate_ex(), Sean Conner, 2012/08/24
- Re: [Tinycc-devel] tcc_relocate() and tcc_relocate_ex(), grischka, 2012/08/27
- Re: [Tinycc-devel] tcc_relocate() and tcc_relocate_ex(),
Sean Conner <=
- Re: [Tinycc-devel] tcc_relocate() and tcc_relocate_ex(), David Mertens, 2012/08/28
- Re: [Tinycc-devel] tcc_relocate() and tcc_relocate_ex(), Michael Matz, 2012/08/28
- Re: [Tinycc-devel] tcc_relocate() and tcc_relocate_ex(), grischka, 2012/08/29
- Re: [Tinycc-devel] tcc_relocate() and tcc_relocate_ex(), Sean Conner, 2012/08/29
Re: [Tinycc-devel] tcc_relocate() and tcc_relocate_ex(), Jared Maddox, 2012/08/29
Re: [Tinycc-devel] tcc_relocate() and tcc_relocate_ex(), Sean Conner, 2012/08/30