Commit 378375d2 authored by Toon Verwaest's avatar Toon Verwaest Committed by Commit Bot

[scanner] Templatize scan functions by encoding

This way we can avoid reencoding everything to utf16 (buffered) and avoid the
overhead of needing to check the encoding for each character individually.

This may result in a minor asm.js scanning regression due to one-byte tokens
possibly being more common.

Change-Id: I90b51c256d56d4f4fa2d235d7e1e58fc01e43f31
Reviewed-on: https://chromium-review.googlesource.com/1172437
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55217}
parent 28300e33
...@@ -20,7 +20,11 @@ namespace { ...@@ -20,7 +20,11 @@ namespace {
static const int kMaxIdentifierCount = 0xF000000; static const int kMaxIdentifierCount = 0xF000000;
}; };
AsmJsScanner::AsmJsScanner(CharacterStream<uint16_t>* stream, int start) #define SPECIALIZE(Call, ...) \
(stream_->is_two_byte() ? Call<uint16_t>(__VA_ARGS__) \
: Call<uint8_t>(__VA_ARGS__))
AsmJsScanner::AsmJsScanner(ScannerStream* stream, int start)
: stream_(stream), : stream_(stream),
token_(kUninitialized), token_(kUninitialized),
preceding_token_(kUninitialized), preceding_token_(kUninitialized),
...@@ -34,7 +38,7 @@ AsmJsScanner::AsmJsScanner(CharacterStream<uint16_t>* stream, int start) ...@@ -34,7 +38,7 @@ AsmJsScanner::AsmJsScanner(CharacterStream<uint16_t>* stream, int start)
double_value_(0.0), double_value_(0.0),
unsigned_value_(0), unsigned_value_(0),
preceded_by_newline_(false) { preceded_by_newline_(false) {
stream->Seek(start); SPECIALIZE(DoSeek, start);
#define V(name, _junk1, _junk2, _junk3) property_names_[#name] = kToken_##name; #define V(name, _junk1, _junk2, _junk3) property_names_[#name] = kToken_##name;
STDLIB_MATH_FUNCTION_LIST(V) STDLIB_MATH_FUNCTION_LIST(V)
STDLIB_ARRAY_TYPE_LIST(V) STDLIB_ARRAY_TYPE_LIST(V)
...@@ -51,7 +55,10 @@ AsmJsScanner::AsmJsScanner(CharacterStream<uint16_t>* stream, int start) ...@@ -51,7 +55,10 @@ AsmJsScanner::AsmJsScanner(CharacterStream<uint16_t>* stream, int start)
Next(); Next();
} }
void AsmJsScanner::Next() { void AsmJsScanner::Next() { SPECIALIZE(Scan); }
template <typename Char>
void AsmJsScanner::Scan() {
if (rewind_) { if (rewind_) {
preceding_token_ = token_; preceding_token_ = token_;
preceding_position_ = position_; preceding_position_ = position_;
...@@ -85,8 +92,8 @@ void AsmJsScanner::Next() { ...@@ -85,8 +92,8 @@ void AsmJsScanner::Next() {
preceding_position_ = position_; preceding_position_ = position_;
for (;;) { for (;;) {
position_ = stream_->pos(); position_ = Source<Char>()->pos();
uc32 ch = stream_->Advance(); uc32 ch = Advance<Char>();
switch (ch) { switch (ch) {
case ' ': case ' ':
case '\t': case '\t':
...@@ -106,20 +113,20 @@ void AsmJsScanner::Next() { ...@@ -106,20 +113,20 @@ void AsmJsScanner::Next() {
case '\'': case '\'':
case '"': case '"':
ConsumeString(ch); ConsumeString<Char>(ch);
return; return;
case '/': case '/':
ch = stream_->Advance(); ch = Advance<Char>();
if (ch == '/') { if (ch == '/') {
ConsumeCPPComment(); ConsumeCPPComment<Char>();
} else if (ch == '*') { } else if (ch == '*') {
if (!ConsumeCComment()) { if (!ConsumeCComment<Char>()) {
token_ = kParseError; token_ = kParseError;
return; return;
} }
} else { } else {
stream_->Back(); Back<Char>();
token_ = '/'; token_ = '/';
return; return;
} }
...@@ -131,7 +138,7 @@ void AsmJsScanner::Next() { ...@@ -131,7 +138,7 @@ void AsmJsScanner::Next() {
case '>': case '>':
case '=': case '=':
case '!': case '!':
ConsumeCompareOrShift(ch); ConsumeCompareOrShift<Char>(ch);
return; return;
#define V(single_char_token) case single_char_token: #define V(single_char_token) case single_char_token:
...@@ -143,9 +150,9 @@ void AsmJsScanner::Next() { ...@@ -143,9 +150,9 @@ void AsmJsScanner::Next() {
default: default:
if (IsIdentifierStart(ch)) { if (IsIdentifierStart(ch)) {
ConsumeIdentifier(ch); ConsumeIdentifier<Char>(ch);
} else if (IsNumberStart(ch)) { } else if (IsNumberStart(ch)) {
ConsumeNumber(ch); ConsumeNumber<Char>(ch);
} else { } else {
// TODO(bradnelson): Support unicode (probably via UnicodeCache). // TODO(bradnelson): Support unicode (probably via UnicodeCache).
token_ = kParseError; token_ = kParseError;
...@@ -213,7 +220,7 @@ std::string AsmJsScanner::Name(token_t token) const { ...@@ -213,7 +220,7 @@ std::string AsmJsScanner::Name(token_t token) const {
#endif #endif
void AsmJsScanner::Seek(size_t pos) { void AsmJsScanner::Seek(size_t pos) {
stream_->Seek(pos); SPECIALIZE(DoSeek, pos);
preceding_token_ = kUninitialized; preceding_token_ = kUninitialized;
token_ = kUninitialized; token_ = kUninitialized;
next_token_ = kUninitialized; next_token_ = kUninitialized;
...@@ -224,15 +231,16 @@ void AsmJsScanner::Seek(size_t pos) { ...@@ -224,15 +231,16 @@ void AsmJsScanner::Seek(size_t pos) {
Next(); Next();
} }
template <typename Char>
void AsmJsScanner::ConsumeIdentifier(uc32 ch) { void AsmJsScanner::ConsumeIdentifier(uc32 ch) {
// Consume characters while still part of the identifier. // Consume characters while still part of the identifier.
identifier_string_.clear(); identifier_string_.clear();
while (IsIdentifierPart(ch)) { while (IsIdentifierPart(ch)) {
identifier_string_ += ch; identifier_string_ += ch;
ch = stream_->Advance(); ch = Advance<Char>();
} }
// Go back one for next time. // Go back one for next time.
stream_->Back(); Back<Char>();
// Decode what the identifier means. // Decode what the identifier means.
if (preceding_token_ == '.') { if (preceding_token_ == '.') {
...@@ -272,13 +280,14 @@ void AsmJsScanner::ConsumeIdentifier(uc32 ch) { ...@@ -272,13 +280,14 @@ void AsmJsScanner::ConsumeIdentifier(uc32 ch) {
} }
} }
template <typename Char>
void AsmJsScanner::ConsumeNumber(uc32 ch) { void AsmJsScanner::ConsumeNumber(uc32 ch) {
std::string number; std::string number;
number = ch; number = ch;
bool has_dot = ch == '.'; bool has_dot = ch == '.';
bool has_prefix = false; bool has_prefix = false;
for (;;) { for (;;) {
ch = stream_->Advance(); ch = Advance<Char>();
if ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || if ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') ||
(ch >= 'A' && ch <= 'F') || ch == '.' || ch == 'b' || ch == 'o' || (ch >= 'A' && ch <= 'F') || ch == '.' || ch == 'b' || ch == 'o' ||
ch == 'x' || ch == 'x' ||
...@@ -297,7 +306,7 @@ void AsmJsScanner::ConsumeNumber(uc32 ch) { ...@@ -297,7 +306,7 @@ void AsmJsScanner::ConsumeNumber(uc32 ch) {
break; break;
} }
} }
stream_->Back(); Back<Char>();
// Special case the most common number. // Special case the most common number.
if (number.size() == 1 && number[0] == '0') { if (number.size() == 1 && number[0] == '0') {
unsigned_value_ = 0; unsigned_value_ = 0;
...@@ -324,7 +333,7 @@ void AsmJsScanner::ConsumeNumber(uc32 ch) { ...@@ -324,7 +333,7 @@ void AsmJsScanner::ConsumeNumber(uc32 ch) {
// problem. // problem.
if (number[0] == '.') { if (number[0] == '.') {
for (size_t k = 1; k < number.size(); ++k) { for (size_t k = 1; k < number.size(); ++k) {
stream_->Back(); Back<Char>();
} }
token_ = '.'; token_ = '.';
return; return;
...@@ -346,11 +355,12 @@ void AsmJsScanner::ConsumeNumber(uc32 ch) { ...@@ -346,11 +355,12 @@ void AsmJsScanner::ConsumeNumber(uc32 ch) {
} }
} }
template <typename Char>
bool AsmJsScanner::ConsumeCComment() { bool AsmJsScanner::ConsumeCComment() {
for (;;) { for (;;) {
uc32 ch = stream_->Advance(); uc32 ch = Advance<Char>();
while (ch == '*') { while (ch == '*') {
ch = stream_->Advance(); ch = Advance<Char>();
if (ch == '/') { if (ch == '/') {
return true; return true;
} }
...@@ -361,33 +371,36 @@ bool AsmJsScanner::ConsumeCComment() { ...@@ -361,33 +371,36 @@ bool AsmJsScanner::ConsumeCComment() {
} }
} }
template <typename Char>
void AsmJsScanner::ConsumeCPPComment() { void AsmJsScanner::ConsumeCPPComment() {
for (;;) { for (;;) {
uc32 ch = stream_->Advance(); uc32 ch = Advance<Char>();
if (ch == '\n' || ch == kEndOfInput) { if (ch == '\n' || ch == kEndOfInput) {
return; return;
} }
} }
} }
template <typename Char>
void AsmJsScanner::ConsumeString(uc32 quote) { void AsmJsScanner::ConsumeString(uc32 quote) {
// Only string allowed is 'use asm' / "use asm". // Only string allowed is 'use asm' / "use asm".
const char* expected = "use asm"; const char* expected = "use asm";
for (; *expected != '\0'; ++expected) { for (; *expected != '\0'; ++expected) {
if (stream_->Advance() != *expected) { if (Advance<Char>() != *expected) {
token_ = kParseError; token_ = kParseError;
return; return;
} }
} }
if (stream_->Advance() != quote) { if (Advance<Char>() != quote) {
token_ = kParseError; token_ = kParseError;
return; return;
} }
token_ = kToken_UseAsm; token_ = kToken_UseAsm;
} }
template <typename Char>
void AsmJsScanner::ConsumeCompareOrShift(uc32 ch) { void AsmJsScanner::ConsumeCompareOrShift(uc32 ch) {
uc32 next_ch = stream_->Advance(); uc32 next_ch = Advance<Char>();
if (next_ch == '=') { if (next_ch == '=') {
switch (ch) { switch (ch) {
case '<': case '<':
...@@ -408,14 +421,14 @@ void AsmJsScanner::ConsumeCompareOrShift(uc32 ch) { ...@@ -408,14 +421,14 @@ void AsmJsScanner::ConsumeCompareOrShift(uc32 ch) {
} else if (ch == '<' && next_ch == '<') { } else if (ch == '<' && next_ch == '<') {
token_ = kToken_SHL; token_ = kToken_SHL;
} else if (ch == '>' && next_ch == '>') { } else if (ch == '>' && next_ch == '>') {
if (stream_->Advance() == '>') { if (Advance<Char>() == '>') {
token_ = kToken_SHR; token_ = kToken_SHR;
} else { } else {
token_ = kToken_SAR; token_ = kToken_SAR;
stream_->Back(); Back<Char>();
} }
} else { } else {
stream_->Back(); Back<Char>();
token_ = ch; token_ = ch;
} }
} }
...@@ -430,5 +443,7 @@ bool AsmJsScanner::IsNumberStart(uc32 ch) { ...@@ -430,5 +443,7 @@ bool AsmJsScanner::IsNumberStart(uc32 ch) {
return ch == '.' || IsDecimalDigit(ch); return ch == '.' || IsDecimalDigit(ch);
} }
#undef SPECIALIZE
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
class ScannerStream;
template <typename Char> template <typename Char>
class CharacterStream; class CharacterStream;
...@@ -32,7 +33,7 @@ class V8_EXPORT_PRIVATE AsmJsScanner { ...@@ -32,7 +33,7 @@ class V8_EXPORT_PRIVATE AsmJsScanner {
public: public:
typedef int32_t token_t; typedef int32_t token_t;
AsmJsScanner(CharacterStream<uint16_t>* stream, int start); AsmJsScanner(ScannerStream* stream, int start);
// Get current token. // Get current token.
token_t Token() const { return token_; } token_t Token() const { return token_; }
...@@ -137,7 +138,7 @@ class V8_EXPORT_PRIVATE AsmJsScanner { ...@@ -137,7 +138,7 @@ class V8_EXPORT_PRIVATE AsmJsScanner {
// clang-format on // clang-format on
private: private:
CharacterStream<uint16_t>* stream_; ScannerStream* const stream_;
token_t token_; token_t token_;
token_t preceding_token_; token_t preceding_token_;
token_t next_token_; // Only set when in {rewind} state. token_t next_token_; // Only set when in {rewind} state.
...@@ -155,12 +156,37 @@ class V8_EXPORT_PRIVATE AsmJsScanner { ...@@ -155,12 +156,37 @@ class V8_EXPORT_PRIVATE AsmJsScanner {
uint32_t unsigned_value_; uint32_t unsigned_value_;
bool preceded_by_newline_; bool preceded_by_newline_;
template <typename Char>
void Scan();
template <typename Char>
inline CharacterStream<Char>* Source() {
return static_cast<CharacterStream<Char>*>(stream_);
}
template <typename Char>
inline uc32 Advance() {
return Source<Char>()->Advance();
}
template <typename Char>
inline void Back() {
return Source<Char>()->Back();
}
template <typename Char>
void DoSeek(size_t pos) {
Source<Char>()->Seek(pos);
}
// Consume multiple characters. // Consume multiple characters.
template <typename Char>
void ConsumeIdentifier(uc32 ch); void ConsumeIdentifier(uc32 ch);
template <typename Char>
void ConsumeNumber(uc32 ch); void ConsumeNumber(uc32 ch);
template <typename Char>
bool ConsumeCComment(); bool ConsumeCComment();
template <typename Char>
void ConsumeCPPComment(); void ConsumeCPPComment();
template <typename Char>
void ConsumeString(uc32 quote); void ConsumeString(uc32 quote);
template <typename Char>
void ConsumeCompareOrShift(uc32 ch); void ConsumeCompareOrShift(uc32 ch);
// Classify character categories. // Classify character categories.
......
...@@ -412,7 +412,8 @@ Parser::Parser(ParseInfo* info) ...@@ -412,7 +412,8 @@ Parser::Parser(ParseInfo* info)
info->runtime_call_stats(), info->logger(), info->runtime_call_stats(), info->logger(),
info->script().is_null() ? -1 : info->script()->id(), info->script().is_null() ? -1 : info->script()->id(),
info->is_module(), true), info->is_module(), true),
scanner_(info->unicode_cache()), scanner_(info->unicode_cache(), info->character_stream(),
info->is_module()),
reusable_preparser_(nullptr), reusable_preparser_(nullptr),
mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly.
source_range_map_(info->source_range_map()), source_range_map_(info->source_range_map()),
...@@ -507,9 +508,8 @@ FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) { ...@@ -507,9 +508,8 @@ FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) {
// Initialize parser state. // Initialize parser state.
DeserializeScopeChain(isolate, info, info->maybe_outer_scope_info()); DeserializeScopeChain(isolate, info, info->maybe_outer_scope_info());
auto stream = scanner_.Initialize();
static_cast<CharacterStream<uint16_t>*>(info->character_stream());
scanner_.Initialize(stream, info->is_module());
FunctionLiteral* result = DoParseProgram(isolate, info); FunctionLiteral* result = DoParseProgram(isolate, info);
MaybeResetCharacterStream(info, result); MaybeResetCharacterStream(info, result);
...@@ -703,9 +703,8 @@ FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info, ...@@ -703,9 +703,8 @@ FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info,
// Initialize parser state. // Initialize parser state.
Handle<String> name(shared_info->Name(), isolate); Handle<String> name(shared_info->Name(), isolate);
info->set_function_name(ast_value_factory()->GetString(name)); info->set_function_name(ast_value_factory()->GetString(name));
auto stream =
static_cast<CharacterStream<uint16_t>*>(info->character_stream()); scanner_.Initialize();
scanner_.Initialize(stream, info->is_module());
FunctionLiteral* result = FunctionLiteral* result =
DoParseFunction(isolate, info, info->function_name()); DoParseFunction(isolate, info, info->function_name());
...@@ -3451,9 +3450,8 @@ void Parser::ParseOnBackground(ParseInfo* info) { ...@@ -3451,9 +3450,8 @@ void Parser::ParseOnBackground(ParseInfo* info) {
DCHECK_NULL(info->literal()); DCHECK_NULL(info->literal());
FunctionLiteral* result = nullptr; FunctionLiteral* result = nullptr;
auto stream = scanner_.Initialize();
static_cast<CharacterStream<uint16_t>*>(info->character_stream());
scanner_.Initialize(stream, info->is_module());
DCHECK(info->maybe_outer_scope_info().is_null()); DCHECK(info->maybe_outer_scope_info().is_null());
DCHECK(original_scope_); DCHECK(original_scope_);
......
...@@ -250,82 +250,45 @@ class Utf8ChunkedStream : public ChunkedStream<uint16_t> { ...@@ -250,82 +250,45 @@ class Utf8ChunkedStream : public ChunkedStream<uint16_t> {
bool seen_bom_ = false; bool seen_bom_ = false;
}; };
// Provides a buffered utf-16 view on the bytes from the underlying ByteStream.
// Chars are buffered if either the underlying stream isn't utf-16 or the
// underlying utf-16 stream might move (is on-heap).
template <template <typename T> class ByteStream>
class BufferedCharacterStream : public CharacterStream<uint16_t> {
public:
template <class... TArgs>
BufferedCharacterStream(size_t pos, TArgs... args) : byte_stream_(args...) {
buffer_pos_ = pos;
}
protected:
bool ReadBlock() final {
size_t position = pos();
buffer_pos_ = position;
buffer_start_ = &buffer_[0];
buffer_cursor_ = buffer_start_;
Range<uint8_t> range = byte_stream_.GetDataAt(position);
if (range.length() == 0) {
buffer_end_ = buffer_start_;
return false;
}
size_t length = Min(kBufferSize, range.length());
i::CopyCharsUnsigned(buffer_, range.start, length);
buffer_end_ = &buffer_[length];
return true;
}
bool can_access_heap() final { return ByteStream<uint8_t>::kCanAccessHeap; }
private:
static const size_t kBufferSize = 512;
uc16 buffer_[kBufferSize];
ByteStream<uint8_t> byte_stream_;
};
// Provides a unbuffered utf-16 view on the bytes from the underlying // Provides a unbuffered utf-16 view on the bytes from the underlying
// ByteStream. // ByteStream.
template <template <typename T> class ByteStream> template <typename Char, template <typename T> class ByteStream>
class UnbufferedCharacterStream : public CharacterStream<uint16_t> { class UnbufferedCharacterStream : public CharacterStream<Char> {
public: public:
template <class... TArgs> template <class... TArgs>
UnbufferedCharacterStream(size_t pos, TArgs... args) : byte_stream_(args...) { UnbufferedCharacterStream(size_t pos, TArgs... args) : byte_stream_(args...) {
buffer_pos_ = pos; this->buffer_pos_ = pos;
} }
protected: protected:
bool ReadBlock() final { bool ReadBlock() final {
size_t position = pos(); size_t position = this->pos();
buffer_pos_ = position; this->buffer_pos_ = position;
Range<uint16_t> range = byte_stream_.GetDataAt(position); Range<Char> range = this->byte_stream_.GetDataAt(position);
buffer_start_ = range.start; this->buffer_start_ = range.start;
buffer_end_ = range.end; this->buffer_end_ = range.end;
buffer_cursor_ = buffer_start_; this->buffer_cursor_ = range.start;
if (range.length() == 0) return false; if (range.length() == 0) return false;
DCHECK(!range.unaligned_start()); DCHECK(!range.unaligned_start());
DCHECK_LE(buffer_start_, buffer_end_); DCHECK_LE(this->buffer_start_, this->buffer_end_);
return true; return true;
} }
bool can_access_heap() final { return ByteStream<uint16_t>::kCanAccessHeap; } bool can_access_heap() final { return ByteStream<Char>::kCanAccessHeap; }
ByteStream<uint16_t> byte_stream_; ByteStream<Char> byte_stream_;
}; };
// Provides a unbuffered utf-16 view on the bytes from the underlying // Provides a unbuffered utf-16 view on the bytes from the underlying
// ByteStream. // ByteStream.
template <typename Char>
class RelocatingCharacterStream class RelocatingCharacterStream
: public UnbufferedCharacterStream<OnHeapStream> { : public UnbufferedCharacterStream<Char, OnHeapStream> {
public: public:
template <class... TArgs> template <class... TArgs>
RelocatingCharacterStream(Isolate* isolate, size_t pos, TArgs... args) RelocatingCharacterStream(Isolate* isolate, size_t pos, TArgs... args)
: UnbufferedCharacterStream<OnHeapStream>(pos, args...), : UnbufferedCharacterStream<Char, OnHeapStream>(pos, args...),
isolate_(isolate) { isolate_(isolate) {
isolate->heap()->AddGCEpilogueCallback(UpdateBufferPointersCallback, isolate->heap()->AddGCEpilogueCallback(UpdateBufferPointersCallback,
v8::kGCTypeAll, this); v8::kGCTypeAll, this);
...@@ -341,16 +304,17 @@ class RelocatingCharacterStream ...@@ -341,16 +304,17 @@ class RelocatingCharacterStream
v8::GCType type, v8::GCType type,
v8::GCCallbackFlags flags, v8::GCCallbackFlags flags,
void* stream) { void* stream) {
reinterpret_cast<RelocatingCharacterStream*>(stream) reinterpret_cast<RelocatingCharacterStream<Char>*>(stream)
->UpdateBufferPointers(); ->UpdateBufferPointers();
} }
void UpdateBufferPointers() { void UpdateBufferPointers() {
Range<uint16_t> range = byte_stream_.GetDataAt(0); Range<Char> range = this->byte_stream_.GetDataAt(0);
if (range.start != buffer_start_) { if (range.start != this->buffer_start_) {
buffer_cursor_ = (buffer_cursor_ - buffer_start_) + range.start; this->buffer_cursor_ =
buffer_start_ = range.start; (this->buffer_cursor_ - this->buffer_start_) + range.start;
buffer_end_ = range.end; this->buffer_start_ = range.start;
this->buffer_end_ = range.end;
} }
} }
...@@ -360,6 +324,21 @@ class RelocatingCharacterStream ...@@ -360,6 +324,21 @@ class RelocatingCharacterStream
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// ScannerStream: Create stream instances. // ScannerStream: Create stream instances.
#define SPECIALIZE(Call, ...) \
(is_two_byte_ \
? static_cast<CharacterStream<uint16_t>*>(this)->Call(__VA_ARGS__) \
: static_cast<CharacterStream<uint8_t>*>(this)->Call(__VA_ARGS__))
uc32 ScannerStream::Advance() { return SPECIALIZE(Advance); }
void ScannerStream::Seek(size_t pos) { SPECIALIZE(Seek, pos); }
size_t ScannerStream::pos() { return SPECIALIZE(pos); }
void ScannerStream::Back() { SPECIALIZE(Back); }
#undef SPECIALIZE
ScannerStream* ScannerStream::For(Isolate* isolate, Handle<String> data) { ScannerStream* ScannerStream::For(Isolate* isolate, Handle<String> data) {
return ScannerStream::For(isolate, data, 0, data->length()); return ScannerStream::For(isolate, data, 0, data->length());
} }
...@@ -380,21 +359,22 @@ ScannerStream* ScannerStream::For(Isolate* isolate, Handle<String> data, ...@@ -380,21 +359,22 @@ ScannerStream* ScannerStream::For(Isolate* isolate, Handle<String> data,
data = String::Flatten(isolate, data); data = String::Flatten(isolate, data);
} }
if (data->IsExternalOneByteString()) { if (data->IsExternalOneByteString()) {
return new BufferedCharacterStream<ExternalStringStream>( return new UnbufferedCharacterStream<uint8_t, ExternalStringStream>(
static_cast<size_t>(start_pos), static_cast<size_t>(start_pos),
ExternalOneByteString::cast(*data)->GetChars() + start_offset, ExternalOneByteString::cast(*data)->GetChars() + start_offset,
static_cast<size_t>(end_pos)); static_cast<size_t>(end_pos));
} else if (data->IsExternalTwoByteString()) { } else if (data->IsExternalTwoByteString()) {
return new UnbufferedCharacterStream<ExternalStringStream>( return new UnbufferedCharacterStream<uint16_t, ExternalStringStream>(
static_cast<size_t>(start_pos), static_cast<size_t>(start_pos),
ExternalTwoByteString::cast(*data)->GetChars() + start_offset, ExternalTwoByteString::cast(*data)->GetChars() + start_offset,
static_cast<size_t>(end_pos)); static_cast<size_t>(end_pos));
} else if (data->IsSeqOneByteString()) { } else if (data->IsSeqOneByteString()) {
return new BufferedCharacterStream<OnHeapStream>( return new RelocatingCharacterStream<uint8_t>(
static_cast<size_t>(start_pos), Handle<SeqOneByteString>::cast(data), isolate, static_cast<size_t>(start_pos),
start_offset, static_cast<size_t>(end_pos)); Handle<SeqOneByteString>::cast(data), start_offset,
static_cast<size_t>(end_pos));
} else if (data->IsSeqTwoByteString()) { } else if (data->IsSeqTwoByteString()) {
return new RelocatingCharacterStream( return new RelocatingCharacterStream<uint16_t>(
isolate, static_cast<size_t>(start_pos), isolate, static_cast<size_t>(start_pos),
Handle<SeqTwoByteString>::cast(data), start_offset, Handle<SeqTwoByteString>::cast(data), start_offset,
static_cast<size_t>(end_pos)); static_cast<size_t>(end_pos));
...@@ -403,15 +383,15 @@ ScannerStream* ScannerStream::For(Isolate* isolate, Handle<String> data, ...@@ -403,15 +383,15 @@ ScannerStream* ScannerStream::For(Isolate* isolate, Handle<String> data,
} }
} }
std::unique_ptr<CharacterStream<uint16_t>> ScannerStream::ForTesting( std::unique_ptr<CharacterStream<uint8_t>> ScannerStream::ForTesting(
const char* data) { const char* data) {
return ScannerStream::ForTesting(data, strlen(data)); return ScannerStream::ForTesting(data, strlen(data));
} }
std::unique_ptr<CharacterStream<uint16_t>> ScannerStream::ForTesting( std::unique_ptr<CharacterStream<uint8_t>> ScannerStream::ForTesting(
const char* data, size_t length) { const char* data, size_t length) {
return std::unique_ptr<CharacterStream<uint16_t>>( return std::unique_ptr<CharacterStream<uint8_t>>(
new BufferedCharacterStream<ExternalStringStream>( new UnbufferedCharacterStream<uint8_t, ExternalStringStream>(
static_cast<size_t>(0), reinterpret_cast<const uint8_t*>(data), static_cast<size_t>(0), reinterpret_cast<const uint8_t*>(data),
static_cast<size_t>(length))); static_cast<size_t>(length)));
} }
...@@ -422,13 +402,13 @@ ScannerStream* ScannerStream::For( ...@@ -422,13 +402,13 @@ ScannerStream* ScannerStream::For(
RuntimeCallStats* stats) { RuntimeCallStats* stats) {
switch (encoding) { switch (encoding) {
case v8::ScriptCompiler::StreamedSource::TWO_BYTE: case v8::ScriptCompiler::StreamedSource::TWO_BYTE:
return new UnbufferedCharacterStream<ChunkedStream>( return new UnbufferedCharacterStream<uint16_t, ChunkedStream>(
static_cast<size_t>(0), source_stream, stats); static_cast<size_t>(0), source_stream, stats);
case v8::ScriptCompiler::StreamedSource::ONE_BYTE: case v8::ScriptCompiler::StreamedSource::ONE_BYTE:
return new BufferedCharacterStream<ChunkedStream>(static_cast<size_t>(0), return new UnbufferedCharacterStream<uint8_t, ChunkedStream>(
source_stream, stats); static_cast<size_t>(0), source_stream, stats);
case v8::ScriptCompiler::StreamedSource::UTF8: case v8::ScriptCompiler::StreamedSource::UTF8:
return new UnbufferedCharacterStream<Utf8ChunkedStream>( return new UnbufferedCharacterStream<uint16_t, Utf8ChunkedStream>(
static_cast<size_t>(0), source_stream, stats); static_cast<size_t>(0), source_stream, stats);
} }
UNREACHABLE(); UNREACHABLE();
......
...@@ -32,19 +32,27 @@ class V8_EXPORT_PRIVATE ScannerStream { ...@@ -32,19 +32,27 @@ class V8_EXPORT_PRIVATE ScannerStream {
RuntimeCallStats* stats); RuntimeCallStats* stats);
// For testing: // For testing:
static std::unique_ptr<CharacterStream<uint16_t>> ForTesting( static std::unique_ptr<CharacterStream<uint8_t>> ForTesting(const char* data);
const char* data); static std::unique_ptr<CharacterStream<uint8_t>> ForTesting(const char* data,
static std::unique_ptr<CharacterStream<uint16_t>> ForTesting(const char* data, size_t length);
size_t length);
// Returns true if the stream could access the V8 heap after construction. // Returns true if the stream could access the V8 heap after construction.
virtual bool can_access_heap() = 0; virtual bool can_access_heap() = 0;
virtual uc32 Advance() = 0; uc32 Advance();
virtual void Seek(size_t pos) = 0; void Seek(size_t pos);
virtual size_t pos() const = 0; size_t pos();
virtual void Back() = 0; void Back();
void Back2();
virtual ~ScannerStream() {} virtual ~ScannerStream() {}
bool is_two_byte() const { return is_two_byte_; }
protected:
explicit ScannerStream(bool is_two_byte) : is_two_byte_(is_two_byte) {}
private:
const bool is_two_byte_;
}; };
template <typename Char> template <typename Char>
...@@ -52,7 +60,7 @@ class CharacterStream : public ScannerStream { ...@@ -52,7 +60,7 @@ class CharacterStream : public ScannerStream {
public: public:
// Returns and advances past the next UTF-16 code unit in the input // Returns and advances past the next UTF-16 code unit in the input
// stream. If there are no more code units it returns kEndOfInput. // stream. If there are no more code units it returns kEndOfInput.
inline uc32 Advance() final { inline uc32 Advance() {
uc32 result = Peek(); uc32 result = Peek();
buffer_cursor_++; buffer_cursor_++;
return result; return result;
...@@ -95,7 +103,7 @@ class CharacterStream : public ScannerStream { ...@@ -95,7 +103,7 @@ class CharacterStream : public ScannerStream {
// Go back one by one character in the input stream. // Go back one by one character in the input stream.
// This undoes the most recent Advance(). // This undoes the most recent Advance().
inline void Back() final { inline void Back() {
// The common case - if the previous character is within // The common case - if the previous character is within
// buffer_start_ .. buffer_end_ will be handles locally. // buffer_start_ .. buffer_end_ will be handles locally.
// Otherwise, a new block is requested. // Otherwise, a new block is requested.
...@@ -106,11 +114,11 @@ class CharacterStream : public ScannerStream { ...@@ -106,11 +114,11 @@ class CharacterStream : public ScannerStream {
} }
} }
inline size_t pos() const final { inline size_t pos() const {
return buffer_pos_ + (buffer_cursor_ - buffer_start_); return buffer_pos_ + (buffer_cursor_ - buffer_start_);
} }
inline void Seek(size_t pos) final { inline void Seek(size_t pos) {
if (V8_LIKELY(pos >= buffer_pos_ && if (V8_LIKELY(pos >= buffer_pos_ &&
pos < (buffer_pos_ + (buffer_end_ - buffer_start_)))) { pos < (buffer_pos_ + (buffer_end_ - buffer_start_)))) {
buffer_cursor_ = buffer_start_ + (pos - buffer_pos_); buffer_cursor_ = buffer_start_ + (pos - buffer_pos_);
...@@ -119,13 +127,11 @@ class CharacterStream : public ScannerStream { ...@@ -119,13 +127,11 @@ class CharacterStream : public ScannerStream {
} }
} }
// Returns true if the stream could access the V8 heap after construction.
virtual bool can_access_heap() = 0;
protected: protected:
CharacterStream(const uint16_t* buffer_start, const uint16_t* buffer_cursor, CharacterStream(const Char* buffer_start, const Char* buffer_cursor,
const uint16_t* buffer_end, size_t buffer_pos) const Char* buffer_end, size_t buffer_pos)
: buffer_start_(buffer_start), : ScannerStream(sizeof(Char) == 2),
buffer_start_(buffer_start),
buffer_cursor_(buffer_cursor), buffer_cursor_(buffer_cursor),
buffer_end_(buffer_end), buffer_end_(buffer_end),
buffer_pos_(buffer_pos) {} buffer_pos_(buffer_pos) {}
......
...@@ -11,8 +11,9 @@ ...@@ -11,8 +11,9 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
template <typename Char>
V8_INLINE Token::Value Scanner::SkipWhiteSpace() { V8_INLINE Token::Value Scanner::SkipWhiteSpace() {
int start_position = source_pos(); int start_position = SourcePos<Char>();
while (true) { while (true) {
// We won't skip behind the end of input. // We won't skip behind the end of input.
...@@ -25,11 +26,11 @@ V8_INLINE Token::Value Scanner::SkipWhiteSpace() { ...@@ -25,11 +26,11 @@ V8_INLINE Token::Value Scanner::SkipWhiteSpace() {
} else if (!unicode_cache_->IsWhiteSpace(c0_)) { } else if (!unicode_cache_->IsWhiteSpace(c0_)) {
break; break;
} }
Advance(); Advance<Char>();
} }
// Return whether or not we skipped any characters. // Return whether or not we skipped any characters.
if (source_pos() == start_position) { if (SourcePos<Char>() == start_position) {
DCHECK_NE('0', c0_); DCHECK_NE('0', c0_);
return Token::ILLEGAL; return Token::ILLEGAL;
} }
......
This diff is collapsed.
This diff is collapsed.
...@@ -246,7 +246,7 @@ TEST(AdvanceMatchAdvanceUntil) { ...@@ -246,7 +246,7 @@ TEST(AdvanceMatchAdvanceUntil) {
nullptr)); nullptr));
int32_t au_c0 = int32_t au_c0 =
static_cast<i::CharacterStream<uint16_t>*>(stream_advance_until.get()) static_cast<i::CharacterStream<uint8_t>*>(stream_advance_until.get())
->AdvanceUntil( ->AdvanceUntil(
[](int32_t c0) { return unibrow::IsLineTerminator(c0); }); [](int32_t c0) { return unibrow::IsLineTerminator(c0); });
......
...@@ -27,7 +27,7 @@ struct ScannerTestHelper { ...@@ -27,7 +27,7 @@ struct ScannerTestHelper {
scanner(std::move(other.scanner)) {} scanner(std::move(other.scanner)) {}
std::unique_ptr<UnicodeCache> unicode_cache; std::unique_ptr<UnicodeCache> unicode_cache;
std::unique_ptr<CharacterStream<uint16_t>> stream; std::unique_ptr<CharacterStream<uint8_t>> stream;
std::unique_ptr<Scanner> scanner; std::unique_ptr<Scanner> scanner;
Scanner* operator->() const { return scanner.get(); } Scanner* operator->() const { return scanner.get(); }
...@@ -38,9 +38,9 @@ ScannerTestHelper make_scanner(const char* src) { ...@@ -38,9 +38,9 @@ ScannerTestHelper make_scanner(const char* src) {
ScannerTestHelper helper; ScannerTestHelper helper;
helper.unicode_cache = std::unique_ptr<UnicodeCache>(new UnicodeCache); helper.unicode_cache = std::unique_ptr<UnicodeCache>(new UnicodeCache);
helper.stream = ScannerStream::ForTesting(src); helper.stream = ScannerStream::ForTesting(src);
helper.scanner = helper.scanner = std::unique_ptr<Scanner>(
std::unique_ptr<Scanner>(new Scanner(helper.unicode_cache.get())); new Scanner(helper.unicode_cache.get(), helper.stream.get(), false));
helper.scanner->Initialize(helper.stream.get(), false); helper.scanner->Initialize();
return helper; return helper;
} }
......
...@@ -92,16 +92,16 @@ TEST(ScanKeywords) { ...@@ -92,16 +92,16 @@ TEST(ScanKeywords) {
CHECK(static_cast<int>(sizeof(buffer)) >= length); CHECK(static_cast<int>(sizeof(buffer)) >= length);
{ {
auto stream = i::ScannerStream::ForTesting(keyword, length); auto stream = i::ScannerStream::ForTesting(keyword, length);
i::Scanner scanner(&unicode_cache); i::Scanner scanner(&unicode_cache, stream.get(), false);
scanner.Initialize(stream.get(), false); scanner.Initialize();
CHECK_EQ(key_token.token, scanner.Next()); CHECK_EQ(key_token.token, scanner.Next());
CHECK_EQ(i::Token::EOS, scanner.Next()); CHECK_EQ(i::Token::EOS, scanner.Next());
} }
// Removing characters will make keyword matching fail. // Removing characters will make keyword matching fail.
{ {
auto stream = i::ScannerStream::ForTesting(keyword, length - 1); auto stream = i::ScannerStream::ForTesting(keyword, length - 1);
i::Scanner scanner(&unicode_cache); i::Scanner scanner(&unicode_cache, stream.get(), false);
scanner.Initialize(stream.get(), false); scanner.Initialize();
CHECK_EQ(i::Token::IDENTIFIER, scanner.Next()); CHECK_EQ(i::Token::IDENTIFIER, scanner.Next());
CHECK_EQ(i::Token::EOS, scanner.Next()); CHECK_EQ(i::Token::EOS, scanner.Next());
} }
...@@ -111,8 +111,8 @@ TEST(ScanKeywords) { ...@@ -111,8 +111,8 @@ TEST(ScanKeywords) {
i::MemMove(buffer, keyword, length); i::MemMove(buffer, keyword, length);
buffer[length] = chars_to_append[j]; buffer[length] = chars_to_append[j];
auto stream = i::ScannerStream::ForTesting(buffer, length + 1); auto stream = i::ScannerStream::ForTesting(buffer, length + 1);
i::Scanner scanner(&unicode_cache); i::Scanner scanner(&unicode_cache, stream.get(), false);
scanner.Initialize(stream.get(), false); scanner.Initialize();
CHECK_EQ(i::Token::IDENTIFIER, scanner.Next()); CHECK_EQ(i::Token::IDENTIFIER, scanner.Next());
CHECK_EQ(i::Token::EOS, scanner.Next()); CHECK_EQ(i::Token::EOS, scanner.Next());
} }
...@@ -121,8 +121,8 @@ TEST(ScanKeywords) { ...@@ -121,8 +121,8 @@ TEST(ScanKeywords) {
i::MemMove(buffer, keyword, length); i::MemMove(buffer, keyword, length);
buffer[length - 1] = '_'; buffer[length - 1] = '_';
auto stream = i::ScannerStream::ForTesting(buffer, length); auto stream = i::ScannerStream::ForTesting(buffer, length);
i::Scanner scanner(&unicode_cache); i::Scanner scanner(&unicode_cache, stream.get(), false);
scanner.Initialize(stream.get(), false); scanner.Initialize();
CHECK_EQ(i::Token::IDENTIFIER, scanner.Next()); CHECK_EQ(i::Token::IDENTIFIER, scanner.Next());
CHECK_EQ(i::Token::EOS, scanner.Next()); CHECK_EQ(i::Token::EOS, scanner.Next());
} }
...@@ -188,8 +188,8 @@ TEST(ScanHTMLEndComments) { ...@@ -188,8 +188,8 @@ TEST(ScanHTMLEndComments) {
for (int i = 0; tests[i]; i++) { for (int i = 0; tests[i]; i++) {
const char* source = tests[i]; const char* source = tests[i];
auto stream = i::ScannerStream::ForTesting(source); auto stream = i::ScannerStream::ForTesting(source);
i::Scanner scanner(i_isolate->unicode_cache()); i::Scanner scanner(i_isolate->unicode_cache(), stream.get(), false);
scanner.Initialize(stream.get(), false); scanner.Initialize();
i::Zone zone(i_isolate->allocator(), ZONE_NAME); i::Zone zone(i_isolate->allocator(), ZONE_NAME);
i::AstValueFactory ast_value_factory(&zone, i::AstValueFactory ast_value_factory(&zone,
i_isolate->ast_string_constants(), i_isolate->ast_string_constants(),
...@@ -207,8 +207,8 @@ TEST(ScanHTMLEndComments) { ...@@ -207,8 +207,8 @@ TEST(ScanHTMLEndComments) {
for (int i = 0; fail_tests[i]; i++) { for (int i = 0; fail_tests[i]; i++) {
const char* source = fail_tests[i]; const char* source = fail_tests[i];
auto stream = i::ScannerStream::ForTesting(source); auto stream = i::ScannerStream::ForTesting(source);
i::Scanner scanner(i_isolate->unicode_cache()); i::Scanner scanner(i_isolate->unicode_cache(), stream.get(), false);
scanner.Initialize(stream.get(), false); scanner.Initialize();
i::Zone zone(i_isolate->allocator(), ZONE_NAME); i::Zone zone(i_isolate->allocator(), ZONE_NAME);
i::AstValueFactory ast_value_factory(&zone, i::AstValueFactory ast_value_factory(&zone,
i_isolate->ast_string_constants(), i_isolate->ast_string_constants(),
...@@ -232,8 +232,8 @@ TEST(ScanHtmlComments) { ...@@ -232,8 +232,8 @@ TEST(ScanHtmlComments) {
// Disallow HTML comments. // Disallow HTML comments.
{ {
auto stream = i::ScannerStream::ForTesting(src); auto stream = i::ScannerStream::ForTesting(src);
i::Scanner scanner(&unicode_cache); i::Scanner scanner(&unicode_cache, stream.get(), true);
scanner.Initialize(stream.get(), true); scanner.Initialize();
CHECK_EQ(i::Token::IDENTIFIER, scanner.Next()); CHECK_EQ(i::Token::IDENTIFIER, scanner.Next());
CHECK_EQ(i::Token::ILLEGAL, scanner.Next()); CHECK_EQ(i::Token::ILLEGAL, scanner.Next());
} }
...@@ -241,8 +241,8 @@ TEST(ScanHtmlComments) { ...@@ -241,8 +241,8 @@ TEST(ScanHtmlComments) {
// Skip HTML comments: // Skip HTML comments:
{ {
auto stream = i::ScannerStream::ForTesting(src); auto stream = i::ScannerStream::ForTesting(src);
i::Scanner scanner(&unicode_cache); i::Scanner scanner(&unicode_cache, stream.get(), false);
scanner.Initialize(stream.get(), false); scanner.Initialize();
CHECK_EQ(i::Token::IDENTIFIER, scanner.Next()); CHECK_EQ(i::Token::IDENTIFIER, scanner.Next());
CHECK_EQ(i::Token::EOS, scanner.Next()); CHECK_EQ(i::Token::EOS, scanner.Next());
} }
...@@ -280,8 +280,8 @@ TEST(StandAlonePreParser) { ...@@ -280,8 +280,8 @@ TEST(StandAlonePreParser) {
uintptr_t stack_limit = i_isolate->stack_guard()->real_climit(); uintptr_t stack_limit = i_isolate->stack_guard()->real_climit();
for (int i = 0; programs[i]; i++) { for (int i = 0; programs[i]; i++) {
auto stream = i::ScannerStream::ForTesting(programs[i]); auto stream = i::ScannerStream::ForTesting(programs[i]);
i::Scanner scanner(i_isolate->unicode_cache()); i::Scanner scanner(i_isolate->unicode_cache(), stream.get(), false);
scanner.Initialize(stream.get(), false); scanner.Initialize();
i::Zone zone(i_isolate->allocator(), ZONE_NAME); i::Zone zone(i_isolate->allocator(), ZONE_NAME);
i::AstValueFactory ast_value_factory(&zone, i::AstValueFactory ast_value_factory(&zone,
...@@ -313,8 +313,8 @@ TEST(StandAlonePreParserNoNatives) { ...@@ -313,8 +313,8 @@ TEST(StandAlonePreParserNoNatives) {
uintptr_t stack_limit = isolate->stack_guard()->real_climit(); uintptr_t stack_limit = isolate->stack_guard()->real_climit();
for (int i = 0; programs[i]; i++) { for (int i = 0; programs[i]; i++) {
auto stream = i::ScannerStream::ForTesting(programs[i]); auto stream = i::ScannerStream::ForTesting(programs[i]);
i::Scanner scanner(isolate->unicode_cache()); i::Scanner scanner(isolate->unicode_cache(), stream.get(), false);
scanner.Initialize(stream.get(), false); scanner.Initialize();
// Preparser defaults to disallowing natives syntax. // Preparser defaults to disallowing natives syntax.
i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME);
...@@ -348,8 +348,8 @@ TEST(RegressChromium62639) { ...@@ -348,8 +348,8 @@ TEST(RegressChromium62639) {
// failed in debug mode, and sometimes crashed in release mode. // failed in debug mode, and sometimes crashed in release mode.
auto stream = i::ScannerStream::ForTesting(program); auto stream = i::ScannerStream::ForTesting(program);
i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); i::Scanner scanner(CcTest::i_isolate()->unicode_cache(), stream.get(), false);
scanner.Initialize(stream.get(), false); scanner.Initialize();
i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME);
i::AstValueFactory ast_value_factory( i::AstValueFactory ast_value_factory(
&zone, CcTest::i_isolate()->ast_string_constants(), &zone, CcTest::i_isolate()->ast_string_constants(),
...@@ -381,8 +381,8 @@ TEST(PreParseOverflow) { ...@@ -381,8 +381,8 @@ TEST(PreParseOverflow) {
uintptr_t stack_limit = isolate->stack_guard()->real_climit(); uintptr_t stack_limit = isolate->stack_guard()->real_climit();
auto stream = i::ScannerStream::ForTesting(program.get(), kProgramSize); auto stream = i::ScannerStream::ForTesting(program.get(), kProgramSize);
i::Scanner scanner(isolate->unicode_cache()); i::Scanner scanner(isolate->unicode_cache(), stream.get(), false);
scanner.Initialize(stream.get(), false); scanner.Initialize();
i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME);
i::AstValueFactory ast_value_factory( i::AstValueFactory ast_value_factory(
...@@ -396,12 +396,12 @@ TEST(PreParseOverflow) { ...@@ -396,12 +396,12 @@ TEST(PreParseOverflow) {
CHECK_EQ(i::PreParser::kPreParseStackOverflow, result); CHECK_EQ(i::PreParser::kPreParseStackOverflow, result);
} }
void TestStreamScanner(i::CharacterStream<uint16_t>* stream, void TestStreamScanner(i::ScannerStream* stream,
i::Token::Value* expected_tokens, i::Token::Value* expected_tokens,
int skip_pos = 0, // Zero means not skipping. int skip_pos = 0, // Zero means not skipping.
int skip_to = 0) { int skip_to = 0) {
i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); i::Scanner scanner(CcTest::i_isolate()->unicode_cache(), stream, false);
scanner.Initialize(stream, false); scanner.Initialize();
int i = 0; int i = 0;
do { do {
...@@ -475,8 +475,8 @@ TEST(StreamScanner) { ...@@ -475,8 +475,8 @@ TEST(StreamScanner) {
void TestScanRegExp(const char* re_source, const char* expected) { void TestScanRegExp(const char* re_source, const char* expected) {
auto stream = i::ScannerStream::ForTesting(re_source); auto stream = i::ScannerStream::ForTesting(re_source);
i::HandleScope scope(CcTest::i_isolate()); i::HandleScope scope(CcTest::i_isolate());
i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); i::Scanner scanner(CcTest::i_isolate()->unicode_cache(), stream.get(), false);
scanner.Initialize(stream.get(), false); scanner.Initialize();
i::Token::Value start = scanner.peek(); i::Token::Value start = scanner.peek();
CHECK(start == i::Token::DIV || start == i::Token::ASSIGN_DIV); CHECK(start == i::Token::DIV || start == i::Token::ASSIGN_DIV);
...@@ -1141,8 +1141,6 @@ void SetParserFlags(i::PreParser* parser, i::EnumSet<ParserFlag> flags) { ...@@ -1141,8 +1141,6 @@ void SetParserFlags(i::PreParser* parser, i::EnumSet<ParserFlag> flags) {
parser->set_allow_natives(flags.Contains(kAllowNatives)); parser->set_allow_natives(flags.Contains(kAllowNatives));
parser->set_allow_harmony_public_fields( parser->set_allow_harmony_public_fields(
flags.Contains(kAllowHarmonyPublicFields)); flags.Contains(kAllowHarmonyPublicFields));
parser->set_allow_harmony_private_fields(
flags.Contains(kAllowHarmonyPrivateFields));
parser->set_allow_harmony_static_fields( parser->set_allow_harmony_static_fields(
flags.Contains(kAllowHarmonyStaticFields)); flags.Contains(kAllowHarmonyStaticFields));
parser->set_allow_harmony_dynamic_import( parser->set_allow_harmony_dynamic_import(
...@@ -1151,11 +1149,13 @@ void SetParserFlags(i::PreParser* parser, i::EnumSet<ParserFlag> flags) { ...@@ -1151,11 +1149,13 @@ void SetParserFlags(i::PreParser* parser, i::EnumSet<ParserFlag> flags) {
flags.Contains(kAllowHarmonyImportMeta)); flags.Contains(kAllowHarmonyImportMeta));
parser->set_allow_harmony_do_expressions( parser->set_allow_harmony_do_expressions(
flags.Contains(kAllowHarmonyDoExpressions)); flags.Contains(kAllowHarmonyDoExpressions));
parser->set_allow_harmony_private_fields(
flags.Contains(kAllowHarmonyPrivateFields));
parser->set_allow_harmony_numeric_separator( parser->set_allow_harmony_numeric_separator(
flags.Contains(kAllowHarmonyNumericSeparator)); flags.Contains(kAllowHarmonyNumericSeparator));
} }
template <typename Char>
void TestParserSyncWithFlags(i::Handle<i::String> source, void TestParserSyncWithFlags(i::Handle<i::String> source,
i::EnumSet<ParserFlag> flags, i::EnumSet<ParserFlag> flags,
ParserSyncTestResult result, ParserSyncTestResult result,
...@@ -1169,9 +1169,9 @@ void TestParserSyncWithFlags(i::Handle<i::String> source, ...@@ -1169,9 +1169,9 @@ void TestParserSyncWithFlags(i::Handle<i::String> source,
// Preparse the data. // Preparse the data.
i::PendingCompilationErrorHandler pending_error_handler; i::PendingCompilationErrorHandler pending_error_handler;
if (test_preparser) { if (test_preparser) {
i::Scanner scanner(isolate->unicode_cache());
std::unique_ptr<i::ScannerStream> stream( std::unique_ptr<i::ScannerStream> stream(
i::ScannerStream::For(isolate, source)); i::ScannerStream::For(isolate, source));
i::Scanner scanner(isolate->unicode_cache(), stream.get(), is_module);
i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME);
i::AstValueFactory ast_value_factory( i::AstValueFactory ast_value_factory(
&zone, CcTest::i_isolate()->ast_string_constants(), &zone, CcTest::i_isolate()->ast_string_constants(),
...@@ -1181,8 +1181,8 @@ void TestParserSyncWithFlags(i::Handle<i::String> source, ...@@ -1181,8 +1181,8 @@ void TestParserSyncWithFlags(i::Handle<i::String> source,
isolate->counters()->runtime_call_stats(), isolate->counters()->runtime_call_stats(),
isolate->logger(), -1, is_module); isolate->logger(), -1, is_module);
SetParserFlags(&preparser, flags); SetParserFlags(&preparser, flags);
scanner.Initialize(static_cast<CharacterStream<Char>*>(stream.get()), scanner.Initialize();
is_module); // Make sure we can the first token with the correct flags.
i::PreParser::PreParseResult result = preparser.PreParseProgram(); i::PreParser::PreParseResult result = preparser.PreParseProgram();
CHECK_EQ(i::PreParser::kPreParseSuccess, result); CHECK_EQ(i::PreParser::kPreParseSuccess, result);
} }
...@@ -1292,15 +1292,8 @@ void TestParserSync(const char* source, const ParserFlag* varying_flags, ...@@ -1292,15 +1292,8 @@ void TestParserSync(const char* source, const ParserFlag* varying_flags,
++flag_index) { ++flag_index) {
flags.Remove(always_false_flags[flag_index]); flags.Remove(always_false_flags[flag_index]);
} }
if (str->IsSeqOneByteString()) { TestParserSyncWithFlags(str, flags, result, is_module, test_preparser,
// TODO(verwaest): Switch to uint8_t. ignore_error_msg);
TestParserSyncWithFlags<uint16_t>(str, flags, result, is_module,
test_preparser, ignore_error_msg);
} else {
DCHECK(str->IsSeqTwoByteString());
TestParserSyncWithFlags<uint16_t>(str, flags, result, is_module,
test_preparser, ignore_error_msg);
}
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment