Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(294)

Unified Diff: src/parser.cc

Issue 742643003: Cache template literal callSiteObj (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix raw strings with wide characters, + some new tests Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/parser.cc
diff --git a/src/parser.cc b/src/parser.cc
index 5e7530496bdbcac537a066c30598b21c9c9b9bb4..bb637ee428aa8b6c2a9308b1f2939d15985377a0 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -5231,7 +5231,8 @@ Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state, int start,
}
return expr;
} else {
- ZoneList<Expression*>* raw_strings = TemplateRawStrings(lit);
+ uint32_t hash;
+ ZoneList<Expression*>* raw_strings = TemplateRawStrings(lit, &hash);
Handle<String> source(String::cast(script()->source()));
int cooked_idx = function_state_->NextMaterializedLiteralIndex();
@@ -5247,6 +5248,7 @@ Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state, int start,
factory()->NewArrayLiteral(
const_cast<ZoneList<Expression*>*>(raw_strings), raw_idx, pos),
zone());
+ args->Add(factory()->NewSmiLiteral(hash, pos), zone());
this->CheckPossibleEvalCall(tag, scope_);
Expression* call_site = factory()->NewCallRuntime(
ast_value_factory()->get_template_callsite_string(), NULL, args, start);
@@ -5261,7 +5263,8 @@ Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state, int start,
}
-ZoneList<Expression*>* Parser::TemplateRawStrings(const TemplateLiteral* lit) {
+ZoneList<Expression*>* Parser::TemplateRawStrings(const TemplateLiteral* lit,
+ uint32_t* hash) {
const ZoneList<int>* lengths = lit->lengths();
const ZoneList<Expression*>* cooked_strings = lit->cooked();
int total = lengths->length();
@@ -5281,11 +5284,32 @@ ZoneList<Expression*>* Parser::TemplateRawStrings(const TemplateLiteral* lit) {
raw_strings = new (zone()) ZoneList<Expression*>(total, zone());
+ int num_hash_chars = (total - 1) * 4;
+ for (int index = 0; index < total; ++index) {
+ // Accomodate multi-byte UTF8 characters without re-allocating
+ num_hash_chars += (lengths->at(index) * 5);
+ }
+
+ // Construct a single string to calculate a hash from, joined by a sequence
+ // which cannot be constructed using escape sequences.
+ Vector<uint8_t> hash_string = Vector<uint8_t>::New(num_hash_chars);
+ num_hash_chars = 0;
+
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 to_index = 0;
+ bool has_multibyte = false;
+
+ if (index) {
+ // Separate raw string elements by sequence which cannot otherwise be
+ // encountered.
+ hash_string[num_hash_chars++] = '$';
+ hash_string[num_hash_chars++] = '{';
+ hash_string[num_hash_chars++] = '.';
arv (Not doing code reviews) 2014/11/19 21:29:04 Can we skip the '.' here?
+ hash_string[num_hash_chars++] = '}';
+ }
SmartArrayPointer<char> raw_chars =
source->ToCString(ALLOW_NULLS, FAST_STRING_TRAVERSAL, span_start,
arv (Not doing code reviews) 2014/11/19 21:29:04 I still think this is suspicious. The scanner know
@@ -5301,15 +5325,37 @@ ZoneList<Expression*>* Parser::TemplateRawStrings(const TemplateLiteral* lit) {
++from_index;
}
}
+ if (ch & 0x80) has_multibyte = true;
+ hash_string[num_hash_chars++] = ch;
raw_chars[to_index++] = ch;
}
- const AstRawString* raw_str = ast_value_factory()->GetOneByteString(
- OneByteVector(raw_chars.get(), to_index));
- Literal* raw_lit = factory()->NewStringLiteral(raw_str, span_start - 1);
- raw_strings->Add(raw_lit, zone());
+ if (has_multibyte) {
+ // Convert to UTF16 --- One-byte AstRawStrings do not seem to be
arv (Not doing code reviews) 2014/11/19 21:29:04 one byte is used for ascii
+ // decoded from UTF8.
+ unibrow::Utf8Decoder<256> decoder(raw_chars.get(), to_index);
caitp (gmail) 2014/11/19 20:16:54 A better solution for this is probably to make sur
arv (Not doing code reviews) 2014/11/19 21:29:04 We have code in the scanner for handling this alre
+ uc16* buffer = zone()->NewArray<uc16>(to_index);
+ int utf16_length = decoder.WriteUtf16(buffer, to_index);
+
+ const AstRawString* raw_str = ast_value_factory()->GetTwoByteString(
+ Vector<const uint16_t>(reinterpret_cast<const uint16_t*>(buffer),
+ utf16_length));
+ Literal* raw_lit = factory()->NewStringLiteral(raw_str, span_start - 1);
+ raw_strings->Add(raw_lit, zone());
+ } else {
+ const AstRawString* raw_str = ast_value_factory()->GetOneByteString(
+ OneByteVector(raw_chars.get(), to_index));
+ Literal* raw_lit = factory()->NewStringLiteral(raw_str, span_start - 1);
+ raw_strings->Add(raw_lit, zone());
+ }
}
+ int utf16_length;
+ hash_string.Truncate(num_hash_chars);
+ *hash = StringHasher::ComputeUtf8Hash(Vector<const char>::cast(hash_string),
+ /* seed */ 0, &utf16_length);
+ hash_string.Dispose();
+
return raw_strings;
}
} } // namespace v8::internal
« src/harmony-templates.js ('K') | « src/parser.h ('k') | test/mjsunit/harmony/templates.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698