Commit d9b9ca66 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Make accesses to f.func_code return the same object

parent 247c0171
...@@ -264,6 +264,7 @@ public: ...@@ -264,6 +264,7 @@ public:
typedef std::vector<CompiledFunction*> FunctionList; typedef std::vector<CompiledFunction*> FunctionList;
struct CallRewriteArgs; struct CallRewriteArgs;
class BoxedCode;
class CLFunction { class CLFunction {
public: public:
int num_args; int num_args;
...@@ -278,6 +279,9 @@ public: ...@@ -278,6 +279,9 @@ public:
CompiledFunction* always_use_version; // if this version is set, always use it (for unboxed cases) CompiledFunction* always_use_version; // if this version is set, always use it (for unboxed cases)
std::unordered_map<const OSREntryDescriptor*, CompiledFunction*> osr_versions; std::unordered_map<const OSREntryDescriptor*, CompiledFunction*> osr_versions;
// Please use codeForFunction() to access this:
BoxedCode* code_obj;
// Functions can provide an "internal" version, which will get called instead // Functions can provide an "internal" version, which will get called instead
// of the normal dispatch through the functionlist. // of the normal dispatch through the functionlist.
// This can be used to implement functions which know how to rewrite themselves, // This can be used to implement functions which know how to rewrite themselves,
...@@ -289,12 +293,12 @@ public: ...@@ -289,12 +293,12 @@ public:
CLFunction(int num_args, int num_defaults, bool takes_varargs, bool takes_kwargs, CLFunction(int num_args, int num_defaults, bool takes_varargs, bool takes_kwargs,
std::unique_ptr<SourceInfo> source) std::unique_ptr<SourceInfo> source)
: num_args(num_args), num_defaults(num_defaults), takes_varargs(takes_varargs), takes_kwargs(takes_kwargs), : num_args(num_args), num_defaults(num_defaults), takes_varargs(takes_varargs), takes_kwargs(takes_kwargs),
source(std::move(source)), param_names(this->source->ast), always_use_version(NULL) { source(std::move(source)), param_names(this->source->ast), always_use_version(NULL), code_obj(NULL) {
assert(num_args >= num_defaults); assert(num_args >= num_defaults);
} }
CLFunction(int num_args, int num_defaults, bool takes_varargs, bool takes_kwargs, const ParamNames& param_names) CLFunction(int num_args, int num_defaults, bool takes_varargs, bool takes_kwargs, const ParamNames& param_names)
: num_args(num_args), num_defaults(num_defaults), takes_varargs(takes_varargs), takes_kwargs(takes_kwargs), : num_args(num_args), num_defaults(num_defaults), takes_varargs(takes_varargs), takes_kwargs(takes_kwargs),
source(nullptr), param_names(param_names), always_use_version(NULL) { source(nullptr), param_names(param_names), always_use_version(NULL), code_obj(NULL) {
assert(num_args >= num_defaults); assert(num_args >= num_defaults);
} }
......
...@@ -102,12 +102,17 @@ public: ...@@ -102,12 +102,17 @@ public:
} }
}; };
Box* codeForFunction(BoxedFunction* f) { Box* codeForCLFunction(CLFunction* f) {
return new BoxedCode(f->f); if (!f->code_obj) {
f->code_obj = new BoxedCode(f);
// CLFunctions don't currently participate in GC. They actually never get freed currently.
gc::registerPermanentRoot(f->code_obj);
}
return f->code_obj;
} }
Box* codeForCLFunction(CLFunction* f) { Box* codeForFunction(BoxedFunction* f) {
return new BoxedCode(f); return codeForCLFunction(f->f);
} }
CLFunction* clfunctionFromCode(Box* code) { CLFunction* clfunctionFromCode(Box* code) {
......
...@@ -838,7 +838,6 @@ static Box* builtinFunctionOrMethodName(Box* b, void*) { ...@@ -838,7 +838,6 @@ static Box* builtinFunctionOrMethodName(Box* b, void*) {
static Box* functionCode(Box* self, void*) { static Box* functionCode(Box* self, void*) {
assert(self->cls == function_cls); assert(self->cls == function_cls);
BoxedFunction* func = static_cast<BoxedFunction*>(self); BoxedFunction* func = static_cast<BoxedFunction*>(self);
// This fails "f.func_code is f.func_code"
return codeForFunction(func); return codeForFunction(func);
} }
...@@ -2424,6 +2423,7 @@ void setupRuntime() { ...@@ -2424,6 +2423,7 @@ void setupRuntime() {
new BoxedFunction(boxRTFunction((void*)functionCall, UNKNOWN, 1, 0, true, true))); new BoxedFunction(boxRTFunction((void*)functionCall, UNKNOWN, 1, 0, true, true)));
function_cls->giveAttr("__nonzero__", new BoxedFunction(boxRTFunction((void*)functionNonzero, BOXED_BOOL, 1))); function_cls->giveAttr("__nonzero__", new BoxedFunction(boxRTFunction((void*)functionNonzero, BOXED_BOOL, 1)));
function_cls->giveAttr("func_code", new (pyston_getset_cls) BoxedGetsetDescriptor(functionCode, NULL, NULL)); function_cls->giveAttr("func_code", new (pyston_getset_cls) BoxedGetsetDescriptor(functionCode, NULL, NULL));
function_cls->giveAttr("__code__", function_cls->getattr("func_code"));
function_cls->giveAttr("func_name", function_cls->getattr("__name__")); function_cls->giveAttr("func_name", function_cls->getattr("__name__"));
function_cls->giveAttr("func_defaults", function_cls->giveAttr("func_defaults",
new (pyston_getset_cls) BoxedGetsetDescriptor(functionDefaults, functionSetDefaults, NULL)); new (pyston_getset_cls) BoxedGetsetDescriptor(functionDefaults, functionSetDefaults, NULL));
......
...@@ -17,3 +17,6 @@ def f(): ...@@ -17,3 +17,6 @@ def f():
pass pass
print f.func_defaults print f.func_defaults
print f.func_code.co_firstlineno print f.func_code.co_firstlineno
# pytest uses this:
print f.__code__ is f.__code__
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