|
41 | 41 | package com.oracle.graal.python.builtins.modules.functools;
|
42 | 42 |
|
43 | 43 | import static com.oracle.graal.python.builtins.PythonBuiltinClassType.PythonObject;
|
44 |
| -import static com.oracle.graal.python.nodes.BuiltinNames.J_PARTIAL; |
| 44 | +import static com.oracle.graal.python.nodes.BuiltinNames.J_FUNCTOOLS; |
45 | 45 | import static com.oracle.graal.python.nodes.ErrorMessages.REDUCE_EMPTY_SEQ;
|
46 |
| -import static com.oracle.graal.python.nodes.ErrorMessages.S_ARG_MUST_BE_CALLABLE; |
47 | 46 | import static com.oracle.graal.python.nodes.ErrorMessages.S_ARG_N_MUST_SUPPORT_ITERATION;
|
48 |
| -import static com.oracle.graal.python.nodes.ErrorMessages.TYPE_S_TAKES_AT_LEAST_ONE_ARGUMENT; |
49 |
| -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; |
50 | 47 | import static com.oracle.truffle.api.nodes.LoopNode.reportLoopCount;
|
51 | 48 |
|
52 | 49 | import java.util.List;
|
53 | 50 |
|
54 | 51 | import com.oracle.graal.python.builtins.Builtin;
|
55 | 52 | import com.oracle.graal.python.builtins.CoreFunctions;
|
| 53 | +import com.oracle.graal.python.builtins.Python3Core; |
56 | 54 | import com.oracle.graal.python.builtins.PythonBuiltinClassType;
|
57 | 55 | import com.oracle.graal.python.builtins.PythonBuiltins;
|
58 |
| -import com.oracle.graal.python.builtins.objects.PNone; |
59 |
| -import com.oracle.graal.python.builtins.objects.common.HashingStorage; |
60 |
| -import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageAddAllToOther; |
61 |
| -import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageCopy; |
62 |
| -import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageLen; |
63 |
| -import com.oracle.graal.python.builtins.objects.dict.PDict; |
64 |
| -import com.oracle.graal.python.builtins.objects.function.PKeyword; |
65 | 56 | import com.oracle.graal.python.lib.GetNextNode;
|
66 |
| -import com.oracle.graal.python.lib.PyCallableCheckNode; |
67 | 57 | import com.oracle.graal.python.lib.PyObjectGetIter;
|
68 | 58 | import com.oracle.graal.python.nodes.PGuards;
|
| 59 | +import com.oracle.graal.python.nodes.SpecialAttributeNames; |
69 | 60 | import com.oracle.graal.python.nodes.call.CallNode;
|
70 | 61 | import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
|
71 |
| -import com.oracle.graal.python.nodes.function.PythonBuiltinNode; |
72 | 62 | import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode;
|
73 | 63 | import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
|
74 | 64 | import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile;
|
75 |
| -import com.oracle.graal.python.nodes.object.GetDictIfExistsNode; |
76 | 65 | import com.oracle.graal.python.runtime.exception.PException;
|
77 |
| -import com.oracle.graal.python.util.PythonUtils; |
78 | 66 | import com.oracle.truffle.api.CompilerDirectives;
|
79 |
| -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; |
80 | 67 | import com.oracle.truffle.api.dsl.Bind;
|
81 | 68 | import com.oracle.truffle.api.dsl.Cached;
|
82 | 69 | import com.oracle.truffle.api.dsl.GenerateNodeFactory;
|
83 | 70 | import com.oracle.truffle.api.dsl.NodeFactory;
|
84 | 71 | import com.oracle.truffle.api.dsl.Specialization;
|
85 | 72 | import com.oracle.truffle.api.frame.VirtualFrame;
|
86 | 73 | import com.oracle.truffle.api.nodes.Node;
|
| 74 | +import com.oracle.truffle.api.object.HiddenKey; |
87 | 75 | import com.oracle.truffle.api.profiles.InlinedConditionProfile;
|
88 | 76 |
|
89 |
| -@CoreFunctions(defineModule = "_functools") |
| 77 | +@CoreFunctions(defineModule = J_FUNCTOOLS) |
90 | 78 | public final class FunctoolsModuleBuiltins extends PythonBuiltins {
|
91 | 79 | @Override
|
92 | 80 | protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFactories() {
|
93 | 81 | return FunctoolsModuleBuiltinsFactory.getFactories();
|
94 | 82 | }
|
95 | 83 |
|
| 84 | + protected static final HiddenKey KWD_MARK = new HiddenKey("kwd_mark"); |
| 85 | + |
| 86 | + @Override |
| 87 | + public void initialize(Python3Core core) { |
| 88 | + super.initialize(core); |
| 89 | + addBuiltinConstant(SpecialAttributeNames.T___DOC__, |
| 90 | + "Create a cached callable that wraps another function.\n" + // |
| 91 | + "\n" + // |
| 92 | + "user_function: the function being cached\n" + // |
| 93 | + "\n" + // |
| 94 | + "maxsize: 0 for no caching\n" + // |
| 95 | + " None for unlimited cache size\n" + // |
| 96 | + " n for a bounded cache\n" + // |
| 97 | + "\n" + // |
| 98 | + "typed: False cache f(3) and f(3.0) as identical calls\n" + // |
| 99 | + " True cache f(3) and f(3.0) as distinct calls\n" + // |
| 100 | + "\n" + // |
| 101 | + "cache_info_type: namedtuple class with the fields:\n" + // |
| 102 | + " hits misses currsize maxsize\n"); |
| 103 | + addBuiltinConstant(KWD_MARK, core.factory().createPythonObject(PythonObject)); |
| 104 | + } |
| 105 | + |
96 | 106 | // functools.reduce(function, iterable[, initializer])
|
97 | 107 | @Builtin(name = "reduce", minNumOfPositionalArgs = 2, maxNumOfPositionalArgs = 3, doc = "reduce(function, sequence[, initial]) -> value\n" +
|
98 | 108 | "\n" +
|
@@ -165,171 +175,4 @@ Object doConvert(Object myCmp) {
|
165 | 175 | }
|
166 | 176 | }
|
167 | 177 |
|
168 |
| - // functools.partial(func, /, *args, **keywords) |
169 |
| - @Builtin(name = J_PARTIAL, minNumOfPositionalArgs = 1, varArgsMarker = true, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PPartial, doc = "partial(func, *args, **keywords) - new function with partial application\n" + |
170 |
| - "of the given arguments and keywords.\n") |
171 |
| - @GenerateNodeFactory |
172 |
| - public abstract static class PartialNode extends PythonBuiltinNode { |
173 |
| - protected boolean isPartialWithoutDict(GetDictIfExistsNode getDict, Object[] args, HashingStorageLen lenNode, boolean withKwDict) { |
174 |
| - return isPartialWithoutDict(getDict, args) && withKwDict == ((PPartial) args[0]).hasKw(lenNode); |
175 |
| - } |
176 |
| - |
177 |
| - protected boolean isPartialWithoutDict(GetDictIfExistsNode getDict, Object[] args) { |
178 |
| - return getDict.execute(args[0]) == null && args[0] instanceof PPartial; |
179 |
| - } |
180 |
| - |
181 |
| - protected boolean withKeywords(PKeyword[] keywords) { |
182 |
| - return keywords.length > 0; |
183 |
| - } |
184 |
| - |
185 |
| - protected boolean atLeastOneArg(Object[] args) { |
186 |
| - return args.length >= 1; |
187 |
| - } |
188 |
| - |
189 |
| - @Specialization(guards = {"atLeastOneArg(args)", "isPartialWithoutDict(getDict, args, lenNode, false)"}, limit = "1") |
190 |
| - @SuppressWarnings("truffle-static-method") |
191 |
| - Object createFromPartialWoDictWoKw(Object cls, Object[] args, PKeyword[] keywords, |
192 |
| - @Bind("this") Node inliningTarget, |
193 |
| - @SuppressWarnings("unused") @Cached GetDictIfExistsNode getDict, |
194 |
| - @Cached InlinedConditionProfile hasArgsProfile, |
195 |
| - @Cached InlinedConditionProfile hasKeywordsProfile, |
196 |
| - @SuppressWarnings("unused") @Cached HashingStorageLen lenNode) { |
197 |
| - assert args[0] instanceof PPartial; |
198 |
| - final PPartial function = (PPartial) args[0]; |
199 |
| - Object[] funcArgs = getNewPartialArgs(function, args, inliningTarget, hasArgsProfile, 1); |
200 |
| - |
201 |
| - PDict funcKwDict; |
202 |
| - if (hasKeywordsProfile.profile(inliningTarget, keywords.length > 0)) { |
203 |
| - funcKwDict = factory().createDict(keywords); |
204 |
| - } else { |
205 |
| - funcKwDict = factory().createDict(); |
206 |
| - } |
207 |
| - |
208 |
| - return factory().createPartial(cls, function.getFn(), funcArgs, funcKwDict); |
209 |
| - } |
210 |
| - |
211 |
| - @Specialization(guards = {"atLeastOneArg(args)", "isPartialWithoutDict(getDict, args, lenNode, true)", "!withKeywords(keywords)"}, limit = "1") |
212 |
| - @SuppressWarnings("truffle-static-method") |
213 |
| - Object createFromPartialWoDictWKw(Object cls, Object[] args, @SuppressWarnings("unused") PKeyword[] keywords, |
214 |
| - @Bind("this") Node inliningTarget, |
215 |
| - @SuppressWarnings("unused") @Cached GetDictIfExistsNode getDict, |
216 |
| - @Cached InlinedConditionProfile hasArgsProfile, |
217 |
| - @SuppressWarnings("unused") @Cached HashingStorageLen lenNode, |
218 |
| - @Cached HashingStorageCopy copyNode) { |
219 |
| - assert args[0] instanceof PPartial; |
220 |
| - final PPartial function = (PPartial) args[0]; |
221 |
| - Object[] funcArgs = getNewPartialArgs(function, args, inliningTarget, hasArgsProfile, 1); |
222 |
| - return factory().createPartial(cls, function.getFn(), funcArgs, function.getKwCopy(factory(), copyNode)); |
223 |
| - } |
224 |
| - |
225 |
| - @Specialization(guards = {"atLeastOneArg(args)", "isPartialWithoutDict(getDict, args, lenNode, true)", "withKeywords(keywords)"}, limit = "1") |
226 |
| - @SuppressWarnings("truffle-static-method") |
227 |
| - Object createFromPartialWoDictWKwKw(VirtualFrame frame, Object cls, Object[] args, PKeyword[] keywords, |
228 |
| - @Bind("this") Node inliningTarget, |
229 |
| - @SuppressWarnings("unused") @Cached GetDictIfExistsNode getDict, |
230 |
| - @Cached InlinedConditionProfile hasArgsProfile, |
231 |
| - @Cached HashingStorage.InitNode initNode, |
232 |
| - @SuppressWarnings("unused") @Cached HashingStorageLen lenNode, |
233 |
| - @Cached HashingStorageCopy copyHashingStorageNode, |
234 |
| - @Cached HashingStorageAddAllToOther addAllToOtherNode) { |
235 |
| - assert args[0] instanceof PPartial; |
236 |
| - final PPartial function = (PPartial) args[0]; |
237 |
| - Object[] funcArgs = getNewPartialArgs(function, args, inliningTarget, hasArgsProfile, 1); |
238 |
| - |
239 |
| - HashingStorage storage = copyHashingStorageNode.execute(function.getKw().getDictStorage()); |
240 |
| - PDict result = factory().createDict(storage); |
241 |
| - addAllToOtherNode.execute(frame, initNode.execute(frame, PNone.NO_VALUE, keywords), result); |
242 |
| - |
243 |
| - return factory().createPartial(cls, function.getFn(), funcArgs, result); |
244 |
| - } |
245 |
| - |
246 |
| - @Specialization(guards = {"atLeastOneArg(args)", "!isPartialWithoutDict(getDict, args)"}, limit = "1") |
247 |
| - @SuppressWarnings("truffle-static-method") |
248 |
| - Object createGeneric(Object cls, Object[] args, PKeyword[] keywords, |
249 |
| - @Bind("this") Node inliningTarget, |
250 |
| - @SuppressWarnings("unused") @Cached GetDictIfExistsNode getDict, |
251 |
| - @Cached InlinedConditionProfile hasKeywordsProfile, |
252 |
| - @Cached PyCallableCheckNode callableCheckNode) { |
253 |
| - Object function = args[0]; |
254 |
| - if (!callableCheckNode.execute(function)) { |
255 |
| - throw raise(PythonBuiltinClassType.TypeError, S_ARG_MUST_BE_CALLABLE, "the first"); |
256 |
| - } |
257 |
| - |
258 |
| - final Object[] funcArgs = PythonUtils.arrayCopyOfRange(args, 1, args.length); |
259 |
| - PDict funcKwDict; |
260 |
| - if (hasKeywordsProfile.profile(inliningTarget, keywords.length > 0)) { |
261 |
| - funcKwDict = factory().createDict(keywords); |
262 |
| - } else { |
263 |
| - funcKwDict = factory().createDict(); |
264 |
| - } |
265 |
| - return factory().createPartial(cls, function, funcArgs, funcKwDict); |
266 |
| - } |
267 |
| - |
268 |
| - @Specialization(guards = "!atLeastOneArg(args)") |
269 |
| - @SuppressWarnings("unused") |
270 |
| - Object noCallable(Object cls, Object[] args, PKeyword[] keywords) { |
271 |
| - throw raise(PythonBuiltinClassType.TypeError, TYPE_S_TAKES_AT_LEAST_ONE_ARGUMENT, "partial"); |
272 |
| - } |
273 |
| - } |
274 |
| -} |
275 |
| - |
276 |
| -@CoreFunctions(extendClasses = PythonBuiltinClassType.LsprofProfiler) |
277 |
| -class ProfilerBuiltins extends PythonBuiltins { |
278 |
| - @Override |
279 |
| - protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFactories() { |
280 |
| - return ProfilerBuiltinsFactory.getFactories(); |
281 |
| - } |
282 |
| - |
283 |
| - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 1, parameterNames = {"$self", "timer", "timeunit", "subcalls", "builtins"}) |
284 |
| - @GenerateNodeFactory |
285 |
| - abstract static class Init extends PythonBuiltinNode { |
286 |
| - @Specialization |
287 |
| - PNone doit(Profiler self, Object timer, double timeunit, long subcalls, long builtins) { |
288 |
| - self.subcalls = subcalls > 0; |
289 |
| - self.builtins = builtins > 0; |
290 |
| - self.timeunit = timeunit; |
291 |
| - self.externalTimer = timer; |
292 |
| - return PNone.NONE; |
293 |
| - } |
294 |
| - |
295 |
| - @Specialization |
296 |
| - @SuppressWarnings("unused") |
297 |
| - PNone doit(Profiler self, Object timer, PNone timeunit, PNone subcalls, PNone builtins) { |
298 |
| - self.subcalls = true; |
299 |
| - self.builtins = true; |
300 |
| - self.timeunit = -1; |
301 |
| - self.externalTimer = timer; |
302 |
| - return PNone.NONE; |
303 |
| - } |
304 |
| - } |
305 |
| - |
306 |
| - @Builtin(name = "enable", minNumOfPositionalArgs = 1, parameterNames = {"$self", "subcalls", "builtins"}) |
307 |
| - @GenerateNodeFactory |
308 |
| - abstract static class Enable extends PythonBuiltinNode { |
309 |
| - @Specialization |
310 |
| - @TruffleBoundary |
311 |
| - PNone doit(Profiler self, long subcalls, long builtins) { |
312 |
| - self.subcalls = subcalls > 0; |
313 |
| - self.builtins = builtins > 0; |
314 |
| - // TODO: deal with any arguments |
315 |
| - self.time = System.currentTimeMillis(); |
316 |
| - self.sampler.setCollecting(true); |
317 |
| - return PNone.NONE; |
318 |
| - } |
319 |
| - |
320 |
| - @Specialization |
321 |
| - PNone doit(Profiler self, long subcalls, @SuppressWarnings("unused") PNone builtins) { |
322 |
| - return doit(self, subcalls, self.builtins ? 1 : 0); |
323 |
| - } |
324 |
| - |
325 |
| - @Specialization |
326 |
| - PNone doit(Profiler self, @SuppressWarnings("unused") PNone subcalls, long builtins) { |
327 |
| - return doit(self, self.subcalls ? 1 : 0, builtins); |
328 |
| - } |
329 |
| - |
330 |
| - @Specialization |
331 |
| - PNone doit(Profiler self, @SuppressWarnings("unused") PNone subcalls, @SuppressWarnings("unused") PNone builtins) { |
332 |
| - return doit(self, self.subcalls ? 1 : 0, self.builtins ? 1 : 0); |
333 |
| - } |
334 |
| - } |
335 | 178 | }
|
0 commit comments