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 <ar...@tunes.org> wrote: > Hi Yicong, > > On 17 August 2015 at 08:40, Yicong Huang <hengha....@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 >
_______________________________________________ pypy-dev mailing list pypy-dev@python.org https://mail.python.org/mailman/listinfo/pypy-dev