Commit ed29ecd8 authored by caitpotter88's avatar caitpotter88 Committed by Commit bot

Add materialized literals for tagged templates in preparser

LOG=N
R=arv@chromium.org, dslomov@chromium.org, marja@chromium.org
BUG=

Review URL: https://codereview.chromium.org/792083002

Cr-Commit-Position: refs/heads/master@{#25782}
parent 68870ab6
......@@ -632,6 +632,9 @@ class ParserTraits {
V8_INLINE Expression* CloseTemplateLiteral(TemplateLiteralState* state,
int start, Expression* tag);
V8_INLINE Expression* NoTemplateTag() { return NULL; }
V8_INLINE static bool IsTaggedTemplate(const Expression* tag) {
return tag != NULL;
}
private:
Parser* parser_;
......
......@@ -756,6 +756,12 @@ class PreParserExpression {
ExpressionTypeField::encode(kCallExpression));
}
static PreParserExpression NoTemplateTag() {
return PreParserExpression(TypeField::encode(kExpression) |
ExpressionTypeField::encode(
kNoTemplateTagExpression));
}
bool IsIdentifier() const {
return TypeField::decode(code_) == kIdentifierExpression;
}
......@@ -809,6 +815,11 @@ class PreParserExpression {
bool IsFunctionLiteral() const { return false; }
bool IsCallNew() const { return false; }
bool IsNoTemplateTag() const {
return TypeField::decode(code_) == kExpression &&
ExpressionTypeField::decode(code_) == kNoTemplateTagExpression;
}
PreParserExpression AsFunctionLiteral() { return *this; }
bool IsBinaryOperation() const {
......@@ -855,7 +866,8 @@ class PreParserExpression {
kThisPropertyExpression,
kPropertyExpression,
kCallExpression,
kSuperExpression
kSuperExpression,
kNoTemplateTagExpression
};
explicit PreParserExpression(uint32_t expression_code)
......@@ -1398,10 +1410,21 @@ class PreParserTraits {
void AddTemplateSpan(TemplateLiteralState*, bool) {}
void AddTemplateExpression(TemplateLiteralState*, PreParserExpression) {}
PreParserExpression CloseTemplateLiteral(TemplateLiteralState*, int,
PreParserExpression) {
PreParserExpression tag) {
if (IsTaggedTemplate(tag)) {
// Emulate generation of array literals for tag callsite
// 1st is array of cooked strings, second is array of raw strings
MaterializeTemplateCallsiteLiterals();
}
return EmptyExpression();
}
PreParserExpression NoTemplateTag() { return PreParserExpression::Default(); }
inline void MaterializeTemplateCallsiteLiterals();
PreParserExpression NoTemplateTag() {
return PreParserExpression::NoTemplateTag();
}
static bool IsTaggedTemplate(const PreParserExpression tag) {
return !tag.IsNoTemplateTag();
}
static AstValueFactory* ast_value_factory() { return NULL; }
void CheckConflictingVarDeclarations(PreParserScope scope, bool* ok) {}
......@@ -1455,7 +1478,7 @@ class PreParser : public ParserBase<PreParserTraits> {
// success (even if parsing failed, the pre-parse data successfully
// captured the syntax error), and false if a stack-overflow happened
// during parsing.
PreParseResult PreParseProgram() {
PreParseResult PreParseProgram(int* materialized_literals = 0) {
PreParserScope scope(scope_, SCRIPT_SCOPE);
PreParserFactory factory(NULL);
FunctionState top_scope(&function_state_, &scope_, &scope, &factory);
......@@ -1468,6 +1491,9 @@ class PreParser : public ParserBase<PreParserTraits> {
} else if (scope_->strict_mode() == STRICT) {
CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok);
}
if (materialized_literals) {
*materialized_literals = function_state_->materialized_literal_count();
}
return kPreParseSuccess;
}
......@@ -1565,6 +1591,12 @@ class PreParser : public ParserBase<PreParserTraits> {
};
void PreParserTraits::MaterializeTemplateCallsiteLiterals() {
pre_parser_->function_state_->NextMaterializedLiteralIndex();
pre_parser_->function_state_->NextMaterializedLiteralIndex();
}
PreParserStatementList PreParser::ParseEagerFunctionBody(
PreParserIdentifier function_name, int pos, Variable* fvar,
Token::Value fvar_init_op, bool is_generator, bool* ok) {
......
......@@ -1395,6 +1395,8 @@ void TestParserSyncWithFlags(i::Handle<i::String> source,
i::Factory* factory = isolate->factory();
uintptr_t stack_limit = isolate->stack_guard()->real_climit();
int preparser_materialized_literals = -1;
int parser_materialized_literals = -2;
// Preparse the data.
i::CompleteParserRecorder log;
......@@ -1404,7 +1406,8 @@ void TestParserSyncWithFlags(i::Handle<i::String> source,
i::PreParser preparser(&scanner, &log, stack_limit);
SetParserFlags(&preparser, flags);
scanner.Initialize(&stream);
i::PreParser::PreParseResult result = preparser.PreParseProgram();
i::PreParser::PreParseResult result = preparser.PreParseProgram(
&preparser_materialized_literals);
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
}
......@@ -1423,6 +1426,9 @@ void TestParserSyncWithFlags(i::Handle<i::String> source,
info.MarkAsGlobal();
parser.Parse();
function = info.function();
if (function) {
parser_materialized_literals = function->materialized_literal_count();
}
}
// Check that preparsing fails iff parsing fails.
......@@ -1488,6 +1494,15 @@ void TestParserSyncWithFlags(i::Handle<i::String> source,
"However, parser and preparser succeeded",
source->ToCString().get());
CHECK(false);
} else if (preparser_materialized_literals != parser_materialized_literals) {
v8::base::OS::Print(
"Preparser materialized literals (%d) differ from Parser materialized "
"literals (%d) on:\n"
"\t%s\n"
"However, parser and preparser succeeded",
preparser_materialized_literals, parser_materialized_literals,
source->ToCString().get());
CHECK(false);
}
}
......@@ -4469,6 +4484,35 @@ TEST(ScanTaggedTemplateLiterals) {
}
TEST(TemplateMaterializedLiterals) {
const char* context_data[][2] = {
{
"'use strict';\n"
"function tag() {}\n"
"var a, b, c;\n"
"(", ")"
},
{NULL, NULL}
};
const char* data[] = {
"tag``",
"tag`a`",
"tag`a${1}b`",
"tag`a${1}b${2}c`",
"``",
"`a`",
"`a${1}b`",
"`a${1}b${2}c`",
NULL
};
static const ParserFlag always_flags[] = {kAllowHarmonyTemplates};
RunParserSyncTest(context_data, data, kSuccess, NULL, 0, always_flags,
arraysize(always_flags));
}
TEST(ScanUnterminatedTemplateLiterals) {
const char* context_data[][2] = {{"'use strict';", ""},
{"function foo(){ 'use strict';"
......
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