OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/api.h" | 7 #include "src/api.h" |
8 #include "src/ast.h" | 8 #include "src/ast.h" |
9 #include "src/bailout-reason.h" | 9 #include "src/bailout-reason.h" |
10 #include "src/base/platform/platform.h" | 10 #include "src/base/platform/platform.h" |
(...skipping 5213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5224 Token::ADD, cooked_str, expressions->at(i), | 5224 Token::ADD, cooked_str, expressions->at(i), |
5225 cooked_str->position()), | 5225 cooked_str->position()), |
5226 cooked_str->position()); | 5226 cooked_str->position()); |
5227 } | 5227 } |
5228 cooked_str = cooked_strings->at(i); | 5228 cooked_str = cooked_strings->at(i); |
5229 expr = factory()->NewBinaryOperation(Token::ADD, expr, cooked_str, | 5229 expr = factory()->NewBinaryOperation(Token::ADD, expr, cooked_str, |
5230 cooked_str->position()); | 5230 cooked_str->position()); |
5231 } | 5231 } |
5232 return expr; | 5232 return expr; |
5233 } else { | 5233 } else { |
5234 ZoneList<Expression*>* raw_strings = TemplateRawStrings(lit); | 5234 uint32_t hash; |
| 5235 ZoneList<Expression*>* raw_strings = TemplateRawStrings(lit, &hash); |
5235 Handle<String> source(String::cast(script()->source())); | 5236 Handle<String> source(String::cast(script()->source())); |
5236 | 5237 |
5237 int cooked_idx = function_state_->NextMaterializedLiteralIndex(); | 5238 int cooked_idx = function_state_->NextMaterializedLiteralIndex(); |
5238 int raw_idx = function_state_->NextMaterializedLiteralIndex(); | 5239 int raw_idx = function_state_->NextMaterializedLiteralIndex(); |
5239 | 5240 |
5240 // GetTemplateCallSite | 5241 // GetTemplateCallSite |
5241 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(4, zone()); | 5242 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(4, zone()); |
5242 args->Add(factory()->NewArrayLiteral( | 5243 args->Add(factory()->NewArrayLiteral( |
5243 const_cast<ZoneList<Expression*>*>(cooked_strings), | 5244 const_cast<ZoneList<Expression*>*>(cooked_strings), |
5244 cooked_idx, pos), | 5245 cooked_idx, pos), |
5245 zone()); | 5246 zone()); |
5246 args->Add( | 5247 args->Add( |
5247 factory()->NewArrayLiteral( | 5248 factory()->NewArrayLiteral( |
5248 const_cast<ZoneList<Expression*>*>(raw_strings), raw_idx, pos), | 5249 const_cast<ZoneList<Expression*>*>(raw_strings), raw_idx, pos), |
5249 zone()); | 5250 zone()); |
| 5251 |
| 5252 // Ensure hash is suitable as an Smi value |
| 5253 Smi* hash_obj = Smi::cast(Internals::IntToSmi(static_cast<int>(hash))); |
| 5254 args->Add(factory()->NewSmiLiteral(hash_obj->value(), pos), zone()); |
| 5255 |
5250 this->CheckPossibleEvalCall(tag, scope_); | 5256 this->CheckPossibleEvalCall(tag, scope_); |
5251 Expression* call_site = factory()->NewCallRuntime( | 5257 Expression* call_site = factory()->NewCallRuntime( |
5252 ast_value_factory()->get_template_callsite_string(), NULL, args, start); | 5258 ast_value_factory()->get_template_callsite_string(), NULL, args, start); |
5253 | 5259 |
5254 // Call TagFn | 5260 // Call TagFn |
5255 ZoneList<Expression*>* call_args = | 5261 ZoneList<Expression*>* call_args = |
5256 new (zone()) ZoneList<Expression*>(expressions->length() + 1, zone()); | 5262 new (zone()) ZoneList<Expression*>(expressions->length() + 1, zone()); |
5257 call_args->Add(call_site, zone()); | 5263 call_args->Add(call_site, zone()); |
5258 call_args->AddAll(*expressions, zone()); | 5264 call_args->AddAll(*expressions, zone()); |
5259 return factory()->NewCall(tag, call_args, pos); | 5265 return factory()->NewCall(tag, call_args, pos); |
5260 } | 5266 } |
5261 } | 5267 } |
5262 | 5268 |
5263 | 5269 |
5264 ZoneList<Expression*>* Parser::TemplateRawStrings(const TemplateLiteral* lit) { | 5270 ZoneList<Expression*>* Parser::TemplateRawStrings(const TemplateLiteral* lit, |
| 5271 uint32_t* hash) { |
5265 const ZoneList<int>* lengths = lit->lengths(); | 5272 const ZoneList<int>* lengths = lit->lengths(); |
5266 const ZoneList<Expression*>* cooked_strings = lit->cooked(); | 5273 const ZoneList<Expression*>* cooked_strings = lit->cooked(); |
5267 int total = lengths->length(); | 5274 int total = lengths->length(); |
5268 ZoneList<Expression*>* raw_strings; | 5275 ZoneList<Expression*>* raw_strings; |
5269 | 5276 |
5270 // Given a TemplateLiteral, produce a list of raw strings, used for generating | 5277 // Given a TemplateLiteral, produce a list of raw strings, used for generating |
5271 // a CallSite object for a tagged template invocations. | 5278 // a CallSite object for a tagged template invocations. |
5272 // | 5279 // |
5273 // A raw string will consist of the unescaped characters of a template span, | 5280 // A raw string will consist of the unescaped characters of a template span, |
5274 // with end-of-line sequences normalized to U+000A LINE FEEDs, and without | 5281 // with end-of-line sequences normalized to U+000A LINE FEEDs, and without |
5275 // leading or trailing template delimiters. | 5282 // leading or trailing template delimiters. |
5276 // | 5283 // |
5277 | 5284 |
5278 DCHECK(total); | 5285 DCHECK(total); |
5279 | 5286 |
5280 Handle<String> source(String::cast(script()->source())); | 5287 Handle<String> source(String::cast(script()->source())); |
5281 | 5288 |
5282 raw_strings = new (zone()) ZoneList<Expression*>(total, zone()); | 5289 raw_strings = new (zone()) ZoneList<Expression*>(total, zone()); |
5283 | 5290 |
| 5291 int num_hash_chars = (total - 1) * 3; |
| 5292 for (int index = 0; index < total; ++index) { |
| 5293 // Allow about length * 4 to handle most UTF8 sequences. |
| 5294 num_hash_chars += lengths->at(index) * 4; |
| 5295 } |
| 5296 |
| 5297 Vector<uint8_t> hash_string = Vector<uint8_t>::New(num_hash_chars); |
| 5298 num_hash_chars = 0; |
| 5299 |
5284 for (int index = 0; index < total; ++index) { | 5300 for (int index = 0; index < total; ++index) { |
5285 int span_start = cooked_strings->at(index)->position() + 1; | 5301 int span_start = cooked_strings->at(index)->position() + 1; |
5286 int span_end = lengths->at(index) - 1; | 5302 int span_end = lengths->at(index) - 1; |
5287 int length; | 5303 int length; |
5288 int to_index = 0; | 5304 int to_index = 0; |
5289 | 5305 |
| 5306 if (index) { |
| 5307 hash_string[num_hash_chars++] = '$'; |
| 5308 hash_string[num_hash_chars++] = '{'; |
| 5309 hash_string[num_hash_chars++] = '}'; |
| 5310 } |
| 5311 |
5290 SmartArrayPointer<char> raw_chars = | 5312 SmartArrayPointer<char> raw_chars = |
5291 source->ToCString(ALLOW_NULLS, FAST_STRING_TRAVERSAL, span_start, | 5313 source->ToCString(ALLOW_NULLS, FAST_STRING_TRAVERSAL, span_start, |
5292 span_end, &length); | 5314 span_end, &length); |
5293 | 5315 |
5294 // Normalize raw line-feeds. [U+000D U+000A] (CRLF) and [U+000D] (CR) must | 5316 // Normalize raw line-feeds. [U+000D U+000A] (CRLF) and [U+000D] (CR) must |
5295 // be translated into U+000A (LF). | 5317 // be translated into U+000A (LF). |
5296 for (int from_index = 0; from_index < length; ++from_index) { | 5318 for (int from_index = 0; from_index < length; ++from_index) { |
5297 char ch = raw_chars[from_index]; | 5319 char ch = raw_chars[from_index]; |
5298 if (ch == '\r') { | 5320 if (ch == '\r') { |
5299 ch = '\n'; | 5321 ch = '\n'; |
5300 if (from_index + 1 < length && raw_chars[from_index + 1] == '\n') { | 5322 if (from_index + 1 < length && raw_chars[from_index + 1] == '\n') { |
5301 ++from_index; | 5323 ++from_index; |
5302 } | 5324 } |
5303 } | 5325 } |
| 5326 hash_string[num_hash_chars++] = ch; |
5304 raw_chars[to_index++] = ch; | 5327 raw_chars[to_index++] = ch; |
5305 } | 5328 } |
5306 | 5329 |
5307 const AstRawString* raw_str = ast_value_factory()->GetOneByteString( | 5330 const AstRawString* raw_str = ast_value_factory()->GetOneByteString( |
5308 OneByteVector(raw_chars.get(), to_index)); | 5331 OneByteVector(raw_chars.get(), to_index)); |
5309 Literal* raw_lit = factory()->NewStringLiteral(raw_str, span_start - 1); | 5332 Literal* raw_lit = factory()->NewStringLiteral(raw_str, span_start - 1); |
5310 raw_strings->Add(raw_lit, zone()); | 5333 raw_strings->Add(raw_lit, zone()); |
5311 } | 5334 } |
5312 | 5335 |
| 5336 hash_string.Truncate(num_hash_chars); |
| 5337 int utf16_length; |
| 5338 *hash = StringHasher::ComputeUtf8Hash(Vector<const char>::cast(hash_string), |
| 5339 num_hash_chars, &utf16_length); |
| 5340 hash_string.Dispose(); |
| 5341 |
5313 return raw_strings; | 5342 return raw_strings; |
5314 } | 5343 } |
5315 } } // namespace v8::internal | 5344 } } // namespace v8::internal |
OLD | NEW |