42
42
43
43
import static com .oracle .graal .python .builtins .PythonBuiltinClassType .OverflowError ;
44
44
import static com .oracle .graal .python .builtins .PythonBuiltinClassType .ValueError ;
45
+ import static com .oracle .graal .python .nodes .SpecialMethodNames .J___LEN__ ;
45
46
import static com .oracle .graal .python .nodes .SpecialMethodNames .T___LEN__ ;
46
47
48
+ import com .oracle .graal .python .PythonLanguage ;
47
49
import com .oracle .graal .python .builtins .objects .cext .capi .ExternalFunctionNodes .CheckPrimitiveFunctionResultNode ;
48
50
import com .oracle .graal .python .builtins .objects .cext .capi .ExternalFunctionNodes .ExternalFunctionInvokeNode ;
49
51
import com .oracle .graal .python .builtins .objects .cext .capi .ExternalFunctionNodes .PExternalFunctionWrapper ;
50
52
import com .oracle .graal .python .builtins .objects .cext .capi .transitions .CApiTiming ;
51
53
import com .oracle .graal .python .builtins .objects .cext .capi .transitions .CApiTransitions .PythonToNativeNode ;
54
+ import com .oracle .graal .python .builtins .objects .function .PArguments ;
52
55
import com .oracle .graal .python .builtins .objects .ints .PInt ;
53
56
import com .oracle .graal .python .builtins .objects .type .slots .HPyDispatchers .UnaryHPySlotDispatcherNode ;
54
57
import com .oracle .graal .python .builtins .objects .type .slots .PythonDispatchers .UnaryPythonSlotDispatcherNode ;
58
+ import com .oracle .graal .python .builtins .objects .type .slots .TpSlot .TpSlotBuiltinBase ;
55
59
import com .oracle .graal .python .builtins .objects .type .slots .TpSlot .TpSlotNative ;
56
60
import com .oracle .graal .python .builtins .objects .type .slots .TpSlot .TpSlotPythonSingle ;
57
- import com .oracle .graal .python .builtins .objects .type .slots .TpSlot .TpSlotSimpleBuiltinBase ;
58
61
import com .oracle .graal .python .lib .PyNumberAsSizeNode ;
59
62
import com .oracle .graal .python .lib .PyNumberIndexNode ;
60
63
import com .oracle .graal .python .nodes .ErrorMessages ;
63
66
import com .oracle .graal .python .nodes .PRaiseNode .Lazy ;
64
67
import com .oracle .graal .python .nodes .function .builtins .PythonUnaryBuiltinNode ;
65
68
import com .oracle .graal .python .nodes .util .CastToJavaIntLossyNode ;
69
+ import com .oracle .graal .python .runtime .ExecutionContext .CallContext ;
66
70
import com .oracle .graal .python .runtime .PythonContext ;
67
71
import com .oracle .graal .python .runtime .PythonContext .GetThreadStateNode ;
68
72
import com .oracle .graal .python .runtime .PythonContext .PythonThreadState ;
69
73
import com .oracle .graal .python .runtime .exception .PException ;
70
74
import com .oracle .truffle .api .HostCompilerDirectives .InliningCutoff ;
75
+ import com .oracle .truffle .api .RootCallTarget ;
71
76
import com .oracle .truffle .api .dsl .Bind ;
72
77
import com .oracle .truffle .api .dsl .Cached ;
73
78
import com .oracle .truffle .api .dsl .GenerateCached ;
76
81
import com .oracle .truffle .api .dsl .NodeFactory ;
77
82
import com .oracle .truffle .api .dsl .Specialization ;
78
83
import com .oracle .truffle .api .frame .VirtualFrame ;
84
+ import com .oracle .truffle .api .nodes .IndirectCallNode ;
79
85
import com .oracle .truffle .api .nodes .Node ;
80
86
import com .oracle .truffle .api .nodes .UnexpectedResultException ;
81
87
import com .oracle .truffle .api .profiles .InlinedBranchProfile ;
88
+ import com .oracle .truffle .api .profiles .InlinedConditionProfile ;
82
89
83
90
public abstract class TpSlotLen {
84
91
private TpSlotLen () {
@@ -88,16 +95,44 @@ private TpSlotLen() {
88
95
// the BCI interpreter. For the time being we do what GraalPy used to do before slots were
89
96
// introduced: raise overflow error if native code returns number larger than INT_MAX
90
97
91
- public abstract static class TpSlotLenBuiltin <T extends LenBuiltinNode > extends TpSlotSimpleBuiltinBase <T > {
98
+ public abstract static sealed class TpSlotLenBuiltin <T extends LenBuiltinNode >
99
+ extends TpSlotBuiltinBase <T > permits TpSlotLenBuiltinSimple , TpSlotLenBuiltinComplex {
100
+ static final BuiltinSlotWrapperSignature SIGNATURE = BuiltinSlotWrapperSignature .UNARY ;
101
+
92
102
protected TpSlotLenBuiltin (NodeFactory <T > nodeFactory ) {
93
- super (nodeFactory , BuiltinSlotWrapperSignature . UNARY , PExternalFunctionWrapper .LENFUNC );
103
+ super (nodeFactory , SIGNATURE , PExternalFunctionWrapper .LENFUNC );
94
104
}
95
105
96
106
final LenBuiltinNode createSlotNode () {
97
107
return createNode ();
98
108
}
109
+ }
110
+
111
+ public abstract static non-sealed class TpSlotLenBuiltinSimple <T extends LenBuiltinNode > extends TpSlotLenBuiltin <T > {
112
+ protected TpSlotLenBuiltinSimple (NodeFactory <T > nodeFactory ) {
113
+ super (nodeFactory );
114
+ }
99
115
100
116
protected abstract int executeUncached (Object self );
117
+
118
+ @ Override
119
+ public final void initialize (PythonLanguage language ) {
120
+ // nop
121
+ }
122
+ }
123
+
124
+ public abstract static non-sealed class TpSlotLenBuiltinComplex <T extends LenBuiltinNode > extends TpSlotLenBuiltin <T > {
125
+ private final int callTargetIndex = TpSlotBuiltinCallTargetRegistry .getNextCallTargetIndex ();
126
+
127
+ protected TpSlotLenBuiltinComplex (NodeFactory <T > nodeFactory ) {
128
+ super (nodeFactory );
129
+ }
130
+
131
+ @ Override
132
+ public final void initialize (PythonLanguage language ) {
133
+ RootCallTarget callTarget = createBuiltinCallTarget (language , SIGNATURE , getNodeFactory (), J___LEN__ );
134
+ language .setBuiltinSlotCallTarget (callTargetIndex , callTarget );
135
+ }
101
136
}
102
137
103
138
@ GenerateInline (value = false , inherit = true )
@@ -125,12 +160,6 @@ static int callCachedBuiltin(VirtualFrame frame, @SuppressWarnings("unused") TpS
125
160
return slotNode .executeInt (frame , self );
126
161
}
127
162
128
- @ Specialization (replaces = "callCachedBuiltin" )
129
- static int callGenericSimpleBuiltin (TpSlotLenBuiltin <?> slot , Object self ) {
130
- // Assumption: all len builtins don't need a frame and PE
131
- return slot .executeUncached (self );
132
- }
133
-
134
163
@ Specialization
135
164
static int callPython (VirtualFrame frame , TpSlotPythonSingle slot , Object self ,
136
165
@ Cached (inline = false ) CallSlotLenPythonNode callSlotNode ) {
@@ -155,6 +184,22 @@ static int callNative(VirtualFrame frame, Node inliningTarget, TpSlotNative slot
155
184
return (int ) l ;
156
185
}
157
186
187
+ @ Specialization (replaces = "callCachedBuiltin" )
188
+ static int callGenericSimpleBuiltin (TpSlotLenBuiltinSimple <?> slot , Object self ) {
189
+ return slot .executeUncached (self );
190
+ }
191
+
192
+ @ Specialization (replaces = "callCachedBuiltin" )
193
+ @ InliningCutoff
194
+ static int callGenericComplexBuiltin (VirtualFrame frame , Node inliningTarget , TpSlotLenBuiltinComplex <?> slot , Object self ,
195
+ @ Cached (inline = false ) CallContext callContext ,
196
+ @ Cached InlinedConditionProfile isNullFrameProfile ,
197
+ @ Cached (inline = false ) IndirectCallNode indirectCallNode ) {
198
+ Object [] arguments = PArguments .create (1 );
199
+ PArguments .setArgument (arguments , 0 , self );
200
+ return (int ) BuiltinDispatchers .callGenericBuiltin (frame , inliningTarget , slot .callTargetIndex , arguments , callContext , isNullFrameProfile , indirectCallNode );
201
+ }
202
+
158
203
// @Specialization(guards = "slot.isHPySlot()")
159
204
// @InliningCutoff
160
205
@ SuppressWarnings ("unused" )
0 commit comments