Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some small fixings #1398

Merged
merged 5 commits into from
Dec 2, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions from_cpython/Include/classobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ PyAPI_FUNC(PyObject *) PyMethod_Function(PyObject *) PYSTON_NOEXCEPT;
PyAPI_FUNC(PyObject *) PyMethod_Self(PyObject *) PYSTON_NOEXCEPT;
PyAPI_FUNC(PyObject *) PyMethod_Class(PyObject *) PYSTON_NOEXCEPT;

// Pyston change: add help API to allow extensions to set the fields of PyMethodObject
PyAPI_FUNC(int) PyMethod_SetSelf(PyObject *, PyObject*) PYSTON_NOEXCEPT;

/* Look up attribute with name (a string) on instance object pinst, using
* only the instance and base class dicts. If a descriptor is found in
* a class dict, the descriptor is returned without calling it.
Expand Down
5 changes: 5 additions & 0 deletions from_cpython/Include/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,11 @@ PyAPI_FUNC(int) PyObject_HasAttrString(PyObject *, const char *) PYSTON_NOEXCEPT
PyAPI_FUNC(PyObject *) PyObject_GetAttr(PyObject *, PyObject *) PYSTON_NOEXCEPT;
PyAPI_FUNC(int) PyObject_SetAttr(PyObject *, PyObject *, PyObject *) PYSTON_NOEXCEPT;
PyAPI_FUNC(int) PyObject_HasAttr(PyObject *, PyObject *) PYSTON_NOEXCEPT;
// Pyston change: Add new APIs to access instance's dict
PyAPI_FUNC(PyObject *) PyObject_GetDictCopy(PyObject *) PYSTON_NOEXCEPT;
PyAPI_FUNC(void) PyObject_ClearDict(PyObject *) PYSTON_NOEXCEPT;
PyAPI_FUNC(void) PyObject_UpdateDict(PyObject *, PyObject *) PYSTON_NOEXCEPT;

PyAPI_FUNC(PyObject **) _PyObject_GetDictPtr(PyObject *) PYSTON_NOEXCEPT;
PyAPI_FUNC(PyObject *) PyObject_SelfIter(PyObject *) PYSTON_NOEXCEPT;
PyAPI_FUNC(PyObject *) _PyObject_NextNotImplemented(PyObject *) PYSTON_NOEXCEPT;
Expand Down
29 changes: 29 additions & 0 deletions src/capi/object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,35 @@ extern "C" PyObject** _PyObject_GetDictPtr(PyObject* obj) noexcept {
}
}

// This function returns the copy of object's dict, not a writable dict.
extern "C" PyObject* PyObject_GetDictCopy(PyObject* obj) noexcept {
PyTypeObject* tp = Py_TYPE(obj);
if (!tp->instancesHaveHCAttrs()) {
if (!tp->instancesHaveDictAttrs())
return NULL;
return PyDict_Copy(obj->getDict());
} else {
Box* attrwrapper = obj->getAttrWrapper();
// unwritable dict, this is just a copy of object's dict.
return attrwrapperToDict(attrwrapper);
}
}

extern "C" void PyObject_ClearDict(PyObject* obj) noexcept {
obj->clearAttrsForDealloc();
}

// This API just add or update key-value pairs. It will not remove existed items
// if the key is not contained in the new dict.
extern "C" void PyObject_UpdateDict(PyObject* obj, PyObject* dict) noexcept {
PyObject* d_key, *d_value;
Py_ssize_t i = 0;
while (PyDict_Next(dict, &i, &d_key, &d_value)) {
if (PyObject_SetAttr(obj, d_key, d_value) < 0)
return;
}
}

/* These methods are used to control infinite recursion in repr, str, print,
etc. Container objects that may recursively contain themselves,
e.g. builtin dictionaries and lists, should used Py_ReprEnter() and
Expand Down
17 changes: 9 additions & 8 deletions src/codegen/ast_interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -819,25 +819,26 @@ Value ASTInterpreter::visit_importfrom(BST_ImportFrom* node) {
Value module = getVReg(node->vreg_module);
AUTO_DECREF(module.o);

Value name_boxed = getVReg(node->vreg_name);
AUTO_DECREF(name_boxed.o);
InternedString name = getCodeConstants().getInternedString(node->index_id);

Value v;
if (jit)
v.var = jit->emitImportFrom(module, name_boxed);
v.o = importFrom(module.o, (BoxedString*)name_boxed.o);
v.var = jit->emitImportFrom(module, name);
v.o = importFrom(module.o, (BoxedString*)name);
return v;
}

Value ASTInterpreter::visit_importname(BST_ImportName* node) {
int level = node->level;
Value froms = getVReg(node->vreg_from);
AUTO_DECREF(froms.o);
Value module_name = getVReg(node->vreg_name);
AUTO_DECREF(module_name.o);

InternedString name = getCodeConstants().getInternedString(node->index_id);

Value v;
if (jit)
v.var = jit->emitImportName(level, froms, module_name);
v.o = import(level, froms.o, (BoxedString*)module_name.o);
v.var = jit->emitImportName(level, froms, name.getBox());
v.o = import(level, froms.o, (BoxedString*)name);
return v;
}

Expand Down
8 changes: 4 additions & 4 deletions src/codegen/baseline_jit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -482,12 +482,12 @@ RewriterVar* JitFragmentWriter::emitHasnext(RewriterVar* v) {
return rtn;
}

RewriterVar* JitFragmentWriter::emitImportFrom(RewriterVar* module, RewriterVar* name) {
return call(false, (void*)importFrom, module, name)->setType(RefType::OWNED);
RewriterVar* JitFragmentWriter::emitImportFrom(RewriterVar* module, BoxedString* s) {
return call(false, (void*)importFrom, module, imm(s))->setType(RefType::OWNED);
}

RewriterVar* JitFragmentWriter::emitImportName(int level, RewriterVar* from_imports, RewriterVar* module_name) {
return call(false, (void*)import, imm(level), from_imports, module_name)->setType(RefType::OWNED);
RewriterVar* JitFragmentWriter::emitImportName(int level, RewriterVar* from_imports, BoxedString* s) {
return call(false, (void*)import, imm(level), from_imports, imm(s))->setType(RefType::OWNED);
}

RewriterVar* JitFragmentWriter::emitImportStar(RewriterVar* module) {
Expand Down
4 changes: 2 additions & 2 deletions src/codegen/baseline_jit.h
Original file line number Diff line number Diff line change
Expand Up @@ -293,8 +293,8 @@ class JitFragmentWriter : ICInfoManager, public Rewriter {
RewriterVar* emitGetLocalMustExist(int vreg);
RewriterVar* emitGetPystonIter(RewriterVar* v);
RewriterVar* emitHasnext(RewriterVar* v);
RewriterVar* emitImportFrom(RewriterVar* module, RewriterVar* name);
RewriterVar* emitImportName(int level, RewriterVar* from_imports, RewriterVar* module_name);
RewriterVar* emitImportFrom(RewriterVar* module, BoxedString* s);
RewriterVar* emitImportName(int level, RewriterVar* from_imports, BoxedString* s);
RewriterVar* emitImportStar(RewriterVar* module);
RewriterVar* emitLandingpad();
RewriterVar* emitNonzero(RewriterVar* v);
Expand Down
20 changes: 10 additions & 10 deletions src/codegen/irgen/irgenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -942,12 +942,12 @@ class IRGeneratorImpl : public IRGenerator {
CompilerVariable* evalImportFrom(BST_ImportFrom* node, const UnwindInfo& unw_info) {
CompilerVariable* module = evalVReg(node->vreg_module);
ConcreteCompilerVariable* converted_module = module->makeConverted(emitter, module->getBoxType());
InternedString name = irstate->getCodeConstants().getInternedString(node->index_id);

CompilerVariable* name = evalVReg(node->vreg_name);
ConcreteCompilerVariable* converted_name = name->makeConverted(emitter, name->getBoxType());

llvm::Value* r = emitter.createCall2(unw_info, g.funcs.importFrom, converted_module->getValue(),
converted_name->getValue());
llvm::Value* converted_name = embedRelocatablePtr(name, g.llvm_boxedstring_type_ptr);
emitter.setType(converted_name, RefType::BORROWED);
llvm::Value* r
= emitter.createCall2(unw_info, g.funcs.importFrom, converted_module->getValue(), converted_name);
emitter.setType(r, RefType::OWNED);

CompilerVariable* v = new ConcreteCompilerVariable(UNKNOWN, r);
Expand All @@ -973,12 +973,12 @@ class IRGeneratorImpl : public IRGenerator {
CompilerVariable* froms = evalVReg(node->vreg_from);
ConcreteCompilerVariable* converted_froms = froms->makeConverted(emitter, froms->getBoxType());

CompilerVariable* name = evalVReg(node->vreg_name);
ConcreteCompilerVariable* converted_name = name->makeConverted(emitter, name->getBoxType());
InternedString name = irstate->getCodeConstants().getInternedString(node->index_id);

llvm::Value* imported
= emitter.createCall(unw_info, g.funcs.import, { getConstantInt(level, g.i32), converted_froms->getValue(),
converted_name->getValue() });
llvm::Value* converted_name = embedRelocatablePtr(name, g.llvm_boxedstring_type_ptr);
emitter.setType(converted_name, RefType::BORROWED);
llvm::Value* imported = emitter.createCall(
unw_info, g.funcs.import, { getConstantInt(level, g.i32), converted_froms->getValue(), converted_name });
emitter.setType(imported, RefType::OWNED);
ConcreteCompilerVariable* v = new ConcreteCompilerVariable(UNKNOWN, imported);
return v;
Expand Down
8 changes: 4 additions & 4 deletions src/core/bst.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ void BST_ImportFrom::accept(BSTVisitor* v) {
return;

v->visit_vreg(&vreg_module);
v->visit_vreg(&vreg_name);
v->visit_vreg(&index_id);
v->visit_vreg(&vreg_dst, true);
}

Expand All @@ -314,7 +314,7 @@ void BST_ImportName::accept(BSTVisitor* v) {
return;

v->visit_vreg(&vreg_from);
v->visit_vreg(&vreg_name);
v->visit_vreg(&index_id);
v->visit_vreg(&vreg_dst, true);
}

Expand Down Expand Up @@ -1007,7 +1007,7 @@ bool PrintVisitor::visit_importfrom(BST_ImportFrom* node) {
stream << ":IMPORT_FROM(";
visit_vreg(&node->vreg_module);
stream << ", ";
visit_vreg(&node->vreg_name);
visit_vreg(&node->index_id);
stream << ")";
return true;
}
Expand All @@ -1018,7 +1018,7 @@ bool PrintVisitor::visit_importname(BST_ImportName* node) {
stream << ":IMPORT_NAME(";
visit_vreg(&node->vreg_from);
stream << ", ";
visit_vreg(&node->vreg_name);
visit_vreg(&node->index_id);
stream << ", " << node->level << ")";
return true;
}
Expand Down
4 changes: 2 additions & 2 deletions src/core/bst.h
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,7 @@ class BST_GetIter : public BST_stmt_with_dest {
class BST_ImportFrom : public BST_stmt_with_dest {
public:
int vreg_module = VREG_UNDEFINED;
int vreg_name = VREG_UNDEFINED;
int index_id = VREG_UNDEFINED;

BSTFIXEDVREGS(ImportFrom, BST_stmt_with_dest)
} PACKED;
Expand All @@ -670,7 +670,7 @@ class BST_ImportName : public BST_stmt_with_dest {
public:
int vreg_from = VREG_UNDEFINED;
int level = VREG_UNDEFINED;
int vreg_name = VREG_UNDEFINED;
int index_id = VREG_UNDEFINED;

BSTFIXEDVREGS(ImportName, BST_stmt_with_dest)
} PACKED;
Expand Down
6 changes: 3 additions & 3 deletions src/core/cfg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1990,7 +1990,7 @@ class CFGVisitor : public ASTVisitor {
import->level = level;

unmapExpr(makeNone(node->lineno), &import->vreg_from);
unmapExpr(makeStr(a->name.s(), node->lineno), &import->vreg_name);
import->index_id = remapInternedString(a->name);

TmpValue tmpname = createDstName(import);

Expand Down Expand Up @@ -2049,7 +2049,7 @@ class CFGVisitor : public ASTVisitor {
import->level = level;

unmapExpr(tuple_name, &import->vreg_from);
unmapExpr(makeStr(node->module.s()), &import->vreg_name);
import->index_id = remapInternedString(internString(node->module.s()));

TmpValue tmp_module_name = createDstName(import);

Expand All @@ -2068,7 +2068,7 @@ class CFGVisitor : public ASTVisitor {
BST_ImportFrom* import_from = allocAndPush<BST_ImportFrom>();
import_from->lineno = node->lineno;
unmapExpr(remapped_tmp_module_name, &import_from->vreg_module);
unmapExpr(makeStr(a->name.s()), &import_from->vreg_name);
import_from->index_id = remapInternedString(a->name);

TmpValue tmp_import_name = createDstName(import_from);
pushAssign(a->asname.s().size() ? a->asname : a->name, tmp_import_name);
Expand Down
2 changes: 2 additions & 0 deletions src/runtime/builtin_modules/builtins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1428,6 +1428,7 @@ extern "C" BORROWED(PyObject*) PyEval_GetBuiltins(void) noexcept {
Box* ellipsisRepr(Box* self) {
return boxString("Ellipsis");
}

Box* divmod(Box* lhs, Box* rhs) {
return binopInternal<NOT_REWRITABLE, false>(lhs, rhs, AST_TYPE::DivMod, NULL);
}
Expand Down Expand Up @@ -2381,6 +2382,7 @@ void setupBuiltins() {
= BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(Box), false, "ellipsis", false, NULL, NULL, false);
ellipsis_cls->giveAttr("__repr__",
new BoxedFunction(BoxedCode::create((void*)ellipsisRepr, STR, 1, "ellipsis.__repr__")));
ellipsis_cls->freeze();
Ellipsis = new (ellipsis_cls) Box();
assert(Ellipsis->cls);

Expand Down
15 changes: 14 additions & 1 deletion src/runtime/classobj.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ static Box* instanceGetattributeSimple(BoxedInstance* inst, BoxedString* attr_st

Box* r = inst->getattr<rewritable>(attr_str, rewrite_args);
if (r) {
if (rewrite_args)
if (rewrite_args && rewrite_args->isSuccessful())
rewrite_args->assertReturnConvention(ReturnConvention::HAS_RETURN);
return incref(r);
}
Expand Down Expand Up @@ -1927,6 +1927,19 @@ extern "C" PyObject* PyMethod_Self(PyObject* im) noexcept {
return ((BoxedInstanceMethod*)im)->obj;
}

extern "C" int PyMethod_SetSelf(PyObject* im, PyObject* instance) noexcept {
if (!PyMethod_Check(im)) {
PyErr_BadInternalCall();
return 0;
}

Box* old = ((BoxedInstanceMethod*)im)->obj;
Py_INCREF(instance);
((BoxedInstanceMethod*)im)->obj = instance;
Py_XDECREF(old);
return 1;
}

extern "C" PyObject* PyMethod_Class(PyObject* im) noexcept {
if (!PyMethod_Check(im)) {
PyErr_BadInternalCall();
Expand Down
5 changes: 2 additions & 3 deletions src/runtime/import.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,8 @@ extern "C" PyObject* PyImport_ExecCodeModuleEx(const char* name, PyObject* co, c
}
}

extern "C" Box* import(int level, Box* from_imports, Box* _module_name) {
assert(_module_name->cls == str_cls);
BoxedString* module_name = (BoxedString*)_module_name;
extern "C" Box* import(int level, Box* from_imports, BoxedString* module_name) {
assert(module_name->cls == str_cls);
Box* rtn = PyImport_ImportModuleLevel(module_name->c_str(), getGlobalsDict(), NULL, from_imports, level);
if (!rtn)
throwCAPIException();
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/import.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
namespace pyston {

extern "C" PyObject* PyImport_GetImporter(PyObject* path) noexcept;
extern "C" Box* import(int level, Box* from_imports, Box* module_name);
extern "C" Box* import(int level, Box* from_imports, BoxedString* module_name);
BoxedModule* importCExtension(BoxedString* full_name, const std::string& last_name, const std::string& path);

#ifdef Py_REF_DEBUG
Expand Down
5 changes: 2 additions & 3 deletions src/runtime/objmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7462,11 +7462,10 @@ extern "C" void setGlobal(Box* globals, BoxedString* name, STOLEN(Box*) value) {
}
}

extern "C" Box* importFrom(Box* _m, Box* _name) {
extern "C" Box* importFrom(Box* _m, BoxedString* name) {
STAT_TIMER(t0, "us_timer_importFrom", 10);

assert(_name->cls == str_cls);
BoxedString* name = (BoxedString*)_name;
assert(name->cls == str_cls);

Box* r = getattrInternal<CXX>(_m, name);
if (r)
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/objmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ extern "C" void assignSlice(PyObject* u, PyObject* v, PyObject* w, PyObject* x);
extern "C" Box* getclsattr(Box* obj, BoxedString* attr) __attribute__((noinline));
extern "C" Box* getclsattrMaybeNonstring(Box* obj, Box* attr) __attribute__((noinline));
extern "C" Box* unaryop(Box* operand, int op_type) __attribute__((noinline));
extern "C" Box* importFrom(Box* obj, Box* attr) __attribute__((noinline));
extern "C" Box* importFrom(Box* obj, BoxedString* attr) __attribute__((noinline));
extern "C" Box* importStar(Box* from_module, Box* to_globals) __attribute__((noinline));
extern "C" Box** unpackIntoArray(Box* obj, int64_t expected_size, Box** out_keep_alive);
extern "C" void assertNameDefined(bool b, const char* name, BoxedClass* exc_cls, bool local_var_msg);
Expand Down
46 changes: 46 additions & 0 deletions test/test_extension/api_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,55 @@ test_attrwrapper_parse(PyObject *self, PyObject* args) {
Py_RETURN_NONE;
}

static PyObject*
change_self(PyObject* self, PyObject* args) {
PyObject *im, *inst;
if (!PyArg_ParseTuple(args, "OO", &im, &inst))
return NULL;

#if defined(PYSTON_VERSION)
if (!PyMethod_SetSelf(im, inst))
return NULL;
#else
Py_XDECREF(((PyMethodObject*)im)->im_self);
Py_INCREF(inst);
((PyMethodObject*)im)->im_self = inst;
#endif
Py_RETURN_NONE;
}

static PyObject*
dict_API_test(PyObject* self, PyObject* args) {
PyObject *inst;
if (!PyArg_ParseTuple(args, "O", &inst))
return NULL;

#if defined(PYSTON_VERSION)
// Get `name` field in inst.
PyObject* dict = PyObject_GetDictCopy(inst);
if (dict == Py_None)
return NULL;
PyObject* name = PyDict_GetItem(dict, PyString_FromString("name"));

// Clear the object's dict.
PyObject_ClearDict(inst);
PyObject* old_dict = PyObject_GetDictCopy(inst);
// Set new items for object's dict.
PyObject* new_dict = PyDict_New();
PyDict_SetItem(new_dict, PyString_FromString("value"), PyInt_FromLong(42));
PyObject_UpdateDict(inst, new_dict);

// The return values should be 'Pyston', {}
return Py_BuildValue("OO", name, old_dict);
#endif
return Py_BuildValue("OO", Py_None, Py_None);
}

static PyMethodDef TestMethods[] = {
{"set_size", set_size, METH_O, "Get set size by PySet_Size." },
{"test_attrwrapper_parse", test_attrwrapper_parse, METH_VARARGS, "Test PyArg_ParseTuple for attrwrappers." },
{"change_self", change_self, METH_VARARGS, "A function which the self point to its base class."},
{"dict_API_test", dict_API_test, METH_VARARGS, ""},
{NULL, NULL, 0, NULL} /* Sentinel */
};

Expand Down
Loading