Skip to content

Commit b8cd6e6

Browse files
committed
Merge pull request #577 from kmod/tp_richcompare
tp_richcompare
2 parents cd6654b + f97bfec commit b8cd6e6

File tree

14 files changed

+363
-432
lines changed

14 files changed

+363
-432
lines changed

libunwind_patches/0003-use-a-sorted-array-for-registered-objects-and-do-a-b.patch

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ diff --git a/src/mi/dyn-register.c b/src/mi/dyn-register.c
119119
index c28954a..c4f88b1 100644
120120
--- a/src/mi/dyn-register.c
121121
+++ b/src/mi/dyn-register.c
122-
@@ -32,13 +32,28 @@ _U_dyn_register (unw_dyn_info_t *di)
122+
@@ -32,13 +32,27 @@ _U_dyn_register (unw_dyn_info_t *di)
123123
{
124124
mutex_lock (&_U_dyn_info_list_lock);
125125
{
@@ -148,8 +148,7 @@ index c28954a..c4f88b1 100644
148148
+ break;
149149
+ }
150150
+
151-
+ if (_U_dyn_info_list_size > 1)
152-
+ memmove(&_U_dyn_info_list[i+1], &_U_dyn_info_list[i], (_U_dyn_info_list_size - i) * sizeof(unw_dyn_info_t*));
151+
+ memmove(&_U_dyn_info_list[i+1], &_U_dyn_info_list[i], (_U_dyn_info_list_size - i) * sizeof(unw_dyn_info_t*));
153152
+ _U_dyn_info_list[i] = di;
154153
+ _U_dyn_info_list_size ++;
155154
}

src/capi/object.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -764,7 +764,7 @@ static int try_3way_compare(PyObject* v, PyObject* w) {
764764
0 if v == w;
765765
1 if v > w.
766766
*/
767-
static int default_3way_compare(PyObject* v, PyObject* w) {
767+
/* Pyston change: static*/ int default_3way_compare(PyObject* v, PyObject* w) {
768768
int c;
769769
const char* vname, *wname;
770770

@@ -865,7 +865,7 @@ extern "C" int PyObject_Compare(PyObject* v, PyObject* w) noexcept {
865865
}
866866

867867
/* Return (new reference to) Py_True or Py_False. */
868-
static PyObject* convert_3way_to_object(int op, int c) noexcept {
868+
/* Pyston change: static */ PyObject* convert_3way_to_object(int op, int c) noexcept {
869869
PyObject* result;
870870
switch (op) {
871871
case Py_LT:

src/capi/typeobject.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -761,7 +761,15 @@ static PyObject* half_richcompare(PyObject* self, PyObject* other, int op) noexc
761761
return res;
762762
}
763763

764-
static PyObject* slot_tp_richcompare(PyObject* self, PyObject* other, int op) noexcept {
764+
/* Pyston change: static*/ PyObject* slot_tp_richcompare(PyObject* self, PyObject* other, int op) noexcept {
765+
static StatCounter slowpath_richcompare("slowpath_richcompare");
766+
slowpath_richcompare.log();
767+
#if 0
768+
std::string per_name_stat_name = "slowpath_richcompare." + std::string(self->cls->tp_name);
769+
int id = Stats::getStatId(per_name_stat_name);
770+
Stats::log(id);
771+
#endif
772+
765773
PyObject* res;
766774

767775
if (Py_TYPE(self)->tp_richcompare == slot_tp_richcompare) {

src/capi/typeobject.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ void commonClassSetup(BoxedClass* cls);
3333
PyTypeObject* best_base(PyObject* bases) noexcept;
3434
PyObject* mro_external(PyObject* self) noexcept;
3535
int type_set_bases(PyTypeObject* type, PyObject* value, void* context) noexcept;
36+
37+
PyObject* slot_tp_richcompare(PyObject* self, PyObject* other, int op) noexcept;
3638
}
3739

3840
#endif

src/capi/types.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,9 @@ class BoxedMethodDescriptor : public Box {
237237
}
238238
};
239239

240+
PyObject* convert_3way_to_object(int op, int c) noexcept;
241+
int default_3way_compare(PyObject* v, PyObject* w);
242+
240243
} // namespace pyston
241244

242245
#endif

src/runtime/builtin_modules/builtins.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -162,10 +162,11 @@ extern "C" Box* min(Box* arg0, BoxedTuple* args) {
162162
if (!minElement) {
163163
minElement = e;
164164
} else {
165-
Box* comp_result = compareInternal(minElement, e, AST_TYPE::Gt, NULL);
166-
if (nonzero(comp_result)) {
165+
int r = PyObject_RichCompareBool(minElement, e, Py_GT);
166+
if (r == -1)
167+
throwCAPIException();
168+
if (r)
167169
minElement = e;
168-
}
169170
}
170171
}
171172

@@ -192,10 +193,11 @@ extern "C" Box* max(Box* arg0, BoxedTuple* args) {
192193
if (!maxElement) {
193194
maxElement = e;
194195
} else {
195-
Box* comp_result = compareInternal(maxElement, e, AST_TYPE::Lt, NULL);
196-
if (nonzero(comp_result)) {
196+
int r = PyObject_RichCompareBool(maxElement, e, Py_LT);
197+
if (r == -1)
198+
throwCAPIException();
199+
if (r)
197200
maxElement = e;
198-
}
199201
}
200202
}
201203

src/runtime/capi.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -586,8 +586,11 @@ extern "C" long _Py_HashPointer(void* p) noexcept {
586586
}
587587

588588
extern "C" int PyObject_IsTrue(PyObject* o) noexcept {
589+
if (o->cls == bool_cls)
590+
return o == True;
591+
589592
try {
590-
return nonzero(o);
593+
return o->nonzeroIC();
591594
} catch (ExcInfo e) {
592595
fatalOrError(PyExc_NotImplementedError, "unimplemented");
593596
return -1;
@@ -1647,6 +1650,13 @@ static Box* methodGetDoc(Box* b, void*) {
16471650
return None;
16481651
}
16491652

1653+
static Box* wrapperdescrGetDoc(Box* b, void*) {
1654+
assert(b->cls == wrapperdescr_cls);
1655+
auto s = static_cast<BoxedWrapperDescriptor*>(b)->wrapper->doc;
1656+
assert(s.size());
1657+
return boxString(s);
1658+
}
1659+
16501660
/* extension modules might be compiled with GC support so these
16511661
functions must always be available */
16521662

@@ -1735,6 +1745,8 @@ void setupCAPI() {
17351745
new BoxedFunction(boxRTFunction((void*)BoxedWrapperDescriptor::__get__, UNKNOWN, 3)));
17361746
wrapperdescr_cls->giveAttr("__call__", new BoxedFunction(boxRTFunction((void*)BoxedWrapperDescriptor::__call__,
17371747
UNKNOWN, 2, 0, true, true)));
1748+
wrapperdescr_cls->giveAttr("__doc__",
1749+
new (pyston_getset_cls) BoxedGetsetDescriptor(wrapperdescrGetDoc, NULL, NULL));
17381750
wrapperdescr_cls->freeze();
17391751

17401752
wrapperobject_cls->giveAttr(

src/runtime/int.cpp

Lines changed: 29 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -566,109 +566,6 @@ extern "C" Box* intTruediv(BoxedInt* lhs, Box* rhs) {
566566
}
567567
}
568568

569-
extern "C" Box* intEqInt(BoxedInt* lhs, BoxedInt* rhs) {
570-
assert(isSubclass(lhs->cls, int_cls));
571-
assert(isSubclass(rhs->cls, int_cls));
572-
return boxBool(lhs->n == rhs->n);
573-
}
574-
575-
extern "C" Box* intEq(BoxedInt* lhs, Box* rhs) {
576-
if (!isSubclass(lhs->cls, int_cls))
577-
raiseExcHelper(TypeError, "descriptor '__eq__' requires a 'int' object but received a '%s'", getTypeName(lhs));
578-
579-
if (isSubclass(rhs->cls, int_cls)) {
580-
BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs);
581-
return boxBool(lhs->n == rhs_int->n);
582-
} else {
583-
return NotImplemented;
584-
}
585-
}
586-
587-
extern "C" Box* intNeInt(BoxedInt* lhs, BoxedInt* rhs) {
588-
assert(isSubclass(lhs->cls, int_cls));
589-
assert(isSubclass(rhs->cls, int_cls));
590-
return boxBool(lhs->n != rhs->n);
591-
}
592-
593-
extern "C" Box* intNe(BoxedInt* lhs, Box* rhs) {
594-
if (!isSubclass(lhs->cls, int_cls))
595-
raiseExcHelper(TypeError, "descriptor '__ne__' requires a 'int' object but received a '%s'", getTypeName(lhs));
596-
597-
if (!isSubclass(rhs->cls, int_cls)) {
598-
return NotImplemented;
599-
}
600-
BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs);
601-
return boxBool(lhs->n != rhs_int->n);
602-
}
603-
604-
extern "C" Box* intLtInt(BoxedInt* lhs, BoxedInt* rhs) {
605-
assert(isSubclass(lhs->cls, int_cls));
606-
assert(isSubclass(rhs->cls, int_cls));
607-
return boxBool(lhs->n < rhs->n);
608-
}
609-
610-
extern "C" Box* intLt(BoxedInt* lhs, Box* rhs) {
611-
if (!isSubclass(lhs->cls, int_cls))
612-
raiseExcHelper(TypeError, "descriptor '__lt__' requires a 'int' object but received a '%s'", getTypeName(lhs));
613-
614-
if (!isSubclass(rhs->cls, int_cls)) {
615-
return NotImplemented;
616-
}
617-
BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs);
618-
return boxBool(lhs->n < rhs_int->n);
619-
}
620-
621-
extern "C" Box* intLeInt(BoxedInt* lhs, BoxedInt* rhs) {
622-
assert(isSubclass(lhs->cls, int_cls));
623-
assert(isSubclass(rhs->cls, int_cls));
624-
return boxBool(lhs->n <= rhs->n);
625-
}
626-
627-
extern "C" Box* intLe(BoxedInt* lhs, Box* rhs) {
628-
if (!isSubclass(lhs->cls, int_cls))
629-
raiseExcHelper(TypeError, "descriptor '__le__' requires a 'int' object but received a '%s'", getTypeName(lhs));
630-
631-
if (!isSubclass(rhs->cls, int_cls)) {
632-
return NotImplemented;
633-
}
634-
BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs);
635-
return boxBool(lhs->n <= rhs_int->n);
636-
}
637-
638-
extern "C" Box* intGtInt(BoxedInt* lhs, BoxedInt* rhs) {
639-
assert(isSubclass(lhs->cls, int_cls));
640-
assert(isSubclass(rhs->cls, int_cls));
641-
return boxBool(lhs->n > rhs->n);
642-
}
643-
644-
extern "C" Box* intGt(BoxedInt* lhs, Box* rhs) {
645-
if (!isSubclass(lhs->cls, int_cls))
646-
raiseExcHelper(TypeError, "descriptor '__gt__' requires a 'int' object but received a '%s'", getTypeName(lhs));
647-
648-
if (!isSubclass(rhs->cls, int_cls)) {
649-
return NotImplemented;
650-
}
651-
BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs);
652-
return boxBool(lhs->n > rhs_int->n);
653-
}
654-
655-
extern "C" Box* intGeInt(BoxedInt* lhs, BoxedInt* rhs) {
656-
assert(isSubclass(lhs->cls, int_cls));
657-
assert(isSubclass(rhs->cls, int_cls));
658-
return boxBool(lhs->n >= rhs->n);
659-
}
660-
661-
extern "C" Box* intGe(BoxedInt* lhs, Box* rhs) {
662-
if (!isSubclass(lhs->cls, int_cls))
663-
raiseExcHelper(TypeError, "descriptor '__ge__' requires a 'int' object but received a '%s'", getTypeName(lhs));
664-
665-
if (!isSubclass(rhs->cls, int_cls)) {
666-
return NotImplemented;
667-
}
668-
BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs);
669-
return boxBool(lhs->n >= rhs_int->n);
670-
}
671-
672569
extern "C" Box* intLShiftInt(BoxedInt* lhs, BoxedInt* rhs) {
673570
assert(isSubclass(lhs->cls, int_cls));
674571
assert(isSubclass(rhs->cls, int_cls));
@@ -1119,6 +1016,33 @@ static int64_t int_hash(BoxedInt* o) noexcept {
11191016
return n;
11201017
}
11211018

1019+
static PyObject* int_richcompare(PyObject* v, PyObject* w, int op) noexcept {
1020+
if (!PyInt_Check(v) || !PyInt_Check(w)) {
1021+
Py_INCREF(Py_NotImplemented);
1022+
return Py_NotImplemented;
1023+
}
1024+
1025+
int64_t lhs = static_cast<BoxedInt*>(v)->n;
1026+
int64_t rhs = static_cast<BoxedInt*>(w)->n;
1027+
1028+
switch (op) {
1029+
case Py_EQ:
1030+
return boxBool(lhs == rhs);
1031+
case Py_NE:
1032+
return boxBool(lhs != rhs);
1033+
case Py_LT:
1034+
return boxBool(lhs < rhs);
1035+
case Py_LE:
1036+
return boxBool(lhs <= rhs);
1037+
case Py_GT:
1038+
return boxBool(lhs > rhs);
1039+
case Py_GE:
1040+
return boxBool(lhs >= rhs);
1041+
default:
1042+
RELEASE_ASSERT(0, "%d", op);
1043+
}
1044+
}
1045+
11221046
void setupInt() {
11231047
for (int i = 0; i < NUM_INTERNED_INTS; i++) {
11241048
interned_ints[i] = new BoxedInt(i);
@@ -1138,12 +1062,8 @@ void setupInt() {
11381062
int_cls->giveAttr("__pow__",
11391063
new BoxedFunction(boxRTFunction((void*)intPow, UNKNOWN, 3, 1, false, false), { None }));
11401064

1141-
_addFuncIntUnknown("__eq__", BOXED_BOOL, (void*)intEqInt, (void*)intEq);
1142-
_addFuncIntUnknown("__ne__", BOXED_BOOL, (void*)intNeInt, (void*)intNe);
1143-
_addFuncIntUnknown("__lt__", BOXED_BOOL, (void*)intLtInt, (void*)intLt);
1144-
_addFuncIntUnknown("__le__", BOXED_BOOL, (void*)intLeInt, (void*)intLe);
1145-
_addFuncIntUnknown("__gt__", BOXED_BOOL, (void*)intGtInt, (void*)intGt);
1146-
_addFuncIntUnknown("__ge__", BOXED_BOOL, (void*)intGeInt, (void*)intGe);
1065+
// Note: CPython implements int comparisons using tp_compare
1066+
int_cls->tp_richcompare = int_richcompare;
11471067

11481068
_addFuncIntUnknown("__lshift__", UNKNOWN, (void*)intLShiftInt, (void*)intLShift);
11491069
_addFuncIntUnknown("__rshift__", UNKNOWN, (void*)intRShiftInt, (void*)intRShift);

0 commit comments

Comments
 (0)