@@ -1051,8 +1051,29 @@ IrregexpInterpreter::Result IrregexpInterpreter::MatchForCallFromJs(
1051
1051
return IrregexpInterpreter::RETRY;
1052
1052
}
1053
1053
1054
- return Match (isolate, regexp_obj, subject_string, registers, registers_length,
1055
- start_position, call_origin);
1054
+ // In generated code, registers are allocated on the stack. The given
1055
+ // `registers` argument is only guaranteed to hold enough space for permanent
1056
+ // registers (i.e. for captures), and not for temporary registers used only
1057
+ // during matcher execution. We match that behavior in the interpreter by
1058
+ // using a SmallVector as internal register storage.
1059
+ static constexpr int kBaseRegisterArraySize = 64 ; // Arbitrary.
1060
+ const int internal_register_count =
1061
+ Smi::ToInt (regexp_obj.DataAt (JSRegExp::kIrregexpMaxRegisterCountIndex ));
1062
+ base::SmallVector<int , kBaseRegisterArraySize > internal_registers (
1063
+ internal_register_count);
1064
+
1065
+ Result result =
1066
+ Match (isolate, regexp_obj, subject_string, internal_registers.data (),
1067
+ internal_register_count, start_position, call_origin);
1068
+
1069
+ // Copy capture registers to the output array.
1070
+ if (result == IrregexpInterpreter::SUCCESS) {
1071
+ CHECK_GE (internal_registers.size (), registers_length);
1072
+ MemCopy (registers, internal_registers.data (),
1073
+ registers_length * sizeof (registers[0 ]));
1074
+ }
1075
+
1076
+ return result;
1056
1077
}
1057
1078
1058
1079
IrregexpInterpreter::Result IrregexpInterpreter::MatchForCallFromRuntime (
0 commit comments