[pypy-commit] pypy llimpl: Create ExternalFunctionRepr
rlamy
pypy.commits at gmail.com
Tue Feb 16 13:14:05 EST 2016
Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: llimpl
Changeset: r82299:24d569eefdf9
Date: 2016-02-16 18:13 +0000
http://bitbucket.org/pypy/pypy/changeset/24d569eefdf9/
Log: Create ExternalFunctionRepr
diff --git a/rpython/rtyper/extfunc.py b/rpython/rtyper/extfunc.py
--- a/rpython/rtyper/extfunc.py
+++ b/rpython/rtyper/extfunc.py
@@ -1,10 +1,10 @@
from rpython.annotator.model import unionof, SomeObject
from rpython.annotator.signature import annotation, SignatureError
-from rpython.rtyper.extregistry import ExtRegistryEntry
+from rpython.rtyper.extregistry import ExtRegistryEntry, lookup
from rpython.rtyper.lltypesystem.lltype import (
- typeOf, FuncType, functionptr, _ptr)
+ typeOf, FuncType, functionptr, _ptr, Void)
from rpython.rtyper.error import TyperError
-from rpython.rtyper.rbuiltin import BuiltinFunctionRepr
+from rpython.rtyper.rmodel import Repr
class SomeExternalFunction(SomeObject):
def __init__(self, name, args_s, s_result):
@@ -36,10 +36,58 @@
def rtyper_makerepr(self, rtyper):
if not self.is_constant():
raise TyperError("Non-constant external function!")
- return BuiltinFunctionRepr(self.const)
+ entry = lookup(self.const)
+ impl = getattr(entry, 'lltypeimpl', None)
+ fakeimpl = getattr(entry, 'lltypefakeimpl', None)
+ return ExternalFunctionRepr(self, impl, fakeimpl)
def rtyper_makekey(self):
- return self.__class__, self.const
+ return self.__class__, self
+
+class ExternalFunctionRepr(Repr):
+ lowleveltype = Void
+
+ def __init__(self, s_func, impl, fakeimpl):
+ self.s_func = s_func
+ self.impl = impl
+ self.fakeimpl = fakeimpl
+
+ def rtype_simple_call(self, hop):
+ rtyper = hop.rtyper
+ args_r = [rtyper.getrepr(s_arg) for s_arg in self.s_func.args_s]
+ r_result = rtyper.getrepr(self.s_func.s_result)
+ obj = self.get_funcptr(rtyper, args_r, r_result)
+ hop2 = hop.copy()
+ hop2.r_s_popfirstarg()
+ vlist = [hop2.inputconst(typeOf(obj), obj)] + hop2.inputargs(*args_r)
+ hop2.exception_is_here()
+ return hop2.genop('direct_call', vlist, r_result)
+
+ def get_funcptr(self, rtyper, args_r, r_result):
+ from rpython.rtyper.rtyper import llinterp_backend
+ args_ll = [r_arg.lowleveltype for r_arg in args_r]
+ ll_result = r_result.lowleveltype
+ name = self.s_func.name
+ fakeimpl = getattr(self, 'lltypefakeimpl', self.s_func.const)
+ if self.impl:
+ if self.fakeimpl and rtyper.backend is llinterp_backend:
+ FT = FuncType(args_ll, ll_result)
+ return functionptr(
+ FT, name, _external_name=name, _callable=fakeimpl)
+ elif isinstance(self.impl, _ptr):
+ return self.impl
+ else:
+ # store some attributes to the 'impl' function, where
+ # the eventual call to rtyper.getcallable() will find them
+ # and transfer them to the final lltype.functionptr().
+ self.impl._llfnobjattrs_ = {'_name': name}
+ return rtyper.getannmixlevel().delayedfunction(
+ self.impl, self.s_func.args_s, self.s_func.s_result)
+ else:
+ fakeimpl = self.fakeimpl or self.s_func.const
+ FT = FuncType(args_ll, ll_result)
+ return functionptr(
+ FT, name, _external_name=name, _callable=fakeimpl)
class ExtFuncEntry(ExtRegistryEntry):
@@ -53,42 +101,6 @@
s_result.needs_sandboxing = True
return s_result
- def specialize_call(self, hop):
- rtyper = hop.rtyper
- args_r = [rtyper.getrepr(s_arg) for s_arg in self.signature_args]
- r_result = rtyper.getrepr(self.signature_result)
- obj = self.get_funcptr(rtyper, args_r, r_result)
- vlist = [hop.inputconst(typeOf(obj), obj)] + hop.inputargs(*args_r)
- hop.exception_is_here()
- return hop.genop('direct_call', vlist, r_result)
-
- def get_funcptr(self, rtyper, args_r, r_result):
- from rpython.rtyper.rtyper import llinterp_backend
- args_ll = [r_arg.lowleveltype for r_arg in args_r]
- ll_result = r_result.lowleveltype
- impl = getattr(self, 'lltypeimpl', None)
- fakeimpl = getattr(self, 'lltypefakeimpl', self.instance)
- if impl:
- if hasattr(self, 'lltypefakeimpl') and rtyper.backend is llinterp_backend:
- FT = FuncType(args_ll, ll_result)
- return functionptr(
- FT, self.name, _external_name=self.name,
- _callable=fakeimpl)
- elif isinstance(impl, _ptr):
- return impl
- else:
- # store some attributes to the 'impl' function, where
- # the eventual call to rtyper.getcallable() will find them
- # and transfer them to the final lltype.functionptr().
- impl._llfnobjattrs_ = {'_name': self.name}
- return rtyper.getannmixlevel().delayedfunction(
- impl, self.signature_args, self.signature_result)
- else:
- FT = FuncType(args_ll, ll_result)
- return functionptr(
- FT, self.name, _external_name=self.name, _callable=fakeimpl,
- _safe_not_sandboxed=self.safe_not_sandboxed)
-
def register_external(function, args, result=None, export_name=None,
llimpl=None, llfakeimpl=None, sandboxsafe=False):
More information about the pypy-commit
mailing list