Provide hooks::context iff thread_local is supported.
Change-Id: I984b825fc4831142a520db10a1f5ab9c47ced348
Reviewed-on: https://code-review.googlesource.com/c/re2/+/51979
Reviewed-by: Paul Wankadia <junyer@google.com>
diff --git a/re2/re2.cc b/re2/re2.cc
index 2ac84a9..56dfcfc 100644
--- a/re2/re2.cc
+++ b/re2/re2.cc
@@ -657,7 +657,9 @@
bool can_bit_state = prog_->CanBitState();
size_t bit_state_text_max = kMaxBitStateBitmapSize / prog_->list_count();
+#ifdef RE2_HAVE_THREAD_LOCAL
hooks::context = this;
+#endif
bool dfa_failed = false;
bool skipped_test = false;
switch (re_anchor) {
@@ -1267,7 +1269,9 @@
namespace hooks {
+#ifdef RE2_HAVE_THREAD_LOCAL
thread_local const RE2* context = NULL;
+#endif
template <typename T>
union Hook {
diff --git a/re2/re2.h b/re2/re2.h
index 6d172ca..9bd1d13 100644
--- a/re2/re2.h
+++ b/re2/re2.h
@@ -196,6 +196,10 @@
#include <mutex>
#include <string>
+#ifdef __APPLE__
+#include <TargetConditionals.h>
+#endif
+
#include "re2/stringpiece.h"
namespace re2 {
@@ -950,6 +954,15 @@
namespace hooks {
+// Most platforms support thread_local. Older versions of iOS don't support
+// thread_local, but for the sake of brevity, we lump together all versions
+// of Apple platforms that aren't macOS. If an iOS application really needs
+// the context pointee someday, we can get more specific then...
+#define RE2_HAVE_THREAD_LOCAL
+#if defined(__APPLE__) && defined(TARGET_OS_MAC) && !defined(TARGET_OS_OSX)
+#undef RE2_HAVE_THREAD_LOCAL
+#endif
+
// A hook must not make any assumptions regarding the lifetime of the context
// pointee beyond the current invocation of the hook. Pointers and references
// obtained via the context pointee should be considered invalidated when the
@@ -959,7 +972,9 @@
// A hook must not use RE2 for matching. Control flow reentering RE2::Match()
// could result in infinite mutual recursion. To discourage that possibility,
// RE2 will not maintain the context pointer correctly when used in that way.
+#ifdef RE2_HAVE_THREAD_LOCAL
extern thread_local const RE2* context;
+#endif
struct DFAStateCacheReset {
int64_t state_budget;