[pypy-commit] pypy default: improve the embedding interface a little
fijal
noreply at buildbot.pypy.org
Wed Feb 26 15:30:10 CET 2014
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch:
Changeset: r69463:849a6171a311
Date: 2014-02-26 16:29 +0200
http://bitbucket.org/pypy/pypy/changeset/849a6171a311/
Log: improve the embedding interface a little
diff --git a/include/PyPy.h b/include/PyPy.h
--- a/include/PyPy.h
+++ b/include/PyPy.h
@@ -8,9 +8,14 @@
extern "C" {
#endif
+/* You should call this first once. */
+#define pypy_init(need_threads) do { pypy_asm_stack_bottom(); \
+rpython_startup_code();\
+ if (need_threads) pypy_init_threads(); } while (0)
-/* You should call this first once. */
+// 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 @@
/* 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,
+ see below). DO NOT CALL IT IN THE MAIN THREAD
*/
-void pypy_init_threads(void);
void pypy_thread_attach(void);
diff --git a/pypy/doc/embedding.rst b/pypy/doc/embedding.rst
--- a/pypy/doc/embedding.rst
+++ b/pypy/doc/embedding.rst
@@ -23,7 +23,6 @@
.. 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 @@
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 @@
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/libpypy-c.so``. 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;
+
+ rpython_startup_code();
+ 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 at hermann:/opt/pypy$ gcc -o x x.c -lpypy-c -L.
+ fijal at hermann:~/src/pypy$ LD_LIBRARY_PATH=. ./x
+ hello from pypy
+
+Worked!
+
+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.
+
+xxx
Threading
---------
XXXX I don't understand what's going on, discuss with unbit
-.. _`cffi`: xxx
-.. _`uwsgi`: xxx
-.. _`PyPy uwsgi plugin`: xxx
+.. _`cffi`: http://cffi.readthedocs.org/
+.. _`uwsgi`: http://uwsgi-docs.readthedocs.org/en/latest/
+.. _`PyPy uwsgi plugin`: http://uwsgi-docs.readthedocs.org/en/latest/PyPy.html
diff --git a/pypy/goal/targetpypystandalone.py b/pypy/goal/targetpypystandalone.py
--- a/pypy/goal/targetpypystandalone.py
+++ b/pypy/goal/targetpypystandalone.py
@@ -82,6 +82,7 @@
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 @@
@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
+ llop.gc_stack_bottom(lltype.Void)
verbose = rffi.cast(lltype.Signed, verbose)
if ll_home:
home = rffi.charp2str(ll_home)
@@ -121,6 +123,7 @@
@entrypoint('main', [rffi.CCHARP], c_name='pypy_execute_source')
def pypy_execute_source(ll_source):
rffi.aroundstate.after()
+ llop.gc_stack_bottom(lltype.Void)
source = rffi.charp2str(ll_source)
res = _pypy_execute_source(source)
rffi.aroundstate.before()
More information about the pypy-commit
mailing list