v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
scanner.h
Go to the documentation of this file.
1// Copyright 2011 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
5#ifndef V8_PARSING_SCANNER_H_
6#define V8_PARSING_SCANNER_H_
7
8// Features shared by parsing and pre-parsing scanners.
9
10#include <algorithm>
11#include <memory>
12#include <optional>
13
14#include "src/base/logging.h"
15#include "src/base/strings.h"
16#include "src/common/globals.h"
20#include "src/parsing/token.h"
23#include "src/strings/unicode.h"
25
26namespace v8::internal {
27
28class AstRawString;
29class AstValueFactory;
30class ExternalOneByteString;
31class ExternalTwoByteString;
32class ParserRecorder;
33class RuntimeCallStats;
34class Zone;
35
36// ---------------------------------------------------------------------
37// Buffered stream of UTF-16 code units, using an internal UTF-16 buffer.
38// A code unit is a 16 bit value representing either a 16 bit code point
39// or one part of a surrogate pair that make a single 21 bit code point.
41 public:
42 static constexpr base::uc32 kEndOfInput = static_cast<base::uc32>(-1);
43
44 virtual ~Utf16CharacterStream() = default;
45
47 // source_pos() returns one previous position of the cursor.
48 // Offset 1 cancels this out and makes it return exactly buffer_end_.
50 has_parser_error_ = true;
51 }
54
55 inline base::uc32 Peek() {
57 return static_cast<base::uc32>(*buffer_cursor_);
58 } else if (ReadBlockChecked(pos())) {
59 return static_cast<base::uc32>(*buffer_cursor_);
60 } else {
61 return kEndOfInput;
62 }
63 }
64
65 // Returns and advances past the next UTF-16 code unit in the input
66 // stream. If there are no more code units it returns kEndOfInput.
70 return result;
71 }
72
73 // Returns and advances past the next UTF-16 code unit in the input stream
74 // that meets the checks requirement. If there are no more code units it
75 // returns kEndOfInput.
76 template <typename FunctionType>
78 while (true) {
79 auto next_cursor_pos =
80 std::find_if(buffer_cursor_, buffer_end_, [&check](uint16_t raw_c0_) {
81 base::uc32 c0_ = static_cast<base::uc32>(raw_c0_);
82 return check(c0_);
83 });
84
85 if (next_cursor_pos == buffer_end_) {
87 if (!ReadBlockChecked(pos())) {
89 return kEndOfInput;
90 }
91 } else {
92 buffer_cursor_ = next_cursor_pos + 1;
93 return static_cast<base::uc32>(*next_cursor_pos);
94 }
95 }
96 }
97
98 // Go back one by one character in the input stream.
99 // This undoes the most recent Advance().
100 inline void Back() {
101 // The common case - if the previous character is within
102 // buffer_start_ .. buffer_end_ will be handles locally.
103 // Otherwise, a new block is requested.
106 } else {
107 ReadBlockChecked(pos() - 1);
108 }
109 }
110
111 inline size_t pos() const {
113 }
114
115 inline void Seek(size_t pos) {
116 if (V8_LIKELY(pos >= buffer_pos_ &&
119 } else {
121 }
122 }
123
124 // Returns true if the stream could access the V8 heap after construction.
126 return can_be_cloned() && !can_access_heap();
127 }
128
129 // Returns true if the stream can be cloned with Clone.
130 // TODO(rmcilroy): Remove this once ChunkedStreams can be cloned.
131 virtual bool can_be_cloned() const = 0;
132
133 // Clones the character stream to enable another independent scanner to access
134 // the same underlying stream.
135 virtual std::unique_ptr<Utf16CharacterStream> Clone() const = 0;
136
137 // Returns true if the stream could access the V8 heap after construction.
138 virtual bool can_access_heap() const = 0;
139
144
145 protected:
146 Utf16CharacterStream(const uint16_t* buffer_start,
147 const uint16_t* buffer_cursor,
148 const uint16_t* buffer_end, size_t buffer_pos)
149 : buffer_start_(buffer_start),
150 buffer_cursor_(buffer_cursor),
151 buffer_end_(buffer_end),
152 buffer_pos_(buffer_pos) {}
153 Utf16CharacterStream() : Utf16CharacterStream(nullptr, nullptr, nullptr, 0) {}
154
156 // The callers of this method (Back/Back2/Seek) should handle the easy
157 // case (seeking within the current buffer), and we should only get here
158 // if we actually require new data.
159 // (This is really an efficiency check, not a correctness invariant.)
162
163 bool success = !has_parser_error() && ReadBlock(position);
164
165 // Post-conditions: 1, We should always be at the right position.
166 // 2, Cursor should be inside the buffer.
167 // 3, We should have more characters available iff success.
172 return success;
173 }
174
175 // Read more data, and update buffer_*_ to point to it.
176 // Returns true if more data was available.
177 //
178 // ReadBlock(position) may modify any of the buffer_*_ members, but must make
179 // sure that the result of pos() becomes |position|.
180 //
181 // Examples:
182 // - a stream could either fill a separate buffer. Then buffer_start_ and
183 // buffer_cursor_ would point to the beginning of the buffer, and
184 // buffer_pos would be the old pos().
185 // - a stream with existing buffer chunks would set buffer_start_ and
186 // buffer_end_ to cover the full chunk, and then buffer_cursor_ would
187 // point into the middle of the buffer, while buffer_pos_ would describe
188 // the start of the buffer.
189 virtual bool ReadBlock(size_t position) = 0;
190
191 // Fields describing the location of the current buffer physically in memory,
192 // and semantically within the source string.
193 //
194 // 0 buffer_pos_ pos()
195 // | | |
196 // v________________________v___v_____________
197 // | | | |
198 // Source string: | | Buffer | |
199 // |________________________|________|________|
200 // ^ ^ ^
201 // | | |
202 // Pointers: buffer_start_ | buffer_end_
203 // buffer_cursor_
204 const uint16_t* buffer_start_;
205 const uint16_t* buffer_cursor_;
206 const uint16_t* buffer_end_;
209 bool has_parser_error_ = false;
210};
211
212// ----------------------------------------------------------------------------
213// JavaScript Scanner.
214
216 public:
217 // Scoped helper for a re-settable bookmark.
219 public:
220 explicit BookmarkScope(Scanner* scanner)
221 : scanner_(scanner),
222 bookmark_(kNoBookmark),
223 had_parser_error_(scanner->has_parser_error()) {
224 DCHECK_NOT_NULL(scanner_);
225 }
226 ~BookmarkScope() = default;
227 BookmarkScope(const BookmarkScope&) = delete;
229
230 void Set(size_t bookmark);
231 void Apply();
232 bool HasBeenSet() const;
233 bool HasBeenApplied() const;
234
235 private:
236 static const size_t kNoBookmark;
237 static const size_t kBookmarkWasApplied;
238
240 size_t bookmark_;
242 };
243
244 // Sets the Scanner into an error state to stop further scanning and terminate
245 // the parsing by only returning kIllegal tokens after that.
247 if (!has_parser_error()) {
248 c0_ = kEndOfInput;
249 source_->set_parser_error();
250 for (TokenDesc& desc : token_storage_) {
251 if (desc.token != Token::kUninitialized) desc.token = Token::kIllegal;
252 }
253 }
254 }
256 source_->reset_parser_error_flag();
257 }
259 return source_->has_parser_error();
260 }
261
262 // Representation of an interval of source positions.
263 struct Location {
264 Location(int b, int e) : beg_pos(b), end_pos(e) { }
265 Location() : beg_pos(0), end_pos(0) { }
266
267 int length() const { return end_pos - beg_pos; }
268 bool IsValid() const { return base::IsInRange(beg_pos, 0, end_pos); }
269
270 static Location invalid() { return Location(-1, 0); }
271
274 };
275
276 // -1 is outside of the range of any real source code.
277 static constexpr base::uc32 kEndOfInput = Utf16CharacterStream::kEndOfInput;
278 static constexpr base::uc32 kInvalidSequence = static_cast<base::uc32>(-1);
279
280 static constexpr base::uc32 Invalid() { return Scanner::kInvalidSequence; }
281 static bool IsInvalid(base::uc32 c);
282
284
285 void Initialize();
286
287 // Returns the next token and advances input.
288 Token::Value Next();
289 // Returns the token following peek()
290 Token::Value PeekAhead();
291 // Returns the token following PeekAhead()
292 Token::Value PeekAheadAhead();
293 // Returns the current token again.
294 Token::Value current_token() const { return current().token; }
295
296 // Returns the location information for the current token
297 // (the token last returned by Next()).
298 const Location& location() const { return current().location; }
299
300 // This error is specifically an invalid hex or unicode escape sequence.
301 bool has_error() const { return scanner_error_ != MessageTemplate::kNone; }
302 MessageTemplate error() const { return scanner_error_; }
303 const Location& error_location() const { return scanner_error_location_; }
304
306 return current().invalid_template_escape_message != MessageTemplate::kNone;
307 }
309 DCHECK(has_invalid_template_escape());
310 return current().invalid_template_escape_message;
311 }
312
314 DCHECK(has_invalid_template_escape());
315 current_->invalid_template_escape_message = MessageTemplate::kNone;
316 }
317
319 DCHECK(has_invalid_template_escape());
320 return current().invalid_template_escape_location;
321 }
322
323 // Similar functions for the upcoming token.
324
325 // One token look-ahead (past the token returned by Next()).
326 Token::Value peek() const { return next().token; }
327
328 const Location& peek_location() const { return next().location; }
329
331 return LiteralContainsEscapes(current());
332 }
333
335 return LiteralContainsEscapes(next());
336 }
337
338 const AstRawString* CurrentSymbol(AstValueFactory* ast_value_factory) const;
339
340 const AstRawString* NextSymbol(AstValueFactory* ast_value_factory) const;
341 const AstRawString* CurrentRawSymbol(
342 AstValueFactory* ast_value_factory) const;
343
344 double DoubleValue();
346 return literal_one_byte_string();
347 }
348
349 const char* CurrentLiteralAsCString(Zone* zone) const;
350
351 inline bool CurrentMatches(Token::Value token) const {
352 DCHECK(Token::IsKeyword(token));
353 return current().token == token;
354 }
355
356 template <size_t N>
357 bool NextLiteralExactlyEquals(const char (&s)[N]) {
358 DCHECK(next().CanAccessLiteral());
359 // The length of the token is used to make sure the literal equals without
360 // taking escape sequences (e.g., "use \x73trict") or line continuations
361 // (e.g., "use \‍(newline) strict") into account.
362 if (!is_next_literal_one_byte()) return false;
363 if (peek_location().length() != N + 1) return false;
364
365 base::Vector<const uint8_t> next = next_literal_one_byte_string();
366 const char* chars = reinterpret_cast<const char*>(next.begin());
367 return next.length() == N - 1 && strncmp(s, chars, N - 1) == 0;
368 }
369
370 template <size_t N>
371 bool CurrentLiteralEquals(const char (&s)[N]) {
372 DCHECK(current().CanAccessLiteral());
373 if (!is_literal_one_byte()) return false;
374
375 base::Vector<const uint8_t> current = literal_one_byte_string();
376 const char* chars = reinterpret_cast<const char*>(current.begin());
377 return current.length() == N - 1 && strncmp(s, chars, N - 1) == 0;
378 }
379
380 // Returns the location of the last seen octal literal.
381 Location octal_position() const { return octal_pos_; }
383 octal_pos_ = Location::invalid();
384 octal_message_ = MessageTemplate::kNone;
385 }
386 MessageTemplate octal_message() const { return octal_message_; }
387
388 // Returns the value of the last smi that was scanned.
389 uint32_t smi_value() const { return current().smi_value; }
390
391 // Seek forward to the given position. This operation does not
392 // work in general, for instance when there are pushed back
393 // characters, but works for seeking forward until simple delimiter
394 // tokens, which is what it is used for.
395 void SeekForward(int pos);
396
397 // Returns true if there was a line terminator before the peek'ed token,
398 // possibly inside a multi-line comment.
400 return next().after_line_terminator;
401 }
402
404 Token::Value ensure_next_next = PeekAhead();
405 USE(ensure_next_next);
406 return next_next().after_line_terminator;
407 }
408
410 Token::Value ensure_next_next_next = PeekAheadAhead();
411 USE(ensure_next_next_next);
412 return next_next_next().after_line_terminator;
413 }
414
415 // Scans the input as a regular expression pattern, next token must be /(=).
416 // Returns true if a pattern is scanned.
417 bool ScanRegExpPattern();
418 // Scans the input as regular expression flags. Returns the flags on success.
419 std::optional<RegExpFlags> ScanRegExpFlags();
420
421 // Scans the input as a template literal
423 DCHECK_EQ(next().token, Token::kRightBrace);
424 DCHECK_EQ(source_pos() - 1, next().location.beg_pos);
425 return ScanTemplateSpan();
426 }
427
428 template <typename IsolateT>
429 DirectHandle<String> SourceUrl(IsolateT* isolate) const;
430 template <typename IsolateT>
431 DirectHandle<String> SourceMappingUrl(IsolateT* isolate) const;
432
434 return saw_source_mapping_url_magic_comment_at_sign_;
435 }
436
438 return saw_magic_comment_compile_hints_all_;
439 }
440
441 bool HasPerFunctionCompileHint(int position);
442
443 bool FoundHtmlComment() const { return found_html_comment_; }
444
445 const Utf16CharacterStream* stream() const { return source_; }
446
447 private:
448 // Scoped helper for saving & restoring scanner error state.
449 // This is used for tagged template literals, in which normally forbidden
450 // escape sequences are allowed.
451 class ErrorState;
452
459 DECIMAL_WITH_LEADING_ZERO
460 };
461
462 // The current and look-ahead tokens.
463 struct TokenDesc {
464 Location location = {0, 0};
467 Token::Value token = Token::kUninitialized;
468 MessageTemplate invalid_template_escape_message = MessageTemplate::kNone;
471 uint32_t smi_value = 0;
472 bool after_line_terminator = false;
473
474#ifdef DEBUG
475 bool CanAccessLiteral() const {
476 return token == Token::kPrivateName || token == Token::kIllegal ||
477 token == Token::kEscapedKeyword ||
478 token == Token::kUninitialized || token == Token::kRegExpLiteral ||
479 base::IsInRange(token, Token::kNumber, Token::kString) ||
480 Token::IsAnyIdentifier(token) || Token::IsKeyword(token) ||
481 base::IsInRange(token, Token::kTemplateSpan, Token::kTemplateTail);
482 }
483 bool CanAccessRawLiteral() const {
484 return token == Token::kIllegal || token == Token::kUninitialized ||
485 base::IsInRange(token, Token::kTemplateSpan, Token::kTemplateTail);
486 }
487#endif // DEBUG
488 };
489
491 return base::IsInRange(kind, BINARY, DECIMAL);
492 }
493
495 return base::IsInRange(kind, DECIMAL, DECIMAL_WITH_LEADING_ZERO);
496 }
497
498 static const int kCharacterLookaheadBufferSize = 1;
499 static const int kMaxAscii = 127;
500
501 // Scans octal escape sequence. Also accepts "\0" decimal escape sequence.
502 template <bool capture_raw>
503 base::uc32 ScanOctalEscape(base::uc32 c, int length);
504
505 // Call this after setting source_ to the input.
506 void Init() {
507 // Set c0_ (one character ahead)
508 static_assert(kCharacterLookaheadBufferSize == 1);
509 Advance();
510
511 current_ = &token_storage_[0];
512 next_ = &token_storage_[1];
513 next_next_ = &token_storage_[2];
514 next_next_next_ = &token_storage_[3];
515
516 found_html_comment_ = false;
517 scanner_error_ = MessageTemplate::kNone;
518 }
519
520 void ReportScannerError(const Location& location, MessageTemplate error) {
521 if (has_error()) return;
522 scanner_error_ = error;
523 scanner_error_location_ = location;
524 }
525
527 if (has_error()) return;
528 scanner_error_ = error;
529 scanner_error_location_ = Location(pos, pos + 1);
530 }
531
532 // Seek to the next_ token at the given position.
533 void SeekNext(size_t position);
534
536 next().literal_chars.AddChar(c);
537 }
538
539 V8_INLINE void AddLiteralChar(char c) { next().literal_chars.AddChar(c); }
540
542 next().raw_literal_chars.AddChar(c);
543 }
544
546 AddLiteralChar(c0_);
547 Advance();
548 }
549
550 // Low-level scanning support.
551 template <bool capture_raw = false>
552 void Advance() {
553 if (capture_raw) {
554 AddRawLiteralChar(c0_);
555 }
556 c0_ = source_->Advance();
557 }
558
559 template <typename FunctionType>
560 V8_INLINE void AdvanceUntil(FunctionType check) {
561 c0_ = source_->AdvanceUntil(check);
562 }
563
567 base::uc32 c1 = source_->Advance();
571 return true;
572 }
573 source_->Back();
574 }
575 return false;
576 }
577
579 DCHECK(IsInvalid(c0_) ||
580 base::IsInRange(c0_, 0u, unibrow::Utf16::kMaxNonSurrogateCharCode));
581 source_->Back();
582 c0_ = ch;
583 }
584
585 base::uc32 Peek() const { return source_->Peek(); }
586
588 Advance();
589 return tok;
590 }
591
593 Token::Value else_) {
594 Advance();
595 if (c0_ == next) {
596 Advance();
597 return then;
598 } else {
599 return else_;
600 }
601 }
602 // Returns the literal string, if any, for the current token (the
603 // token last returned by Next()). The string is 0-terminated.
604 // Literal strings are collected for identifiers, strings, numbers as well
605 // as for template literals. For template literals we also collect the raw
606 // form.
607 // These functions only give the correct result if the literal was scanned
608 // when a LiteralScope object is alive.
609 //
610 // Current usage of these functions is unfortunately a little undisciplined,
611 // and is_literal_one_byte() + is_literal_one_byte_string() is also
612 // requested for tokens that do not have a literal. Hence, we treat any
613 // token as a one-byte literal. E.g. Token::kFunction pretends to have a
614 // literal "function".
616 DCHECK(current().CanAccessLiteral() || Token::IsKeyword(current().token) ||
617 current().token == Token::kEscapedKeyword);
618 return current().literal_chars.one_byte_literal();
619 }
621 DCHECK(current().CanAccessLiteral() || Token::IsKeyword(current().token) ||
622 current().token == Token::kEscapedKeyword);
623 return current().literal_chars.two_byte_literal();
624 }
625 bool is_literal_one_byte() const {
626 DCHECK(current().CanAccessLiteral() || Token::IsKeyword(current().token) ||
627 current().token == Token::kEscapedKeyword);
628 return current().literal_chars.is_one_byte();
629 }
630 // Returns the literal string for the next token (the token that
631 // would be returned if Next() were called).
633 DCHECK(next().CanAccessLiteral());
634 return next().literal_chars.one_byte_literal();
635 }
637 DCHECK(next().CanAccessLiteral());
638 return next().literal_chars.two_byte_literal();
639 }
641 DCHECK(next().CanAccessLiteral());
642 return next().literal_chars.is_one_byte();
643 }
645 DCHECK(current().CanAccessRawLiteral());
646 return current().raw_literal_chars.one_byte_literal();
647 }
649 DCHECK(current().CanAccessRawLiteral());
650 return current().raw_literal_chars.two_byte_literal();
651 }
653 DCHECK(current().CanAccessRawLiteral());
654 return current().raw_literal_chars.is_one_byte();
655 }
656
657 template <bool capture_raw, bool unicode = false>
658 base::uc32 ScanHexNumber(int expected_length);
659 // Scan a number of any length but not bigger than max_value. For example, the
660 // number can be 000000001, so it's very long in characters but its value is
661 // small.
662 template <bool capture_raw>
663 base::uc32 ScanUnlimitedLengthHexNumber(base::uc32 max_value, int beg_pos);
664
665 // Scans a single JavaScript token.
666 V8_INLINE Token::Value ScanSingleToken();
667 V8_INLINE void Scan();
668 // Performance hack: pass through a pre-calculated "next()" value to avoid
669 // having to re-calculate it in Scan. You'd think the compiler would be able
670 // to hoist the next() calculation out of the inlined Scan method, but seems
671 // that pointer aliasing analysis fails show that this is safe.
672 V8_INLINE void Scan(TokenDesc* next_desc);
673
674 V8_INLINE Token::Value SkipWhiteSpace();
675 Token::Value SkipSingleHTMLComment();
676 Token::Value SkipSingleLineComment();
677 Token::Value SkipMagicComment(base::uc32 hash_or_at_sign);
678 void TryToParseMagicComment(base::uc32 hash_or_at_sign);
679 Token::Value SkipMultiLineComment();
680 // Scans a possible HTML comment -- begins with '<!'.
681 Token::Value ScanHtmlComment();
682
683 bool ScanDigitsWithNumericSeparators(bool (*predicate)(base::uc32 ch),
684 bool is_check_first_digit);
685 bool ScanDecimalDigits(bool allow_numeric_separator);
686 // Optimized function to scan decimal number as Smi.
687 bool ScanDecimalAsSmi(uint64_t* value, bool allow_numeric_separator);
688 bool ScanDecimalAsSmiWithNumericSeparators(uint64_t* value);
689 bool ScanHexDigits();
690 bool ScanBinaryDigits();
691 bool ScanSignedInteger();
692 bool ScanOctalDigits();
693 bool ScanImplicitOctalDigits(int start_pos, NumberKind* kind);
694
695 Token::Value ScanNumber(bool seen_period);
696 V8_INLINE Token::Value ScanIdentifierOrKeyword();
697 V8_INLINE Token::Value ScanIdentifierOrKeywordInner();
698 Token::Value ScanIdentifierOrKeywordInnerSlow(bool escaped,
699 bool can_be_keyword);
700
701 Token::Value ScanString();
702 Token::Value ScanPrivateName();
703
704 // Scans an escape-sequence which is part of a string and adds the
705 // decoded character to the current literal. Returns true if a pattern
706 // is scanned.
707 template <bool capture_raw>
708 bool ScanEscape();
709
710 // Decodes a Unicode escape-sequence which is part of an identifier.
711 // If the escape sequence cannot be decoded the result is kBadChar.
712 base::uc32 ScanIdentifierUnicodeEscape();
713 // Helper for the above functions.
714 template <bool capture_raw>
715 base::uc32 ScanUnicodeEscape();
716
717 Token::Value ScanTemplateSpan();
718
719 // Return the current source position.
721 return static_cast<int>(source_->pos()) - kCharacterLookaheadBufferSize;
722 }
723
724 static bool LiteralContainsEscapes(const TokenDesc& token) {
725 Location location = token.location;
726 int source_length = (location.end_pos - location.beg_pos);
727 if (token.token == Token::kString) {
728 // Subtract delimiters.
729 source_length -= 2;
730 }
731 return token.literal_chars.length() != source_length;
732 }
733
734#ifdef DEBUG
735 void SanityCheckTokenDesc(const TokenDesc&) const;
736#endif
737
738 TokenDesc& next() { return *next_; }
739
740 const TokenDesc& current() const { return *current_; }
741 const TokenDesc& next() const { return *next_; }
742 const TokenDesc& next_next() const { return *next_next_; }
743 const TokenDesc& next_next_next() const { return *next_next_next_; }
744
746
747 TokenDesc* current_; // desc for current token (as returned by Next())
748 TokenDesc* next_; // desc for next token (one token look-ahead)
749 TokenDesc* next_next_; // desc for the token after next (after peek())
750 TokenDesc* next_next_next_; // desc for the token after next of next (after
751 // PeekAhead())
752
753 // Input stream. Must be initialized to an Utf16CharacterStream.
755
756 // One Unicode character look-ahead; c0_ < 0 at the end of the input.
758
759 TokenDesc token_storage_[4];
760
761 // Whether this scanner encountered an HTML comment.
763
764 // Values parsed from magic comments.
767 bool saw_source_mapping_url_magic_comment_at_sign_ = false;
768 bool saw_magic_comment_compile_hints_all_ = false;
769 bool saw_non_comment_ = false;
771 size_t per_function_compile_hint_positions_idx_ = 0;
772
773 // Last-seen positions of potentially problematic tokens.
776
779};
780
781} // namespace v8::internal
782
783#endif // V8_PARSING_SCANNER_H_
friend Zone
Definition asm-types.cc:195
Builtins::Kind kind
Definition builtins.cc:40
SourcePosition pos
static const uchar kMaxNonSurrogateCharCode
Definition unicode.h:116
static int CombineSurrogatePair(uchar lead, uchar trail)
Definition unicode.h:113
static bool IsTrailSurrogate(int code)
Definition unicode.h:109
static bool IsLeadSurrogate(int code)
Definition unicode.h:106
int length() const
Definition vector.h:64
constexpr T * begin() const
Definition vector.h:96
BookmarkScope & operator=(const BookmarkScope &)=delete
static const size_t kNoBookmark
Definition scanner.h:236
static const size_t kBookmarkWasApplied
Definition scanner.h:237
BookmarkScope(const BookmarkScope &)=delete
V8_INLINE void AddLiteralCharAdvance()
Definition scanner.h:545
MessageTemplate error() const
Definition scanner.h:302
MessageTemplate octal_message_
Definition scanner.h:775
base::Vector< const uint16_t > literal_two_byte_string() const
Definition scanner.h:620
bool IsValidBigIntKind(NumberKind kind)
Definition scanner.h:490
Token::Value peek() const
Definition scanner.h:326
const TokenDesc & next() const
Definition scanner.h:741
base::Vector< const uint16_t > raw_literal_two_byte_string() const
Definition scanner.h:648
TokenDesc * current_
Definition scanner.h:747
TokenDesc * next_next_next_
Definition scanner.h:750
void clear_invalid_template_escape_message()
Definition scanner.h:313
base::Vector< const uint8_t > BigIntLiteral() const
Definition scanner.h:345
Location invalid_template_escape_location() const
Definition scanner.h:318
static bool LiteralContainsEscapes(const TokenDesc &token)
Definition scanner.h:724
const TokenDesc & next_next() const
Definition scanner.h:742
void PushBack(base::uc32 ch)
Definition scanner.h:578
V8_INLINE void AddLiteralChar(base::uc32 c)
Definition scanner.h:535
bool has_invalid_template_escape() const
Definition scanner.h:305
bool IsDecimalNumberKind(NumberKind kind)
Definition scanner.h:494
bool FoundHtmlComment() const
Definition scanner.h:443
bool SawMagicCommentCompileHintsAll() const
Definition scanner.h:437
const Utf16CharacterStream * stream() const
Definition scanner.h:445
bool next_literal_contains_escapes() const
Definition scanner.h:334
void ReportScannerError(int pos, MessageTemplate error)
Definition scanner.h:526
bool CombineSurrogatePair()
Definition scanner.h:564
uint32_t smi_value() const
Definition scanner.h:389
bool literal_contains_escapes() const
Definition scanner.h:330
base::Vector< const uint8_t > literal_one_byte_string() const
Definition scanner.h:615
bool SawSourceMappingUrlMagicCommentAtSign() const
Definition scanner.h:433
LiteralBuffer source_mapping_url_
Definition scanner.h:766
const Location & location() const
Definition scanner.h:298
Token::Value current_token() const
Definition scanner.h:294
V8_INLINE bool has_parser_error() const
Definition scanner.h:258
Token::Value ScanTemplateContinuation()
Definition scanner.h:422
bool CurrentMatches(Token::Value token) const
Definition scanner.h:351
bool HasLineTerminatorBeforeNext() const
Definition scanner.h:399
base::Vector< const uint8_t > next_literal_one_byte_string() const
Definition scanner.h:632
V8_INLINE void AddLiteralChar(char c)
Definition scanner.h:539
V8_INLINE void AddRawLiteralChar(base::uc32 c)
Definition scanner.h:541
Utf16CharacterStream *const source_
Definition scanner.h:754
TokenDesc * next_
Definition scanner.h:748
bool HasLineTerminatorAfterNextNext()
Definition scanner.h:409
base::Vector< const uint16_t > next_literal_two_byte_string() const
Definition scanner.h:636
base::Vector< const uint8_t > raw_literal_one_byte_string() const
Definition scanner.h:644
V8_INLINE void AdvanceUntil(FunctionType check)
Definition scanner.h:560
bool NextLiteralExactlyEquals(const char(&s)[N])
Definition scanner.h:357
bool is_next_literal_one_byte() const
Definition scanner.h:640
UnoptimizedCompileFlags flags_
Definition scanner.h:745
V8_INLINE void reset_parser_error_flag()
Definition scanner.h:255
bool has_error() const
Definition scanner.h:301
V8_INLINE void set_parser_error()
Definition scanner.h:246
LiteralBuffer source_url_
Definition scanner.h:765
bool CurrentLiteralEquals(const char(&s)[N])
Definition scanner.h:371
TokenDesc & next()
Definition scanner.h:738
base::uc32 Peek() const
Definition scanner.h:585
MessageTemplate scanner_error_
Definition scanner.h:777
bool is_raw_literal_one_byte() const
Definition scanner.h:652
MessageTemplate octal_message() const
Definition scanner.h:386
Token::Value Select(base::uc32 next, Token::Value then, Token::Value else_)
Definition scanner.h:592
const TokenDesc & next_next_next() const
Definition scanner.h:743
std::vector< int > per_function_compile_hint_positions_
Definition scanner.h:770
const Location & error_location() const
Definition scanner.h:303
void clear_octal_position()
Definition scanner.h:382
Location scanner_error_location_
Definition scanner.h:778
const Location & peek_location() const
Definition scanner.h:328
MessageTemplate invalid_template_escape_message() const
Definition scanner.h:308
bool is_literal_one_byte() const
Definition scanner.h:625
TokenDesc * next_next_
Definition scanner.h:749
static constexpr base::uc32 Invalid()
Definition scanner.h:280
Location octal_position() const
Definition scanner.h:381
bool HasLineTerminatorAfterNext()
Definition scanner.h:403
Token::Value Select(Token::Value tok)
Definition scanner.h:587
void ReportScannerError(const Location &location, MessageTemplate error)
Definition scanner.h:520
const TokenDesc & current() const
Definition scanner.h:740
bool can_be_cloned_for_parallel_access() const
Definition scanner.h:125
RuntimeCallStats * runtime_call_stats_
Definition scanner.h:208
V8_INLINE bool has_parser_error() const
Definition scanner.h:53
V8_INLINE void set_parser_error()
Definition scanner.h:46
virtual ~Utf16CharacterStream()=default
V8_INLINE void reset_parser_error_flag()
Definition scanner.h:52
RuntimeCallStats * runtime_call_stats() const
Definition scanner.h:140
Utf16CharacterStream(const uint16_t *buffer_start, const uint16_t *buffer_cursor, const uint16_t *buffer_end, size_t buffer_pos)
Definition scanner.h:146
void set_runtime_call_stats(RuntimeCallStats *runtime_call_stats)
Definition scanner.h:141
virtual bool can_be_cloned() const =0
bool ReadBlockChecked(size_t position)
Definition scanner.h:155
static constexpr base::uc32 kEndOfInput
Definition scanner.h:42
const uint16_t * buffer_cursor_
Definition scanner.h:205
virtual bool ReadBlock(size_t position)=0
virtual bool can_access_heap() const =0
V8_INLINE base::uc32 AdvanceUntil(FunctionType check)
Definition scanner.h:77
virtual std::unique_ptr< Utf16CharacterStream > Clone() const =0
Handle< String > source_
Definition compiler.cc:3791
LineAndColumn current
ZoneVector< RpoNumber > & result
int position
Definition liveedit.cc:290
uint32_t uc32
Definition strings.h:19
bool(* FunctionType)(const Operation &op, Zone *zone)
Definition use-map.h:12
constexpr int N
base::uc32 current_
#define DCHECK_LE(v1, v2)
Definition logging.h:490
#define DCHECK_NOT_NULL(val)
Definition logging.h:492
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_EQ(v1, v2)
Definition logging.h:485
#define USE(...)
Definition macros.h:293
#define V8_EXPORT_PRIVATE
Definition macros.h:460
static Location invalid()
Definition scanner.h:270
#define V8_INLINE
Definition v8config.h:500
#define V8_LIKELY(condition)
Definition v8config.h:661
#define V8_NODISCARD
Definition v8config.h:693