[pypy-commit] pypy exc-later: Use annotations to represent the exception behaviour of operations
rlamy
noreply at buildbot.pypy.org
Sun Nov 22 13:00:01 EST 2015
Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: exc-later
Changeset: r80833:9c9c044a9aff
Date: 2015-11-22 01:50 +0000
http://bitbucket.org/pypy/pypy/changeset/9c9c044a9aff/
Log: Use annotations to represent the exception behaviour of operations
diff --git a/rpython/annotator/annrpython.py b/rpython/annotator/annrpython.py
--- a/rpython/annotator/annrpython.py
+++ b/rpython/annotator/annrpython.py
@@ -11,7 +11,7 @@
from rpython.translator import simplify, transform
from rpython.annotator import model as annmodel, signature
from rpython.annotator.model import (
- typeof, SomeExceptCase, s_ImpossibleValue)
+ typeof, SomeExceptCase, s_ImpossibleValue, SomeInstance)
from rpython.annotator.bookkeeper import Bookkeeper
from rpython.rtyper.normalizecalls import perform_normalizations
@@ -488,31 +488,20 @@
if block.canraise:
op = block.raising_op
- can_only_throw = op.get_can_only_throw(self)
- if can_only_throw is not None:
- # filter out those exceptions which cannot
- # occur for this specific, typed operation.
- s_exception = self.bookkeeper.new_exception(can_only_throw)
- for link in exits:
- case = link.exitcase
- if case is None:
- self.follow_link(graph, link, {})
- continue
- if s_exception == s_ImpossibleValue:
- break
- s_case = SomeExceptCase(
- self.bookkeeper.getuniqueclassdef(case))
- s_matching_exc = s_exception.intersection(s_case)
- if s_matching_exc != s_ImpossibleValue:
- self.follow_raise_link(graph, link, s_matching_exc)
- s_exception = s_exception.difference(s_case)
- else:
- for link in exits:
- if link.exitcase is None:
- self.follow_link(graph, link, {})
- else:
- s_exception = self.bookkeeper.valueoftype(link.exitcase)
- self.follow_raise_link(graph, link, s_exception)
+ s_exception = self.get_exception(op)
+ for link in exits:
+ case = link.exitcase
+ if case is None:
+ self.follow_link(graph, link, {})
+ continue
+ if s_exception == s_ImpossibleValue:
+ break
+ s_case = SomeExceptCase(
+ self.bookkeeper.getuniqueclassdef(case))
+ s_matching_exc = s_exception.intersection(s_case)
+ if s_matching_exc != s_ImpossibleValue:
+ self.follow_raise_link(graph, link, s_matching_exc)
+ s_exception = s_exception.difference(s_case)
else:
if isinstance(block.exitswitch, Variable):
knowntypedata = getattr(block.exitswitch.annotation,
@@ -615,6 +604,16 @@
assert isinstance(op.result, Variable)
self.setbinding(op.result, resultcell) # bind resultcell to op.result
+ def get_exception(self, operation):
+ """
+ Return the annotation for all exceptions that `operation` may raise.
+ """
+ can_only_throw = operation.get_can_only_throw(self)
+ if can_only_throw is None:
+ return SomeInstance(self.bookkeeper.getuniqueclassdef(Exception))
+ else:
+ return self.bookkeeper.new_exception(can_only_throw)
+
class BlockedInference(Exception):
"""This exception signals the type inference engine that the situation
diff --git a/rpython/annotator/model.py b/rpython/annotator/model.py
--- a/rpython/annotator/model.py
+++ b/rpython/annotator/model.py
@@ -445,6 +445,22 @@
else:
return None
+ def intersection(self, other):
+ assert isinstance(other, SomeExceptCase)
+ if self.classdef.issubclass(other.case):
+ return self
+ elif other.case.issubclass(self.classdef):
+ return SomeInstance(other.case)
+ else:
+ return s_ImpossibleValue
+
+ def difference(self, other):
+ assert isinstance(other, SomeExceptCase)
+ if self.classdef.issubclass(other.case):
+ return s_ImpossibleValue
+ else:
+ return self
+
def can_be_none(self):
return self.can_be_None
More information about the pypy-commit
mailing list