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

Side by Side Diff: src/parser.cc

Issue 663683006: Implement ES6 Template Literals (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebased against https://chromium.googlesource.com/v8/v8.git/master 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | src/preparser.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 784 matching lines...) Expand 10 before | Expand all | Expand 10 after
795 pre_parse_timer_(NULL) { 795 pre_parse_timer_(NULL) {
796 DCHECK(!script().is_null() || info->source_stream() != NULL); 796 DCHECK(!script().is_null() || info->source_stream() != NULL);
797 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); 797 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping);
798 set_allow_modules(!info->is_native() && FLAG_harmony_modules); 798 set_allow_modules(!info->is_native() && FLAG_harmony_modules);
799 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); 799 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native());
800 set_allow_lazy(false); // Must be explicitly enabled. 800 set_allow_lazy(false); // Must be explicitly enabled.
801 set_allow_arrow_functions(FLAG_harmony_arrow_functions); 801 set_allow_arrow_functions(FLAG_harmony_arrow_functions);
802 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); 802 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals);
803 set_allow_classes(FLAG_harmony_classes); 803 set_allow_classes(FLAG_harmony_classes);
804 set_allow_harmony_object_literals(FLAG_harmony_object_literals); 804 set_allow_harmony_object_literals(FLAG_harmony_object_literals);
805 set_allow_harmony_templates(FLAG_harmony_templates);
805 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; 806 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
806 ++feature) { 807 ++feature) {
807 use_counts_[feature] = 0; 808 use_counts_[feature] = 0;
808 } 809 }
809 if (info->ast_value_factory() == NULL) { 810 if (info->ast_value_factory() == NULL) {
810 // info takes ownership of AstValueFactory. 811 // info takes ownership of AstValueFactory.
811 info->SetAstValueFactory( 812 info->SetAstValueFactory(
812 new AstValueFactory(zone(), parse_info->hash_seed)); 813 new AstValueFactory(zone(), parse_info->hash_seed));
813 } 814 }
814 } 815 }
(...skipping 3060 matching lines...) Expand 10 before | Expand all | Expand 10 after
3875 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); 3876 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping());
3876 reusable_preparser_->set_allow_modules(allow_modules()); 3877 reusable_preparser_->set_allow_modules(allow_modules());
3877 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); 3878 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax());
3878 reusable_preparser_->set_allow_lazy(true); 3879 reusable_preparser_->set_allow_lazy(true);
3879 reusable_preparser_->set_allow_arrow_functions(allow_arrow_functions()); 3880 reusable_preparser_->set_allow_arrow_functions(allow_arrow_functions());
3880 reusable_preparser_->set_allow_harmony_numeric_literals( 3881 reusable_preparser_->set_allow_harmony_numeric_literals(
3881 allow_harmony_numeric_literals()); 3882 allow_harmony_numeric_literals());
3882 reusable_preparser_->set_allow_classes(allow_classes()); 3883 reusable_preparser_->set_allow_classes(allow_classes());
3883 reusable_preparser_->set_allow_harmony_object_literals( 3884 reusable_preparser_->set_allow_harmony_object_literals(
3884 allow_harmony_object_literals()); 3885 allow_harmony_object_literals());
3886 reusable_preparser_->set_allow_harmony_templates(allow_harmony_templates());
3885 } 3887 }
3886 PreParser::PreParseResult result = 3888 PreParser::PreParseResult result =
3887 reusable_preparser_->PreParseLazyFunction(strict_mode(), 3889 reusable_preparser_->PreParseLazyFunction(strict_mode(),
3888 is_generator(), 3890 is_generator(),
3889 logger); 3891 logger);
3890 if (pre_parse_timer_ != NULL) { 3892 if (pre_parse_timer_ != NULL) {
3891 pre_parse_timer_->Stop(); 3893 pre_parse_timer_->Stop();
3892 } 3894 }
3893 return result; 3895 return result;
3894 } 3896 }
(...skipping 1182 matching lines...) Expand 10 before | Expand all | Expand 10 after
5077 info()->SetFunction(result); 5079 info()->SetFunction(result);
5078 5080
5079 // We cannot internalize on a background thread; a foreground task will take 5081 // We cannot internalize on a background thread; a foreground task will take
5080 // care of calling Parser::Internalize just before compilation. 5082 // care of calling Parser::Internalize just before compilation.
5081 5083
5082 if (compile_options() == ScriptCompiler::kProduceParserCache) { 5084 if (compile_options() == ScriptCompiler::kProduceParserCache) {
5083 if (result != NULL) *info_->cached_data() = recorder.GetScriptData(); 5085 if (result != NULL) *info_->cached_data() = recorder.GetScriptData();
5084 log_ = NULL; 5086 log_ = NULL;
5085 } 5087 }
5086 } 5088 }
5089
5090
5091 ParserTraits::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) {
5092 return new (zone()) ParserTraits::TemplateLiteral(zone(), pos);
5093 }
5094
5095
5096 void Parser::AddTemplateSpan(TemplateLiteralState* state, bool tail) {
5097 int pos = scanner()->location().beg_pos;
5098 int end = scanner()->location().end_pos - (tail ? 1 : 2);
5099 const AstRawString* tv = scanner()->CurrentSymbol(ast_value_factory());
5100 Literal* cooked = factory()->NewStringLiteral(tv, pos);
5101 (*state)->AddTemplateSpan(cooked, end, zone());
5102 }
5103
5104
5105 void Parser::AddTemplateExpression(TemplateLiteralState* state,
5106 Expression* expression) {
5107 (*state)->AddExpression(expression, zone());
5108 }
5109
5110
5111 Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state, int start,
5112 Expression* tag) {
5113 TemplateLiteral* lit = *state;
5114 int pos = lit->position();
5115 const ZoneList<Expression*>* cooked_strings = lit->cooked();
5116 const ZoneList<Expression*>* expressions = lit->expressions();
5117 CHECK(cooked_strings->length() == (expressions->length() + 1));
5118
5119 if (!tag) {
5120 // Build tree of BinaryOps to simplify code-generation
5121 Expression* expr = NULL;
5122
5123 if (expressions->length() == 0) {
5124 // Simple case: treat as string literal
5125 expr = cooked_strings->at(0);
5126 } else {
5127 int i;
5128 Expression* cooked_str = cooked_strings->at(0);
5129 expr = factory()->NewBinaryOperation(
5130 Token::ADD, cooked_str, expressions->at(0), cooked_str->position());
5131 for (i = 1; i < expressions->length(); ++i) {
5132 cooked_str = cooked_strings->at(i);
5133 expr = factory()->NewBinaryOperation(
5134 Token::ADD, expr, factory()->NewBinaryOperation(
5135 Token::ADD, cooked_str, expressions->at(i),
5136 cooked_str->position()),
5137 cooked_str->position());
5138 }
5139 cooked_str = cooked_strings->at(i);
5140 expr = factory()->NewBinaryOperation(Token::ADD, expr, cooked_str,
5141 cooked_str->position());
5142 }
5143 return expr;
5144 } else {
5145 ZoneList<Expression*>* raw_strings = TemplateRawStrings(lit);
5146 Handle<String> source(String::cast(script()->source()));
5147
5148 int cooked_idx = function_state_->NextMaterializedLiteralIndex();
5149 int raw_idx = function_state_->NextMaterializedLiteralIndex();
5150
5151 // GetTemplateCallSite
5152 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(4, zone());
5153 args->Add(factory()->NewArrayLiteral(
5154 const_cast<ZoneList<Expression*>*>(cooked_strings),
5155 cooked_idx, pos),
5156 zone());
5157 args->Add(
5158 factory()->NewArrayLiteral(
5159 const_cast<ZoneList<Expression*>*>(raw_strings), raw_idx, pos),
5160 zone());
5161 this->CheckPossibleEvalCall(tag, scope_);
5162 Expression* call_site = factory()->NewCallRuntime(
5163 ast_value_factory()->get_template_callsite_string(), NULL, args, start);
5164
5165 // Call TagFn
5166 ZoneList<Expression*>* call_args =
5167 new (zone()) ZoneList<Expression*>(expressions->length() + 1, zone());
5168 call_args->Add(call_site, zone());
5169 call_args->AddAll(*expressions, zone());
5170 return factory()->NewCall(tag, call_args, pos);
5171 }
5172 }
5173
5174
5175 ZoneList<Expression*>* Parser::TemplateRawStrings(const TemplateLiteral* lit) {
5176 const ZoneList<int>* lengths = lit->lengths();
5177 const ZoneList<Expression*>* cooked_strings = lit->cooked();
5178 int total = lengths->length();
5179 ZoneList<Expression*>* raw_strings;
5180
5181 // Given a TemplateLiteral, produce a list of raw strings, used for generating
5182 // a CallSite object for a tagged template invocations.
5183 //
5184 // A raw string will consist of the unescaped characters of a template span,
5185 // with end-of-line sequences normalized to U+000A LINE FEEDs, and without
5186 // leading or trailing template delimiters.
5187 //
5188
5189 DCHECK(total);
5190
5191 Handle<String> source(String::cast(script()->source()));
5192
5193 raw_strings = new (zone()) ZoneList<Expression*>(total, zone());
5194
5195 for (int index = 0; index < total; ++index) {
5196 int span_start = cooked_strings->at(index)->position() + 1;
5197 int span_end = lengths->at(index) - 1;
5198 int length;
5199 int to_index = 0;
5200
5201 SmartArrayPointer<char> raw_chars =
5202 source->ToCString(ALLOW_NULLS, FAST_STRING_TRAVERSAL, span_start,
5203 span_end, &length);
5204
5205 // Normalize raw line-feeds. [U+000D U+000A] (CRLF) and [U+000D] (CR) must
5206 // be translated into U+000A (LF).
5207 for (int from_index = 0; from_index < length; ++from_index) {
5208 char ch = raw_chars[from_index];
5209 if (ch == '\r') {
5210 ch = '\n';
5211 if (from_index + 1 < length && raw_chars[from_index + 1] == '\n') {
5212 ++from_index;
5213 }
5214 }
5215 raw_chars[to_index++] = ch;
5216 }
5217
5218 const AstRawString* raw_str = ast_value_factory()->GetOneByteString(
5219 OneByteVector(raw_chars.get(), to_index));
5220 Literal* raw_lit = factory()->NewStringLiteral(raw_str, span_start - 1);
5221 raw_strings->Add(raw_lit, zone());
5222 }
5223
5224 return raw_strings;
5225 }
5087 } } // namespace v8::internal 5226 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | src/preparser.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698