Commit f1e90870 authored by Kevin Modzelewski's avatar Kevin Modzelewski Committed by Kevin Modzelewski

Some basic compile()/exec refcounting

parent 5e13f1e3
......@@ -131,8 +131,11 @@ SourceInfo::SourceInfo(BoxedModule* m, ScopingAnalysis* scoping, FutureFlags fut
cfg(NULL),
body(std::move(body)) {
assert(fn);
// TODO: we should track this reference correctly rather than making it a root
//gc::registerPermanentRoot(fn, true);
// TODO: this is a very bad way of handling this:
incref(fn);
late_constants.push_back(fn);
this->fn = fn;
switch (ast->type) {
......
......@@ -107,6 +107,11 @@ InternedStringPool& SourceInfo::getInternedStrings() {
return scoping->getInternedStrings();
}
BORROWED(BoxedString*) SourceInfo::getFn() {
assert(fn->ob_refcnt >= 1);
return fn;
}
BORROWED(BoxedString*) SourceInfo::getName() {
assert(ast);
......@@ -323,7 +328,8 @@ void compileAndRunModule(AST_Module* m, BoxedModule* bm) {
FutureFlags future_flags = getFutureFlags(m->body, fn);
ScopingAnalysis* scoping = new ScopingAnalysis(m, true);
auto fn_str = getStaticString(fn); // XXX this is not a static string
auto fn_str = boxString(fn);
AUTO_DECREF(fn_str);
std::unique_ptr<SourceInfo> si(new SourceInfo(bm, scoping, future_flags, m, m->body, fn_str));
static BoxedString* doc_str = getStaticString("__doc__");
......@@ -525,7 +531,7 @@ extern "C" PyObject* PyEval_EvalCode(PyCodeObject* co, PyObject* globals, PyObje
}
}
Box* exec(Box* boxedCode, Box* globals, Box* locals, FutureFlags caller_future_flags) {
void exec(Box* boxedCode, Box* globals, Box* locals, FutureFlags caller_future_flags) {
if (!globals)
globals = None;
if (!locals)
......@@ -608,7 +614,7 @@ Box* exec(Box* boxedCode, Box* globals, Box* locals, FutureFlags caller_future_f
}
#endif
if (PyString_AsStringAndSize(prog, &str, NULL))
return 0;
throwCAPIException();
cf.cf_flags |= caller_future_flags & PyCF_MASK;
if (cf.cf_flags)
v = PyRun_StringFlags(str, Py_file_input, globals, locals, &cf);
......@@ -619,7 +625,9 @@ Box* exec(Box* boxedCode, Box* globals, Box* locals, FutureFlags caller_future_f
if (!v)
throwCAPIException();
return v;
assert(v == None); // not really necessary but I think this should be true
Py_DECREF(v);
}
// If a function version keeps failing its speculations, kill it (remove it
......
......@@ -39,7 +39,7 @@ void compileAndRunModule(AST_Module* m, BoxedModule* bm);
// will we always want to generate unique function names? (ie will this function always be reasonable?)
CompiledFunction* cfForMachineFunctionName(const std::string&);
extern "C" Box* exec(Box* boxedCode, Box* globals, Box* locals, FutureFlags caller_future_flags);
extern "C" void exec(Box* boxedCode, Box* globals, Box* locals, FutureFlags caller_future_flags);
}
#endif
......@@ -1394,6 +1394,7 @@ private:
std::vector<llvm::Value*> args{ cvar->getValue() };
llvm::Value* rtn = emitter.createCall(unw_info, g.funcs.repr, args);
emitter.setType(rtn, RefType::BORROWED); // Well, really it's owned, and we handoff the ref to the bitcast
rtn = emitter.getBuilder()->CreateBitCast(rtn, g.llvm_value_type_ptr);
emitter.setType(rtn, RefType::OWNED);
......
......@@ -409,7 +409,7 @@ public:
const std::vector<AST_stmt*> body;
BORROWED(BoxedString*) getName();
BORROWED(BoxedString*) getFn() { return fn; }
BORROWED(BoxedString*) getFn();
InternedString mangleName(InternedString id);
......
......@@ -34,7 +34,7 @@ BORROWED(Box*) BoxedCode::name(Box* b, void*) {
return code->f->source->getName();
}
Box* BoxedCode::f_name(Box* b, void* arg) {
Box* BoxedCode::co_name(Box* b, void* arg) {
return incref(name(b, arg));
}
......@@ -46,7 +46,7 @@ BORROWED(Box*) BoxedCode::filename(Box* b, void*) {
return code->f->source->getFn();
}
Box* BoxedCode::f_filename(Box* b, void* arg) {
Box* BoxedCode::co_filename(Box* b, void* arg) {
return incref(filename(b, arg));
}
......@@ -213,8 +213,8 @@ void setupCode() {
code_cls->giveAttrBorrowed("__new__", None); // Hacky way of preventing users from instantiating this
code_cls->giveAttrDescriptor("co_name", BoxedCode::f_name, NULL);
code_cls->giveAttrDescriptor("co_filename", BoxedCode::f_filename, NULL);
code_cls->giveAttrDescriptor("co_name", BoxedCode::co_name, NULL);
code_cls->giveAttrDescriptor("co_filename", BoxedCode::co_filename, NULL);
code_cls->giveAttrDescriptor("co_firstlineno", BoxedCode::firstlineno, NULL);
code_cls->giveAttrDescriptor("co_argcount", BoxedCode::argcount, NULL);
code_cls->giveAttrDescriptor("co_varnames", BoxedCode::varnames, NULL);
......
......@@ -41,8 +41,8 @@ public:
// pointers could point to them.
static BORROWED(Box*) name(Box* b, void*);
static BORROWED(Box*) filename(Box* b, void*);
static Box* f_name(Box* b, void*);
static Box* f_filename(Box* b, void*);
static Box* co_name(Box* b, void*);
static Box* co_filename(Box* b, void*);
static Box* firstlineno(Box* b, void*);
static Box* argcount(Box* b, void*);
static Box* varnames(Box* b, void*);
......
# expected: reffail
import _ast
def ast_parse(source, filename='<unknown>', mode='exec'):
......
# expected: reffail
print `42`
print `int`
print `2+3`
......
# expected: reffail
print compile
c = compile("a", "test.py", "eval")
print type(c), c.co_filename, c.co_name
......
# expected: reffail
from __future__ import division
# compile() inherits the future flags of the parent module
......
# expected: reffail
try:
import __pyston__
__pyston__.setOption("LAZY_SCOPING_ANALYSIS", 0)
......
# expected: reffail
# skip-if: '-O' in EXTRA_JIT_ARGS
# statcheck: 4 <= noninit_count('num_deopt') < 50
# statcheck: 1 <= stats["num_osr_exits"] <= 2
......
# expected: reffail
d = {}
exec "a = 5" in d
print d['a']
......
# expected: reffail
def f():
exec "a = 5"
print a
......
# expected: reffail
s = """
def f():
a = 1
......
# expected: reffail
# fail-if: '-x' in EXTRA_JIT_ARGS
# - we don't get syntax errors through the old parser correctly
......
# expected: reffail
import test_package.import_target
import import_target
print
......
# expected: reffail
# I really don't understand all the intricacies of unicode parsing, but apparently in addition to
# Python-specific coding lines, you can put a unicode byte order mark to signify that the text
# is encoded.
......
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