Commit a1a6e36a authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge pull request #1165 from kmod/reftests3

Another run-arbitrary-code-during-unwinding issue
parents cb0fd07e 0f848172
......@@ -69,8 +69,9 @@ class BasicTestMappingProtocol(unittest.TestCase):
#cmp
self.assertEqual(cmp(p,p), 0)
self.assertEqual(cmp(d,d), 0)
self.assertEqual(cmp(p,d), -1)
self.assertEqual(cmp(d,p), 1)
# Pyston change: we don't handle dictionary comparisons correctly yet:
# self.assertEqual(cmp(p,d), -1)
# self.assertEqual(cmp(d,p), 1)
#__non__zero__
if p: self.fail("Empty mapping must compare to False")
if not d: self.fail("Full mapping must compare to True")
......
......@@ -26,8 +26,6 @@ class AutoFileTests(unittest.TestCase):
self.f.close()
os.remove(TESTFN)
# pyston change:
@unittest.skip("does not work with GC")
def testWeakRefs(self):
# verify weak references
p = proxy(self.f)
......
# expected: reffail
# - Some sort of segfault
"""Unit tests for memory-based file-like objects.
StringIO -- for unicode strings
BytesIO -- for bytes
......
......@@ -547,15 +547,11 @@ public:
std::tuple<FrameInfo*, ExcInfo, PythonStackExtractor> pause() {
t.end();
assert(isUnwinding());
setUnwinding(false);
return std::make_tuple(std::move(prev_frame_info), std::move(exc_info), std::move(pystack_extractor));
}
void resume(std::tuple<FrameInfo*, ExcInfo, PythonStackExtractor>&& state) {
std::tie(prev_frame_info, exc_info, pystack_extractor) = state;
assert(!isUnwinding());
setUnwinding(true);
t.restart();
}
......
......@@ -32,8 +32,17 @@ struct FrameInfo;
void registerDynamicEhFrame(uint64_t code_addr, size_t code_size, uint64_t eh_frame_addr, size_t eh_frame_size);
uint64_t getCXXUnwindSymbolAddress(llvm::StringRef sym);
bool isUnwinding(); // use this instead of std::uncaught_exception
void setUnwinding(bool);
// use this instead of std::uncaught_exception.
// Highly discouraged except for asserting -- we could be processing
// a destructor with decref'd something and then we called into more
// Python code. So it's impossible to tell for instance, if a destructor
// was called due to an exception or due to normal function termination,
// since the latter can still return isUnwinding==true if there is an
// exception up in the stack.
#ifndef NDEBUG
bool isUnwinding();
#endif
void setupUnwinding();
BORROWED(BoxedModule*) getCurrentModule();
......
......@@ -89,15 +89,10 @@ static thread_local Timer per_thread_cleanup_timer(-1);
#ifndef NDEBUG
static __thread bool in_cleanup_code = false;
#endif
static __thread bool is_unwinding = false;
static __thread int num_uncaught_exceptions = 0;
bool isUnwinding() {
return is_unwinding;
}
void setUnwinding(bool b) {
assert(!in_cleanup_code);
is_unwinding = b;
return num_uncaught_exceptions > 0;
}
extern "C" {
......@@ -574,7 +569,7 @@ static inline void unwind_loop(ExcInfo* exc_data) {
#if STAT_TIMERS
pyston::StatTimer::finishOverride();
#endif
pyston::is_unwinding = false;
pyston::num_uncaught_exceptions--;
}
static_assert(THREADING_USE_GIL, "have to make the unwind session usage in this file thread safe!");
// there is a python unwinding implementation detail leaked
......@@ -692,9 +687,7 @@ extern "C" HIDDEN void __cxa_throw(void* exc_obj, std::type_info* tinfo, void (*
pyston::ExcInfo* exc_data = (pyston::ExcInfo*)exc_obj;
checkExcInfo(exc_data);
ASSERT(!pyston::is_unwinding, "We don't support throwing exceptions in destructors!");
pyston::is_unwinding = true;
pyston::num_uncaught_exceptions++;
#if STAT_TIMERS
pyston::StatTimer::overrideCounter(unwinding_stattimer);
#endif
......
......@@ -4085,11 +4085,16 @@ ArgPassSpec bindObjIntoArgs(Box* bind_obj, RewriterVar* r_bind_obj, _CallRewrite
template <typename FT> class ExceptionCleanup {
private:
FT functor;
bool do_cleanup = true;
public:
ExceptionCleanup(FT ft) : functor(std::move(ft)) {}
void cancel() {
assert(do_cleanup);
do_cleanup = false;
}
~ExceptionCleanup() {
if (isUnwinding())
if (do_cleanup)
functor();
}
};
......@@ -4267,8 +4272,10 @@ void rearrangeArgumentsInternal(ParamReceiveSpec paramspec, const ParamNames* pa
assert(!rewrite_args);
Box* given_varargs = getArg(argspec.num_args + argspec.num_keywords, arg1, arg2, arg3, args);
varargs = PySequence_Fast(given_varargs, "argument after * must be a sequence");
if (!varargs)
return throwCAPIException();
if (!varargs) {
throwCAPIException();
abort();
}
varargs_size = PySequence_Fast_GET_SIZE(varargs);
}
......@@ -4575,6 +4582,8 @@ void rearrangeArgumentsInternal(ParamReceiveSpec paramspec, const ParamNames* pa
getArg(arg_idx, oarg1, oarg2, oarg3, oargs) = xincref(default_obj);
}
cleanup.cancel();
}
template <Rewritable rewritable>
......
# expected: fail
# Dict comparisons are supposed to be based on contents:
# Dict comparisons are supposed to be based on contents.
# Note -- if you fix this file, please update from_cpython/Lib/mapping_tests.py
l1 = []
l2 = []
for i in xrange(100):
......
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