175
175
import static com .oracle .graal .python .nodes .SpecialMethodNames .T___SUB__ ;
176
176
import static com .oracle .graal .python .nodes .SpecialMethodNames .T___TRUEDIV__ ;
177
177
import static com .oracle .graal .python .nodes .SpecialMethodNames .T___XOR__ ;
178
+ import static com .oracle .graal .python .util .PythonUtils .TS_ENCODING ;
178
179
import static com .oracle .graal .python .util .PythonUtils .tsLiteral ;
179
180
180
181
import java .nio .charset .CharsetEncoder ;
191
192
import com .oracle .graal .python .builtins .objects .PythonAbstractObject .PInteropGetAttributeNode ;
192
193
import com .oracle .graal .python .builtins .objects .bytes .PByteArray ;
193
194
import com .oracle .graal .python .builtins .objects .bytes .PBytes ;
194
- import com .oracle .graal .python .builtins .objects .cext .PythonAbstractNativeObject ;
195
+ import com .oracle .graal .python .builtins .objects .cext .capi . CApiContext ;
195
196
import com .oracle .graal .python .builtins .objects .cext .capi .CExtNodes .AsCharPointerNode ;
196
197
import com .oracle .graal .python .builtins .objects .cext .capi .CExtNodes .LookupNativeMemberInMRONode ;
197
198
import com .oracle .graal .python .builtins .objects .cext .capi .CExtNodes .ObSizeNode ;
230
231
import com .oracle .graal .python .builtins .objects .dict .PDict ;
231
232
import com .oracle .graal .python .builtins .objects .frame .PFrame ;
232
233
import com .oracle .graal .python .builtins .objects .function .PBuiltinFunction ;
233
- import com .oracle .graal .python .builtins .objects .function .PFunction ;
234
234
import com .oracle .graal .python .builtins .objects .function .PKeyword ;
235
235
import com .oracle .graal .python .builtins .objects .getsetdescriptor .GetSetDescriptor ;
236
236
import com .oracle .graal .python .builtins .objects .ints .PInt ;
265
265
import com .oracle .graal .python .nodes .attributes .ReadAttributeFromObjectNode ;
266
266
import com .oracle .graal .python .nodes .attributes .WriteAttributeToBuiltinTypeNode ;
267
267
import com .oracle .graal .python .nodes .attributes .WriteAttributeToObjectNode ;
268
+ import com .oracle .graal .python .nodes .classes .IsSubtypeNode ;
268
269
import com .oracle .graal .python .nodes .object .BuiltinClassProfiles .InlineIsBuiltinClassProfile ;
269
270
import com .oracle .graal .python .nodes .object .BuiltinClassProfiles .IsBuiltinObjectProfile ;
270
271
import com .oracle .graal .python .nodes .object .GetDictIfExistsNode ;
@@ -1979,9 +1980,11 @@ public Object get(@SuppressWarnings("unused") Object object) {
1979
1980
}
1980
1981
1981
1982
public abstract static class PyGetTypeSlotNode extends CApiUnaryBuiltinNode {
1983
+ private final TruffleString name ;
1982
1984
private @ Child LookupAttributeInMRONode lookup ;
1983
1985
1984
1986
PyGetTypeSlotNode (TruffleString name ) {
1987
+ this .name = name ;
1985
1988
lookup = LookupAttributeInMRONode .create (name );
1986
1989
}
1987
1990
@@ -1996,28 +1999,26 @@ public Object getClass(PythonManagedClass object) {
1996
1999
}
1997
2000
1998
2001
@ TruffleBoundary
1999
- private Object getProcsWrapper (Object object ) {
2000
- Object value = lookup .execute (object );
2002
+ private Object getProcsWrapper (Object type ) {
2003
+ Object value = lookup .execute (type );
2001
2004
if (value instanceof PNone ) {
2002
2005
// both None and NO_VALUE can appear
2003
2006
return getNULL ();
2004
2007
}
2005
- if (value instanceof PFunction ) {
2006
- PFunction func = (PFunction ) value ;
2007
- if (func .procsWrapper != null ) {
2008
- return func .procsWrapper ;
2008
+ /*
2009
+ * The method can be a slot wrapper that already wraps a native slot function. If it
2010
+ * matches in type and slot name, we should unwrap it to avoid nesting multiple
2011
+ * wrappers.
2012
+ */
2013
+ if (value instanceof PBuiltinFunction function ) {
2014
+ Object wrappedPtr = ExternalFunctionNodes .tryGetHiddenCallable (function );
2015
+ if (wrappedPtr != null && name .equalsUncached (function .getName (), TS_ENCODING ) &&
2016
+ function .getEnclosingType () != null && IsSubtypeNode .getUncached ().execute (type , function .getEnclosingType ())) {
2017
+ return wrappedPtr ;
2009
2018
}
2010
- return func .procsWrapper = createProcsWrapper (value );
2011
- } else if (value instanceof PBuiltinFunction ) {
2012
- PBuiltinFunction func = (PBuiltinFunction ) value ;
2013
- if (func .procsWrapper != null ) {
2014
- return func .procsWrapper ;
2015
- }
2016
- return func .procsWrapper = createProcsWrapper (value );
2017
- } else if (value instanceof PythonAbstractNativeObject ) {
2018
- return ((PythonAbstractNativeObject ) value ).getPtr ();
2019
2019
}
2020
- throw CompilerDirectives .shouldNotReachHere (value .getClass ().getSimpleName ());
2020
+ CApiContext cApiContext = PythonContext .get (this ).getCApiContext ();
2021
+ return cApiContext .getOrCreateProcWrapper (value , this ::createProcsWrapper );
2021
2022
}
2022
2023
2023
2024
private Object createProcsWrapper (Object value ) {
0 commit comments