From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jakob Gruber <jgruber@chromium.org>
Date: Mon, 6 Sep 2021 08:29:33 +0200
Subject: Add a (currently failing) cctest for irregexp reentrancy

The test should be enabled once reentrancy is supported.

Bug: v8:11382
Change-Id: Ifb90d8a6fd8bf9f05e9ca2405d4e04e013ce7ee3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3138201
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Auto-Submit: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Patrick Thier <pthier@chromium.org>
Cr-Commit-Position: refs/heads/main@{#76667}

diff --git a/test/cctest/cctest.status b/test/cctest/cctest.status
index 9b369044754443ccf5ce07c3612f0a928e565ad6..21afa5310647eb67f3fe3fc4f2e0721b4bb4e0f6 100644
--- a/test/cctest/cctest.status
+++ b/test/cctest/cctest.status
@@ -136,6 +136,9 @@
   'test-strings/Traverse': [PASS, HEAVY],
   'test-swiss-name-dictionary-csa/DeleteAtBoundaries': [PASS, HEAVY],
   'test-swiss-name-dictionary-csa/SameH2': [PASS, HEAVY],
+
+  # TODO(v8:11382): Reenable once irregexp is reentrant.
+  'test-regexp/RegExpInterruptReentrantExecution': [FAIL],
 }],  # ALWAYS
 
 ##############################################################################
@@ -666,6 +669,9 @@
 
   # Instruction cache flushing is disabled in jitless mode.
   'test-icache/*': [SKIP],
+
+  # Tests generated irregexp code.
+  'test-regexp/RegExpInterruptReentrantExecution': [SKIP],
 }], # lite_mode or variant == jitless
 
 ##############################################################################
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 25fba193bbcc41d127d36949e103cb59688bfed7..b21222f14c533cb630946b6066bfe24d1be49f93 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -21658,10 +21658,6 @@ TEST(RegExpInterruptAndMakeSubjectTwoByteExternal) {
   // experimental engine.
   i::FLAG_enable_experimental_regexp_engine_on_excessive_backtracks = false;
   RegExpInterruptTest test;
-  // We want to be stuck regexp execution, so no fallback to linear-time
-  // engine.
-  // TODO(mbid,v8:10765): Find a way to test interrupt support of the
-  // experimental engine.
   test.RunTest(RegExpInterruptTest::MakeSubjectTwoByteExternal);
 }
 
diff --git a/test/cctest/test-regexp.cc b/test/cctest/test-regexp.cc
index aa24fe3dd230ecc06d9eea2920826dc123979c58..2fb5b3d056f78d3eef3a0a1032ee99df1b2f35c5 100644
--- a/test/cctest/test-regexp.cc
+++ b/test/cctest/test-regexp.cc
@@ -2348,6 +2348,50 @@ TEST(UnicodePropertyEscapeCodeSize) {
   }
 }
 
+namespace {
+
+struct RegExpExecData {
+  i::Isolate* isolate;
+  i::Handle<i::JSRegExp> regexp;
+  i::Handle<i::String> subject;
+};
+
+i::Handle<i::Object> RegExpExec(const RegExpExecData* d) {
+  return i::RegExp::Exec(d->isolate, d->regexp, d->subject, 0,
+                         d->isolate->regexp_last_match_info())
+      .ToHandleChecked();
+}
+
+void ReenterRegExp(v8::Isolate* isolate, void* data) {
+  RegExpExecData* d = static_cast<RegExpExecData*>(data);
+  i::Handle<i::Object> result = RegExpExec(d);
+  CHECK(result->IsNull());
+}
+
+}  // namespace
+
+// Tests reentrant irregexp calls.
+TEST(RegExpInterruptReentrantExecution) {
+  CHECK(!i::FLAG_jitless);
+  i::FLAG_regexp_tier_up = false;  // Enter irregexp, not the interpreter.
+
+  LocalContext context;
+  v8::Isolate* isolate = context->GetIsolate();
+  v8::HandleScope scope(isolate);
+
+  RegExpExecData d;
+  d.isolate = reinterpret_cast<i::Isolate*>(isolate);
+  d.regexp = v8::Utils::OpenHandle(
+      *v8::RegExp::New(context.local(), v8_str("(a*)*x"), v8::RegExp::kNone)
+           .ToLocalChecked());
+  d.subject = v8::Utils::OpenHandle(*v8_str("aaaa"));
+
+  isolate->RequestInterrupt(&ReenterRegExp, &d);
+
+  i::Handle<i::Object> result = RegExpExec(&d);
+  CHECK(result->IsNull());
+}
+
 #undef CHECK_PARSE_ERROR
 #undef CHECK_SIMPLE
 #undef CHECK_MIN_MAX
