Commit 01c3fc5c authored by Kevin Modzelewski's avatar Kevin Modzelewski

Getattr guarding issue

Wasn't checking the return convention -- not sure how I missed this
when I added that.
parent 1671aba4
...@@ -67,6 +67,9 @@ public: ...@@ -67,6 +67,9 @@ public:
void push_back(AST_stmt* node) { body.push_back(node); } void push_back(AST_stmt* node) { body.push_back(node); }
void print(llvm::raw_ostream& stream = llvm::outs()); void print(llvm::raw_ostream& stream = llvm::outs());
void _print() {
print();
}
}; };
// Control Flow Graph // Control Flow Graph
......
...@@ -564,13 +564,17 @@ Box* getattrFuncInternal(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ...@@ -564,13 +564,17 @@ Box* getattrFuncInternal(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args,
if (rewrite_args) { if (rewrite_args) {
GetattrRewriteArgs grewrite_args(rewrite_args->rewriter, rewrite_args->arg1, rewrite_args->destination); GetattrRewriteArgs grewrite_args(rewrite_args->rewriter, rewrite_args->arg1, rewrite_args->destination);
rtn = getattrInternal<CAPI>(obj, str, &grewrite_args); rtn = getattrInternal<CAPI>(obj, str, &grewrite_args);
if (!grewrite_args.out_success) // TODO could make the return valid in the NOEXC_POSSIBLE case via a helper
if (!grewrite_args.out_success || grewrite_args.out_return_convention == GetattrRewriteArgs::NOEXC_POSSIBLE)
rewrite_args = NULL; rewrite_args = NULL;
else { else {
if (!rtn && !PyErr_Occurred()) if (!rtn && !PyErr_Occurred()) {
assert(grewrite_args.out_return_convention == GetattrRewriteArgs::NO_RETURN);
r_rtn = rewrite_args->rewriter->loadConst(0); r_rtn = rewrite_args->rewriter->loadConst(0);
else } else {
assert(grewrite_args.out_return_convention == GetattrRewriteArgs::VALID_RETURN);
r_rtn = grewrite_args.out_rtn; r_rtn = grewrite_args.out_rtn;
}
} }
} else { } else {
rtn = getattrInternal<CAPI>(obj, str, NULL); rtn = getattrInternal<CAPI>(obj, str, NULL);
...@@ -673,13 +677,16 @@ Box* hasattrFuncInternal(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ...@@ -673,13 +677,16 @@ Box* hasattrFuncInternal(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args,
if (rewrite_args) { if (rewrite_args) {
GetattrRewriteArgs grewrite_args(rewrite_args->rewriter, rewrite_args->arg1, rewrite_args->destination); GetattrRewriteArgs grewrite_args(rewrite_args->rewriter, rewrite_args->arg1, rewrite_args->destination);
rtn = getattrInternal<CAPI>(obj, str, &grewrite_args); rtn = getattrInternal<CAPI>(obj, str, &grewrite_args);
if (!grewrite_args.out_success) if (!grewrite_args.out_success || grewrite_args.out_return_convention == GetattrRewriteArgs::NOEXC_POSSIBLE)
rewrite_args = NULL; rewrite_args = NULL;
else { else {
if (!rtn && !PyErr_Occurred()) if (!rtn && !PyErr_Occurred()) {
assert(grewrite_args.out_return_convention == GetattrRewriteArgs::NO_RETURN);
r_rtn = rewrite_args->rewriter->loadConst(0); r_rtn = rewrite_args->rewriter->loadConst(0);
else } else {
assert(grewrite_args.out_return_convention == GetattrRewriteArgs::VALID_RETURN);
r_rtn = grewrite_args.out_rtn; r_rtn = grewrite_args.out_rtn;
}
} }
} else { } else {
rtn = getattrInternal<CAPI>(obj, str, NULL); rtn = getattrInternal<CAPI>(obj, str, NULL);
...@@ -1322,8 +1329,8 @@ Box* getreversed(Box* o) { ...@@ -1322,8 +1329,8 @@ Box* getreversed(Box* o) {
return new (seqreviter_cls) BoxedSeqIter(o, len - 1); return new (seqreviter_cls) BoxedSeqIter(o, len - 1);
} }
Box* pydump(Box* p) { Box* pydump(Box* p, BoxedInt* level) {
dump(p); dumpEx(p, level->n);
return None; return None;
} }
...@@ -1587,8 +1594,8 @@ void setupBuiltins() { ...@@ -1587,8 +1594,8 @@ void setupBuiltins() {
builtins_module->giveAttr("ord", ord_obj); builtins_module->giveAttr("ord", ord_obj);
trap_obj = new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)trap, UNKNOWN, 0), "trap"); trap_obj = new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)trap, UNKNOWN, 0), "trap");
builtins_module->giveAttr("trap", trap_obj); builtins_module->giveAttr("trap", trap_obj);
builtins_module->giveAttr("dump", builtins_module->giveAttr(
new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)pydump, UNKNOWN, 1), "dump")); "dump", new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)pydump, UNKNOWN, 2), "dump", { boxInt(0) }));
builtins_module->giveAttr( builtins_module->giveAttr(
"dumpAddr", new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)pydumpAddr, UNKNOWN, 1), "dumpAddr")); "dumpAddr", new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)pydumpAddr, UNKNOWN, 1), "dumpAddr"));
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "runtime/util.h" #include "runtime/util.h"
#include "codegen/codegen.h" #include "codegen/codegen.h"
#include "core/cfg.h"
#include "core/options.h" #include "core/options.h"
#include "core/types.h" #include "core/types.h"
#include "runtime/long.h" #include "runtime/long.h"
...@@ -258,6 +259,11 @@ extern "C" void dumpEx(void* p, int levels) { ...@@ -258,6 +259,11 @@ extern "C" void dumpEx(void* p, int levels) {
CLFunction* cl = f->f; CLFunction* cl = f->f;
if (cl->source) { if (cl->source) {
printf("User-defined function '%s'\n", cl->source->getName()->c_str()); printf("User-defined function '%s'\n", cl->source->getName()->c_str());
printf("Defined at %s:%d\n", cl->source->getFn()->c_str(), cl->source->body[0]->lineno);
if (cl->source->cfg && levels > 0) {
cl->source->cfg->print();
}
} else { } else {
printf("A builtin function\n"); printf("A builtin function\n");
} }
......
# Test some weird hasattr guarding scenarios # Test some weird getattr/hasattr guarding scenarios
# I think this applies equally well to getattr
# Make sure that we guard correctly when a __getattr__ is involved:
def f(o): def f(o):
print hasattr(o, "a") print hasattr(o, "a")
print getattr(o, "a", None) print getattr(o, "a", None)
...@@ -21,3 +22,14 @@ for i in xrange(300): ...@@ -21,3 +22,14 @@ for i in xrange(300):
setattr(c, str(i), i) setattr(c, str(i), i)
f(c) f(c)
# Make sure that we guard correctly when we are megamorphic
class C(object):
pass
l = []
for i in xrange(200):
c = C()
setattr(c, "a%d" % i, i)
# We should do the right guarding so that when i==150 comes around, this will return True/None:
print i, hasattr(c, "a150"), getattr(c, "a150", None)
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