[pypy-dev] pypy callback function pointer become invalid
Yicong Huang
hengha.mao at gmail.com
Mon Aug 17 12:59:52 CEST 2015
Hi Armin,
Great thanks for the demo code!
I think the approach should work, but there might be a lot of work to do in
"run_function" to perform a simple python function call.
Assuming we would like to do the simple work as original
pypy_execute_source_ptr()
does, with such approch, we need to pass python code as char* to callback
function "def run_function(p_src)".
In theory we could do everything, even much more complex than eval().
However, to perform the python function call, we need to parse char*(python
code), a python code lexer, praser, JIT and etc, in other words do all the
work that pypy_execute_source() did. The only difference is we don't need
pypy_execute_source_ptr(), but pypy_execute_source().
I think pypy_execute_source() plays the same role as eval() in your example
code.
So why don't PyPy expose and API to do such job ? ( pypy_execute_source(),
either python or C)
On Mon, Aug 17, 2015 at 4:08 PM, Armin Rigo <arigo at tunes.org> wrote:
> Hi Yicong,
>
> On 17 August 2015 at 08:40, Yicong Huang <hengha.mao at gmail.com> wrote:
> > yes, we could use a structure to wrap severl python callback function
> > pointers in one execution.
> > However, the issue is that we might not be able to get all python
> functions
> > that would be executed at the beginning.
>
> The basic idea is to define whatever API you need with just one call
> to pypy_execute_source_ptr(). If you want to be able to compile and
> execute arbitrary Python functions, just make that feature available
> in your API. This is the same idea as PyRun_SimpleString(), which is
> *one* API function but lets you execute arbitrary Python code.
> Example:
>
>
> struct API {
> long (*run_function)(char *);
> };
> struct API api; /* global var */
>
> int initialize_api(void) { /* run this only once */
> static char source[] =
> "import sys; sys.path.insert(0, '.'); "
> "import interface; interface.fill_api(c_argument)";
> pypy_execute_source_ptr(source, &api);
> }
>
> /* then execute 'api.run_function(some_source_code)' any number of times */
>
>
> # file "interface.py"
>
> import cffi
>
> ffi = cffi.FFI()
> ffi.cdef('''
> struct API {
> long (*run_function)(char *);
> };
> ''')
>
> @ffi.callback("long(char *)")
> def run_function(p_src):
> src = ffi.string(p_src)
> # here 'src' is a string, we can do whatever we want with it---like
> eval()
> return eval(src, {})
>
> def fill_api(ptr):
> global api
> api = ffi.cast("struct API*", ptr)
> api.run_function = run_function
>
>
> ---
> Armin
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/pypy-dev/attachments/20150817/d73e04e1/attachment.html>
More information about the pypy-dev
mailing list