|
69 | 69 | import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.NativeBuiltin;
|
70 | 70 | import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.PyErrRestoreNode;
|
71 | 71 | import com.oracle.graal.python.builtins.objects.PNone;
|
| 72 | +import com.oracle.graal.python.builtins.objects.cext.PythonNativeVoidPtr; |
| 73 | +import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes; |
72 | 74 | import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.AddRefCntNode;
|
73 | 75 | import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.AsPythonObjectNode;
|
74 | 76 | import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.PRaiseNativeNode;
|
75 | 77 | import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.ToNewRefNode;
|
76 | 78 | import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.TransformExceptionToNativeNode;
|
77 | 79 | import com.oracle.graal.python.builtins.objects.cext.capi.DynamicObjectNativeWrapper.PrimitiveNativeWrapper;
|
| 80 | +import com.oracle.graal.python.builtins.objects.common.HashingCollectionNodes; |
| 81 | +import com.oracle.graal.python.builtins.objects.common.PHashingCollection; |
| 82 | +import com.oracle.graal.python.builtins.objects.common.SequenceNodes; |
78 | 83 | import com.oracle.graal.python.builtins.objects.dict.DictBuiltins.ItemsNode;
|
79 | 84 | import com.oracle.graal.python.builtins.objects.dict.DictBuiltins.KeysNode;
|
80 | 85 | import com.oracle.graal.python.builtins.objects.dict.DictBuiltins.ValuesNode;
|
81 | 86 | import com.oracle.graal.python.builtins.objects.dict.PDict;
|
82 | 87 | import com.oracle.graal.python.builtins.objects.list.PList;
|
83 | 88 | import com.oracle.graal.python.builtins.objects.tuple.PTuple;
|
| 89 | +import com.oracle.graal.python.lib.PyMappingCheckNode; |
84 | 90 | import com.oracle.graal.python.lib.PyNumberFloatNode;
|
85 | 91 | import com.oracle.graal.python.lib.PyObjectDelItem;
|
86 | 92 | import com.oracle.graal.python.lib.PyObjectGetAttr;
|
87 | 93 | import com.oracle.graal.python.lib.PyObjectLookupAttr;
|
| 94 | +import com.oracle.graal.python.lib.PyObjectSizeNode; |
88 | 95 | import com.oracle.graal.python.lib.PySequenceCheckNode;
|
89 | 96 | import com.oracle.graal.python.nodes.ErrorMessages;
|
| 97 | +import com.oracle.graal.python.nodes.SpecialMethodNames; |
90 | 98 | import com.oracle.graal.python.nodes.builtins.ListNodes.ConstructListNode;
|
91 | 99 | import com.oracle.graal.python.nodes.call.CallNode;
|
| 100 | +import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode; |
92 | 101 | import com.oracle.graal.python.nodes.expression.BinaryArithmetic;
|
93 | 102 | import com.oracle.graal.python.nodes.expression.BinaryArithmetic.MulNode;
|
94 | 103 | import com.oracle.graal.python.nodes.expression.BinaryOpNode;
|
|
106 | 115 | import com.oracle.graal.python.nodes.subscript.SliceLiteralNode;
|
107 | 116 | import com.oracle.graal.python.nodes.truffle.PythonTypes;
|
108 | 117 | import com.oracle.graal.python.runtime.exception.PException;
|
| 118 | +import com.oracle.graal.python.runtime.sequence.PSequence; |
109 | 119 | import com.oracle.truffle.api.CompilerDirectives;
|
110 | 120 | import com.oracle.truffle.api.dsl.Cached;
|
111 | 121 | import com.oracle.truffle.api.dsl.Fallback;
|
112 | 122 | import com.oracle.truffle.api.dsl.GenerateNodeFactory;
|
| 123 | +import com.oracle.truffle.api.dsl.ImportStatic; |
113 | 124 | import com.oracle.truffle.api.dsl.NodeFactory;
|
114 | 125 | import com.oracle.truffle.api.dsl.Specialization;
|
115 | 126 | import com.oracle.truffle.api.dsl.TypeSystemReference;
|
@@ -976,6 +987,53 @@ Object doManaged(VirtualFrame frame, Object listWrapper, Object key,
|
976 | 987 | }
|
977 | 988 | }
|
978 | 989 |
|
| 990 | + @Builtin(name = "PyObject_Size", minNumOfPositionalArgs = 1) |
| 991 | + @GenerateNodeFactory |
| 992 | + @ImportStatic(SpecialMethodNames.class) |
| 993 | + abstract static class PyObject_Size extends PythonUnaryBuiltinNode { |
| 994 | + |
| 995 | + // n.b.: specializations 'doSequence' and 'doMapping' are not just shortcuts but also |
| 996 | + // required for correctness because CPython's implementation uses |
| 997 | + // 'type->tp_as_sequence->sq_length', 'type->tp_as_mapping->mp_length' which will bypass |
| 998 | + // any |
| 999 | + // user implementation of '__len__'. |
| 1000 | + @Specialization |
| 1001 | + static int doSequence(PSequence sequence, |
| 1002 | + @Cached SequenceNodes.LenNode seqLenNode) { |
| 1003 | + return seqLenNode.execute(sequence); |
| 1004 | + } |
| 1005 | + |
| 1006 | + @Specialization |
| 1007 | + static int doMapping(PHashingCollection container, |
| 1008 | + @Cached HashingCollectionNodes.LenNode seqLenNode) { |
| 1009 | + return seqLenNode.execute(container); |
| 1010 | + } |
| 1011 | + |
| 1012 | + @Specialization(guards = "!isMappingOrSequence(obj)") |
| 1013 | + static Object doGenericUnboxed(VirtualFrame frame, Object obj, |
| 1014 | + @Cached("create(Len)") LookupAndCallUnaryNode callLenNode, |
| 1015 | + @Cached ConditionProfile noLenProfile, |
| 1016 | + @Cached CExtNodes.CastToNativeLongNode castToLongNode, |
| 1017 | + @Cached TransformExceptionToNativeNode transformExceptionToNativeNode) { |
| 1018 | + try { |
| 1019 | + Object result = callLenNode.executeObject(frame, obj); |
| 1020 | + if (noLenProfile.profile(result == PNone.NO_VALUE)) { |
| 1021 | + return -1; |
| 1022 | + } |
| 1023 | + Object lresult = castToLongNode.execute(result); |
| 1024 | + assert lresult instanceof Long || lresult instanceof PythonNativeVoidPtr; |
| 1025 | + return lresult; |
| 1026 | + } catch (PException e) { |
| 1027 | + transformExceptionToNativeNode.execute(frame, e); |
| 1028 | + return -1; |
| 1029 | + } |
| 1030 | + } |
| 1031 | + |
| 1032 | + protected static boolean isMappingOrSequence(Object obj) { |
| 1033 | + return obj instanceof PSequence || obj instanceof PHashingCollection; |
| 1034 | + } |
| 1035 | + } |
| 1036 | + |
979 | 1037 | /////// PyMapping ///////
|
980 | 1038 |
|
981 | 1039 | @Builtin(name = "PyMapping_Keys", minNumOfPositionalArgs = 1)
|
|
0 commit comments