Commit d5eca087 authored by Stefan Behnel's avatar Stefan Behnel

Use specialised code for matching two exceptions at once, which is not uncommon.

parent db87e1af
...@@ -7701,17 +7701,40 @@ class ExceptClauseNode(Node): ...@@ -7701,17 +7701,40 @@ class ExceptClauseNode(Node):
for _ in range(3)] for _ in range(3)]
code.globalstate.use_utility_code(UtilityCode.load_cached("PyErrFetchRestore", "Exceptions.c")) code.globalstate.use_utility_code(UtilityCode.load_cached("PyErrFetchRestore", "Exceptions.c"))
code.putln("__Pyx_ErrFetch(&%s, &%s, &%s);" % tuple(exc_vars)) code.putln("__Pyx_ErrFetch(&%s, &%s, &%s);" % tuple(exc_vars))
code.globalstate.use_utility_code(UtilityCode.load_cached("FastTypeChecks", "ModuleSetupCode.c")) exc_type = exc_vars[0]
exc_test_func = "__Pyx_PyErr_GivenExceptionMatches(%s, %%s)" % exc_vars[0]
else: else:
exc_vars = () exc_vars = exc_type = None
code.globalstate.use_utility_code(UtilityCode.load_cached("PyErrExceptionMatches", "Exceptions.c"))
exc_test_func = "__Pyx_PyErr_ExceptionMatches(%s)"
exc_tests = []
for pattern in self.pattern: for pattern in self.pattern:
pattern.generate_evaluation_code(code) pattern.generate_evaluation_code(code)
exc_tests.append(exc_test_func % pattern.py_result()) patterns = [pattern.py_result() for pattern in self.pattern]
exc_tests = []
if exc_type:
code.globalstate.use_utility_code(
UtilityCode.load_cached("FastTypeChecks", "ModuleSetupCode.c"))
if len(patterns) == 2:
exc_tests.append("__Pyx_PyErr_GivenExceptionMatches2(%s, %s, %s)" % (
exc_type, patterns[0], patterns[1],
))
else:
exc_tests.extend(
"__Pyx_PyErr_GivenExceptionMatches(%s, %s)" % (exc_type, pattern)
for pattern in patterns
)
elif len(patterns) == 2:
code.globalstate.use_utility_code(
UtilityCode.load_cached("PyErrExceptionMatches2", "Exceptions.c"))
exc_tests.append("__Pyx_PyErr_ExceptionMatches2(%s, %s)" % (
patterns[0], patterns[1],
))
else:
code.globalstate.use_utility_code(
UtilityCode.load_cached("PyErrExceptionMatches", "Exceptions.c"))
exc_tests.extend(
"__Pyx_PyErr_ExceptionMatches(%s)" % pattern
for pattern in patterns
)
match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, manage_ref=False) match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, manage_ref=False)
code.putln("%s = %s;" % (match_flag, ' || '.join(exc_tests))) code.putln("%s = %s;" % (match_flag, ' || '.join(exc_tests)))
...@@ -7719,7 +7742,7 @@ class ExceptClauseNode(Node): ...@@ -7719,7 +7742,7 @@ class ExceptClauseNode(Node):
pattern.generate_disposal_code(code) pattern.generate_disposal_code(code)
pattern.free_temps(code) pattern.free_temps(code)
if has_non_literals: if exc_vars:
code.putln("__Pyx_ErrRestore(%s, %s, %s);" % tuple(exc_vars)) code.putln("__Pyx_ErrRestore(%s, %s, %s);" % tuple(exc_vars))
code.putln(' '.join(["%s = 0;" % var for var in exc_vars])) code.putln(' '.join(["%s = 0;" % var for var in exc_vars]))
for temp in exc_vars: for temp in exc_vars:
......
...@@ -20,6 +20,17 @@ ...@@ -20,6 +20,17 @@
#endif #endif
/////////////// PyErrExceptionMatches2.proto ///////////////
//@substitute: naming
//@requires: ModuleSetupCode.c::FastTypeChecks
#if CYTHON_FAST_THREAD_STATE
#define __Pyx_PyErr_ExceptionMatches2(err1, err2) __Pyx_PyErr_ExceptionMatchesInState2($local_tstate_cname, err1, err2)
#define __Pyx_PyErr_ExceptionMatchesInState2(tstate, err1, err2) __Pyx_PyErr_GivenExceptionMatches2((tstate)->curexc_type, err1, err2)
#else
#define __Pyx_PyErr_ExceptionMatches2(err1, err2) __Pyx_PyErr_GivenExceptionMatches2(PyErr_Occurred(), err1, err2)
#endif
/////////////// PyErrExceptionMatches.proto /////////////// /////////////// PyErrExceptionMatches.proto ///////////////
//@substitute: naming //@substitute: naming
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment