aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/src/Python/sysmodule.c
diff options
context:
space:
mode:
authorshadchin <shadchin@yandex-team.com>2024-02-12 07:53:52 +0300
committershadchin <shadchin@yandex-team.com>2024-02-12 08:07:36 +0300
commitce1b7ca3171f9158180640c6a02a74b4afffedea (patch)
treee47c1e8391b1b0128262c1e9b1e6ed4c8fff2348 /contrib/tools/python3/src/Python/sysmodule.c
parent57350d96f030db90f220ce50ee591d5c5d403df7 (diff)
downloadydb-ce1b7ca3171f9158180640c6a02a74b4afffedea.tar.gz
Update Python from 3.11.8 to 3.12.2
Diffstat (limited to 'contrib/tools/python3/src/Python/sysmodule.c')
-rw-r--r--contrib/tools/python3/src/Python/sysmodule.c745
1 files changed, 555 insertions, 190 deletions
diff --git a/contrib/tools/python3/src/Python/sysmodule.c b/contrib/tools/python3/src/Python/sysmodule.c
index fd8819bc46..3146f2a943 100644
--- a/contrib/tools/python3/src/Python/sysmodule.c
+++ b/contrib/tools/python3/src/Python/sysmodule.c
@@ -17,19 +17,18 @@ Data members:
#include "Python.h"
#include "pycore_call.h" // _PyObject_CallNoArgs()
#include "pycore_ceval.h" // _PyEval_SetAsyncGenFinalizer()
-#include "pycore_code.h" // _Py_QuickenedCount
#include "pycore_frame.h" // _PyInterpreterFrame
#include "pycore_initconfig.h" // _PyStatus_EXCEPTION()
#include "pycore_long.h" // _PY_LONG_MAX_STR_DIGITS_THRESHOLD
#include "pycore_namespace.h" // _PyNamespace_New()
#include "pycore_object.h" // _PyObject_IS_GC()
#include "pycore_pathconfig.h" // _PyPathConfig_ComputeSysPath0()
-#include "pycore_pyerrors.h" // _PyErr_Fetch()
+#include "pycore_pyerrors.h" // _PyErr_GetRaisedException()
#include "pycore_pylifecycle.h" // _PyErr_WriteUnraisableDefaultHook()
#include "pycore_pymath.h" // _PY_SHORT_FLOAT_REPR
#include "pycore_pymem.h" // _PyMem_SetDefaultAllocator()
#include "pycore_pystate.h" // _PyThreadState_GET()
-#include "pycore_structseq.h" // _PyStructSequence_InitType()
+#include "pycore_structseq.h" // _PyStructSequence_InitBuiltinWithFlags()
#include "pycore_tuple.h" // _PyTuple_FromArray()
#include "frameobject.h" // PyFrame_FastToLocalsWithError()
@@ -53,6 +52,10 @@ extern const char *PyWin_DLLVersionString;
#error #include <emscripten.h>
#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
/*[clinic input]
module sys
[clinic start generated code]*/
@@ -67,12 +70,11 @@ _PySys_GetAttr(PyThreadState *tstate, PyObject *name)
if (sd == NULL) {
return NULL;
}
- PyObject *exc_type, *exc_value, *exc_tb;
- _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
+ PyObject *exc = _PyErr_GetRaisedException(tstate);
/* XXX Suppress a new exception if it was raised and restore
* the old one. */
PyObject *value = _PyDict_GetItemWithError(sd, name);
- _PyErr_Restore(tstate, exc_type, exc_value, exc_tb);
+ _PyErr_SetRaisedException(tstate, exc);
return value;
}
@@ -91,12 +93,11 @@ PySys_GetObject(const char *name)
{
PyThreadState *tstate = _PyThreadState_GET();
- PyObject *exc_type, *exc_value, *exc_tb;
- _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
+ PyObject *exc = _PyErr_GetRaisedException(tstate);
PyObject *value = _PySys_GetObject(tstate->interp, name);
/* XXX Suppress a new exception if it was raised and restore
* the old one. */
- _PyErr_Restore(tstate, exc_type, exc_value, exc_tb);
+ _PyErr_SetRaisedException(tstate, exc);
return value;
}
@@ -144,6 +145,20 @@ PySys_SetObject(const char *name, PyObject *v)
return sys_set_object_str(interp, name, v);
}
+int
+_PySys_ClearAttrString(PyInterpreterState *interp,
+ const char *name, int verbose)
+{
+ if (verbose) {
+ PySys_WriteStderr("# clear sys.%s\n", name);
+ }
+ /* To play it safe, we set the attr to None instead of deleting it. */
+ if (PyDict_SetItemString(interp->sysdict, name, Py_None) < 0) {
+ return -1;
+ }
+ return 0;
+}
+
static int
should_audit(PyInterpreterState *interp)
@@ -153,7 +168,7 @@ should_audit(PyInterpreterState *interp)
if (!interp) {
return 0;
}
- return (interp->runtime->audit_hook_head
+ return (interp->runtime->audit_hooks.head
|| interp->audit_hooks
|| PyDTrace_AUDIT_ENABLED());
}
@@ -191,16 +206,15 @@ sys_audit_tstate(PyThreadState *ts, const char *event,
int dtrace = PyDTrace_AUDIT_ENABLED();
- PyObject *exc_type, *exc_value, *exc_tb;
- _PyErr_Fetch(ts, &exc_type, &exc_value, &exc_tb);
+
+ PyObject *exc = _PyErr_GetRaisedException(ts);
/* Initialize event args now */
if (argFormat && argFormat[0]) {
eventArgs = _Py_VaBuildValue_SizeT(argFormat, vargs);
if (eventArgs && !PyTuple_Check(eventArgs)) {
PyObject *argTuple = PyTuple_Pack(1, eventArgs);
- Py_DECREF(eventArgs);
- eventArgs = argTuple;
+ Py_SETREF(eventArgs, argTuple);
}
}
else {
@@ -210,8 +224,11 @@ sys_audit_tstate(PyThreadState *ts, const char *event,
goto exit;
}
- /* Call global hooks */
- _Py_AuditHookEntry *e = is->runtime->audit_hook_head;
+ /* Call global hooks
+ *
+ * We don't worry about any races on hooks getting added,
+ * since that would not leave is in an inconsistent state. */
+ _Py_AuditHookEntry *e = is->runtime->audit_hooks.head;
for (; e; e = e->next) {
if (e->hookCFunction(event, eventArgs, e->userData) < 0) {
goto exit;
@@ -276,13 +293,11 @@ exit:
Py_XDECREF(eventArgs);
if (!res) {
- _PyErr_Restore(ts, exc_type, exc_value, exc_tb);
+ _PyErr_SetRaisedException(ts, exc);
}
else {
assert(_PyErr_Occurred(ts));
- Py_XDECREF(exc_type);
- Py_XDECREF(exc_value);
- Py_XDECREF(exc_tb);
+ Py_XDECREF(exc);
}
return res;
@@ -293,11 +308,7 @@ _PySys_Audit(PyThreadState *tstate, const char *event,
const char *argFormat, ...)
{
va_list vargs;
-#ifdef HAVE_STDARG_PROTOTYPES
va_start(vargs, argFormat);
-#else
- va_start(vargs);
-#endif
int res = sys_audit_tstate(tstate, event, argFormat, vargs);
va_end(vargs);
return res;
@@ -308,11 +319,7 @@ PySys_Audit(const char *event, const char *argFormat, ...)
{
PyThreadState *tstate = _PyThreadState_GET();
va_list vargs;
-#ifdef HAVE_STDARG_PROTOTYPES
va_start(vargs, argFormat);
-#else
- va_start(vargs);
-#endif
int res = sys_audit_tstate(tstate, event, argFormat, vargs);
va_end(vargs);
return res;
@@ -332,6 +339,7 @@ _PySys_ClearAuditHooks(PyThreadState *ts)
}
_PyRuntimeState *runtime = ts->interp->runtime;
+ /* The hooks are global so we have to check for runtime finalization. */
PyThreadState *finalizing = _PyRuntimeState_GetFinalizing(runtime);
assert(finalizing == ts);
if (finalizing != ts) {
@@ -348,8 +356,12 @@ _PySys_ClearAuditHooks(PyThreadState *ts)
_PySys_Audit(ts, "cpython._PySys_ClearAuditHooks", NULL);
_PyErr_Clear(ts);
- _Py_AuditHookEntry *e = runtime->audit_hook_head, *n;
- runtime->audit_hook_head = NULL;
+ /* We don't worry about the very unlikely race right here,
+ * since it's entirely benign. Nothing else removes entries
+ * from the list and adding an entry right now would not cause
+ * any trouble. */
+ _Py_AuditHookEntry *e = runtime->audit_hooks.head, *n;
+ runtime->audit_hooks.head = NULL;
while (e) {
n = e->next;
PyMem_RawFree(e);
@@ -357,6 +369,22 @@ _PySys_ClearAuditHooks(PyThreadState *ts)
}
}
+static void
+add_audit_hook_entry_unlocked(_PyRuntimeState *runtime,
+ _Py_AuditHookEntry *entry)
+{
+ if (runtime->audit_hooks.head == NULL) {
+ runtime->audit_hooks.head = entry;
+ }
+ else {
+ _Py_AuditHookEntry *last = runtime->audit_hooks.head;
+ while (last->next) {
+ last = last->next;
+ }
+ last->next = entry;
+ }
+}
+
int
PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData)
{
@@ -365,7 +393,7 @@ PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData)
_PyRuntimeState *runtime = &_PyRuntime;
PyThreadState *tstate;
if (runtime->initialized) {
- tstate = _PyRuntimeState_GetThreadState(runtime);
+ tstate = _PyThreadState_GET();
}
else {
tstate = NULL;
@@ -384,29 +412,28 @@ PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData)
}
}
- _Py_AuditHookEntry *e = runtime->audit_hook_head;
- if (!e) {
- e = (_Py_AuditHookEntry*)PyMem_RawMalloc(sizeof(_Py_AuditHookEntry));
- runtime->audit_hook_head = e;
- } else {
- while (e->next) {
- e = e->next;
- }
- e = e->next = (_Py_AuditHookEntry*)PyMem_RawMalloc(
+ _Py_AuditHookEntry *e = (_Py_AuditHookEntry*)PyMem_RawMalloc(
sizeof(_Py_AuditHookEntry));
- }
-
if (!e) {
if (tstate != NULL) {
_PyErr_NoMemory(tstate);
}
return -1;
}
-
e->next = NULL;
e->hookCFunction = (Py_AuditHookFunction)hook;
e->userData = userData;
+ if (runtime->audit_hooks.mutex == NULL) {
+ /* The runtime must not be initailized yet. */
+ add_audit_hook_entry_unlocked(runtime, e);
+ }
+ else {
+ PyThread_acquire_lock(runtime->audit_hooks.mutex, WAIT_LOCK);
+ add_audit_hook_entry_unlocked(runtime, e);
+ PyThread_release_lock(runtime->audit_hooks.mutex);
+ }
+
return 0;
}
@@ -742,7 +769,7 @@ sys_excepthook_impl(PyObject *module, PyObject *exctype, PyObject *value,
PyObject *traceback)
/*[clinic end generated code: output=18d99fdda21b6b5e input=ecf606fa826f19d9]*/
{
- PyErr_Display(exctype, value, traceback);
+ PyErr_Display(NULL, value, traceback);
Py_RETURN_NONE;
}
@@ -849,8 +876,7 @@ sys_getdefaultencoding_impl(PyObject *module)
{
_Py_DECLARE_STR(utf_8, "utf-8");
PyObject *ret = &_Py_STR(utf_8);
- Py_INCREF(ret);
- return ret;
+ return Py_NewRef(ret);
}
/*[clinic input]
@@ -957,10 +983,6 @@ static int
profile_trampoline(PyObject *self, PyFrameObject *frame,
int what, PyObject *arg)
{
- if (arg == NULL) {
- arg = Py_None;
- }
-
PyThreadState *tstate = _PyThreadState_GET();
PyObject *result = call_trampoline(tstate, self, frame, what, arg);
if (result == NULL) {
@@ -1029,6 +1051,36 @@ function call. See the debugger chapter in the library manual."
);
/*[clinic input]
+sys._settraceallthreads
+
+ arg: object
+ /
+
+Set the global debug tracing function in all running threads belonging to the current interpreter.
+
+It will be called on each function call. See the debugger chapter
+in the library manual.
+[clinic start generated code]*/
+
+static PyObject *
+sys__settraceallthreads(PyObject *module, PyObject *arg)
+/*[clinic end generated code: output=161cca30207bf3ca input=5906aa1485a50289]*/
+{
+ PyObject* argument = NULL;
+ Py_tracefunc func = NULL;
+
+ if (arg != Py_None) {
+ func = trace_trampoline;
+ argument = arg;
+ }
+
+
+ PyEval_SetTraceAllThreads(func, argument);
+
+ Py_RETURN_NONE;
+}
+
+/*[clinic input]
sys.gettrace
Return the global debug tracing function set with sys.settrace.
@@ -1045,8 +1097,7 @@ sys_gettrace_impl(PyObject *module)
if (temp == NULL)
temp = Py_None;
- Py_INCREF(temp);
- return temp;
+ return Py_NewRef(temp);
}
static PyObject *
@@ -1074,6 +1125,35 @@ and return. See the profiler chapter in the library manual."
);
/*[clinic input]
+sys._setprofileallthreads
+
+ arg: object
+ /
+
+Set the profiling function in all running threads belonging to the current interpreter.
+
+It will be called on each function call and return. See the profiler chapter
+in the library manual.
+[clinic start generated code]*/
+
+static PyObject *
+sys__setprofileallthreads(PyObject *module, PyObject *arg)
+/*[clinic end generated code: output=2d61319e27b309fe input=d1a356d3f4f9060a]*/
+{
+ PyObject* argument = NULL;
+ Py_tracefunc func = NULL;
+
+ if (arg != Py_None) {
+ func = profile_trampoline;
+ argument = arg;
+ }
+
+ PyEval_SetProfileAllThreads(func, argument);
+
+ Py_RETURN_NONE;
+}
+
+/*[clinic input]
sys.getprofile
Return the profiling function set with sys.setprofile.
@@ -1090,8 +1170,7 @@ sys_getprofile_impl(PyObject *module)
if (temp == NULL)
temp = Py_None;
- Py_INCREF(temp);
- return temp;
+ return Py_NewRef(temp);
}
@@ -1165,7 +1244,7 @@ sys_setrecursionlimit_impl(PyObject *module, int new_limit)
/* Reject too low new limit if the current recursion depth is higher than
the new low-water mark. */
- int depth = tstate->recursion_limit - tstate->recursion_remaining;
+ int depth = tstate->py_recursion_limit - tstate->py_recursion_remaining;
if (depth >= new_limit) {
_PyErr_Format(tstate, PyExc_RecursionError,
"cannot set the recursion limit to %i at "
@@ -1316,11 +1395,8 @@ sys_get_asyncgen_hooks_impl(PyObject *module)
finalizer = Py_None;
}
- Py_INCREF(firstiter);
- PyStructSequence_SET_ITEM(res, 0, firstiter);
-
- Py_INCREF(finalizer);
- PyStructSequence_SET_ITEM(res, 1, finalizer);
+ PyStructSequence_SET_ITEM(res, 0, Py_NewRef(firstiter));
+ PyStructSequence_SET_ITEM(res, 1, Py_NewRef(finalizer));
return res;
}
@@ -1434,6 +1510,48 @@ static PyStructSequence_Desc windows_version_desc = {
via indexing, the rest are name only */
};
+static PyObject *
+_sys_getwindowsversion_from_kernel32(void)
+{
+#ifndef MS_WINDOWS_DESKTOP
+ return NULL;
+#else
+ HANDLE hKernel32;
+ wchar_t kernel32_path[MAX_PATH];
+ LPVOID verblock;
+ DWORD verblock_size;
+ VS_FIXEDFILEINFO *ffi;
+ UINT ffi_len;
+ DWORD realMajor, realMinor, realBuild;
+
+ Py_BEGIN_ALLOW_THREADS
+ hKernel32 = GetModuleHandleW(L"kernel32.dll");
+ Py_END_ALLOW_THREADS
+ if (!hKernel32 || !GetModuleFileNameW(hKernel32, kernel32_path, MAX_PATH)) {
+ PyErr_SetFromWindowsErr(0);
+ return NULL;
+ }
+ verblock_size = GetFileVersionInfoSizeW(kernel32_path, NULL);
+ if (!verblock_size) {
+ PyErr_SetFromWindowsErr(0);
+ return NULL;
+ }
+ verblock = PyMem_RawMalloc(verblock_size);
+ if (!verblock ||
+ !GetFileVersionInfoW(kernel32_path, 0, verblock_size, verblock) ||
+ !VerQueryValueW(verblock, L"", (LPVOID)&ffi, &ffi_len)) {
+ PyErr_SetFromWindowsErr(0);
+ return NULL;
+ }
+
+ realMajor = HIWORD(ffi->dwProductVersionMS);
+ realMinor = LOWORD(ffi->dwProductVersionMS);
+ realBuild = HIWORD(ffi->dwProductVersionLS);
+ PyMem_RawFree(verblock);
+ return Py_BuildValue("(kkk)", realMajor, realMinor, realBuild);
+#endif /* !MS_WINDOWS_DESKTOP */
+}
+
/* Disable deprecation warnings about GetVersionEx as the result is
being passed straight through to the caller, who is responsible for
using it correctly. */
@@ -1463,11 +1581,13 @@ sys_getwindowsversion_impl(PyObject *module)
PyObject *version;
int pos = 0;
OSVERSIONINFOEXW ver;
- DWORD realMajor, realMinor, realBuild;
- HANDLE hKernel32;
- wchar_t kernel32_path[MAX_PATH];
- LPVOID verblock;
- DWORD verblock_size;
+
+ version = PyObject_GetAttrString(module, "_cached_windows_version");
+ if (version && PyObject_TypeCheck(version, &WindowsVersionType)) {
+ return version;
+ }
+ Py_XDECREF(version);
+ PyErr_Clear();
ver.dwOSVersionInfoSize = sizeof(ver);
if (!GetVersionExW((OSVERSIONINFOW*) &ver))
@@ -1487,41 +1607,34 @@ sys_getwindowsversion_impl(PyObject *module)
PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wSuiteMask));
PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wProductType));
- realMajor = ver.dwMajorVersion;
- realMinor = ver.dwMinorVersion;
- realBuild = ver.dwBuildNumber;
-
// GetVersion will lie if we are running in a compatibility mode.
// We need to read the version info from a system file resource
// to accurately identify the OS version. If we fail for any reason,
// just return whatever GetVersion said.
- Py_BEGIN_ALLOW_THREADS
- hKernel32 = GetModuleHandleW(L"kernel32.dll");
- Py_END_ALLOW_THREADS
- if (hKernel32 && GetModuleFileNameW(hKernel32, kernel32_path, MAX_PATH) &&
- (verblock_size = GetFileVersionInfoSizeExW(0, kernel32_path, NULL)) &&
- (verblock = PyMem_RawMalloc(verblock_size))) {
- VS_FIXEDFILEINFO *ffi;
- UINT ffi_len;
-
- if (GetFileVersionInfoExW(0, kernel32_path, 0, verblock_size, verblock) &&
- VerQueryValueW(verblock, L"", (LPVOID)&ffi, &ffi_len)) {
- realMajor = HIWORD(ffi->dwProductVersionMS);
- realMinor = LOWORD(ffi->dwProductVersionMS);
- realBuild = HIWORD(ffi->dwProductVersionLS);
- }
- PyMem_RawFree(verblock);
+ PyObject *realVersion = _sys_getwindowsversion_from_kernel32();
+ if (!realVersion) {
+ PyErr_Clear();
+ realVersion = Py_BuildValue("(kkk)",
+ ver.dwMajorVersion,
+ ver.dwMinorVersion,
+ ver.dwBuildNumber
+ );
+ }
+
+ if (realVersion) {
+ PyStructSequence_SET_ITEM(version, pos++, realVersion);
}
- PyStructSequence_SET_ITEM(version, pos++, Py_BuildValue("(kkk)",
- realMajor,
- realMinor,
- realBuild
- ));
if (PyErr_Occurred()) {
Py_DECREF(version);
return NULL;
}
+
+ if (PyObject_SetAttrString(module, "_cached_windows_version", version) < 0) {
+ Py_DECREF(version);
+ return NULL;
+ }
+
return version;
}
@@ -1575,7 +1688,7 @@ sys_setdlopenflags_impl(PyObject *module, int new_val)
/*[clinic end generated code: output=ec918b7fe0a37281 input=4c838211e857a77f]*/
{
PyInterpreterState *interp = _PyInterpreterState_GET();
- interp->dlopenflags = new_val;
+ _PyImport_SetDLOpenFlags(interp, new_val);
Py_RETURN_NONE;
}
@@ -1593,7 +1706,8 @@ sys_getdlopenflags_impl(PyObject *module)
/*[clinic end generated code: output=e92cd1bc5005da6e input=dc4ea0899c53b4b6]*/
{
PyInterpreterState *interp = _PyInterpreterState_GET();
- return PyLong_FromLong(interp->dlopenflags);
+ return PyLong_FromLong(
+ _PyImport_GetDLOpenFlags(interp));
}
#endif /* HAVE_DLOPEN */
@@ -1631,7 +1745,7 @@ sys_get_int_max_str_digits_impl(PyObject *module)
/*[clinic end generated code: output=0042f5e8ae0e8631 input=61bf9f99bc8b112d]*/
{
PyInterpreterState *interp = _PyInterpreterState_GET();
- return PyLong_FromSsize_t(interp->int_max_str_digits);
+ return PyLong_FromLong(interp->long_state.max_str_digits);
}
/*[clinic input]
@@ -1648,7 +1762,7 @@ sys_set_int_max_str_digits_impl(PyObject *module, int maxdigits)
{
PyThreadState *tstate = _PyThreadState_GET();
if ((!maxdigits) || (maxdigits >= _PY_LONG_MAX_STR_DIGITS_THRESHOLD)) {
- tstate->interp->int_max_str_digits = maxdigits;
+ tstate->interp->long_state.max_str_digits = maxdigits;
Py_RETURN_NONE;
} else {
PyErr_Format(
@@ -1720,8 +1834,7 @@ sys_getsizeof(PyObject *self, PyObject *args, PyObject *kwds)
/* Has a default value been given */
if (dflt != NULL && _PyErr_ExceptionMatches(tstate, PyExc_TypeError)) {
_PyErr_Clear(tstate);
- Py_INCREF(dflt);
- return dflt;
+ return Py_NewRef(dflt);
}
else
return NULL;
@@ -1764,36 +1877,41 @@ static Py_ssize_t
sys_gettotalrefcount_impl(PyObject *module)
/*[clinic end generated code: output=4103886cf17c25bc input=53b744faa5d2e4f6]*/
{
- return _Py_GetRefTotal();
+ /* It may make sense to return the total for the current interpreter
+ or have a second function that does so. */
+ return _Py_GetGlobalRefTotal();
}
#endif /* Py_REF_DEBUG */
/*[clinic input]
-sys._getquickenedcount -> Py_ssize_t
+sys.getallocatedblocks -> Py_ssize_t
+
+Return the number of memory blocks currently allocated.
[clinic start generated code]*/
static Py_ssize_t
-sys__getquickenedcount_impl(PyObject *module)
-/*[clinic end generated code: output=1ab259e7f91248a2 input=249d448159eca912]*/
+sys_getallocatedblocks_impl(PyObject *module)
+/*[clinic end generated code: output=f0c4e873f0b6dcf7 input=dab13ee346a0673e]*/
{
- return _Py_QuickenedCount;
+ // It might make sense to return the count
+ // for just the current interpreter.
+ return _Py_GetGlobalAllocatedBlocks();
}
/*[clinic input]
-sys.getallocatedblocks -> Py_ssize_t
+sys.getunicodeinternedsize -> Py_ssize_t
-Return the number of memory blocks currently allocated.
+Return the number of elements of the unicode interned dictionary
[clinic start generated code]*/
static Py_ssize_t
-sys_getallocatedblocks_impl(PyObject *module)
-/*[clinic end generated code: output=f0c4e873f0b6dcf7 input=dab13ee346a0673e]*/
+sys_getunicodeinternedsize_impl(PyObject *module)
+/*[clinic end generated code: output=ad0e4c9738ed4129 input=726298eaa063347a]*/
{
- return _Py_GetAllocatedBlocks();
+ return _PyUnicode_InternedSize();
}
-
/*[clinic input]
sys._getframe
@@ -1820,13 +1938,10 @@ sys__getframe_impl(PyObject *module, int depth)
if (frame != NULL) {
while (depth > 0) {
- frame = frame->previous;
+ frame = _PyFrame_GetFirstComplete(frame->previous);
if (frame == NULL) {
break;
}
- if (_PyFrame_IsIncomplete(frame)) {
- continue;
- }
--depth;
}
}
@@ -1928,11 +2043,6 @@ sys__debugmallocstats_impl(PyObject *module)
extern PyObject *_Py_GetObjects(PyObject *, PyObject *);
#endif
-#ifdef Py_STATS
-/* Defined in ceval.c because it uses static globals in that file */
-extern PyObject *_Py_GetDXProfile(PyObject *, PyObject *);
-#endif
-
#ifdef __cplusplus
}
#endif
@@ -1952,6 +2062,9 @@ sys__clear_type_cache_impl(PyObject *module)
Py_RETURN_NONE;
}
+/* Note that, for now, we do not have a per-interpreter equivalent
+ for sys.is_finalizing(). */
+
/*[clinic input]
sys.is_finalizing
@@ -1965,6 +2078,66 @@ sys_is_finalizing_impl(PyObject *module)
return PyBool_FromLong(_Py_IsFinalizing());
}
+#ifdef Py_STATS
+/*[clinic input]
+sys._stats_on
+
+Turns on stats gathering (stats gathering is on by default).
+[clinic start generated code]*/
+
+static PyObject *
+sys__stats_on_impl(PyObject *module)
+/*[clinic end generated code: output=aca53eafcbb4d9fe input=8ddc6df94e484f3a]*/
+{
+ _py_stats = &_py_stats_struct;
+ Py_RETURN_NONE;
+}
+
+/*[clinic input]
+sys._stats_off
+
+Turns off stats gathering (stats gathering is on by default).
+[clinic start generated code]*/
+
+static PyObject *
+sys__stats_off_impl(PyObject *module)
+/*[clinic end generated code: output=1534c1ee63812214 input=b3e50e71ecf29f66]*/
+{
+ _py_stats = NULL;
+ Py_RETURN_NONE;
+}
+
+/*[clinic input]
+sys._stats_clear
+
+Clears the stats.
+[clinic start generated code]*/
+
+static PyObject *
+sys__stats_clear_impl(PyObject *module)
+/*[clinic end generated code: output=fb65a2525ee50604 input=3e03f2654f44da96]*/
+{
+ _Py_StatsClear();
+ Py_RETURN_NONE;
+}
+
+/*[clinic input]
+sys._stats_dump
+
+Dump stats to file, and clears the stats.
+[clinic start generated code]*/
+
+static PyObject *
+sys__stats_dump_impl(PyObject *module)
+/*[clinic end generated code: output=79f796fb2b4ddf05 input=92346f16d64f6f95]*/
+{
+ _Py_PrintSpecializationStats(1);
+ _Py_StatsClear();
+ Py_RETURN_NONE;
+}
+
+#endif
+
#ifdef ANDROID_API_LEVEL
/*[clinic input]
sys.getandroidapilevel
@@ -1980,6 +2153,196 @@ sys_getandroidapilevel_impl(PyObject *module)
}
#endif /* ANDROID_API_LEVEL */
+/*[clinic input]
+sys.activate_stack_trampoline
+
+ backend: str
+ /
+
+Activate stack profiler trampoline *backend*.
+[clinic start generated code]*/
+
+static PyObject *
+sys_activate_stack_trampoline_impl(PyObject *module, const char *backend)
+/*[clinic end generated code: output=5783cdeb51874b43 input=a12df928758a82b4]*/
+{
+#ifdef PY_HAVE_PERF_TRAMPOLINE
+ if (strcmp(backend, "perf") == 0) {
+ _PyPerf_Callbacks cur_cb;
+ _PyPerfTrampoline_GetCallbacks(&cur_cb);
+ if (cur_cb.write_state != _Py_perfmap_callbacks.write_state) {
+ if (_PyPerfTrampoline_SetCallbacks(&_Py_perfmap_callbacks) < 0 ) {
+ PyErr_SetString(PyExc_ValueError, "can't activate perf trampoline");
+ return NULL;
+ }
+ }
+ }
+ else {
+ PyErr_Format(PyExc_ValueError, "invalid backend: %s", backend);
+ return NULL;
+ }
+ if (_PyPerfTrampoline_Init(1) < 0) {
+ return NULL;
+ }
+ Py_RETURN_NONE;
+#else
+ PyErr_SetString(PyExc_ValueError, "perf trampoline not available");
+ return NULL;
+#endif
+}
+
+
+/*[clinic input]
+sys.deactivate_stack_trampoline
+
+Deactivate the current stack profiler trampoline backend.
+
+If no stack profiler is activated, this function has no effect.
+[clinic start generated code]*/
+
+static PyObject *
+sys_deactivate_stack_trampoline_impl(PyObject *module)
+/*[clinic end generated code: output=b50da25465df0ef1 input=9f629a6be9fe7fc8]*/
+{
+ if (_PyPerfTrampoline_Init(0) < 0) {
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+/*[clinic input]
+sys.is_stack_trampoline_active
+
+Return *True* if a stack profiler trampoline is active.
+[clinic start generated code]*/
+
+static PyObject *
+sys_is_stack_trampoline_active_impl(PyObject *module)
+/*[clinic end generated code: output=ab2746de0ad9d293 input=29616b7bf6a0b703]*/
+{
+#ifdef PY_HAVE_PERF_TRAMPOLINE
+ if (_PyIsPerfTrampolineActive()) {
+ Py_RETURN_TRUE;
+ }
+#endif
+ Py_RETURN_FALSE;
+}
+
+
+/*[clinic input]
+sys._getframemodulename
+
+ depth: int = 0
+
+Return the name of the module for a calling frame.
+
+The default depth returns the module containing the call to this API.
+A more typical use in a library will pass a depth of 1 to get the user's
+module rather than the library module.
+
+If no frame, module, or name can be found, returns None.
+[clinic start generated code]*/
+
+static PyObject *
+sys__getframemodulename_impl(PyObject *module, int depth)
+/*[clinic end generated code: output=1d70ef691f09d2db input=d4f1a8ed43b8fb46]*/
+{
+ if (PySys_Audit("sys._getframemodulename", "i", depth) < 0) {
+ return NULL;
+ }
+ _PyInterpreterFrame *f = _PyThreadState_GET()->cframe->current_frame;
+ while (f && (_PyFrame_IsIncomplete(f) || depth-- > 0)) {
+ f = f->previous;
+ }
+ if (f == NULL || f->f_funcobj == NULL) {
+ Py_RETURN_NONE;
+ }
+ PyObject *r = PyFunction_GetModule(f->f_funcobj);
+ if (!r) {
+ PyErr_Clear();
+ r = Py_None;
+ }
+ return Py_NewRef(r);
+}
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static PerfMapState perf_map_state;
+
+PyAPI_FUNC(int) PyUnstable_PerfMapState_Init(void) {
+#ifndef MS_WINDOWS
+ char filename[100];
+ pid_t pid = getpid();
+ // Use nofollow flag to prevent symlink attacks.
+ int flags = O_WRONLY | O_CREAT | O_APPEND | O_NOFOLLOW;
+#ifdef O_CLOEXEC
+ flags |= O_CLOEXEC;
+#endif
+ snprintf(filename, sizeof(filename) - 1, "/tmp/perf-%jd.map",
+ (intmax_t)pid);
+ int fd = open(filename, flags, 0600);
+ if (fd == -1) {
+ return -1;
+ }
+ else{
+ perf_map_state.perf_map = fdopen(fd, "a");
+ if (perf_map_state.perf_map == NULL) {
+ close(fd);
+ return -1;
+ }
+ }
+ perf_map_state.map_lock = PyThread_allocate_lock();
+ if (perf_map_state.map_lock == NULL) {
+ fclose(perf_map_state.perf_map);
+ return -2;
+ }
+#endif
+ return 0;
+}
+
+PyAPI_FUNC(int) PyUnstable_WritePerfMapEntry(
+ const void *code_addr,
+ unsigned int code_size,
+ const char *entry_name
+) {
+#ifndef MS_WINDOWS
+ if (perf_map_state.perf_map == NULL) {
+ int ret = PyUnstable_PerfMapState_Init();
+ if(ret != 0){
+ return ret;
+ }
+ }
+ PyThread_acquire_lock(perf_map_state.map_lock, 1);
+ fprintf(perf_map_state.perf_map, "%" PRIxPTR " %x %s\n", (uintptr_t) code_addr, code_size, entry_name);
+ fflush(perf_map_state.perf_map);
+ PyThread_release_lock(perf_map_state.map_lock);
+#endif
+ return 0;
+}
+
+PyAPI_FUNC(void) PyUnstable_PerfMapState_Fini(void) {
+#ifndef MS_WINDOWS
+ if (perf_map_state.perf_map != NULL) {
+ // close the file
+ PyThread_acquire_lock(perf_map_state.map_lock, 1);
+ fclose(perf_map_state.perf_map);
+ PyThread_release_lock(perf_map_state.map_lock);
+
+ // clean up the lock and state
+ PyThread_free_lock(perf_map_state.map_lock);
+ perf_map_state.perf_map = NULL;
+ }
+#endif
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+
static PyMethodDef sys_methods[] = {
/* Might as well keep this in alphabetic order */
SYS_ADDAUDITHOOK_METHODDEF
@@ -1997,12 +2360,9 @@ static PyMethodDef sys_methods[] = {
SYS_GETDEFAULTENCODING_METHODDEF
SYS_GETDLOPENFLAGS_METHODDEF
SYS_GETALLOCATEDBLOCKS_METHODDEF
-#ifdef Py_STATS
- {"getdxp", _Py_GetDXProfile, METH_VARARGS},
-#endif
+ SYS_GETUNICODEINTERNEDSIZE_METHODDEF
SYS_GETFILESYSTEMENCODING_METHODDEF
SYS_GETFILESYSTEMENCODEERRORS_METHODDEF
- SYS__GETQUICKENEDCOUNT_METHODDEF
#ifdef Py_TRACE_REFS
{"getobjects", _Py_GetObjects, METH_VARARGS},
#endif
@@ -2012,6 +2372,7 @@ static PyMethodDef sys_methods[] = {
{"getsizeof", _PyCFunction_CAST(sys_getsizeof),
METH_VARARGS | METH_KEYWORDS, getsizeof_doc},
SYS__GETFRAME_METHODDEF
+ SYS__GETFRAMEMODULENAME_METHODDEF
SYS_GETWINDOWSVERSION_METHODDEF
SYS__ENABLELEGACYWINDOWSFSENCODING_METHODDEF
SYS_INTERN_METHODDEF
@@ -2021,9 +2382,11 @@ static PyMethodDef sys_methods[] = {
SYS_GETSWITCHINTERVAL_METHODDEF
SYS_SETDLOPENFLAGS_METHODDEF
{"setprofile", sys_setprofile, METH_O, setprofile_doc},
+ SYS__SETPROFILEALLTHREADS_METHODDEF
SYS_GETPROFILE_METHODDEF
SYS_SETRECURSIONLIMIT_METHODDEF
{"settrace", sys_settrace, METH_O, settrace_doc},
+ SYS__SETTRACEALLTHREADS_METHODDEF
SYS_GETTRACE_METHODDEF
SYS_CALL_TRACING_METHODDEF
SYS__DEBUGMALLOCSTATS_METHODDEF
@@ -2033,9 +2396,18 @@ static PyMethodDef sys_methods[] = {
METH_VARARGS | METH_KEYWORDS, set_asyncgen_hooks_doc},
SYS_GET_ASYNCGEN_HOOKS_METHODDEF
SYS_GETANDROIDAPILEVEL_METHODDEF
+ SYS_ACTIVATE_STACK_TRAMPOLINE_METHODDEF
+ SYS_DEACTIVATE_STACK_TRAMPOLINE_METHODDEF
+ SYS_IS_STACK_TRAMPOLINE_ACTIVE_METHODDEF
SYS_UNRAISABLEHOOK_METHODDEF
SYS_GET_INT_MAX_STR_DIGITS_METHODDEF
SYS_SET_INT_MAX_STR_DIGITS_METHODDEF
+#ifdef Py_STATS
+ SYS__STATS_ON_METHODDEF
+ SYS__STATS_OFF_METHODDEF
+ SYS__STATS_CLEAR_METHODDEF
+ SYS__STATS_DUMP_METHODDEF
+#endif
{NULL, NULL} // sentinel
};
@@ -2043,21 +2415,10 @@ static PyMethodDef sys_methods[] = {
static PyObject *
list_builtin_module_names(void)
{
- PyObject *list = PyList_New(0);
+ PyObject *list = _PyImport_GetBuiltinModuleNames();
if (list == NULL) {
return NULL;
}
- for (Py_ssize_t i = 0; PyImport_Inittab[i].name != NULL; i++) {
- PyObject *name = PyUnicode_FromString(PyImport_Inittab[i].name);
- if (name == NULL) {
- goto error;
- }
- if (PyList_Append(list, name) < 0) {
- Py_DECREF(name);
- goto error;
- }
- Py_DECREF(name);
- }
if (PyList_Sort(list) != 0) {
goto error;
}
@@ -2363,8 +2724,7 @@ _PySys_AddXOptionWithError(const wchar_t *s)
if (name == NULL) {
goto error;
}
- value = Py_True;
- Py_INCREF(value);
+ value = Py_NewRef(Py_True);
}
else {
name = PyUnicode_FromWideChar(s, name_end - s);
@@ -2436,11 +2796,13 @@ stderr -- standard error object; used for error messages\n\
By assigning other file objects (or objects that behave like files)\n\
to these, it is possible to redirect all of the interpreter's I/O.\n\
\n\
+last_exc - the last uncaught exception\n\
+ Only available in an interactive session after a\n\
+ traceback has been printed.\n\
last_type -- type of last uncaught exception\n\
last_value -- value of last uncaught exception\n\
last_traceback -- traceback of last uncaught exception\n\
- These three are only available in an interactive session after a\n\
- traceback has been printed.\n\
+ These three are the (deprecated) legacy representation of last_exc.\n\
"
)
/* concatenating string here */
@@ -2585,7 +2947,7 @@ set_flags_from_config(PyInterpreterState *interp, PyObject *flags)
SetFlag(preconfig->utf8_mode);
SetFlag(config->warn_default_encoding);
SetFlagObj(PyBool_FromLong(config->safe_path));
- SetFlag(_Py_global_config_int_max_str_digits);
+ SetFlag(config->int_max_str_digits);
#undef SetFlagObj
#undef SetFlag
return 0;
@@ -2822,8 +3184,7 @@ make_emscripten_info(void)
}
PyStructSequence_SET_ITEM(emscripten_info, pos++, oua);
} else {
- Py_INCREF(Py_None);
- PyStructSequence_SET_ITEM(emscripten_info, pos++, Py_None);
+ PyStructSequence_SET_ITEM(emscripten_info, pos++, Py_NewRef(Py_None));
}
#define SetBoolItem(flag) \
@@ -2889,6 +3250,7 @@ _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict)
{
PyObject *version_info;
int res;
+ PyInterpreterState *interp = tstate->interp;
/* stdin/stdout/stderr are set in pylifecycle.c */
@@ -2914,10 +3276,10 @@ _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict)
SET_SYS("float_info", PyFloat_GetInfo());
SET_SYS("int_info", PyLong_GetInfo());
/* initialize hash_info */
- if (Hash_InfoType.tp_name == NULL) {
- if (PyStructSequence_InitType2(&Hash_InfoType, &hash_info_desc) < 0) {
- goto type_init_failed;
- }
+ if (_PyStructSequence_InitBuiltin(interp, &Hash_InfoType,
+ &hash_info_desc) < 0)
+ {
+ goto type_init_failed;
}
SET_SYS("hash_info", get_hash_info(tstate));
SET_SYS("maxunicode", PyLong_FromLong(0x10FFFF));
@@ -2937,14 +3299,16 @@ _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict)
SET_SYS_FROM_STRING("abiflags", ABIFLAGS);
#endif
+#define ENSURE_INFO_TYPE(TYPE, DESC) \
+ do { \
+ if (_PyStructSequence_InitBuiltinWithFlags( \
+ interp, &TYPE, &DESC, Py_TPFLAGS_DISALLOW_INSTANTIATION) < 0) { \
+ goto type_init_failed; \
+ } \
+ } while (0)
+
/* version_info */
- if (VersionInfoType.tp_name == NULL) {
- if (_PyStructSequence_InitType(&VersionInfoType,
- &version_info_desc,
- Py_TPFLAGS_DISALLOW_INSTANTIATION) < 0) {
- goto type_init_failed;
- }
- }
+ ENSURE_INFO_TYPE(VersionInfoType, version_info_desc);
version_info = make_version_info(tstate);
SET_SYS("version_info", version_info);
@@ -2952,27 +3316,18 @@ _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict)
SET_SYS("implementation", make_impl_info(version_info));
// sys.flags: updated in-place later by _PySys_UpdateConfig()
- if (FlagsType.tp_name == 0) {
- if (_PyStructSequence_InitType(&FlagsType, &flags_desc,
- Py_TPFLAGS_DISALLOW_INSTANTIATION) < 0) {
- goto type_init_failed;
- }
- }
+ ENSURE_INFO_TYPE(FlagsType, flags_desc);
SET_SYS("flags", make_flags(tstate->interp));
#if defined(MS_WINDOWS)
/* getwindowsversion */
- if (WindowsVersionType.tp_name == 0) {
- if (_PyStructSequence_InitType(&WindowsVersionType,
- &windows_version_desc,
- Py_TPFLAGS_DISALLOW_INSTANTIATION) < 0) {
- goto type_init_failed;
- }
- }
+ ENSURE_INFO_TYPE(WindowsVersionType, windows_version_desc);
SET_SYS_FROM_STRING("_vpath", VPATH);
#endif
+#undef ENSURE_INFO_TYPE
+
/* float repr style: 0.03 (short) vs 0.029999999999999999 (legacy) */
#if _PY_SHORT_FLOAT_REPR == 1
SET_SYS_FROM_STRING("float_repr_style", "short");
@@ -2983,11 +3338,10 @@ _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict)
SET_SYS("thread_info", PyThread_GetInfo());
/* initialize asyncgen_hooks */
- if (AsyncGenHooksType.tp_name == NULL) {
- if (PyStructSequence_InitType2(
- &AsyncGenHooksType, &asyncgen_hooks_desc) < 0) {
- goto type_init_failed;
- }
+ if (_PyStructSequence_InitBuiltin(interp, &AsyncGenHooksType,
+ &asyncgen_hooks_desc) < 0)
+ {
+ goto type_init_failed;
}
#ifdef __EMSCRIPTEN__
@@ -3028,8 +3382,7 @@ sys_add_xoption(PyObject *opts, const wchar_t *s)
if (name == NULL) {
goto error;
}
- value = Py_True;
- Py_INCREF(value);
+ value = Py_NewRef(Py_True);
}
else {
name = PyUnicode_FromWideChar(s, name_end - s);
@@ -3191,6 +3544,7 @@ error:
return _PyStatus_ERR("can't set preliminary stderr");
}
+PyObject *_Py_CreateMonitoringObject(void);
/* Create sys module without all attributes.
_PySys_UpdateConfig() should be called later to add remaining attributes. */
@@ -3201,11 +3555,10 @@ _PySys_Create(PyThreadState *tstate, PyObject **sysmod_p)
PyInterpreterState *interp = tstate->interp;
- PyObject *modules = PyDict_New();
+ PyObject *modules = _PyImport_InitModules(interp);
if (modules == NULL) {
goto error;
}
- interp->modules = modules;
PyObject *sysmod = _PyModule_CreateInitialized(&sysmodule, PYTHON_API_VERSION);
if (sysmod == NULL) {
@@ -3216,10 +3569,14 @@ _PySys_Create(PyThreadState *tstate, PyObject **sysmod_p)
if (sysdict == NULL) {
goto error;
}
- Py_INCREF(sysdict);
- interp->sysdict = sysdict;
+ interp->sysdict = Py_NewRef(sysdict);
+
+ interp->sysdict_copy = PyDict_Copy(sysdict);
+ if (interp->sysdict_copy == NULL) {
+ goto error;
+ }
- if (PyDict_SetItemString(sysdict, "modules", interp->modules) < 0) {
+ if (PyDict_SetItemString(sysdict, "modules", modules) < 0) {
goto error;
}
@@ -3233,7 +3590,17 @@ _PySys_Create(PyThreadState *tstate, PyObject **sysmod_p)
return status;
}
- if (_PyImport_FixupBuiltin(sysmod, "sys", interp->modules) < 0) {
+ if (_PyImport_FixupBuiltin(sysmod, "sys", modules) < 0) {
+ goto error;
+ }
+
+ PyObject *monitoring = _Py_CreateMonitoringObject();
+ if (monitoring == NULL) {
+ goto error;
+ }
+ int err = PyDict_SetItemString(sysdict, "monitoring", monitoring);
+ Py_DECREF(monitoring);
+ if (err < 0) {
goto error;
}
@@ -3248,20 +3615,20 @@ error:
void
-_PySys_Fini(PyInterpreterState *interp)
+_PySys_FiniTypes(PyInterpreterState *interp)
{
- if (_Py_IsMainInterpreter(interp)) {
- _PyStructSequence_FiniType(&VersionInfoType);
- _PyStructSequence_FiniType(&FlagsType);
+ _PyStructSequence_FiniBuiltin(interp, &VersionInfoType);
+ _PyStructSequence_FiniBuiltin(interp, &FlagsType);
#if defined(MS_WINDOWS)
- _PyStructSequence_FiniType(&WindowsVersionType);
+ _PyStructSequence_FiniBuiltin(interp, &WindowsVersionType);
#endif
- _PyStructSequence_FiniType(&Hash_InfoType);
- _PyStructSequence_FiniType(&AsyncGenHooksType);
+ _PyStructSequence_FiniBuiltin(interp, &Hash_InfoType);
+ _PyStructSequence_FiniBuiltin(interp, &AsyncGenHooksType);
#ifdef __EMSCRIPTEN__
+ if (_Py_IsMainInterpreter(interp)) {
Py_CLEAR(EmscriptenInfoType);
-#endif
}
+#endif
}
@@ -3450,12 +3817,11 @@ static void
sys_write(PyObject *key, FILE *fp, const char *format, va_list va)
{
PyObject *file;
- PyObject *error_type, *error_value, *error_traceback;
char buffer[1001];
int written;
PyThreadState *tstate = _PyThreadState_GET();
- _PyErr_Fetch(tstate, &error_type, &error_value, &error_traceback);
+ PyObject *exc = _PyErr_GetRaisedException(tstate);
file = _PySys_GetAttr(tstate, key);
written = PyOS_vsnprintf(buffer, sizeof(buffer), format, va);
if (sys_pyfile_write(buffer, file) != 0) {
@@ -3467,7 +3833,7 @@ sys_write(PyObject *key, FILE *fp, const char *format, va_list va)
if (sys_pyfile_write(truncated, file) != 0)
fputs(truncated, fp);
}
- _PyErr_Restore(tstate, error_type, error_value, error_traceback);
+ _PyErr_SetRaisedException(tstate, exc);
}
void
@@ -3494,11 +3860,10 @@ static void
sys_format(PyObject *key, FILE *fp, const char *format, va_list va)
{
PyObject *file, *message;
- PyObject *error_type, *error_value, *error_traceback;
const char *utf8;
PyThreadState *tstate = _PyThreadState_GET();
- _PyErr_Fetch(tstate, &error_type, &error_value, &error_traceback);
+ PyObject *exc = _PyErr_GetRaisedException(tstate);
file = _PySys_GetAttr(tstate, key);
message = PyUnicode_FromFormatV(format, va);
if (message != NULL) {
@@ -3510,7 +3875,7 @@ sys_format(PyObject *key, FILE *fp, const char *format, va_list va)
}
Py_DECREF(message);
}
- _PyErr_Restore(tstate, error_type, error_value, error_traceback);
+ _PyErr_SetRaisedException(tstate, exc);
}
void