[pypy-svn] r34602 - in pypy/dist/pypy/translator: cli cli/test oosupport
antocuni at codespeak.net
antocuni at codespeak.net
Tue Nov 14 17:09:52 CET 2006
Author: antocuni
Date: Tue Nov 14 17:09:50 2006
New Revision: 34602
Modified:
pypy/dist/pypy/translator/cli/cts.py
pypy/dist/pypy/translator/cli/dotnet.py
pypy/dist/pypy/translator/cli/function.py
pypy/dist/pypy/translator/cli/support.py
pypy/dist/pypy/translator/cli/test/test_dotnet.py
pypy/dist/pypy/translator/oosupport/function.py
Log:
Added support for handling native exceptions when using .NET-types.
It's a bit involved because .NET exceptions don't share a common root
with RPython exceptions, so we need to cheat a bit by creating a fake
class that will be recognized by the backend and rendered as
appropriate.
This means, for example, that instead of writing something like this:
try:
f()
except CLR.System.Exception:
...
we need to create the fake object first.
SystemException = NativeException(CLR.System.Exception)
try:
f()
except SystemException:
...
Please note that the call to NativeException is *not* RPython, so you
need to call it at initialization-time.
Thanks to pedronis for the original idea.
Modified: pypy/dist/pypy/translator/cli/cts.py
==============================================================================
--- pypy/dist/pypy/translator/cli/cts.py (original)
+++ pypy/dist/pypy/translator/cli/cts.py Tue Nov 14 17:09:50 2006
@@ -147,8 +147,12 @@
elif isinstance(t, lltype.Ptr) and isinstance(t.TO, lltype.OpaqueType):
return self.__class('[mscorlib]System.Object', include_class)
elif isinstance(t, ootype.Instance):
- name = self.db.pending_class(t)
- return self.__class(name, include_class)
+ native_class = t._hints.get('native_class', None)
+ if native_class:
+ return self.__class(native_class, include_class)
+ else:
+ name = self.db.pending_class(t)
+ return self.__class(name, include_class)
elif isinstance(t, ootype.Record):
name = self.db.pending_record(t)
return self.__class(name, include_class)
Modified: pypy/dist/pypy/translator/cli/dotnet.py
==============================================================================
--- pypy/dist/pypy/translator/cli/dotnet.py (original)
+++ pypy/dist/pypy/translator/cli/dotnet.py Tue Nov 14 17:09:50 2006
@@ -1,3 +1,5 @@
+import types
+
from pypy.annotation.pairtype import pair, pairtype
from pypy.annotation.model import SomeObject, SomeOOInstance, SomeInteger, s_None,\
s_ImpossibleValue, lltype_to_annotation, annotation_to_lltype, SomeChar, SomeString
@@ -66,6 +68,7 @@
INSTANCE = hop.args_r[0].cli_class._INSTANCE
cINST = hop.inputconst(ootype.Void, INSTANCE)
vlist = hop.inputargs(*hop.args_r)[1:] # discard the first argument
+ hop.exception_is_here()
return hop.genop("new", [cINST]+vlist, resulttype=hop.r_result.lowleveltype)
class CliStaticMethodRepr(Repr):
@@ -265,6 +268,7 @@
# TODO: check that x is really of type TYPE
return x
+
class Entry(ExtRegistryEntry):
_about_ = box
@@ -298,3 +302,27 @@
return hop.genop('oodowncast', [v_obj], hop.r_result.lowleveltype)
else:
return hop.genop('cliunbox', [v_obj, v_type], hop.r_result.lowleveltype)
+
+
+
+native_exc = {}
+def NativeException(cliClass):
+ try:
+ return native_exc[cliClass._name]
+ except KeyError:
+ res = _create_NativeException(cliClass)
+ native_exc[cliClass._name] = res
+ return res
+
+def _create_NativeException(cliClass):
+ from pypy.translator.cli.query import getattr_ex
+ TYPE = cliClass._INSTANCE
+ if PythonNet.__name__ == 'CLR':
+ # we are using pythonnet -- use the .NET class
+ name = '%s.%s' % (TYPE._namespace, TYPE._classname)
+ res = getattr_ex(PythonNet, name)
+ else:
+ # we are not using pythonnet -- create a fake class
+ res = types.ClassType(TYPE._classname, (Exception,), {})
+ res._rpython_hints = {'native_class': cliClass._name}
+ return res
Modified: pypy/dist/pypy/translator/cli/function.py
==============================================================================
--- pypy/dist/pypy/translator/cli/function.py (original)
+++ pypy/dist/pypy/translator/cli/function.py Tue Nov 14 17:09:50 2006
@@ -25,6 +25,13 @@
def _create_generator(self, ilasm):
return self # Function implements the Generator interface
+ def record_ll_meta_exc(self, ll_meta_exc):
+ # record the type only if it doesn't belong to a native_class
+ ll_exc = ll_meta_exc._inst.class_._INSTANCE
+ native_class = ll_exc._hints.get('native_class', None)
+ if native_class is None:
+ OOFunction.record_ll_meta_exc(self, ll_meta_exc)
+
def begin_try(self):
self.ilasm.begin_try()
Modified: pypy/dist/pypy/translator/cli/support.py
==============================================================================
--- pypy/dist/pypy/translator/cli/support.py (original)
+++ pypy/dist/pypy/translator/cli/support.py Tue Nov 14 17:09:50 2006
@@ -9,6 +9,7 @@
import CLR as PythonNet
except ImportError:
class _PythonNet:
+ __name__ = None
def __getattr__(self, attr):
py.test.skip('Must use pythonnet for being able to access .NET libraries')
PythonNet = _PythonNet()
Modified: pypy/dist/pypy/translator/cli/test/test_dotnet.py
==============================================================================
--- pypy/dist/pypy/translator/cli/test/test_dotnet.py (original)
+++ pypy/dist/pypy/translator/cli/test/test_dotnet.py Tue Nov 14 17:09:50 2006
@@ -6,7 +6,7 @@
ROOT, overload, Instance, new
from pypy.translator.cli.test.runtest import CliTest
from pypy.translator.cli.dotnet import SomeCliClass, SomeCliStaticMethod,\
- NativeInstance, CLR, box, unbox, OverloadingResolver
+ NativeInstance, CLR, box, unbox, OverloadingResolver, NativeException
System = CLR.System
Math = CLR.System.Math
@@ -199,6 +199,29 @@
return x.get_Item(0)
assert self.interpret(fn, []) is None
+ def test_native_exception_precise(self):
+ ArgumentOutOfRangeException = NativeException(CLR.System.ArgumentOutOfRangeException)
+ def fn():
+ x = ArrayList()
+ try:
+ x.get_Item(0)
+ return False
+ except ArgumentOutOfRangeException:
+ return True
+ assert self.interpret(fn, []) == True
+
+ def test_native_exception_superclass(self):
+ SystemException = NativeException(CLR.System.Exception)
+ def fn():
+ x = ArrayList()
+ try:
+ x.get_Item(0)
+ return False
+ except SystemException:
+ return True
+ assert self.interpret(fn, []) == True
+
+
class TestPythonnet(TestDotnetRtyping):
# don't interpreter functions but execute them directly through pythonnet
def interpret(self, f, args):
Modified: pypy/dist/pypy/translator/oosupport/function.py
==============================================================================
--- pypy/dist/pypy/translator/oosupport/function.py (original)
+++ pypy/dist/pypy/translator/oosupport/function.py Tue Nov 14 17:09:50 2006
@@ -132,12 +132,15 @@
continue # see above
assert issubclass(link.exitcase, Exception)
ll_meta_exc = link.llexitcase
- self.db.constant_generator.record_const(ll_meta_exc)
+ self.record_ll_meta_exc(ll_meta_exc)
self.begin_catch(link.llexitcase)
self.store_exception_and_link(link)
target_label = self._get_block_name(link.target)
self.end_catch(target_label)
+ def record_ll_meta_exc(self, ll_meta_exc):
+ self.db.constant_generator.record_const(ll_meta_exc)
+
def store_exception_and_link(self, link):
raise NotImplementedError
More information about the Pypy-commit
mailing list