diff --git a/src/parser.cc b/src/parser.cc index 515eff3fb5..a9ba0e7169 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -37,6 +37,7 @@ #include "parser.h" #include "platform.h" #include "preparser.h" +#include "prescanner.h" #include "runtime.h" #include "scopeinfo.h" #include "string-stream.h" @@ -4637,6 +4638,57 @@ int ScriptDataImpl::ReadNumber(byte** source) { } +static ScriptDataImpl* DoPreParse(UTF16Buffer* stream, + bool allow_lazy, + PartialParserRecorder* recorder) { + typedef preparser::Scanner PreScanner; + PreScanner scanner; + scanner.Initialize(stream); + preparser::PreParser preparser; + if (!preparser.PreParseProgram(&scanner, recorder, allow_lazy)) { + Top::StackOverflow(); + return NULL; + } + + // Extract the accumulated data from the recorder as a single + // contiguous vector that we are responsible for disposing. + Vector store = recorder->ExtractData(); + return new ScriptDataImpl(store); +} + + +// Create an UTF16Buffer for the preparser to use as input, +// and preparse the source. +static ScriptDataImpl* DoPreParse(Handle source, + unibrow::CharacterStream* stream, + bool allow_lazy, + PartialParserRecorder* recorder) { + if (source.is_null()) { + CharacterStreamUTF16Buffer buffer; + int length = stream->Length(); + buffer.Initialize(source, stream, 0, length); + return DoPreParse(&buffer, allow_lazy, recorder); + } else if (source->IsExternalAsciiString()) { + ExternalStringUTF16Buffer buffer; + int length = source->length(); + buffer.Initialize(Handle::cast(source), 0, length); + return DoPreParse(&buffer, allow_lazy, recorder); + } else if (source->IsExternalTwoByteString()) { + ExternalStringUTF16Buffer buffer; + int length = source->length(); + buffer.Initialize(Handle::cast(source), 0, length); + return DoPreParse(&buffer, allow_lazy, recorder); + } else { + CharacterStreamUTF16Buffer buffer; + SafeStringInputBuffer input; + input.Reset(0, source.location()); + int length = source->length(); + buffer.Initialize(source, &input, 0, length); + return DoPreParse(&buffer, allow_lazy, recorder); + } +} + + // Preparse, but only collect data that is immediately useful, // even if the preparser data is only used once. ScriptDataImpl* ParserApi::PartialPreParse(Handle source, @@ -4649,19 +4701,9 @@ ScriptDataImpl* ParserApi::PartialPreParse(Handle source, // If we don't allow lazy compilation, the log data will be empty. return NULL; } - preparser::PreParser parser; - Scanner scanner; - scanner.Initialize(source, stream, JAVASCRIPT); PartialParserRecorder recorder; - if (!parser.PreParseProgram(&scanner, &recorder, allow_lazy)) { - Top::StackOverflow(); - return NULL; - } - // Extract the accumulated data from the recorder as a single - // contiguous vector that we are responsible for disposing. - Vector store = recorder.ExtractData(); - return new ScriptDataImpl(store); + return DoPreParse(source, stream, allow_lazy, &recorder); } @@ -4669,19 +4711,9 @@ ScriptDataImpl* ParserApi::PreParse(Handle source, unibrow::CharacterStream* stream, v8::Extension* extension) { Handle