Commit 768a8f8e authored by Maciej Fijalkowski's avatar Maciej Fijalkowski

improve the embedding interface a little

parent c4ef4b01
......@@ -8,9 +8,14 @@
extern "C" {
/* You should call this first once. */
#define pypy_init(need_threads) do { pypy_asm_stack_bottom(); \
if (need_threads) pypy_init_threads(); } while (0)
// deprecated interface
void rpython_startup_code(void);
void pypy_init_threads(void);
/* Initialize the home directory of PyPy. It is necessary to call this.
......@@ -26,11 +31,10 @@ int pypy_setup_home(char *home, int verbose);
/* If your program has multiple threads, then you need to call
pypy_init_threads() once at init time, and then pypy_thread_attach()
once in each other thread that just started and in which you want to
run Python code (including via callbacks, see below).
pypy_thread_attach() once in each other thread that just started
and in which you want to run Python code (including via callbacks,
void pypy_init_threads(void);
void pypy_thread_attach(void);
......@@ -23,7 +23,6 @@ is:
.. function:: void pypy_init_threads(void);
Initialize threads. Only need to be called if there are any threads involved
XXXX double check
.. function:: long pypy_setup_home(char* home, int verbose);
......@@ -43,7 +42,7 @@ is:
Execute the source code given in the ``source`` argument. Will print
the error message to stderr upon failure and return 1, otherwise returns 0.
You should really do your own error handling in the source. It'll acquire
the GIL.
.. function:: void pypy_thread_attach(void);
......@@ -55,12 +54,51 @@ is:
Simple example
Note that this API is a lot more minimal than say CPython C API, so at first
it's obvious to think that you can't do much. However, the trick is to do
all the logic in Python and expose it via `cffi`_ callbacks. Let's assume
we're on linux and pypy is put in ``/opt/pypy`` (a source checkout) and
library is in ``/opt/pypy/``. We write a little C program
(for simplicity assuming that all operations will be performed::
#include "include/PyPy.h"
#include <stdio.h>
const char source[] = "print 'hello from pypy'";
int main()
int res;
res = pypy_execute_source((char*)source);
if (res) {
printf("Error calling pypy_execute_source!\n");
return res;
If we save it as ``x.c`` now, compile it and run it with::
fijal@hermann:/opt/pypy$ gcc -o x x.c -lpypy-c -L.
fijal@hermann:~/src/pypy$ LD_LIBRARY_PATH=. ./x
hello from pypy
More advanced example
Typically we need something more to do than simply execute source. The following
is a fully fledged example, please consult cffi documentation for details.
XXXX I don't understand what's going on, discuss with unbit
.. _`cffi`: xxx
.. _`uwsgi`: xxx
.. _`PyPy uwsgi plugin`: xxx
.. _`cffi`:
.. _`uwsgi`:
.. _`PyPy uwsgi plugin`:
......@@ -82,6 +82,7 @@ def create_entry_point(space, w_dict):
from rpython.rlib.entrypoint import entrypoint
from rpython.rtyper.lltypesystem import rffi, lltype
from rpython.rtyper.lltypesystem.lloperation import llop
w_pathsetter = space.appexec([], """():
def f(path):
......@@ -93,6 +94,7 @@ def create_entry_point(space, w_dict):
@entrypoint('main', [rffi.CCHARP, rffi.INT], c_name='pypy_setup_home')
def pypy_setup_home(ll_home, verbose):
from pypy.module.sys.initpath import pypy_find_stdlib
verbose = rffi.cast(lltype.Signed, verbose)
if ll_home:
home = rffi.charp2str(ll_home)
......@@ -121,6 +123,7 @@ def create_entry_point(space, w_dict):
@entrypoint('main', [rffi.CCHARP], c_name='pypy_execute_source')
def pypy_execute_source(ll_source):
source = rffi.charp2str(ll_source)
res = _pypy_execute_source(source)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment