[pypy-commit] pypy pypy-in-a-box: try to add some minimal embedding API
fijal
noreply at buildbot.pypy.org
Wed Jul 18 12:06:32 CEST 2012
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: pypy-in-a-box
Changeset: r56124:d5cbfd2fe88a
Date: 2012-07-18 12:06 +0200
http://bitbucket.org/pypy/pypy/changeset/d5cbfd2fe88a/
Log: try to add some minimal embedding API
diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py
--- a/pypy/config/pypyoption.py
+++ b/pypy/config/pypyoption.py
@@ -346,6 +346,10 @@
default=False,
# weakrefs needed, because of get_subclasses()
requires=[("translation.rweakref", True)]),
+ BoolOption("withembeddingapi",
+ "enable embedding API",
+ default=True),
+
]),
])
diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -13,7 +13,6 @@
from pypy.translator.tool.cbuild import ExternalCompilationInfo
from pypy.translator.gensupp import NameManager
from pypy.tool.udir import udir
-from pypy.translator import platform
from pypy.module.cpyext.state import State
from pypy.interpreter.error import OperationError, operationerrfmt
from pypy.interpreter.baseobjspace import W_Root
diff --git a/pypy/objspace/std/embedding.py b/pypy/objspace/std/embedding.py
new file mode 100644
--- /dev/null
+++ b/pypy/objspace/std/embedding.py
@@ -0,0 +1,69 @@
+
+from pypy.rpython.lltypesystem import rffi, lltype
+from pypy.rpython.lltypesystem.lloperation import llop
+from pypy.interpreter.pyopcode import prepare_exec
+from pypy.interpreter.pycode import PyCode
+from pypy.interpreter.error import OperationError
+from pypy.interpreter import eval
+
+FUNCTIONS = {}
+
+class Cache(object):
+ def __init__(self, space):
+ self.w_globals = space.newdict(module=True)
+ space.call_method(self.w_globals, 'setdefault',
+ space.wrap('__builtins__'),
+ space.wrap(space.builtin))
+
+def export_function(argtypes, restype):
+ """ Export the function, sans the space argument
+ """
+ def wrapper(func):
+ def newfunc(*args):
+ llop.gc_stack_bottom(lltype.Void) # marker for trackgcroot.py
+ try:
+ rffi.stackcounter.stacks_counter += 1
+ res = func(*args)
+ except Exception, e:
+ print "Fatal error embedding API, cannot proceed"
+ print str(e)
+ rffi.stackcounter.stacks_counter -= 1
+ return res
+ FUNCTIONS[func.func_name] = (func, argtypes, restype)
+ return func
+ return wrapper
+
+ at export_function([rffi.CArrayPtr(rffi.CCHARP), rffi.CCHARP], lltype.Void)
+def prepare_function(space, ll_names, ll_s):
+ s = rffi.charp2str(ll_s)
+ w_globals = space.fromcache(Cache).w_globals
+ ec = space.getexecutioncontext()
+ code_w = ec.compiler.compile(s, '<input>', 'exec', 0)
+ code_w.exec_code(space, w_globals, w_globals)
+
+ at export_function([rffi.CCHARP, lltype.Signed, rffi.CArrayPtr(rffi.VOIDP)],
+ rffi.VOIDP)
+def call_function(space, ll_name, numargs, ll_args):
+ name = rffi.charp2str(ll_name)
+ w_globals = space.fromcache(Cache).w_globals
+ try:
+ w_item = space.getitem(w_globals, space.wrap(name))
+ except OperationError:
+ print "Cannot find name %s" % name
+ return lltype.nullptr(rffi.VOIDP.TO)
+ args = [rffi.cast(lltype.Signed, ll_args[i]) for i in range(numargs)]
+ try:
+ w_res = space.call(w_item, space.newtuple([space.wrap(i) for i in args]))
+ except OperationError:
+ print "Error calling the function"
+ return lltype.nullptr(rffi.VOIDP)
+ try:
+ res = space.int_w(w_res)
+ except OperationError:
+ print "Function did not return int"
+ return lltype.nullptr(rffi.VOIDP)
+ return res
+
+def initialize(space):
+ for name, func in FUNCTIONS.iteritems():
+ pass
diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py
--- a/pypy/objspace/std/objspace.py
+++ b/pypy/objspace/std/objspace.py
@@ -84,6 +84,10 @@
transparent.setup(self)
self.setup_isinstance_cache()
+ # setup embedding API if enabled
+ if self.config.objspace.std.withembeddingapi:
+ from pypy.objspace.std import embedding
+ embedding.initialize(self)
def get_builtin_types(self):
return self.builtin_types
diff --git a/pypy/objspace/std/test/test_embedding.py b/pypy/objspace/std/test/test_embedding.py
new file mode 100644
--- /dev/null
+++ b/pypy/objspace/std/test/test_embedding.py
@@ -0,0 +1,32 @@
+
+from pypy.objspace.std.embedding import prepare_function, Cache, call_function
+from pypy.rpython.lltypesystem import rffi, lltype
+from pypy.interpreter.function import Function
+
+class TestEmbedding(object):
+ def test_prepare_function(self):
+ space = self.space
+ TP = rffi.CArray(rffi.CCHARP)
+ ll_arr = lltype.malloc(TP, 2, flavor='raw')
+ ll_arr[0] = rffi.str2charp("f")
+ ll_arr[1] = rffi.str2charp("g")
+ ll_source = rffi.str2charp('''
+def f(a, b):
+ return a + b
+def g(a):
+ return a - 2
+''')
+ prepare_function(space, ll_arr, ll_source)
+ w_f = space.getitem(space.fromcache(Cache).w_globals, space.wrap('f'))
+ assert isinstance(w_f, Function)
+ w_res = space.call_function(w_f, space.wrap(1), space.wrap(2))
+ assert space.int_w(w_res) == 3
+ ll_args = lltype.malloc(rffi.CArray(lltype.Signed), 2, flavor='raw')
+ ll_args[0] = 1
+ ll_args[1] = 2
+ call_function(space, ll_arr[0], 2, ll_args)
+ lltype.free(ll_arr[0], flavor='raw')
+ lltype.free(ll_arr[1], flavor='raw')
+ lltype.free(ll_arr, flavor='raw')
+ lltype.free(ll_source, flavor='raw')
+ lltype.free(ll_args, flavor='raw')
More information about the pypy-commit
mailing list