Index: src/parser.cc |
diff --git a/src/parser.cc b/src/parser.cc |
index e34854fe7adacd564655429abd05a62caa2d4b20..b5675cfad2a4415275e800427b83818d4fd1b34b 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,116 @@ void Parser::ParseOnBackground() { |
log_ = NULL; |
} |
} |
+ |
+ |
+ParserTraits::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) { |
+ return new (zone()) ParserTraits::TemplateLiteral(zone(), pos); |
+} |
+ |
+ |
+void Parser::AddTemplateSpan(TemplateLiteralState* state, bool tail) { |
+ int pos = scanner()->location().beg_pos; |
+ int end = scanner()->location().end_pos - (tail ? 1 : 2); |
+ const AstRawString* tv = scanner()->CurrentSymbol(ast_value_factory()); |
+ Literal* cooked = factory()->NewStringLiteral(tv, pos); |
+ (*state)->AddTemplateSpan(cooked, end, 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(); |
marja
2014/11/12 09:23:21
Style: cookedStrings -> cooked_strings (+ other va
caitp (gmail)
2014/11/12 13:33:12
Done.
|
+ 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()) { |
marja
2014/11/12 09:23:21
Style nit: if (expressions->length() == 0)
caitp (gmail)
2014/11/12 13:33:12
Done.
|
+ // 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<int>* lengths = lit->lengths(); |
+ ZoneList<Expression*>* rawStrings = new (zone()) ZoneList<Expression*>( |
marja
2014/11/12 09:23:21
raw_strings
|
+ cookedStrings->length(), zone()); |
+ Handle<String> source(String::cast(script()->source())); |
+ |
+ // Build raw strings |
+ for (int i = 0; i < cookedStrings->length(); ++i) { |
marja
2014/11/12 09:23:21
Gets confusing with i, c and j; could you rename i
caitp (gmail)
2014/11/12 13:33:12
Done. (I'm not sure this is much easier to read, t
marja
2014/11/12 13:41:14
Yeah, they're kinda long. How about just to_index
|
+ int offset = POS(i); |
+ int length = lengths->at(i); |
+ SmartArrayPointer<char> rawChars = source->ToCString( |
+ ALLOW_NULLS, FAST_STRING_TRAVERSAL, offset + 1, length - 1, &length); |
+ int c = 0; |
+ int j = 0; |
+ |
+ // Normalize line endings |
marja
2014/11/12 09:23:21
You could expand this comment to say what exactly
caitp (gmail)
2014/11/12 13:33:12
Done.
|
+ for (; j < length; ++j) { |
+ char ch = rawChars[j]; |
+ if (ch == '\r') { |
+ rawChars[c++] = '\n'; |
+ if (j < length - 1 && rawChars[j + 1] == '\n') { |
+ ++j; |
+ } |
+ } else { |
+ rawChars[c++] = ch; |
+ } |
+ } |
+ rawStrings->Add(factory()->NewStringLiteral( |
+ ast_value_factory()->GetOneByteString( |
+ OneByteVector(rawChars.get(), c)), offset), zone()); |
+ } |
+ |
marja
2014/11/12 09:23:21
I like this version of raw string building thing b
|
+ 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()->get_template_callsite_string(), NULL, args, start); |
+ |
+ // Call TagFn |
+ ZoneList<Expression*>* callArgs = new (zone()) ZoneList<Expression*>( |
marja
2014/11/12 09:23:21
call_args
|
+ expressions->length() + 1, zone()); |
+ callArgs->Add(expr, zone()); |
+ callArgs->AddAll(*expressions, zone()); |
+ expr = factory()->NewCall(tag, callArgs, pos); |
+ return expr; |
+ } |
+#undef COOKED_STRING |
+#undef POS |
+#undef EXPR |
+} |
+ |
} } // namespace v8::internal |