Revision: 18680
Author:   [email protected]
Date:     Mon Jan 20 09:25:23 2014 UTC
Log: Experimental lexer: fix internalization and allocation of literals.

BUG=
[email protected], [email protected]

Review URL: https://codereview.chromium.org/140913009
http://code.google.com/p/v8/source/detail?r=18680

Modified:
 /branches/experimental/parser/src/factory.cc
 /branches/experimental/parser/src/factory.h
 /branches/experimental/parser/src/lexer/experimental-scanner.cc
 /branches/experimental/parser/src/lexer/experimental-scanner.h
 /branches/experimental/parser/src/objects-inl.h
 /branches/experimental/parser/src/objects.cc
 /branches/experimental/parser/src/parser.cc
 /branches/experimental/parser/src/parser.h

=======================================
--- /branches/experimental/parser/src/factory.cc Fri Jan 17 11:13:31 2014 UTC +++ /branches/experimental/parser/src/factory.cc Mon Jan 20 09:25:23 2014 UTC
@@ -227,7 +227,7 @@

 Handle<String> Factory::InternalizeOneByteString(
     Handle<SeqOneByteString> string, int from, int length) {
-  SubStringOneByteStringKey key(string, from, length);
+  SubStringKey<uint8_t> key(string, from, length);
   return InternalizeStringWithKey(&key);
 }

@@ -244,6 +244,12 @@
                      isolate()->heap()->InternalizeStringWithKey(key),
                      String);
 }
+
+
+template Handle<String> Factory::InternalizeStringWithKey<
+    SubStringKey<uint8_t> > (SubStringKey<uint8_t>* key);
+template Handle<String> Factory::InternalizeStringWithKey<
+    SubStringKey<uint16_t> > (SubStringKey<uint16_t>* key);


 Handle<String> Factory::NewStringFromOneByte(Vector<const uint8_t> string,
=======================================
--- /branches/experimental/parser/src/factory.h Fri Jan 17 11:13:31 2014 UTC
+++ /branches/experimental/parser/src/factory.h Mon Jan 20 09:25:23 2014 UTC
@@ -99,9 +99,9 @@
   }
   Handle<String> InternalizeString(Handle<String> str);
   Handle<String> InternalizeOneByteString(Vector<const uint8_t> str);
-  Handle<String> InternalizeOneByteString(Handle<SeqOneByteString>,
-                                   int from,
-                                   int length);
+  Handle<String> InternalizeOneByteString(
+      Handle<SeqOneByteString>, int from, int length);
+
   Handle<String> InternalizeTwoByteString(Vector<const uc16> str);

   template<class StringTableKey>
=======================================
--- /branches/experimental/parser/src/lexer/experimental-scanner.cc Mon Dec 2 15:07:21 2013 UTC +++ /branches/experimental/parser/src/lexer/experimental-scanner.cc Mon Jan 20 09:25:23 2014 UTC
@@ -50,6 +50,33 @@
   String::FlatContent content = source_handle_->GetFlatContent();
return reinterpret_cast<const int8_t*>(content.ToOneByteVector().start());
 }
+
+
+template<>
+bool ExperimentalScanner<uint8_t>::IsSubstringOfSource(const TokenDesc& token) {
+  return !token.has_escapes;
+}
+
+
+template<>
+bool ExperimentalScanner<uint16_t>::IsSubstringOfSource(
+    const TokenDesc& token) {
+  if (token.has_escapes) return false;
+  const uint16_t* start = buffer_ + token.beg_pos;
+  const uint16_t* end = buffer_ + token.end_pos;
+  for (const uint16_t* cursor = start; cursor != end; ++cursor) {
+    if (*cursor >= unibrow::Latin1::kMaxChar) return true;
+  }
+  return false;
+}
+
+
+template<>
+bool ExperimentalScanner<int8_t>::IsSubstringOfSource(const TokenDesc& token) {
+  // FIXME: implement.
+  UNREACHABLE();
+  return false;
+}


 template<>
@@ -62,37 +89,16 @@
     ++start;
     --end;
   }
-  if (!token.has_escapes) {
+  if (IsSubstringOfSource(token)) {
     literal->is_ascii = true;
+    literal->is_in_buffer = false;
+    literal->offset = start - buffer_;
     literal->length = end - start;
     literal->ascii_string = Vector<const char>(
         reinterpret_cast<const char*>(start), literal->length);
     return true;
   }
-  literal->buffer.Reset();
-  for (const uint8_t* cursor = start; cursor != end;) {
-    if (*cursor != '\\') {
-      literal->buffer.AddChar(*cursor++);
-    } else if (token.token == Token::IDENTIFIER) {
-      uc32 c;
-      cursor = ScanIdentifierUnicodeEscape(cursor, end, &c);
-      ASSERT(cursor != NULL);
-      if (cursor == NULL) return false;
-      literal->buffer.AddChar(c);
-    } else {
-      cursor = ScanEscape(cursor, end, &literal->buffer);
-      ASSERT(cursor != NULL);
-      if (cursor == NULL) return false;
-    }
-  }
-  literal->is_ascii = literal->buffer.is_ascii();
-  literal->length = literal->buffer.length();
-  if (literal->is_ascii) {
-    literal->ascii_string = literal->buffer.ascii_literal();
-  } else {
-    literal->utf16_string = literal->buffer.utf16_literal();
-  }
-  return true;
+  return CopyToLiteralBuffer(start, end, token, literal);
 }


@@ -106,44 +112,56 @@
     ++start;
     --end;
   }
-  if (!token.has_escapes) {
-    // UTF-16 can also contain only one byte chars. Note that is_ascii here
-    // means is_onebyte.
-    literal->is_ascii = true;
-    literal->buffer.Reset();
-    for (const uint16_t* cursor = start; cursor != end; ++cursor) {
-      if (*cursor >= unibrow::Latin1::kMaxChar) {
-        literal->is_ascii = false;
-        break;
-      }
-      literal->buffer.AddChar(*cursor);
-    }
+  if (IsSubstringOfSource(token)) {
+    literal->is_ascii = false;
+    literal->is_in_buffer = false;
+    literal->offset = start - buffer_;
     literal->length = end - start;
-    if (literal->is_ascii) {
-      literal->ascii_string = literal->buffer.ascii_literal();
-    } else {
-      literal->buffer.Reset();
- literal->utf16_string = Vector<const uint16_t>(start, literal->length);
-    }
+    literal->utf16_string = Vector<const uint16_t>(start, literal->length);
     return true;
   }
+  return CopyToLiteralBuffer(start, end, token, literal);
+}
+
+
+template<>
+bool ExperimentalScanner<int8_t>::FillLiteral(
+    const TokenDesc& token, LiteralDesc* literal) {
+  // FIXME: implement.
+  UNREACHABLE();
+  return false;
+}
+
+
+template<class Char>
+bool ExperimentalScanner<Char>::CopyToLiteralBuffer(const Char* start,
+                                                    const Char* end,
+                                                    const TokenDesc& token,
+                                                    LiteralDesc* literal) {
   literal->buffer.Reset();
-  for (const uint16_t* cursor = start; cursor != end;) {
-    if (*cursor != '\\') {
-      literal->buffer.AddChar(*cursor++);
-    } else if (token.token == Token::IDENTIFIER) {
-      uc32 c;
-      cursor = ScanIdentifierUnicodeEscape(cursor, end, &c);
-      ASSERT(cursor != NULL);
-      if (cursor == NULL) return false;
-      literal->buffer.AddChar(c);
-    } else {
-      cursor = ScanEscape(cursor, end, &literal->buffer);
-      ASSERT(cursor != NULL);
-      if (cursor == NULL) return false;
+  if (token.has_escapes) {
+    for (const Char* cursor = start; cursor != end;) {
+      if (*cursor != '\\') {
+        literal->buffer.AddChar(*cursor++);
+      } else if (token.token == Token::IDENTIFIER) {
+        uc32 c;
+        cursor = ScanIdentifierUnicodeEscape(cursor, end, &c);
+        ASSERT(cursor != NULL);
+        if (cursor == NULL) return false;
+        literal->buffer.AddChar(c);
+      } else {
+        cursor = ScanEscape(cursor, end, &literal->buffer);
+        ASSERT(cursor != NULL);
+        if (cursor == NULL) return false;
+      }
+    }
+  } else {
+    for (const Char* cursor = start; cursor != end;) {
+        literal->buffer.AddChar(*cursor++);
     }
   }
   literal->is_ascii = literal->buffer.is_ascii();
+  literal->is_in_buffer = true;
   literal->length = literal->buffer.length();
   if (literal->is_ascii) {
     literal->ascii_string = literal->buffer.ascii_literal();
@@ -152,14 +170,80 @@
   }
   return true;
 }
+
+
+template<class Char>
+Handle<String> ExperimentalScanner<Char>::InternalizeLiteral(
+    LiteralDesc* literal) {
+  Factory* factory = isolate_->factory();
+  if (literal->is_in_buffer) {
+    return literal->is_ascii
+        ? factory->InternalizeOneByteString(
+            Vector<const uint8_t>::cast(literal->ascii_string))
+        : factory->InternalizeTwoByteString(literal->utf16_string);
+  }
+  if (sizeof(Char) == 1) {
+    SubStringKey<uint8_t> key(
+        source_handle_, literal->offset, literal->length);
+    return factory->InternalizeStringWithKey(&key);
+  } else {
+    SubStringKey<uint16_t> key(
+        source_handle_, literal->offset, literal->length);
+    return factory->InternalizeStringWithKey(&key);
+  }
+}
+

 template<>
-bool ExperimentalScanner<int8_t>::FillLiteral(
-    const TokenDesc& token, LiteralDesc* literal) {
-  // FIXME: implement.
-  return false;
+Handle<String> ExperimentalScanner<uint8_t>::AllocateLiteral(
+    LiteralDesc* literal, PretenureFlag pretenured) {
+  Factory* factory = isolate_->factory();
+  if (literal->is_in_buffer) {
+    return literal->is_ascii
+        ? factory->NewStringFromAscii(literal->ascii_string, pretenured)
+        : factory->NewStringFromTwoByte(literal->utf16_string, pretenured);
+  }
+  int from = literal->offset;
+  int length = literal->length;
+  // Save the offset and the length before allocating the string as it may
+  // cause a GC, invalidate the literal, and move the source.
+  Handle<String> result = factory->NewRawOneByteString(length, pretenured);
+  uint8_t* chars = SeqOneByteString::cast(*result)->GetChars();
+  String::WriteToFlat(*source_handle_, chars, from, from + length);
+  return result;
 }


+template<>
+Handle<String> ExperimentalScanner<uint16_t>::AllocateLiteral(
+    LiteralDesc* literal, PretenureFlag pretenured) {
+  Factory* factory = isolate_->factory();
+  if (literal->is_in_buffer) {
+    return literal->is_ascii
+        ? factory->NewStringFromAscii(literal->ascii_string, pretenured)
+        : factory->NewStringFromTwoByte(literal->utf16_string, pretenured);
+  }
+  // Save the offset and the length before allocating the string as it may
+  // cause a GC, invalidate the literal, and move the source.
+  int from = literal->offset;
+  int length = literal->length;
+  Handle<String> result = factory->NewRawTwoByteString(length, pretenured);
+  uint16_t* chars = SeqTwoByteString::cast(*result)->GetChars();
+  String::WriteToFlat(*source_handle_, chars, from, from + length);
+  return result;
 }
+
+
+template<>
+Handle<String> ExperimentalScanner<int8_t>::AllocateLiteral(
+    LiteralDesc* literal, PretenureFlag pretenured) {
+  // FIXME: implement
+  UNREACHABLE();
+  return Handle<String>();
 }
+
+template class ExperimentalScanner<uint8_t>;
+template class ExperimentalScanner<uint16_t>;
+template class ExperimentalScanner<int8_t>;
+
+} }  // v8::internal
=======================================
--- /branches/experimental/parser/src/lexer/experimental-scanner.h Fri Jan 17 16:36:05 2014 UTC +++ /branches/experimental/parser/src/lexer/experimental-scanner.h Mon Jan 20 09:25:23 2014 UTC
@@ -156,33 +156,40 @@
     return has_line_terminator_before_next_ ||
            has_multiline_comment_before_next_;
   }
+
+  Handle<String> GetLiteralSymbol() {
+    EnsureCurrentLiteralIsValid();
+    return InternalizeLiteral(current_literal_);
+  }
+
+  Handle<String> GetLiteralString(PretenureFlag tenured) {
+    EnsureCurrentLiteralIsValid();
+    return AllocateLiteral(current_literal_, tenured);
+  }
+
+  Handle<String> GetNextLiteralString(PretenureFlag tenured) {
+    EnsureNextLiteralIsValid();
+    return AllocateLiteral(next_literal_, tenured);
+  }

   Vector<const char> literal_ascii_string() {
-    if (!current_literal_->Valid(current_.beg_pos)) {
-      FillLiteral(current_, current_literal_);
-    }
+    EnsureCurrentLiteralIsValid();
     return current_literal_->ascii_string;
   }

   Vector<const uc16> literal_utf16_string() {
-    if (!current_literal_->Valid(current_.beg_pos)) {
-      FillLiteral(current_, current_literal_);
-    }
+    EnsureCurrentLiteralIsValid();
     return current_literal_->utf16_string;
   }

   int literal_length() {
-    if (!current_literal_->Valid(current_.beg_pos)) {
-      FillLiteral(current_, current_literal_);
-    }
+    EnsureCurrentLiteralIsValid();
     return current_literal_->length;
   }

// This should be is_onebyte or is_latin1; it doesn't mean ASCII for real.
   bool is_literal_ascii() {
-    if (!current_literal_->Valid(current_.beg_pos)) {
-      FillLiteral(current_, current_literal_);
-    }
+    EnsureCurrentLiteralIsValid();
     return current_literal_->is_ascii;
   }

@@ -198,30 +205,22 @@
   }

   Vector<const char> next_literal_ascii_string() {
-    if (!next_literal_->Valid(next_.beg_pos)) {
-      FillLiteral(next_, next_literal_);
-    }
+    EnsureNextLiteralIsValid();
     return next_literal_->ascii_string;
   }

   Vector<const uc16> next_literal_utf16_string() {
-    if (!next_literal_->Valid(next_.beg_pos)) {
-      FillLiteral(next_, next_literal_);
-    }
+    EnsureNextLiteralIsValid();
     return next_literal_->utf16_string;
   }

   int next_literal_length() {
-    if (!next_literal_->Valid(next_.beg_pos)) {
-      FillLiteral(next_, next_literal_);
-    }
+    EnsureNextLiteralIsValid();
     return next_literal_->length;
   }

   bool is_next_literal_ascii() {
-    if (!next_literal_->Valid(next_.beg_pos)) {
-      FillLiteral(next_, next_literal_);
-    }
+    EnsureNextLiteralIsValid();
     return next_literal_->is_ascii;
   }

@@ -244,11 +243,14 @@
   struct LiteralDesc {
     int beg_pos;
     bool is_ascii;
+    bool is_in_buffer;
+    int offset;
     int length;
     Vector<const char> ascii_string;
     Vector<const uc16> utf16_string;
     LiteralBuffer buffer;
-    LiteralDesc() : beg_pos(-1), is_ascii(false), length(0) { }
+    LiteralDesc() : beg_pos(-1), is_ascii(false), is_in_buffer(false),
+                    offset(0), length(0) { }
     bool Valid(int pos) { return beg_pos == pos; }
   };

@@ -256,9 +258,25 @@
virtual bool FillLiteral(const TokenDesc& token, LiteralDesc* literal) = 0;

   void ResetLiterals() {
-    current_literal_->beg_pos = -1;
-    next_literal_->beg_pos = -1;
+    if (!current_literal_->is_in_buffer) current_literal_->beg_pos = -1;
+    if (!next_literal_->is_in_buffer) next_literal_->beg_pos = -1;
+  }
+
+  void EnsureCurrentLiteralIsValid() {
+    if (!current_literal_->Valid(current_.beg_pos)) {
+      FillLiteral(current_, current_literal_);
+    }
+  }
+
+  void EnsureNextLiteralIsValid() {
+    if (!next_literal_->Valid(next_.beg_pos)) {
+      FillLiteral(next_, next_literal_);
+    }
   }
+
+  virtual Handle<String> InternalizeLiteral(LiteralDesc* literal) = 0;
+  virtual Handle<String> AllocateLiteral(LiteralDesc* literal,
+                                         PretenureFlag tenured) = 0;

   Isolate* isolate_;
   UnicodeCache* unicode_cache_;
@@ -340,6 +358,10 @@
   const Char* GetNewBufferBasedOnHandle() const;

   virtual bool FillLiteral(const TokenDesc& token, LiteralDesc* literal);
+  virtual Handle<String> InternalizeLiteral(LiteralDesc* literal);
+  virtual Handle<String> AllocateLiteral(LiteralDesc* literal,
+                                         PretenureFlag tenured);
+

  private:
   bool ValidIdentifierPart() {
@@ -366,6 +388,15 @@
                          const Char* end,
                          LiteralBuffer* literal);

+  // Returns true if the literal of the token can be represented as a
+  // substring of the source.
+  bool IsSubstringOfSource(const TokenDesc& token);
+
+  bool CopyToLiteralBuffer(const Char* start,
+                           const Char* end,
+                           const TokenDesc& token,
+                           LiteralDesc* literal);
+
   Handle<String> source_handle_;
   const Char* buffer_;
   const Char* buffer_end_;
=======================================
--- /branches/experimental/parser/src/objects-inl.h Fri Jan 17 11:13:31 2014 UTC +++ /branches/experimental/parser/src/objects-inl.h Mon Jan 20 09:25:23 2014 UTC
@@ -499,38 +499,34 @@
 };


-class SubStringOneByteStringKey : public HashTableKey {
+template<class Char>
+class SubStringKey : public HashTableKey {
  public:
-  explicit SubStringOneByteStringKey(Handle<SeqOneByteString> string,
-                                     int from,
-                                     int length)
+  SubStringKey(Handle<String> string, int from, int length)
       : string_(string), from_(from), length_(length) { }

   virtual uint32_t Hash() {
     ASSERT(length_ >= 0);
     ASSERT(from_ + length_ <= string_->length());
-    uint8_t* chars = string_->GetChars() + from_;
+    const Char* chars = GetChars() + from_;
     hash_field_ = StringHasher::HashSequentialString(
         chars, length_, string_->GetHeap()->HashSeed());
     uint32_t result = hash_field_ >> String::kHashShift;
ASSERT(result != 0); // Ensure that the hash value of 0 is never computed.
     return result;
   }
-

   virtual uint32_t HashForObject(Object* other) {
     return String::cast(other)->Hash();
   }

-  virtual bool IsMatch(Object* string) {
-    Vector<const uint8_t> chars(string_->GetChars() + from_, length_);
-    return String::cast(string)->IsOneByteEqualTo(chars);
-  }
-
+  virtual bool IsMatch(Object* string);
   virtual MaybeObject* AsObject(Heap* heap);

  private:
-  Handle<SeqOneByteString> string_;
+  const Char* GetChars();
+
+  Handle<String> string_;
   int from_;
   int length_;
   uint32_t hash_field_;
=======================================
--- /branches/experimental/parser/src/objects.cc Fri Jan 17 11:13:31 2014 UTC +++ /branches/experimental/parser/src/objects.cc Mon Jan 20 09:25:23 2014 UTC
@@ -14006,17 +14006,61 @@
 }


-MaybeObject* SubStringOneByteStringKey::AsObject(Heap* heap) {
+MaybeObject* TwoByteStringKey::AsObject(Heap* heap) {
   if (hash_field_ == 0) Hash();
-  Vector<const uint8_t> chars(string_->GetChars() + from_, length_);
+  return heap->AllocateTwoByteInternalizedString(string_, hash_field_);
+}
+
+
+template<>
+const uint8_t* SubStringKey<uint8_t>::GetChars() {
+  return string_->IsSeqOneByteString()
+      ? SeqOneByteString::cast(*string_)->GetChars()
+      : ExternalAsciiString::cast(*string_)->GetChars();
+}
+
+
+template<>
+const uint16_t* SubStringKey<uint16_t>::GetChars() {
+  return string_->IsSeqTwoByteString()
+      ? SeqTwoByteString::cast(*string_)->GetChars()
+      : ExternalTwoByteString::cast(*string_)->GetChars();
+}
+
+
+template<>
+MaybeObject* SubStringKey<uint8_t>::AsObject(Heap* heap) {
+  if (hash_field_ == 0) Hash();
+  Vector<const uint8_t> chars(GetChars() + from_, length_);
   return heap->AllocateOneByteInternalizedString(chars, hash_field_);
 }


-MaybeObject* TwoByteStringKey::AsObject(Heap* heap) {
+template<>
+MaybeObject* SubStringKey<uint16_t>::AsObject(
+    Heap* heap) {
   if (hash_field_ == 0) Hash();
-  return heap->AllocateTwoByteInternalizedString(string_, hash_field_);
+  Vector<const uint16_t> chars(GetChars() + from_, length_);
+  return heap->AllocateTwoByteInternalizedString(chars, hash_field_);
 }
+
+
+template<>
+bool SubStringKey<uint8_t>::IsMatch(Object* string) {
+  Vector<const uint8_t> chars(GetChars() + from_, length_);
+  return String::cast(string)->IsOneByteEqualTo(chars);
+}
+
+
+template<>
+bool SubStringKey<uint16_t>::IsMatch(Object* string) {
+  Vector<const uint16_t> chars(GetChars() + from_, length_);
+  return String::cast(string)->IsTwoByteEqualTo(chars);
+}
+
+
+template class SubStringKey<uint8_t>;
+template class SubStringKey<uint16_t>;


// InternalizedStringKey carries a string/internalized-string object as key.
=======================================
--- /branches/experimental/parser/src/parser.cc Wed Dec 11 14:40:08 2013 UTC
+++ /branches/experimental/parser/src/parser.cc Mon Jan 20 09:25:23 2014 UTC
@@ -256,13 +256,7 @@
   // if there is some preparser data.
   if (static_cast<unsigned>(symbol_id)
       >= static_cast<unsigned>(symbol_cache_.length())) {
-    if (scanner().is_literal_ascii()) {
-      return isolate()->factory()->InternalizeOneByteString(
-          Vector<const uint8_t>::cast(scanner().literal_ascii_string()));
-    } else {
-      return isolate()->factory()->InternalizeTwoByteString(
-          scanner().literal_utf16_string());
-    }
+    return scanner().GetLiteralSymbol();
   }
   return LookupCachedSymbol(symbol_id);
 }
@@ -277,13 +271,7 @@
   }
   Handle<String> result = symbol_cache_.at(symbol_id);
   if (result.is_null()) {
-    if (scanner().is_literal_ascii()) {
-      result = isolate()->factory()->InternalizeOneByteString(
-          Vector<const uint8_t>::cast(scanner().literal_ascii_string()));
-    } else {
-      result = isolate()->factory()->InternalizeTwoByteString(
-          scanner().literal_utf16_string());
-    }
+    result = scanner().GetLiteralSymbol();
     symbol_cache_.at(symbol_id) = result;
     return result;
   }
@@ -576,7 +564,7 @@
   fni_ = new(zone()) FuncNameInferrer(isolate(), zone());

   // Initialize parser state.
-  FlattenString(source);
+  source = FlattenGetString(source);
   FunctionLiteral* result;
   if (source->IsTwoByteRepresentation()) {
     delete reusable_preparser_;
@@ -707,7 +695,6 @@
     timer.Start();
   }
   // Initialize parser state.
-  FlattenString(source);
   Handle<SharedFunctionInfo> shared_info = info()->shared_info();
   FunctionLiteral* result = ParseLazy(
       source, shared_info->start_position(), shared_info->end_position());
@@ -721,6 +708,7 @@


FunctionLiteral* Parser::ParseLazy(Handle<String> source, int start, int end) {
+  source = FlattenGetString(source);
   delete reusable_preparser_;
   delete scanner_;
   if (source->IsTwoByteRepresentation()) {
@@ -5614,6 +5602,7 @@
                                        Handle<String> source) {
   CompleteParserRecorder recorder;
   HistogramTimerScope timer(isolate->counters()->pre_parse());
+  source = FlattenGetString(source);
   ScannerBase* scanner = NULL;
   if (source->IsTwoByteRepresentation()) {
     scanner = new ExperimentalScanner<uint16_t>(source, isolate);
=======================================
--- /branches/experimental/parser/src/parser.h  Thu Jan  9 09:32:53 2014 UTC
+++ /branches/experimental/parser/src/parser.h  Mon Jan 20 09:25:23 2014 UTC
@@ -666,23 +666,11 @@
bool CheckInOrOf(bool accept_OF, ForEachStatement::VisitMode* visit_mode);

   Handle<String> LiteralString(PretenureFlag tenured) {
-    if (scanner().is_literal_ascii()) {
-      return isolate_->factory()->NewStringFromAscii(
-          scanner().literal_ascii_string(), tenured);
-    } else {
-      return isolate_->factory()->NewStringFromTwoByte(
-            scanner().literal_utf16_string(), tenured);
-    }
+    return scanner().GetLiteralString(tenured);
   }

   Handle<String> NextLiteralString(PretenureFlag tenured) {
-    if (scanner().is_next_literal_ascii()) {
-      return isolate_->factory()->NewStringFromAscii(
-          scanner().next_literal_ascii_string(), tenured);
-    } else {
-      return isolate_->factory()->NewStringFromTwoByte(
-          scanner().next_literal_utf16_string(), tenured);
-    }
+    return scanner().GetNextLiteralString(tenured);
   }

   Handle<String> GetSymbol();

--
--
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/groups/opt_out.

Reply via email to