Bug 1370214 - Don't allocate RegExp objects during syntax parsing for RegExp literals. r=shu

This commit is contained in:
André Bargull 2017-06-07 03:19:41 -07:00
Родитель e9c7254a37
Коммит 735eb4e675
4 изменённых файлов: 39 добавлений и 5 удалений

Просмотреть файл

@ -19,6 +19,7 @@
#include "frontend/Parser.h"
#include "mozilla/Range.h"
#include "mozilla/Sprintf.h"
#include "jsapi.h"
@ -34,6 +35,7 @@
#include "frontend/BytecodeCompiler.h"
#include "frontend/FoldConstants.h"
#include "frontend/TokenStream.h"
#include "irregexp/RegExpParser.h"
#include "vm/RegExpObject.h"
#include "wasm/AsmJS.h"
@ -9387,12 +9389,13 @@ Parser<ParseHandler, CharT>::noSubstitutionUntaggedTemplate()
return handler.newTemplateStringLiteral(tokenStream.currentToken().atom(), pos());
}
template <template <typename CharT> class ParseHandler, typename CharT>
typename ParseHandler<CharT>::Node
Parser<ParseHandler, CharT>::newRegExp()
template <>
ParseNode*
Parser<FullParseHandler, char16_t>::newRegExp()
{
MOZ_ASSERT(!options().selfHostingMode);
// Create the regexp even when doing a syntax parse, to check the regexp's syntax.
// Create the regexp and check its syntax.
const char16_t* chars = tokenStream.getTokenbuf().begin();
size_t length = tokenStream.getTokenbuf().length();
RegExpFlag flags = tokenStream.currentToken().regExpFlags();
@ -9406,6 +9409,24 @@ Parser<ParseHandler, CharT>::newRegExp()
return handler.newRegExp(reobj, pos(), *this);
}
template <>
SyntaxParseHandlerBase::Node
Parser<SyntaxParseHandler, char16_t>::newRegExp()
{
MOZ_ASSERT(!options().selfHostingMode);
// Only check the regexp's syntax, but don't create a regexp object.
const char16_t* chars = tokenStream.getTokenbuf().begin();
size_t length = tokenStream.getTokenbuf().length();
RegExpFlag flags = tokenStream.currentToken().regExpFlags();
mozilla::Range<const char16_t> source(chars, length);
if (!js::irregexp::ParsePatternSyntax(tokenStream, alloc, source, flags & UnicodeFlag))
return null();
return handler.newRegExp(SyntaxParseHandlerBase::NodeGeneric, pos(), *this);
}
template <template <typename CharT> class ParseHandler, typename CharT>
void
Parser<ParseHandler, CharT>::checkDestructuringAssignmentTarget(Node expr, TokenPos exprPos,

Просмотреть файл

@ -226,7 +226,7 @@ class SyntaxParseHandlerBase
Node newRawUndefinedLiteral(const TokenPos& pos) { return NodeGeneric; }
template <class Boxer>
Node newRegExp(RegExpObject* reobj, const TokenPos& pos, Boxer& boxer) { return NodeGeneric; }
Node newRegExp(Node reobj, const TokenPos& pos, Boxer& boxer) { return NodeGeneric; }
Node newConditional(Node cond, Node thenExpr, Node elseExpr) { return NodeGeneric; }

Просмотреть файл

@ -1966,3 +1966,10 @@ irregexp::ParsePatternSyntax(frontend::TokenStream& ts, LifoAlloc& alloc, JSAtom
? ::ParsePatternSyntax(ts, alloc, str->latin1Chars(nogc), str->length(), unicode)
: ::ParsePatternSyntax(ts, alloc, str->twoByteChars(nogc), str->length(), unicode);
}
bool
irregexp::ParsePatternSyntax(frontend::TokenStream& ts, LifoAlloc& alloc,
const mozilla::Range<const char16_t> chars, bool unicode)
{
return ::ParsePatternSyntax(ts, alloc, chars.begin().get(), chars.length(), unicode);
}

Просмотреть файл

@ -31,6 +31,8 @@
#ifndef V8_PARSER_H_
#define V8_PARSER_H_
#include "mozilla/Range.h"
#include <stdarg.h>
#include "irregexp/RegExpAST.h"
@ -52,6 +54,10 @@ bool
ParsePatternSyntax(frontend::TokenStream& ts, LifoAlloc& alloc, JSAtom* str,
bool unicode);
bool
ParsePatternSyntax(frontend::TokenStream& ts, LifoAlloc& alloc,
const mozilla::Range<const char16_t> chars, bool unicode);
// A BufferedVector is an automatically growing list, just like (and backed
// by) a Vector, that is optimized for the case of adding and removing
// a single element. The last element added is stored outside the backing list,