v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
regexp-macro-assembler.cc
Go to the documentation of this file.
1// Copyright 2012 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
6
8#include "src/codegen/label.h"
15
16#ifdef V8_INTL_SUPPORT
17#include "unicode/uchar.h"
18#include "unicode/unistr.h"
19#endif // V8_INTL_SUPPORT
20
21namespace v8 {
22namespace internal {
23
25 : slow_safe_compiler_(false),
26 backtrack_limit_(JSRegExp::kNoBacktrackLimit),
27 global_mode_(NOT_GLOBAL),
28 isolate_(isolate),
29 zone_(zone) {}
30
34
35// static
37 Address byte_offset2,
38 size_t byte_length,
39 Isolate* isolate) {
40#ifdef V8_INTL_SUPPORT
41 // This function is not allowed to cause a garbage collection.
42 // A GC might move the calling generated code and invalidate the
43 // return address on the stack.
45 DCHECK_EQ(0, byte_length % 2);
46 size_t length = byte_length / 2;
47 base::uc16* substring1 = reinterpret_cast<base::uc16*>(byte_offset1);
48 base::uc16* substring2 = reinterpret_cast<base::uc16*>(byte_offset2);
49
50 for (size_t i = 0; i < length; i++) {
51 UChar32 c1 = RegExpCaseFolding::Canonicalize(substring1[i]);
52 UChar32 c2 = RegExpCaseFolding::Canonicalize(substring2[i]);
53 if (c1 != c2) {
54 return 0;
55 }
56 }
57 return 1;
58#else
59 return CaseInsensitiveCompareUnicode(byte_offset1, byte_offset2, byte_length,
60 isolate);
61#endif
62}
63
64// static
66 Address byte_offset2,
67 size_t byte_length,
68 Isolate* isolate) {
69 // This function is not allowed to cause a garbage collection.
70 // A GC might move the calling generated code and invalidate the
71 // return address on the stack.
73 DCHECK_EQ(0, byte_length % 2);
74
75#ifdef V8_INTL_SUPPORT
76 int32_t length = static_cast<int32_t>(byte_length >> 1);
77 icu::UnicodeString uni_str_1(reinterpret_cast<const char16_t*>(byte_offset1),
78 length);
79 return uni_str_1.caseCompare(reinterpret_cast<const char16_t*>(byte_offset2),
80 length, U_FOLD_CASE_DEFAULT) == 0;
81#else
82 base::uc16* substring1 = reinterpret_cast<base::uc16*>(byte_offset1);
83 base::uc16* substring2 = reinterpret_cast<base::uc16*>(byte_offset2);
84 size_t length = byte_length >> 1;
85 DCHECK_NOT_NULL(isolate);
87 isolate->regexp_macro_assembler_canonicalize();
88 for (size_t i = 0; i < length; i++) {
89 unibrow::uchar c1 = substring1[i];
90 unibrow::uchar c2 = substring2[i];
91 if (c1 != c2) {
92 unibrow::uchar s1[1] = {c1};
93 canonicalize->get(c1, '\0', s1);
94 if (s1[0] != c2) {
95 unibrow::uchar s2[1] = {c2};
96 canonicalize->get(c2, '\0', s2);
97 if (s1[0] != s2[0]) {
98 return 0;
99 }
100 }
101 }
102 }
103 return 1;
104#endif // V8_INTL_SUPPORT
105}
106
107namespace {
108
109uint32_t Hash(const ZoneList<CharacterRange>* ranges) {
110 size_t seed = 0;
111 for (int i = 0; i < ranges->length(); i++) {
112 const CharacterRange& r = ranges->at(i);
113 seed = base::hash_combine(seed, r.from(), r.to());
114 }
115 return static_cast<uint32_t>(seed);
116}
117
118constexpr base::uc32 MaskEndOfRangeMarker(base::uc32 c) {
119 // CharacterRanges may use 0x10ffff as the end-of-range marker irrespective
120 // of whether the regexp IsUnicode or not; translate the marker value here.
122 return c & 0xffff;
123}
124
125int RangeArrayLengthFor(const ZoneList<CharacterRange>* ranges) {
126 const int ranges_length = ranges->length();
127 return MaskEndOfRangeMarker(ranges->at(ranges_length - 1).to()) == kMaxUInt16
128 ? ranges_length * 2 - 1
129 : ranges_length * 2;
130}
131
132bool Equals(const ZoneList<CharacterRange>* lhs,
133 const DirectHandle<FixedUInt16Array>& rhs) {
134 const int rhs_length = rhs->length();
135 if (rhs_length != RangeArrayLengthFor(lhs)) return false;
136 for (int i = 0; i < lhs->length(); i++) {
137 const CharacterRange& r = lhs->at(i);
138 if (rhs->get(i * 2 + 0) != r.from()) return false;
139 if (i * 2 + 1 == rhs_length) break;
140 if (rhs->get(i * 2 + 1) != r.to() + 1) return false;
141 }
142 return true;
143}
144
145Handle<FixedUInt16Array> MakeRangeArray(
146 Isolate* isolate, const ZoneList<CharacterRange>* ranges) {
147 const int ranges_length = ranges->length();
148 const int range_array_length = RangeArrayLengthFor(ranges);
149 Handle<FixedUInt16Array> range_array =
150 FixedUInt16Array::New(isolate, range_array_length);
151 for (int i = 0; i < ranges_length; i++) {
152 const CharacterRange& r = ranges->at(i);
153 DCHECK_LE(r.from(), kMaxUInt16);
154 range_array->set(i * 2 + 0, r.from());
155 const base::uc32 to = MaskEndOfRangeMarker(r.to());
156 if (i == ranges_length - 1 && to == kMaxUInt16) {
157 DCHECK_EQ(range_array_length, ranges_length * 2 - 1);
158 break; // Avoid overflow by leaving the last range open-ended.
159 }
161 range_array->set(i * 2 + 1, to + 1); // Exclusive.
162 }
163 return range_array;
164}
165
166} // namespace
167
169 const ZoneList<CharacterRange>* ranges) {
170 const uint32_t hash = Hash(ranges);
171
172 if (range_array_cache_.count(hash) != 0) {
174 if (Equals(ranges, range_array)) return range_array;
175 }
176
177 Handle<FixedUInt16Array> range_array = MakeRangeArray(isolate(), ranges);
178 range_array_cache_[hash] = range_array;
179 return range_array;
180}
181
182// static
184 Address raw_byte_array) {
185 // Use uint32_t to avoid complexity around bool return types (which may be
186 // optimized to use only the least significant byte).
187 static constexpr uint32_t kTrue = 1;
188 static constexpr uint32_t kFalse = 0;
189
191 Cast<FixedUInt16Array>(Tagged<Object>(raw_byte_array));
192 DCHECK_GE(ranges->length(), 1);
193
194 // Shortcut for fully out of range chars.
195 if (current_char < ranges->get(0)) return kFalse;
196 if (current_char >= ranges->get(ranges->length() - 1)) {
197 // The last range may be open-ended.
198 return (ranges->length() % 2) == 0 ? kFalse : kTrue;
199 }
200
201 // Binary search for the matching range. `ranges` is encoded as
202 // [from0, to0, from1, to1, ..., fromN, toN], or
203 // [from0, to0, from1, to1, ..., fromN] (open-ended last interval).
204
205 int mid, lower = 0, upper = ranges->length();
206 do {
207 mid = lower + (upper - lower) / 2;
208 const base::uc16 elem = ranges->get(mid);
209 if (current_char < elem) {
210 upper = mid;
211 } else if (current_char > elem) {
212 lower = mid + 1;
213 } else {
214 DCHECK_EQ(current_char, elem);
215 break;
216 }
217 } while (lower < upper);
218
219 const bool current_char_ge_last_elem = current_char >= ranges->get(mid);
220 const int current_range_start_index =
221 current_char_ge_last_elem ? mid : mid - 1;
222
223 // Ranges start at even indices and end at odd indices.
224 return (current_range_start_index % 2) == 0 ? kTrue : kFalse;
225}
226
228 Label* on_failure) {
229 Label ok;
230 // Check that current character is not a trail surrogate.
231 LoadCurrentCharacter(cp_offset, &ok);
233 // Check that previous character is not a lead surrogate.
234 LoadCurrentCharacter(cp_offset - 1, &ok);
236 Bind(&ok);
237}
238
240 Label* on_outside_input) {
241 LoadCurrentCharacter(cp_offset, on_outside_input, true);
242}
243
245 Label* on_end_of_input,
246 bool check_bounds,
247 int characters,
248 int eats_at_least) {
249 // By default, eats_at_least = characters.
250 if (eats_at_least == kUseCharactersValue) {
251 eats_at_least = characters;
252 }
253
254 LoadCurrentCharacterImpl(cp_offset, on_end_of_input, check_bounds, characters,
255 eats_at_least);
256}
257
259 int cp_offset, Label* on_end_of_input, bool check_bounds, int characters,
260 int eats_at_least) {
261 // It's possible to preload a small number of characters when each success
262 // path requires a large number of characters, but not the reverse.
263 DCHECK_GE(eats_at_least, characters);
264
266 if (check_bounds) {
267 if (cp_offset >= 0) {
268 CheckPosition(cp_offset + eats_at_least - 1, on_end_of_input);
269 } else {
270 CheckPosition(cp_offset, on_end_of_input);
271 }
272 }
273 LoadCurrentCharacterUnchecked(cp_offset, characters);
274}
275
277 return v8_flags.enable_regexp_unaligned_accesses && !slow_safe();
278}
279
280#ifndef COMPILING_IRREGEXP_FOR_EXTERNAL_EMBEDDER
281
282// This method may only be called after an interrupt.
283// static
285 Isolate* isolate, int start_index, RegExp::CallOrigin call_origin,
286 Address* return_address, Tagged<InstructionStream> re_code,
287 Address* subject, const uint8_t** input_start, const uint8_t** input_end,
288 uintptr_t gap) {
290 Address old_pc = PointerAuthentication::AuthenticatePC(return_address, 0);
291 DCHECK_LE(re_code->instruction_start(), old_pc);
292 DCHECK_LE(old_pc, re_code->code(kAcquireLoad)->instruction_end());
293
294 StackLimitCheck check(isolate);
295 bool js_has_overflowed = check.JsHasOverflowed(gap);
296
298 // Direct calls from JavaScript can be interrupted in two ways:
299 // 1. A real stack overflow, in which case we let the caller throw the
300 // exception.
301 // 2. The stack guard was used to interrupt execution for another purpose,
302 // forcing the call through the runtime system.
303
304 // Bug(v8:9540) Investigate why this method is called from JS although no
305 // stackoverflow or interrupt is pending on ARM64. We return 0 in this case
306 // to continue execution normally.
307 if (js_has_overflowed) {
308 return EXCEPTION;
309 } else if (check.InterruptRequested()) {
310 return RETRY;
311 } else {
312 return 0;
313 }
314 }
316
317 // Prepare for possible GC.
318 HandleScope handles(isolate);
319 DirectHandle<InstructionStream> code_handle(re_code, isolate);
320 DirectHandle<String> subject_handle(Cast<String>(Tagged<Object>(*subject)),
321 isolate);
322 bool is_one_byte = String::IsOneByteRepresentationUnderneath(*subject_handle);
323 int return_value = 0;
324
325 {
326 DisableGCMole no_gc_mole;
327 if (js_has_overflowed) {
329 isolate->StackOverflow();
330 return_value = EXCEPTION;
331 } else if (check.InterruptRequested()) {
333 Tagged<Object> result = isolate->stack_guard()->HandleInterrupts();
334 if (IsException(result, isolate)) return_value = EXCEPTION;
335 }
336
337 // We are not using operator == here because it does a slow DCHECK
338 // CheckObjectComparisonAllowed() which might crash when trying to access
339 // the page header of the stale pointer.
340 if (!code_handle->SafeEquals(re_code)) { // Return address no longer valid
341 // Overwrite the return address on the stack.
342 intptr_t delta = code_handle->address() - re_code.address();
343 Address new_pc = old_pc + delta;
344 // TODO(v8:10026): avoid replacing a signed pointer.
345 PointerAuthentication::ReplacePC(return_address, new_pc, 0);
346 }
347 }
348
349 // If we continue, we need to update the subject string addresses.
350 if (return_value == 0) {
351 // String encoding might have changed.
352 if (String::IsOneByteRepresentationUnderneath(*subject_handle) !=
353 is_one_byte) {
354 // If we changed between an LATIN1 and an UC16 string, the specialized
355 // code cannot be used, and we need to restart regexp matching from
356 // scratch (including, potentially, compiling a new version of the code).
357 return_value = RETRY;
358 } else {
359 *subject = subject_handle->ptr();
360 intptr_t byte_length = *input_end - *input_start;
361 *input_start = subject_handle->AddressOfCharacterAt(start_index, no_gc);
362 *input_end = *input_start + byte_length;
363 }
364 }
365 return return_value;
366}
367
368// Returns a {Result} sentinel, or the number of successful matches.
370 DirectHandle<String> subject,
371 int* offsets_vector,
372 int offsets_vector_length,
373 int previous_index, Isolate* isolate) {
374 DCHECK(subject->IsFlat());
375 DCHECK_LE(0, previous_index);
376 DCHECK_LE(previous_index, subject->length());
377
378 // No allocations before calling the regexp, but we can't use
379 // DisallowGarbageCollection, since regexps might be preempted, and another
380 // thread might do allocation anyway.
381
382 Tagged<String> subject_ptr = *subject;
383 // Character offsets into string.
384 int start_offset = previous_index;
385 int char_length = subject_ptr->length() - start_offset;
386 int slice_offset = 0;
387
388 // The string has been flattened, so if it is a cons string it contains the
389 // full string in the first part.
390 if (StringShape(subject_ptr).IsCons()) {
391 DCHECK_EQ(0, Cast<ConsString>(subject_ptr)->second()->length());
392 subject_ptr = Cast<ConsString>(subject_ptr)->first();
393 } else if (StringShape(subject_ptr).IsSliced()) {
394 Tagged<SlicedString> slice = Cast<SlicedString>(subject_ptr);
395 subject_ptr = slice->parent();
396 slice_offset = slice->offset();
397 }
398 if (StringShape(subject_ptr).IsThin()) {
399 subject_ptr = Cast<ThinString>(subject_ptr)->actual();
400 }
401 // Ensure that an underlying string has the same representation.
402 bool is_one_byte = subject_ptr->IsOneByteRepresentation();
403 DCHECK(IsExternalString(subject_ptr) || IsSeqString(subject_ptr));
404 // String is now either Sequential or External
405 int char_size_shift = is_one_byte ? 0 : 1;
406
408 const uint8_t* input_start =
409 subject_ptr->AddressOfCharacterAt(start_offset + slice_offset, no_gc);
410 int byte_length = char_length << char_size_shift;
411 const uint8_t* input_end = input_start + byte_length;
412 return Execute(*subject, start_offset, input_start, input_end, offsets_vector,
413 offsets_vector_length, isolate, *regexp_data);
414}
415
416// static
418 Tagged<String> input, int start_offset, const uint8_t* input_start,
419 const uint8_t* input_end, int* output, int output_size, Isolate* isolate,
420 Tagged<JSRegExp> regexp) {
421 Tagged<RegExpData> data = regexp->data(isolate);
423 return Execute(input, start_offset, input_start, input_end, output,
424 output_size, isolate, Cast<IrRegExpData>(data));
425}
426
427// Returns a {Result} sentinel, or the number of successful matches.
430 input, // This needs to be the unpacked (sliced, cons) string.
431 int start_offset, const uint8_t* input_start, const uint8_t* input_end,
432 int* output, int output_size, Isolate* isolate,
433 Tagged<IrRegExpData> regexp_data) {
434 bool is_one_byte = String::IsOneByteRepresentationUnderneath(input);
435 Tagged<Code> code = regexp_data->code(isolate, is_one_byte);
437
438 using RegexpMatcherSig =
439 // NOLINTNEXTLINE(readability/casting)
440 int(Address input_string, int start_offset, const uint8_t* input_start,
441 const uint8_t* input_end, int* output, int output_size,
442 int call_origin, Isolate* isolate, Address regexp_data);
443
444 auto fn = GeneratedCode<RegexpMatcherSig>::FromCode(isolate, code);
445 int result =
446 fn.Call(input.ptr(), start_offset, input_start, input_end, output,
447 output_size, call_origin, isolate, regexp_data.ptr());
449
450 if (result == EXCEPTION && !isolate->has_exception()) {
451 // We detected a stack overflow (on the backtrack stack) in RegExp code,
452 // but haven't created the exception yet. Additionally, we allow heap
453 // allocation because even though it invalidates {input_start} and
454 // {input_end}, we are about to return anyway.
455 AllowGarbageCollection allow_allocation;
456 isolate->StackOverflow();
457 }
458 return result;
459}
460
461#endif // !COMPILING_IRREGEXP_FOR_EXTERNAL_EMBEDDER
462
463// clang-format off
465 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
466 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
467 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
468 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
469
470 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
471 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
472 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, // '0' - '7'
473 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, // '8' - '9'
474
475 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, // 'A' - 'G'
476 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, // 'H' - 'O'
477 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, // 'P' - 'W'
478 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x00u, 0xFFu, // 'X' - 'Z', '_'
479
480 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, // 'a' - 'g'
481 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, // 'h' - 'o'
482 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, // 'p' - 'w'
483 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, // 'x' - 'z'
484 // Latin-1 range
485 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
486 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
487 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
488 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
489
490 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
491 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
492 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
493 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
494
495 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
496 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
497 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
498 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
499
500 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
501 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
502 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
503 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
504};
505// clang-format on
506
507// static
510
511 RegExpStack* regexp_stack = isolate->regexp_stack();
512 const size_t old_size = regexp_stack->memory_size();
513
514#ifdef DEBUG
515 const Address old_stack_top = regexp_stack->memory_top();
516 const Address old_stack_pointer = regexp_stack->stack_pointer();
517 CHECK_LE(old_stack_pointer, old_stack_top);
518 CHECK_LE(static_cast<size_t>(old_stack_top - old_stack_pointer), old_size);
519#endif // DEBUG
520
521 Address new_stack_base = regexp_stack->EnsureCapacity(old_size * 2);
522 if (new_stack_base == kNullAddress) return kNullAddress;
523
524 return regexp_stack->stack_pointer();
525}
526
527} // namespace internal
528} // namespace v8
Isolate * isolate_
#define SBXCHECK(condition)
Definition check.h:61
int get(uchar c, uchar n, uchar *result)
Definition unicode-inl.h:32
V8_INLINE Address address() const
Definition handles.h:695
static Handle< FixedIntegerArrayBase< T, Base > > New(Isolate *isolate, int length, MoreArgs &&... more_args)
static GeneratedCode FromCode(Isolate *isolate, Tagged< Code > code)
Definition simulator.h:162
static constexpr uint32_t kNoBacktrackLimit
Definition js-regexp.h:133
Handle< ByteArray > GetOrAddRangeArray(const ZoneList< CharacterRange > *ranges)
ZoneUnorderedMap< uint32_t, IndirectHandle< FixedUInt16Array > > range_array_cache_
static int Match(DirectHandle< IrRegExpData > regexp_data, DirectHandle< String > subject, int *offsets_vector, int offsets_vector_length, int previous_index, Isolate *isolate)
virtual void LoadCurrentCharacterUnchecked(int cp_offset, int character_count)=0
static int Execute(Tagged< String > input, int start_offset, const uint8_t *input_start, const uint8_t *input_end, int *output, int output_size, Isolate *isolate, Tagged< IrRegExpData > regexp_data)
void LoadCurrentCharacterImpl(int cp_offset, Label *on_end_of_input, bool check_bounds, int characters, int eats_at_least) override
static int CheckStackGuardState(Isolate *isolate, int start_index, RegExp::CallOrigin call_origin, Address *return_address, Tagged< InstructionStream > re_code, Address *subject, const uint8_t **input_start, const uint8_t **input_end, uintptr_t gap)
static V8_EXPORT_PRIVATE int ExecuteForTesting(Tagged< String > input, int start_offset, const uint8_t *input_start, const uint8_t *input_end, int *output, int output_size, Isolate *isolate, Tagged< JSRegExp > regexp)
static V8_INLINE void ReplacePC(Address *pc_address, Address new_pc, int offset_from_sp)
static V8_INLINE Address AuthenticatePC(Address *pc_address, unsigned offset_from_sp)
void CheckNotInSurrogatePair(int cp_offset, Label *on_failure)
virtual void CheckCharacterInRange(base::uc16 from, base::uc16 to, Label *on_in_range)=0
virtual void LoadCurrentCharacterImpl(int cp_offset, Label *on_end_of_input, bool check_bounds, int characters, int eats_at_least)=0
static int CaseInsensitiveCompareUnicode(Address byte_offset1, Address byte_offset2, size_t byte_length, Isolate *isolate)
virtual void Bind(Label *label)=0
static uint32_t IsCharacterInRangeArray(uint32_t current_char, Address raw_byte_array)
static int CaseInsensitiveCompareNonUnicode(Address byte_offset1, Address byte_offset2, size_t byte_length, Isolate *isolate)
RegExpMacroAssembler(Isolate *isolate, Zone *zone)
virtual void CheckPosition(int cp_offset, Label *on_outside_input)
V8_EXPORT_PRIVATE void LoadCurrentCharacter(int cp_offset, Label *on_end_of_input, bool check_bounds=true, int characters=1, int eats_at_least=kUseCharactersValue)
virtual void CheckCharacterNotInRange(base::uc16 from, base::uc16 to, Label *on_not_in_range)=0
Address memory_top() const
size_t memory_size() const
Address EnsureCapacity(size_t size)
Address stack_pointer() const
static bool IsOneByteRepresentationUnderneath(Tagged< String > string)
Definition string-inl.h:373
static const base::uc32 kMaxCodePoint
Definition string.h:504
V8_INLINE constexpr StorageType ptr() const
Zone * zone_
double second
ZoneVector< RpoNumber > & result
EmitFn fn
int r
Definition mul-fft.cc:298
unsigned int uchar
Definition unicode.h:21
V8_INLINE size_t hash_combine(size_t seed, size_t hash)
Definition hashing.h:77
uint32_t uc32
Definition strings.h:19
constexpr bool IsInRange(T value, U lower_limit, U higher_limit)
Definition bounds.h:20
uint16_t uc16
Definition strings.h:18
static const base::uc32 kTrailSurrogateStart
static constexpr uint32_t kFalse
bool Is(IndirectHandle< U > value)
Definition handles-inl.h:51
constexpr int kMaxUInt16
Definition globals.h:382
static const base::uc32 kTrailSurrogateEnd
static uint32_t Hash(RegisteredExtension *extension)
V8_EXPORT_PRIVATE FlagValues v8_flags
static const base::uc32 kLeadSurrogateStart
static constexpr Address kNullAddress
Definition v8-internal.h:53
static const base::uc32 kLeadSurrogateEnd
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
Definition casting.h:150
Local< T > Handle
static constexpr AcquireLoadTag kAcquireLoad
Definition globals.h:2908
#define DCHECK_LE(v1, v2)
Definition logging.h:490
#define CHECK_LE(lhs, rhs)
#define DCHECK_NOT_NULL(val)
Definition logging.h:492
#define DCHECK_IMPLIES(v1, v2)
Definition logging.h:493
#define DCHECK_GE(v1, v2)
Definition logging.h:488
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_LT(v1, v2)
Definition logging.h:489
#define DCHECK_EQ(v1, v2)
Definition logging.h:485