[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