Commit 2b5141a7 authored by Boxiang Sun's avatar Boxiang Sun

[WIP]custom builtin support

parent d915f9e4
...@@ -384,23 +384,29 @@ static void pickGlobalsAndLocals(Box*& globals, Box*& locals) { ...@@ -384,23 +384,29 @@ static void pickGlobalsAndLocals(Box*& globals, Box*& locals) {
RELEASE_ASSERT(globals && (globals->cls == module_cls || globals->cls == dict_cls), "Unspported globals type: %s", RELEASE_ASSERT(globals && (globals->cls == module_cls || globals->cls == dict_cls), "Unspported globals type: %s",
globals ? globals->cls->tp_name : "NULL"); globals ? globals->cls->tp_name : "NULL");
//
// if (globals) { if (globals) {
// // From CPython (they set it to be f->f_builtins): // From CPython (they set it to be f->f_builtins):
// Box* globals_dict; Box* globals_dict;
// if (globals->cls == module_cls) if (globals->cls == module_cls)
// globals_dict = globals->getAttrWrapper(); globals_dict = globals->getAttrWrapper();
// else else
// globals_dict = globals; globals_dict = globals;
//
// auto requested_builtins = PyDict_GetItemString(globals_dict, "__builtins__"); auto requested_builtins = PyDict_GetItemString(globals_dict, "__builtins__");
// if (requested_builtins == NULL) if (requested_builtins == NULL)
// PyDict_SetItemString(globals_dict, "__builtins__", PyEval_GetBuiltins()); PyDict_SetItemString(globals_dict, "__builtins__", PyEval_GetBuiltins());
// else else
// RELEASE_ASSERT(requested_builtins == builtins_module // ((FrameInfo*)cur_thread_state.frame_info)->builtins = requested_builtins;
// || requested_builtins == builtins_module->getAttrWrapper(), PyDict_SetItemString(globals_dict, "__builtins__", requested_builtins);
// "we don't support overriding __builtins__"); // ((FrameInfo*)cur_thread_state.frame_info)->builtins = globals_dict;
// } // if (requested_builtins != builtins_module
// && requested_builtins != builtins_module->getAttrWrapper()) {
// PyDict_SetItemString(globals_dict, "__builtins__", requested_builtins);
// builtins_module->clearAttrsForDealloc();
// builtins_module = (BoxedModule*)requested_builtins;
// }
}
} }
extern "C" PyObject* PyEval_EvalCode(PyCodeObject* co, PyObject* globals, PyObject* locals) noexcept { extern "C" PyObject* PyEval_EvalCode(PyCodeObject* co, PyObject* globals, PyObject* locals) noexcept {
......
...@@ -1053,6 +1053,8 @@ struct FrameInfo { ...@@ -1053,6 +1053,8 @@ struct FrameInfo {
FrameInfo* back; FrameInfo* back;
// TODO does this need to be owned? how does cpython do it? // TODO does this need to be owned? how does cpython do it?
BORROWED(BoxedCode*) code; BORROWED(BoxedCode*) code;
// What type of this field should be?
BORROWED(Box*) builtins;
BORROWED(Box*) updateBoxedLocals(); BORROWED(Box*) updateBoxedLocals();
......
...@@ -490,7 +490,8 @@ static PyObject* sys_displayhook(PyObject* self, PyObject* o) noexcept { ...@@ -490,7 +490,8 @@ static PyObject* sys_displayhook(PyObject* self, PyObject* o) noexcept {
return NULL; return NULL;
} }
*/ */
PyObject* builtins = builtins_module; // PyObject* builtins = builtins_module;
PyObject* builtins = ((FrameInfo*)cur_thread_state.frame_info)->builtins;
/* Print value except if None */ /* Print value except if None */
/* After printing, also assign to '_' */ /* After printing, also assign to '_' */
......
...@@ -235,9 +235,53 @@ void frameInvalidateBack(BoxedFrame* frame) { ...@@ -235,9 +235,53 @@ void frameInvalidateBack(BoxedFrame* frame) {
} }
extern "C" void initFrame(FrameInfo* frame_info) { extern "C" void initFrame(FrameInfo* frame_info) {
frame_info->back = (FrameInfo*)(cur_thread_state.frame_info); FrameInfo* back = (FrameInfo*)(cur_thread_state.frame_info);
frame_info->back = back;
cur_thread_state.frame_info = frame_info; cur_thread_state.frame_info = frame_info;
Box* builtins;
static BoxedString* builtins_str = getStaticString("__builtins__");
if (back == NULL || back->globals != frame_info->globals) {
if (PyModule_Check(frame_info->globals))
builtins = frame_info->globals->getattr(builtins_str);
else
builtins = PyDict_GetItem(frame_info->globals, builtins_str);
if (builtins && builtins->cls == attrwrapper_cls)
builtins = unwrapAttrWrapper(builtins);
if (builtins == NULL) {
builtins = PyDict_New();
if (builtins == NULL || PyDict_SetItemString(builtins, "None", Py_None) < 0)
RELEASE_ASSERT(0, "error");
} else
Py_INCREF(builtins);
} else {
builtins = incref(back->builtins);
}
frame_info->builtins = builtins;
} }
// Box* global_dict = PyModule_GetDict(frame_info->globals);
// builtins = PyDict_GetItem(global_dict, builtins_str);
// if (builtins) {
// if (PyModule_Check(builtins)) {
// builtins = PyModule_GetDict(builtins);
// assert(!builtins || PyDict_Check(builtins) || builtins->cls != attrwrapper_cls);
// } else if (!PyDict_Check(builtins) && builtins->cls != attrwrapper_cls)
// builtins = NULL;
// }
// if (builtins == NULL) {
// builtins = PyDict_New();
// if (builtins == NULL || PyDict_SetItemString(builtins, "None", Py_None) < 0)
// return;
// } else
// Py_INCREF(builtins);
// } else {
// builtins = builtins_module;
// // builtins = back->builtins;
// // assert(builtins != NULL && PyDict_Check
// }
// frame_info->builtins = builtins;
// }
FrameInfo* const FrameInfo::NO_DEINIT = (FrameInfo*)-2; // not -1 to not match memset(-1) FrameInfo* const FrameInfo::NO_DEINIT = (FrameInfo*)-2; // not -1 to not match memset(-1)
...@@ -303,6 +347,7 @@ extern "C" void deinitFrame(FrameInfo* frame_info) noexcept { ...@@ -303,6 +347,7 @@ extern "C" void deinitFrame(FrameInfo* frame_info) noexcept {
Py_CLEAR(frame_info->boxedLocals); Py_CLEAR(frame_info->boxedLocals);
Py_CLEAR(frame_info->globals); Py_CLEAR(frame_info->globals);
Py_CLEAR(frame_info->builtins);
assert(!PyErr_Occurred()); assert(!PyErr_Occurred());
if (restore_exc) if (restore_exc)
......
...@@ -7569,31 +7569,80 @@ extern "C" Box* getGlobal(Box* globals, BoxedString* name) { ...@@ -7569,31 +7569,80 @@ extern "C" Box* getGlobal(Box* globals, BoxedString* name) {
static StatCounter stat_builtins("getglobal_builtins"); static StatCounter stat_builtins("getglobal_builtins");
stat_builtins.log(); stat_builtins.log();
Box* rtn; Box* builtins = ((FrameInfo*)cur_thread_state.frame_info)->builtins;
if (rewriter.get()) {
RewriterVar* builtins = rewriter->loadConst((intptr_t)builtins_module, Location::any());
GetattrRewriteArgs rewrite_args(rewriter.get(), builtins, rewriter->getReturnDestination());
rewrite_args.obj_shape_guarded = true; // always builtin module
rtn = builtins_module->getattr(name, &rewrite_args);
if (!rewrite_args.isSuccessful()) if (builtins->cls == module_cls) {
rewriter.reset(NULL); Box* rtn;
else if (rtn) {
auto r_rtn = rewrite_args.getReturn(ReturnConvention::HAS_RETURN); if (rewriter.get() && builtins == builtins_module) {
rewriter->commitReturning(r_rtn); RewriterVar* r_builtins = rewriter->loadConst((intptr_t)builtins, Location::any());
GetattrRewriteArgs rewrite_args(rewriter.get(), r_builtins, rewriter->getReturnDestination());
rewrite_args.obj_shape_guarded = true; // always builtin module
rtn = builtins->getattr(name, &rewrite_args);
if (!rewrite_args.isSuccessful())
rewriter.reset(NULL);
else if(rtn) {
auto r_rtn = rewrite_args.getReturn(ReturnConvention::HAS_RETURN);
rewriter->commitReturning(r_rtn);
} else {
rewrite_args.getReturn(); // just make the asserts happy
rewriter.reset(NULL);
}
} else { } else {
rewrite_args.getReturn(); // just to make the asserts happy rtn = builtins->getattr(name);
rewriter.reset(NULL); }
if (rtn) {
assert(rtn->ob_refcnt > 0);
Py_INCREF(rtn);
return rtn;
} }
} else { } else {
rtn = builtins_module->getattr(name); ASSERT(builtins->cls == dict_cls || builtins->cls == attrwrapper_cls, "%s", builtins->cls->tp_name);
} BoxedDict* d = static_cast<BoxedDict*>(builtins);
if (rtn) { rewriter.reset(NULL);
assert(rtn->ob_refcnt > 0); REWRITE_ABORTED("Rewriting not implemented for getGlobals with a dict builtins yet");
Py_INCREF(rtn);
return rtn; auto it = d->d.find(name);
if (it != d->d.end()) {
assert(it->second->ob_refcnt > 0);
Py_INCREF(it->second);
return it->second;
}
} }
// Box* rtn;
// if (rewriter.get()) {
// RewriterVar* builtins = rewriter->loadConst((intptr_t)((FrameInfo*)cur_thread_state.frame_info)->builtins, Location::any());
// // RewriterVar* builtins = rewriter->loadConst((intptr_t)builtins_module, Location::any());
// GetattrRewriteArgs rewrite_args(rewriter.get(), builtins, rewriter->getReturnDestination());
// rewrite_args.obj_shape_guarded = true; // always builtin module
// rtn = ((FrameInfo*)cur_thread_state.frame_info)->builtins->getattr(name, &rewrite_args);
// // rtn = builtins_module->getattr(name, &rewrite_args);
//
// if (!rewrite_args.isSuccessful())
// rewriter.reset(NULL);
// else if (rtn) {
// auto r_rtn = rewrite_args.getReturn(ReturnConvention::HAS_RETURN);
// rewriter->commitReturning(r_rtn);
// } else {
// rewrite_args.getReturn(); // just to make the asserts happy
// rewriter.reset(NULL);
// }
// } else {
// rtn = ((FrameInfo*)cur_thread_state.frame_info)->builtins->getattr(name);
// // rtn = builtins_module->getattr(name);
// }
//
// if (rtn) {
// assert(rtn->ob_refcnt > 0);
// Py_INCREF(rtn);
// return rtn;
// } else {
// raiseExcHelper(NameError, "name '%s' is not defined", name->data());
// }
} }
assert(name->data()[name->size()] == '\0'); assert(name->data()[name->size()] == '\0');
......
...@@ -4814,6 +4814,7 @@ BORROWED(BoxedModule*) createModule(BoxedString* name, const char* fn, const cha ...@@ -4814,6 +4814,7 @@ BORROWED(BoxedModule*) createModule(BoxedString* name, const char* fn, const cha
if (name->s() == "__main__") if (name->s() == "__main__")
module->setattr(autoDecref(internStringMortal("__builtins__")), builtins_module, NULL); module->setattr(autoDecref(internStringMortal("__builtins__")), builtins_module, NULL);
// module->setattr(autoDecref(internStringMortal("__builtins__")), builtins_module, NULL);
return module; return module;
} }
......
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