aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/memory/qv4stacklimits_p.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/memory/qv4stacklimits_p.h')
-rw-r--r--src/qml/memory/qv4stacklimits_p.h74
1 files changed, 74 insertions, 0 deletions
diff --git a/src/qml/memory/qv4stacklimits_p.h b/src/qml/memory/qv4stacklimits_p.h
new file mode 100644
index 0000000000..9e7fdb279b
--- /dev/null
+++ b/src/qml/memory/qv4stacklimits_p.h
@@ -0,0 +1,74 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QV4STACKLIMITS_P_H
+#define QV4STACKLIMITS_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qtqmlglobal_p.h>
+
+#ifndef Q_STACK_GROWTH_DIRECTION
+# ifdef Q_PROCESSOR_HPPA
+# define Q_STACK_GROWTH_DIRECTION (1)
+# else
+# define Q_STACK_GROWTH_DIRECTION (-1)
+# endif
+#endif
+
+QT_BEGIN_NAMESPACE
+
+namespace QV4 {
+
+// Note: This does not return a completely accurate stack pointer.
+// Depending on whether this function is inlined or not, we may get the address of
+// this function's stack frame or the caller's stack frame.
+// Always use a safety margin when determining stack limits.
+inline const void *currentStackPointer()
+{
+ // TODO: How often do we actually need the assembler mess below? Is that worth it?
+
+ void *stackPointer;
+#if defined(Q_CC_GNU) || __has_builtin(__builtin_frame_address)
+ stackPointer = __builtin_frame_address(0);
+#elif defined(Q_CC_MSVC)
+ stackPointer = &stackPointer;
+#elif defined(Q_PROCESSOR_X86_64)
+ __asm__ __volatile__("movq %%rsp, %0" : "=r"(stackPointer) : :);
+#elif defined(Q_PROCESSOR_X86)
+ __asm__ __volatile__("movl %%esp, %0" : "=r"(stackPointer) : :);
+#elif defined(Q_PROCESSOR_ARM_64) && defined(__ILP32__)
+ quint64 stackPointerRegister = 0;
+ __asm__ __volatile__("mov %0, sp" : "=r"(stackPointerRegister) : :);
+ stackPointer = reinterpret_cast<void *>(stackPointerRegister);
+#elif defined(Q_PROCESSOR_ARM_64) || defined(Q_PROCESSOR_ARM_32)
+ __asm__ __volatile__("mov %0, sp" : "=r"(stackPointer) : :);
+#else
+ stackPointer = &stackPointer;
+#endif
+ return stackPointer;
+}
+
+struct StackProperties
+{
+ const void *base = nullptr;
+ const void *softLimit = nullptr;
+ const void *hardLimit = nullptr;
+};
+
+StackProperties stackProperties();
+
+} // namespace QV4
+
+QT_END_NAMESPACE
+
+#endif // QV4STACKLIMITS_P_H