Commit b163e6cd authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge pull request #1160 from kmod/reftests3

Fix test_set.py
parents a941cdf4 31050d60
# expected: fail
from collections import deque
import unittest
from test import test_support, seq_tests
......
# expected: reffail
# - leaked refs
import unittest
from test import test_support
import operator
......
# expected: reffail
# - unknown segfault
import unittest
from test import test_support
import gc
......
......@@ -100,6 +100,8 @@ class urlopenNetworkTests(unittest.TestCase):
open_url.close()
self.assertEqual(gotten_url, URL)
# Pyston change -- this test is flaky
@unittest.skip("Pyston change -- Not hitting 3rd party website")
def test_getcode(self):
# test getcode() with the fancy opener to get 404 error codes
URL = "http://www.example.com/XXXinvalidXXX"
......
......@@ -41,9 +41,13 @@ public:
llvm::BasicBlock* exc_dest;
// Frame handling changes a bit after a deopt happens.
bool is_after_deopt;
bool hasHandler() const { return exc_dest != NULL; }
UnwindInfo(AST_stmt* current_stmt, llvm::BasicBlock* exc_dest) : current_stmt(current_stmt), exc_dest(exc_dest) {}
UnwindInfo(AST_stmt* current_stmt, llvm::BasicBlock* exc_dest, bool is_after_deopt = false)
: current_stmt(current_stmt), exc_dest(exc_dest), is_after_deopt(is_after_deopt) {}
ExceptionStyle preferredExceptionStyle() const;
......
......@@ -411,23 +411,21 @@ private:
#endif
}
void checkAndPropagateCapiException(const UnwindInfo& unw_info, llvm::Value* returned_val, llvm::Value* exc_val,
bool double_check = false) {
assert(!double_check); // need to call PyErr_Occurred
void checkAndPropagateCapiException(const UnwindInfo& unw_info, llvm::Value* returned_val, llvm::Value* exc_val) {
assert(exc_val);
llvm::BasicBlock* normal_dest
= llvm::BasicBlock::Create(g.context, curblock->getName(), irstate->getLLVMFunction());
normal_dest->moveAfter(curblock);
llvm::BasicBlock* exc_dest = irgenerator->getCAPIExcDest(curblock, unw_info.exc_dest, unw_info.current_stmt);
llvm::BasicBlock* exc_dest
= irgenerator->getCAPIExcDest(curblock, unw_info.exc_dest, unw_info.current_stmt, unw_info.is_after_deopt);
if (exc_val == ALWAYS_THROWS) {
assert(returned_val->getType() == g.void_);
llvm::BasicBlock* exc_dest
= irgenerator->getCAPIExcDest(curblock, unw_info.exc_dest, unw_info.current_stmt);
llvm::BasicBlock* exc_dest = irgenerator->getCAPIExcDest(curblock, unw_info.exc_dest, unw_info.current_stmt,
unw_info.is_after_deopt);
getBuilder()->CreateBr(exc_dest);
} else {
assert(returned_val->getType() == exc_val->getType());
......@@ -678,7 +676,7 @@ public:
ICSetupInfo* pp = createDeoptIC();
llvm::Value* v
= createIC(pp, (void*)pyston::deopt, { embedRelocatablePtr(node, g.llvm_astexpr_type_ptr), node_value },
UnwindInfo(current_stmt, NULL));
UnwindInfo(current_stmt, NULL, /* is_after_deopt*/ true));
llvm::Value* rtn = getBuilder()->CreateIntToPtr(v, g.llvm_value_type_ptr);
setType(rtn, RefType::OWNED);
return rtn;
......@@ -841,9 +839,6 @@ private:
curblock = deopt_bb;
emitter.getBuilder()->SetInsertPoint(curblock);
llvm::Value* v = emitter.createDeopt(current_statement, (AST_expr*)node, node_value);
// TODO: this might not be necessary since it should never fire?
if (!irstate->getCurFunction()->entry_descriptor)
emitter.getBuilder()->CreateCall(g.funcs.deinitFrameMaybe, irstate->getFrameInfoVar());
llvm::Instruction* ret_inst = emitter.getBuilder()->CreateRet(v);
irstate->getRefcounts()->refConsumed(v, ret_inst);
......@@ -3009,8 +3004,8 @@ public:
// LANDINGPAD, and this function will create a helper block that fetches the exception.
// As a special-case, a NULL value for final_dest means that this helper block should
// instead propagate the exception out of the function.
llvm::BasicBlock* getCAPIExcDest(llvm::BasicBlock* from_block, llvm::BasicBlock* final_dest,
AST_stmt* current_stmt) override {
llvm::BasicBlock* getCAPIExcDest(llvm::BasicBlock* from_block, llvm::BasicBlock* final_dest, AST_stmt* current_stmt,
bool is_after_deopt) override {
llvm::BasicBlock*& capi_exc_dest = capi_exc_dests[final_dest];
llvm::PHINode*& phi_node = capi_phis[final_dest];
......@@ -3032,7 +3027,7 @@ public:
emitter.getBuilder()->CreateCall(g.funcs.reraiseCapiExcAsCxx);
emitter.getBuilder()->CreateUnreachable();
} else {
if (!irstate->getCurFunction()->entry_descriptor)
if (!irstate->getCurFunction()->entry_descriptor && !is_after_deopt)
emitter.getBuilder()->CreateCall(g.funcs.deinitFrame, irstate->getFrameInfoVar());
emitter.getBuilder()->CreateRet(getNullPtr(g.llvm_value_type_ptr));
}
......@@ -3122,8 +3117,9 @@ public:
irstate->getRefcounts()->refConsumed(exc_type, call_inst);
irstate->getRefcounts()->refConsumed(exc_value, call_inst);
irstate->getRefcounts()->refConsumed(exc_traceback, call_inst);
if (!irstate->getCurFunction()->entry_descriptor)
if (!irstate->getCurFunction()->entry_descriptor && !unw_info.is_after_deopt) {
emitter.getBuilder()->CreateCall(g.funcs.deinitFrame, irstate->getFrameInfoVar());
}
emitter.getBuilder()->CreateRet(getNullPtr(g.llvm_value_type_ptr));
} else {
// auto call_inst = emitter.createCall3(UnwindInfo(unw_info.current_stmt, NO_CXX_INTERCEPTION),
......
......@@ -168,7 +168,7 @@ public:
virtual void setIncomingExceptionState(llvm::SmallVector<ExceptionState, 2> exc_state) = 0;
virtual llvm::BasicBlock* getCXXExcDest(const UnwindInfo&) = 0;
virtual llvm::BasicBlock* getCAPIExcDest(llvm::BasicBlock* from_block, llvm::BasicBlock* final_dest,
AST_stmt* current_stmt) = 0;
AST_stmt* current_stmt, bool is_after_deopt = false) = 0;
virtual CFGBlock* getCFGBlock() = 0;
};
......
......@@ -36,10 +36,16 @@ BoxedClass* dictiteritem_cls = NULL;
}
static void _dictSetStolen(BoxedDict* self, BoxAndHash k, STOLEN(Box*) v) {
Box*& slot = self->d[k];
Box* old_val = slot;
Box** slot = NULL;
try {
slot = &self->d[k];
} catch (ExcInfo e) {
Py_DECREF(v);
throw e;
}
Box* old_val = *slot;
slot = v;
*slot = v;
if (old_val) {
Py_DECREF(old_val);
......
......@@ -661,7 +661,7 @@ extern "C" Box* listDelitem(BoxedList* self, Box* slice) {
Py_ssize_t i = PyNumber_AsSsize_t(slice, PyExc_IndexError);
if (i == -1 && PyErr_Occurred())
throwCAPIException();
rtn = listDelitemInt(self, (BoxedInt*)boxInt(i));
rtn = listDelitemInt(self, (BoxedInt*)autoDecref(boxInt(i)));
} else if (slice->cls == slice_cls) {
rtn = listDelitemSlice(self, static_cast<BoxedSlice*>(slice));
} else {
......
......@@ -25,11 +25,22 @@ extern "C" Box* createSet() {
}
static void _setAddStolen(BoxedSet* self, STOLEN(BoxAndHash) val) {
try {
auto&& p = self->s.insert(val);
// Is there a nicer way to represent try-else?
try {
if (!p.second /* already exists */) {
// keep the original key
Py_DECREF(val.value);
}
} catch (ExcInfo e) {
abort();
}
} catch (ExcInfo e) {
Py_DECREF(val.value);
throw e;
}
}
void _setAddStolen(BoxedSet* self, STOLEN(Box*) val) {
......
......@@ -703,6 +703,8 @@ static Box* assertInitNone(STOLEN(Box*) rtn, STOLEN(Box*) obj) {
}
static PyObject* cpythonTypeCall(BoxedClass* type, PyObject* args, PyObject* kwds) {
assert(PyType_Check(type));
Box* r = cpython_type_call(type, args, kwds);
if (!r)
throwCAPIException();
......@@ -810,6 +812,10 @@ static Box* typeCallInner(CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Bo
}
}
if (rewrite_args) {
rewrite_args->arg1->addGuard((intptr_t)cls);
}
// Special-case unicode for now, maybe there's something about this that can eventually be generalized:
if (cls->tp_new == unicode_cls->tp_new) {
// TODO: implement
......@@ -824,10 +830,6 @@ static Box* typeCallInner(CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Bo
assert(S == CXX && "implement me");
if (rewrite_args) {
rewrite_args->arg1->addGuard((intptr_t)cls);
}
ParamReceiveSpec paramspec(4, 3, false, false);
bool rewrite_success = false;
static ParamNames param_names({ "", "string", "encoding", "errors" }, "", "");
......
......@@ -55,3 +55,18 @@ d = {}
for i in xrange(1000):
d[C(i)] = i
print len(d)
class NonEq(object):
def __eq__(self, rhs):
1/0
def __hash__(self):
return 0
d = {}
d[NonEq()] = 1
try:
d[NonEq()] = 2
except ZeroDivisionError as e:
print e
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