Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Roblox
GitHub Repository: Roblox/luau
Path: blob/master/Analysis/src/NativeStackGuard.cpp
2746 views
1
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
2
3
#include "Luau/NativeStackGuard.h"
4
#include "Luau/Common.h"
5
#include <iostream>
6
7
LUAU_FASTFLAGVARIABLE(LuauUseNativeStackGuard);
8
9
// The minimum number of available bytes in the stack's address space.
10
// If we have less, we want to fail and exit rather than risking an overflow.
11
LUAU_FASTINTVARIABLE(LuauStackGuardThreshold, 1024);
12
13
#if defined(_MSC_VER)
14
15
#define WIN32_LEAN_AND_MEAN
16
#include <Windows.h>
17
#include <intrin.h>
18
19
namespace Luau
20
{
21
22
NativeStackGuard::NativeStackGuard()
23
: high(0)
24
, low(0)
25
{
26
if (!FFlag::LuauUseNativeStackGuard)
27
return;
28
29
GetCurrentThreadStackLimits((PULONG_PTR)&low, (PULONG_PTR)&high);
30
}
31
32
bool NativeStackGuard::isOk() const
33
{
34
if (!FFlag::LuauUseNativeStackGuard || FInt::LuauStackGuardThreshold <= 0)
35
return true;
36
37
const uintptr_t sp = uintptr_t(_AddressOfReturnAddress());
38
39
const uintptr_t remaining = sp - low;
40
41
return remaining > uintptr_t(FInt::LuauStackGuardThreshold);
42
}
43
44
uintptr_t getStackAddressSpaceSize()
45
{
46
uintptr_t low = 0;
47
uintptr_t high = 0;
48
GetCurrentThreadStackLimits((PULONG_PTR)&low, (PULONG_PTR)&high);
49
50
return high - low;
51
}
52
53
} // namespace Luau
54
55
#elif defined(__APPLE__)
56
57
#include <pthread.h>
58
59
namespace Luau
60
{
61
62
NativeStackGuard::NativeStackGuard()
63
: high(0)
64
, low(0)
65
{
66
if (!FFlag::LuauUseNativeStackGuard)
67
return;
68
69
pthread_t self = pthread_self();
70
char* addr = static_cast<char*>(pthread_get_stackaddr_np(self));
71
size_t size = pthread_get_stacksize_np(self);
72
73
low = uintptr_t(addr - size);
74
high = uintptr_t(addr);
75
}
76
77
bool NativeStackGuard::isOk() const
78
{
79
if (!FFlag::LuauUseNativeStackGuard || FInt::LuauStackGuardThreshold <= 0)
80
return true;
81
82
const uintptr_t sp = uintptr_t(__builtin_frame_address(0));
83
84
const uintptr_t remaining = sp - low;
85
86
return remaining > uintptr_t(FInt::LuauStackGuardThreshold);
87
}
88
89
uintptr_t getStackAddressSpaceSize()
90
{
91
pthread_t self = pthread_self();
92
return pthread_get_stacksize_np(self);
93
}
94
95
} // namespace Luau
96
97
#else
98
99
100
namespace Luau
101
{
102
103
NativeStackGuard::NativeStackGuard()
104
: high(0)
105
, low(0)
106
{
107
(void)low;
108
(void)high;
109
}
110
111
bool NativeStackGuard::isOk() const
112
{
113
return true;
114
}
115
116
uintptr_t getStackAddressSpaceSize()
117
{
118
return 0;
119
}
120
121
} // namespace Luau
122
123
#endif
124
125