Skip to content

Commit 2952f59

Browse files
fangerertimfel
authored andcommitted
Support native subclass in ComplexBuiltins.HashNode
1 parent 9593c44 commit 2952f59

File tree

3 files changed

+51
-3
lines changed

3 files changed

+51
-3
lines changed

graalpython/com.oracle.graal.python.cext/src/capi.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,12 @@ PyAPI_FUNC(RESULT) get_##NAME(RECEIVER obj) { \
432432
PyAPI_FUNC(RESULT) get_##NAME(RECEIVER obj) { \
433433
return obj->FIELD? obj->FIELD->NAME : NULL; \
434434
}
435+
436+
#define PRIMITIVE_EMBEDDED_FIELD_GETTER(RECEIVER, FIELD, RESULT, NAME) \
437+
PyAPI_FUNC(RESULT) get_##FIELD##_##NAME(RECEIVER obj) { \
438+
return obj->FIELD.NAME; \
439+
}
440+
435441
TYPE_FIELD_GETTER(PyObject*, ob_type)
436442
PRIMITIVE_FIELD_GETTER(PyObject*, Py_ssize_t, ob_refcnt)
437443
PRIMITIVE_FIELD_GETTER(PyVarObject*, Py_ssize_t, ob_size)
@@ -514,6 +520,8 @@ PRIMITIVE_FIELD_GETTER(PyTypeObject*, unsigned long, tp_flags)
514520
PRIMITIVE_FIELD_GETTER(PyModuleDef_Base*, Py_ssize_t, m_index)
515521
PRIMITIVE_FIELD_GETTER(PyModuleDef*, Py_ssize_t, m_size)
516522
PRIMITIVE_FIELD_GETTER(PyModuleDef*, const char*, m_doc)
523+
PRIMITIVE_EMBEDDED_FIELD_GETTER(PyComplexObject*, cval, double, real)
524+
PRIMITIVE_EMBEDDED_FIELD_GETTER(PyComplexObject*, cval, double, imag)
517525

518526
char* get_ob_sval(PyObject* op) {
519527
return ((PyBytesObject *)(op))->ob_sval;

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/NativeCAPISymbol.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,8 @@ public enum NativeCAPISymbol implements NativeCExtSymbol {
194194
FUN_GET_MP_LENGTH("get_mp_length"),
195195
FUN_GET_MP_SUBSCRIPT("get_mp_subscript"),
196196
FUN_GET_MP_ASS_SUBSCRIPT("get_mp_ass_subscript"),
197+
FUN_GET_PY_COMPLEX_CVAL_REAL("get_cval_real"),
198+
FUN_GET_PY_COMPLEX_CVAL_IMAG("get_cval_imag"),
197199
FUN_GET_PYMODULEDEF_M_METHODS("get_PyModuleDef_m_methods"),
198200
FUN_GET_PYMODULEDEF_M_SLOTS("get_PyModuleDef_m_slots"),
199201
FUN_GET_BYTE_ARRAY_TYPE_ID("get_byte_array_typeid"),

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/complex/ComplexBuiltins.java

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@
8181
import com.oracle.graal.python.builtins.modules.SysModuleBuiltins;
8282
import com.oracle.graal.python.builtins.objects.PNone;
8383
import com.oracle.graal.python.builtins.objects.PNotImplemented;
84+
import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject;
85+
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.PCallCapiFunction;
86+
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.ToSulongNode;
87+
import com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol;
8488
import com.oracle.graal.python.builtins.objects.common.FormatNodeBase;
8589
import com.oracle.graal.python.builtins.objects.complex.ComplexBuiltinsClinicProviders.FormatNodeClinicProviderGen;
8690
import com.oracle.graal.python.builtins.objects.floats.FloatBuiltins;
@@ -102,6 +106,7 @@
102106
import com.oracle.graal.python.runtime.formatting.InternalFormat;
103107
import com.oracle.graal.python.runtime.formatting.InternalFormat.Spec;
104108
import com.oracle.graal.python.runtime.object.PythonObjectFactory;
109+
import com.oracle.truffle.api.CompilerDirectives;
105110
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
106111
import com.oracle.truffle.api.dsl.Bind;
107112
import com.oracle.truffle.api.dsl.Cached;
@@ -112,6 +117,8 @@
112117
import com.oracle.truffle.api.dsl.Specialization;
113118
import com.oracle.truffle.api.dsl.TypeSystemReference;
114119
import com.oracle.truffle.api.frame.VirtualFrame;
120+
import com.oracle.truffle.api.interop.InteropLibrary;
121+
import com.oracle.truffle.api.interop.UnsupportedMessageException;
115122
import com.oracle.truffle.api.nodes.Node;
116123
import com.oracle.truffle.api.profiles.InlinedConditionProfile;
117124
import com.oracle.truffle.api.strings.TruffleString;
@@ -798,12 +805,43 @@ static double get(PComplex self) {
798805
@Builtin(name = J___HASH__, minNumOfPositionalArgs = 1)
799806
abstract static class HashNode extends PythonUnaryBuiltinNode {
800807
@Specialization
801-
static long hash(PComplex self) {
808+
static long doPComplex(PComplex self) {
809+
return complexHash(self.getReal(), self.getImag());
810+
}
811+
812+
@Specialization
813+
static long doNative(PythonAbstractNativeObject self,
814+
@Cached ToSulongNode toSulongNode,
815+
@Cached PCallCapiFunction callGetRealNode,
816+
@Cached PCallCapiFunction callGetImagNode) {
817+
Object ptr = toSulongNode.execute(self);
818+
Object realObj = callGetRealNode.call(NativeCAPISymbol.FUN_GET_PY_COMPLEX_CVAL_REAL, ptr);
819+
Object imagObj = callGetImagNode.call(NativeCAPISymbol.FUN_GET_PY_COMPLEX_CVAL_IMAG, ptr);
820+
return complexHash(expectDouble(realObj), expectDouble(imagObj));
821+
}
822+
823+
private static long complexHash(double real, double imag) {
802824
// just like CPython
803-
long realHash = PyObjectHashNode.hash(self.getReal());
804-
long imagHash = PyObjectHashNode.hash(self.getImag());
825+
long realHash = PyObjectHashNode.hash(real);
826+
long imagHash = PyObjectHashNode.hash(imag);
805827
return realHash + SysModuleBuiltins.HASH_IMAG * imagHash;
806828
}
829+
830+
private static double expectDouble(Object val) {
831+
if (val instanceof Double) {
832+
return (double) val;
833+
}
834+
InteropLibrary lib = InteropLibrary.getUncached(val);
835+
if (lib.fitsInDouble(val)) {
836+
try {
837+
return lib.asDouble(val);
838+
} catch (UnsupportedMessageException e) {
839+
// fall through
840+
}
841+
}
842+
throw CompilerDirectives.shouldNotReachHere();
843+
}
844+
807845
}
808846

809847
@GenerateNodeFactory

0 commit comments

Comments
 (0)