| Index: src/parser.cc
|
| diff --git a/src/parser.cc b/src/parser.cc
|
| index e34854fe7adacd564655429abd05a62caa2d4b20..ee8951e218c6aaea3d8bfbf88adf0a7f7821e265 100644
|
| --- a/src/parser.cc
|
| +++ b/src/parser.cc
|
| @@ -815,6 +815,7 @@ Parser::Parser(CompilationInfo* info, ParseInfo* parse_info)
|
| set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals);
|
| set_allow_classes(FLAG_harmony_classes);
|
| set_allow_harmony_object_literals(FLAG_harmony_object_literals);
|
| + set_allow_harmony_templates(FLAG_harmony_templates);
|
| for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
|
| ++feature) {
|
| use_counts_[feature] = 0;
|
| @@ -5029,4 +5030,88 @@ void Parser::ParseOnBackground() {
|
| log_ = NULL;
|
| }
|
| }
|
| +
|
| +
|
| +ParserTraits::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) {
|
| + return new (zone()) ParserTraits::TemplateLiteral(zone(), pos);
|
| +}
|
| +
|
| +
|
| +void Parser::AddTemplateSpan(TemplateLiteralState* state) {
|
| + int pos = scanner()->location().beg_pos;
|
| + const AstRawString* tv = scanner()->CurrentSymbol(ast_value_factory());
|
| + const AstRawString* trv = scanner()->CurrentRawSymbol(ast_value_factory());
|
| + Literal* cooked = factory()->NewStringLiteral(tv, pos);
|
| + Literal* raw = factory()->NewStringLiteral(trv, pos);
|
| + (*state)->AddTemplateSpan(cooked, raw, zone());
|
| +}
|
| +
|
| +
|
| +void Parser::AddTemplateExpression(TemplateLiteralState* state,
|
| + Expression* expression) {
|
| + (*state)->AddExpression(expression, zone());
|
| +}
|
| +
|
| +
|
| +Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state,
|
| + int start, Expression* tag) {
|
| +#define COOKED_STRING(i) cookedStrings->at(i)
|
| +#define POS(i) cookedStrings->at(i)->position()
|
| +#define EXPR(i) expressions->at(i)
|
| + TemplateLiteral* lit = *state;
|
| + int pos = lit->position();
|
| + const ZoneList<Expression*>* cookedStrings = lit->cooked();
|
| + const ZoneList<Expression*>* expressions = lit->expressions();
|
| + CHECK(cookedStrings->length() == (expressions->length() + 1));
|
| +
|
| + if (!tag) {
|
| + // Build tree of BinaryOps to simplify code-generation
|
| + Expression* expr = NULL;
|
| +
|
| + if (!expressions->length()) {
|
| + // Simple case: treat as string literal
|
| + expr = COOKED_STRING(0);
|
| + } else {
|
| + int i;
|
| + expr = factory()->NewBinaryOperation(Token::ADD,
|
| + COOKED_STRING(0), EXPR(0), POS(0));
|
| + for (i = 1; i < expressions->length(); ++i) {
|
| + expr = factory()->NewBinaryOperation(Token::ADD,
|
| + expr, factory()->NewBinaryOperation(Token::ADD, COOKED_STRING(i),
|
| + EXPR(i), POS(i)), POS(i));
|
| + }
|
| + expr = factory()->NewBinaryOperation(Token::ADD, expr, COOKED_STRING(i),
|
| + POS(i));
|
| + }
|
| + return expr;
|
| + } else {
|
| + const ZoneList<Expression*>* rawStrings = lit->raw();
|
| + int cooked_idx = function_state_->NextMaterializedLiteralIndex();
|
| + int raw_idx = function_state_->NextMaterializedLiteralIndex();
|
| +
|
| + // GetTemplateCallSite
|
| + ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(4, zone());
|
| + args->Add(factory()->NewArrayLiteral(
|
| + const_cast<ZoneList<Expression*>*>(cookedStrings), cooked_idx, pos),
|
| + zone());
|
| + args->Add(factory()->NewArrayLiteral(
|
| + const_cast<ZoneList<Expression*>*>(rawStrings), raw_idx, pos), zone());
|
| + this->CheckPossibleEvalCall(tag, scope_);
|
| + Expression* expr = factory()->NewCallRuntime(
|
| + ast_value_factory()->GetTemplateCallSite_string(), NULL, args, start);
|
| +
|
| + // Call TagFn
|
| + ZoneList<Expression*>* callArgs = new (zone()) ZoneList<Expression*>(
|
| + expressions->length() + 1, zone());
|
| + callArgs->Add(expr, zone());
|
| + callArgs->AddAll(*expressions, zone());
|
| + expr = factory()->NewCall(tag, callArgs, pos);
|
| + if (fni_ != NULL) fni_->RemoveLastFunction();
|
| + return expr;
|
| + }
|
| +#undef COOKED_STRING
|
| +#undef POS
|
| +#undef EXPR
|
| +}
|
| +
|
| } } // namespace v8::internal
|
|
|