Nuitka
The Python compiler
Loading...
Searching...
No Matches
calling.h
1// Copyright 2025, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file
2
3#ifndef __NUITKA_CALLING_H__
4#define __NUITKA_CALLING_H__
5
6/* This file is included from another C file, help IDEs to still parse it on its own. */
7#ifdef __IDE_ONLY__
8#include "nuitka/prelude.h"
9#endif
10
11// For exception test formatting and call code mostly.
12extern char const *GET_CALLABLE_NAME(PyObject *object);
13extern char const *GET_CALLABLE_DESC(PyObject *object);
14extern char const *GET_CLASS_NAME(PyObject *class_object);
15extern char const *GET_INSTANCE_CLASS_NAME(PyThreadState *tstate, PyObject *instance);
16
17// Also used in generated helper code.
18NUITKA_MAY_BE_UNUSED static inline PyObject *Nuitka_CheckFunctionResult(PyThreadState *tstate, PyObject *callable,
19 PyObject *result) {
20 if (result == NULL) {
21 if (unlikely(!HAS_ERROR_OCCURRED(tstate))) {
22#if PYTHON_VERSION < 0x3b0
23 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_SystemError, "NULL result without error from call");
24#else
25 PyErr_Format(PyExc_SystemError, "%R returned NULL without setting an exception", callable);
26#endif
27 }
28
29 return NULL;
30 } else {
31 // Some buggy C functions do this, and Nuitka inner workings can get
32 // upset from it.
33 if (unlikely(DROP_ERROR_OCCURRED(tstate))) {
34 Py_DECREF(result);
35
36#if PYTHON_VERSION < 0x3a0
37 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_SystemError, "result with error set from call");
38#elif PYTHON_VERSION < 0x3b0
39 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_SystemError, "result with exception set from call");
40#else
41 SET_CURRENT_EXCEPTION_TYPE0_FORMAT1(PyExc_SystemError, "%s() returned a result with an exception set",
42 GET_CALLABLE_NAME(callable));
43#endif
44 return NULL;
45 }
46
47 return result;
48 }
49}
50
51NUITKA_MAY_BE_UNUSED static PyObject *CALL_FUNCTION(PyThreadState *tstate, PyObject *function_object,
52 PyObject *positional_args, PyObject *named_args) {
53 // Not allowed to enter with an error set. This often catches leaked errors from
54 // elsewhere.
55 assert(!HAS_ERROR_OCCURRED(tstate));
56
57 CHECK_OBJECT(function_object);
58 CHECK_OBJECT(positional_args);
59 assert(named_args == NULL || Py_REFCNT(named_args) > 0);
60
61 ternaryfunc call_slot = Py_TYPE(function_object)->tp_call;
62
63 if (unlikely(call_slot == NULL)) {
64 SET_CURRENT_EXCEPTION_TYPE_COMPLAINT("'%s' object is not callable", function_object);
65
66 return NULL;
67 }
68
69 if (unlikely(Py_EnterRecursiveCall((char *)" while calling a Python object"))) {
70 return NULL;
71 }
72
73 PyObject *result = (*call_slot)(function_object, positional_args, named_args);
74
75 Py_LeaveRecursiveCall();
76
77 return Nuitka_CheckFunctionResult(tstate, function_object, result);
78}
79
80// Function call variant with no arguments provided at all.
81extern PyObject *CALL_FUNCTION_NO_ARGS(PyThreadState *tstate, PyObject *called);
82
83// Function call variants with positional arguments tuple.
84NUITKA_MAY_BE_UNUSED static PyObject *CALL_FUNCTION_WITH_POS_ARGS(PyThreadState *tstate, PyObject *function_object,
85 PyObject *positional_args) {
86 return CALL_FUNCTION(tstate, function_object, positional_args, NULL);
87}
88
89// Method call variants with positional arguments tuple.
90extern PyObject *CALL_METHOD_WITH_POS_ARGS(PyThreadState *tstate, PyObject *source, PyObject *attr_name,
91 PyObject *positional_args);
92
93// TODO: Specialize in template too.
94NUITKA_MAY_BE_UNUSED static PyObject *CALL_FUNCTION_WITH_KW_ARGS(PyThreadState *tstate, PyObject *function_object,
95 PyObject *named_args) {
96 return CALL_FUNCTION(tstate, function_object, const_tuple_empty, named_args);
97}
98
99// Call built-in functions with using defaulted values.
100extern PyObject *CALL_BUILTIN_KW_ARGS(PyThreadState *tstate, PyObject *callable, PyObject **args,
101 char const **arg_names, int max_args, int kw_only_args);
102
103// For abstract class instantiation error message, during call.
104extern void formatCannotInstantiateAbstractClass(PyThreadState *tstate, PyTypeObject *type);
105
106#include "nuitka/helper/calling_generated.h"
107
108#endif
109
110// Part of "Nuitka", an optimizing Python compiler that is compatible and
111// integrates with CPython, but also works on its own.
112//
113// Licensed under the Apache License, Version 2.0 (the "License");
114// you may not use this file except in compliance with the License.
115// You may obtain a copy of the License at
116//
117// http://www.apache.org/licenses/LICENSE-2.0
118//
119// Unless required by applicable law or agreed to in writing, software
120// distributed under the License is distributed on an "AS IS" BASIS,
121// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
122// See the License for the specific language governing permissions and
123// limitations under the License.