|
40 | 40 | */
|
41 | 41 | package com.oracle.graal.python.builtins.objects.iterator;
|
42 | 42 |
|
| 43 | +import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError; |
| 44 | +import static com.oracle.graal.python.nodes.SpecialMethodNames.__LENGTH_HINT__; |
| 45 | +import static com.oracle.graal.python.nodes.SpecialMethodNames.__LEN__; |
| 46 | + |
43 | 47 | import com.oracle.graal.python.builtins.objects.PNone;
|
| 48 | +import com.oracle.graal.python.builtins.objects.PNotImplemented; |
44 | 49 | import com.oracle.graal.python.builtins.objects.object.PythonObjectLibrary;
|
| 50 | +import com.oracle.graal.python.nodes.ErrorMessages; |
45 | 51 | import com.oracle.graal.python.nodes.PGuards;
|
46 | 52 | import com.oracle.graal.python.nodes.PNodeWithContext;
|
| 53 | +import com.oracle.graal.python.nodes.PRaiseNode; |
47 | 54 | import com.oracle.graal.python.nodes.SpecialMethodNames;
|
48 | 55 | import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode;
|
49 | 56 | import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode;
|
| 57 | +import com.oracle.graal.python.nodes.object.IsBuiltinClassProfile; |
50 | 58 | import com.oracle.graal.python.nodes.util.CastToJavaIntLossyNode;
|
| 59 | +import com.oracle.graal.python.runtime.exception.PException; |
51 | 60 | import com.oracle.truffle.api.dsl.Cached;
|
52 | 61 | import com.oracle.truffle.api.dsl.GenerateNodeFactory;
|
53 | 62 | import com.oracle.truffle.api.dsl.ImportStatic;
|
54 | 63 | import com.oracle.truffle.api.dsl.Specialization;
|
55 | 64 | import com.oracle.truffle.api.frame.VirtualFrame;
|
56 | 65 | import com.oracle.truffle.api.library.CachedLibrary;
|
| 66 | +import com.oracle.truffle.api.profiles.ConditionProfile; |
57 | 67 |
|
58 | 68 | public abstract class IteratorNodes {
|
59 | 69 |
|
@@ -86,22 +96,51 @@ int length(VirtualFrame frame, Object iterable,
|
86 | 96 | @Cached CastToJavaIntLossyNode cast,
|
87 | 97 | @Cached("create(__LEN__)") LookupAttributeInMRONode lenNode,
|
88 | 98 | @Cached("create(__LENGTH_HINT__)") LookupAttributeInMRONode lenHintNode,
|
89 |
| - @Cached CallUnaryMethodNode dispatchGetattribute) { |
90 |
| - Object len; |
| 99 | + @Cached CallUnaryMethodNode dispatchGetattribute, |
| 100 | + @Cached IsBuiltinClassProfile errorProfile, |
| 101 | + @Cached ConditionProfile hasLenProfile, |
| 102 | + @Cached ConditionProfile hasLenghtHintProfile, |
| 103 | + @Cached PRaiseNode raiseNode) { |
91 | 104 | Object clazz = plib.getLazyPythonClass(iterable);
|
92 | 105 | Object attrLenObj = lenNode.execute(clazz);
|
93 |
| - if (attrLenObj != PNone.NO_VALUE && attrLenObj != PNone.NONE) { |
94 |
| - len = dispatchGetattribute.executeObject(frame, attrLenObj, iterable); |
95 |
| - } else { |
96 |
| - Object attrLenHintObj = lenHintNode.execute(clazz); |
97 |
| - if (attrLenHintObj != PNone.NO_VALUE && attrLenHintObj != PNone.NONE) { |
98 |
| - len = dispatchGetattribute.executeObject(frame, attrLenHintObj, iterable); |
99 |
| - } else { |
100 |
| - return -1; |
| 106 | + if (hasLenProfile.profile(attrLenObj != PNone.NO_VALUE && attrLenObj != PNotImplemented.NOT_IMPLEMENTED)) { |
| 107 | + Object len = null; |
| 108 | + try { |
| 109 | + len = dispatchGetattribute.executeObject(frame, attrLenObj, iterable); |
| 110 | + } catch (PException e) { |
| 111 | + e.expect(TypeError, errorProfile); |
| 112 | + } |
| 113 | + if (len != null) { |
| 114 | + if (toInt.canBeIndex(len)) { |
| 115 | + int intLen = cast.execute(toInt.asIndex(len)); |
| 116 | + if (intLen < 0) { |
| 117 | + throw raiseNode.raise(TypeError, ErrorMessages.LEN_SHOULD_RETURN_MT_ZERO); |
| 118 | + } |
| 119 | + return intLen; |
| 120 | + } else { |
| 121 | + throw raiseNode.raise(TypeError, ErrorMessages.MUST_BE_INTEGER, __LEN__, len); |
| 122 | + } |
101 | 123 | }
|
102 | 124 | }
|
103 |
| - if (toInt.canBeIndex(len)) { |
104 |
| - return cast.execute(toInt.asIndex(len)); |
| 125 | + Object attrLenHintObj = lenHintNode.execute(clazz); |
| 126 | + if (hasLenghtHintProfile.profile(attrLenHintObj != PNone.NO_VALUE && attrLenHintObj != PNotImplemented.NOT_IMPLEMENTED)) { |
| 127 | + Object len = null; |
| 128 | + try { |
| 129 | + len = dispatchGetattribute.executeObject(frame, attrLenHintObj, iterable); |
| 130 | + } catch (PException e) { |
| 131 | + e.expect(TypeError, errorProfile); |
| 132 | + } |
| 133 | + if (len != null) { |
| 134 | + if (toInt.canBeIndex(len)) { |
| 135 | + int intLen = cast.execute(toInt.asIndex(len)); |
| 136 | + if (intLen < 0) { |
| 137 | + throw raiseNode.raise(TypeError, ErrorMessages.LENGTH_HINT_SHOULD_RETURN_MT_ZERO); |
| 138 | + } |
| 139 | + return intLen; |
| 140 | + } else { |
| 141 | + throw raiseNode.raise(TypeError, ErrorMessages.MUST_BE_INTEGER, __LENGTH_HINT__, len); |
| 142 | + } |
| 143 | + } |
105 | 144 | }
|
106 | 145 | return -1;
|
107 | 146 | }
|
|
0 commit comments