Reviewers: Dmitry Lomov (chromium), marja,

Message:
PTAL

Instead of using an UTF8 encoder use a StringCharacterStream.



Description:
Simplify template literal raw string creation

BUG=v8:3710
LOG=Y
[email protected], [email protected]

Please review this at https://codereview.chromium.org/768203002/

Base URL: https://chromium.googlesource.com/v8/v8.git@master

Affected files (+33, -34 lines):
  M src/parser.cc
  M test/mjsunit/harmony/templates.js


Index: src/parser.cc
diff --git a/src/parser.cc b/src/parser.cc
index 22c0f5c142c918cc45043fc1b11efb6f4a46488d..485a23a882b58dd5999f32c85bcabcdaf2067af6 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -5291,8 +5291,6 @@ ZoneList<Expression*>* Parser::TemplateRawStrings(const TemplateLiteral* lit,

   DCHECK(total);

-  Handle<String> source(String::cast(script()->source()));
-
   raw_strings = new (zone()) ZoneList<Expression*>(total, zone());

   uint32_t running_hash = 0;
@@ -5300,7 +5298,7 @@ ZoneList<Expression*>* Parser::TemplateRawStrings(const TemplateLiteral* lit,
   for (int index = 0; index < total; ++index) {
     int span_start = cooked_strings->at(index)->position() + 1;
     int span_end = lengths->at(index) - 1;
-    int length;
+    int length = span_end;
     int to_index = 0;

     if (index) {
@@ -5308,42 +5306,31 @@ ZoneList<Expression*>* Parser::TemplateRawStrings(const TemplateLiteral* lit,
           running_hash, "${}", 3);
     }

-    SmartArrayPointer<char> raw_chars =
-        source->ToCString(ALLOW_NULLS, FAST_STRING_TRAVERSAL, span_start,
-                          span_end, &length);
-
// Normalize raw line-feeds. [U+000D U+000A] (CRLF) and [U+000D] (CR) must
     // be translated into U+000A (LF).
-    for (int from_index = 0; from_index < length; ++from_index) {
-      char ch = raw_chars[from_index];
-      if (ch == '\r') {
-        ch = '\n';
-        if (from_index + 1 < length && raw_chars[from_index + 1] == '\n') {
-          ++from_index;
-        }
+ StringCharacterStream stream(String::cast(script()->source()), span_start);
+    uc16* normalized_raw_chars = zone()->NewArray<uc16>(length);
+    bool last_was_cr = false;
+    for (int from_index = 0; from_index < length && stream.HasMore();
+         ++from_index) {
+      uc16 ch = stream.GetNext();
+      switch (ch) {
+        case '\r':
+          normalized_raw_chars[to_index++] = '\n';
+          last_was_cr = true;
+          continue;
+        case '\n':
+          if (last_was_cr) break;
+        // Fall through.
+        default:
+          normalized_raw_chars[to_index++] = ch;
       }
-      raw_chars[to_index++] = ch;
+      last_was_cr = false;
     }

-    Access<UnicodeCache::Utf8Decoder>
-        decoder(isolate()->unicode_cache()->utf8_decoder());
-    decoder->Reset(raw_chars.get(), to_index);
-    int utf16_length = decoder->Utf16Length();
-    Literal* raw_lit = NULL;
-    if (utf16_length > 0) {
-      uc16* utf16_buffer = zone()->NewArray<uc16>(utf16_length);
-      to_index = decoder->WriteUtf16(utf16_buffer, utf16_length);
-      running_hash = StringHasher::ComputeRunningHash(
-          running_hash, utf16_buffer, to_index);
- const uint16_t* data = reinterpret_cast<const uint16_t*>(utf16_buffer);
-      const AstRawString* raw_str = ast_value_factory()->GetTwoByteString(
-          Vector<const uint16_t>(data, to_index));
-      raw_lit = factory()->NewStringLiteral(raw_str, span_start - 1);
-    } else {
-      raw_lit = factory()->NewStringLiteral(
-          ast_value_factory()->empty_string(), span_start - 1);
-    }
-    DCHECK_NOT_NULL(raw_lit);
+    const AstRawString* raw_str = ast_value_factory()->GetTwoByteString(
+        Vector<const uc16>(normalized_raw_chars, to_index));
+ Literal* raw_lit = factory()->NewStringLiteral(raw_str, span_start - 1);
     raw_strings->Add(raw_lit, zone());
   }

Index: test/mjsunit/harmony/templates.js
diff --git a/test/mjsunit/harmony/templates.js b/test/mjsunit/harmony/templates.js index ee37d8241219a2de1aad479cd3648338c5689d3f..eb53dfeb00ba09abb3206c921026f26382938e2d 100644
--- a/test/mjsunit/harmony/templates.js
+++ b/test/mjsunit/harmony/templates.js
@@ -428,3 +428,15 @@ var obj = {
   function tag(){}
   tag`a${1}b`;
 })();
+
+
+(function testRawLineNormalization() {
+  function raw0(callSiteObj) {
+    return callSiteObj.raw[0];
+  }
+  assertEquals(eval("raw0`\r`"), "\n");
+  assertEquals(eval("raw0`\r\n`"), "\n");
+  assertEquals(eval("raw0`\r\r\n`"), "\n\n");
+  assertEquals(eval("raw0`\r\n\r\n`"), "\n\n");
+  assertEquals(eval("raw0`\r\r\r\n`"), "\n\n\n");
+})();


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to