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

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: Add more redundant and thorough mjsunit 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 unified diff | Download patch | Annotate | Revision Log
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 797 matching lines...) Expand 10 before | Expand all | Expand 10 after
808 pre_parse_timer_(NULL) { 808 pre_parse_timer_(NULL) {
809 DCHECK(!script().is_null() || info->source_stream() != NULL); 809 DCHECK(!script().is_null() || info->source_stream() != NULL);
810 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); 810 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping);
811 set_allow_modules(!info->is_native() && FLAG_harmony_modules); 811 set_allow_modules(!info->is_native() && FLAG_harmony_modules);
812 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); 812 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native());
813 set_allow_lazy(false); // Must be explicitly enabled. 813 set_allow_lazy(false); // Must be explicitly enabled.
814 set_allow_arrow_functions(FLAG_harmony_arrow_functions); 814 set_allow_arrow_functions(FLAG_harmony_arrow_functions);
815 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); 815 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals);
816 set_allow_classes(FLAG_harmony_classes); 816 set_allow_classes(FLAG_harmony_classes);
817 set_allow_harmony_object_literals(FLAG_harmony_object_literals); 817 set_allow_harmony_object_literals(FLAG_harmony_object_literals);
818 set_allow_harmony_templates(FLAG_harmony_templates);
818 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; 819 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
819 ++feature) { 820 ++feature) {
820 use_counts_[feature] = 0; 821 use_counts_[feature] = 0;
821 } 822 }
822 if (info->ast_value_factory() == NULL) { 823 if (info->ast_value_factory() == NULL) {
823 // info takes ownership of AstValueFactory. 824 // info takes ownership of AstValueFactory.
824 info->SetAstValueFactory( 825 info->SetAstValueFactory(
825 new AstValueFactory(zone(), parse_info->hash_seed)); 826 new AstValueFactory(zone(), parse_info->hash_seed));
826 } 827 }
827 } 828 }
(...skipping 3076 matching lines...) Expand 10 before | Expand all | Expand 10 after
3904 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); 3905 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping());
3905 reusable_preparser_->set_allow_modules(allow_modules()); 3906 reusable_preparser_->set_allow_modules(allow_modules());
3906 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); 3907 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax());
3907 reusable_preparser_->set_allow_lazy(true); 3908 reusable_preparser_->set_allow_lazy(true);
3908 reusable_preparser_->set_allow_arrow_functions(allow_arrow_functions()); 3909 reusable_preparser_->set_allow_arrow_functions(allow_arrow_functions());
3909 reusable_preparser_->set_allow_harmony_numeric_literals( 3910 reusable_preparser_->set_allow_harmony_numeric_literals(
3910 allow_harmony_numeric_literals()); 3911 allow_harmony_numeric_literals());
3911 reusable_preparser_->set_allow_classes(allow_classes()); 3912 reusable_preparser_->set_allow_classes(allow_classes());
3912 reusable_preparser_->set_allow_harmony_object_literals( 3913 reusable_preparser_->set_allow_harmony_object_literals(
3913 allow_harmony_object_literals()); 3914 allow_harmony_object_literals());
3915 reusable_preparser_->set_allow_harmony_templates(allow_harmony_templates());
3914 } 3916 }
3915 PreParser::PreParseResult result = 3917 PreParser::PreParseResult result =
3916 reusable_preparser_->PreParseLazyFunction(strict_mode(), 3918 reusable_preparser_->PreParseLazyFunction(strict_mode(),
3917 is_generator(), 3919 is_generator(),
3918 logger); 3920 logger);
3919 if (pre_parse_timer_ != NULL) { 3921 if (pre_parse_timer_ != NULL) {
3920 pre_parse_timer_->Stop(); 3922 pre_parse_timer_->Stop();
3921 } 3923 }
3922 return result; 3924 return result;
3923 } 3925 }
(...skipping 1098 matching lines...) Expand 10 before | Expand all | Expand 10 after
5022 info()->SetFunction(result); 5024 info()->SetFunction(result);
5023 5025
5024 // We cannot internalize on a background thread; a foreground task will take 5026 // We cannot internalize on a background thread; a foreground task will take
5025 // care of calling Parser::Internalize just before compilation. 5027 // care of calling Parser::Internalize just before compilation.
5026 5028
5027 if (compile_options() == ScriptCompiler::kProduceParserCache) { 5029 if (compile_options() == ScriptCompiler::kProduceParserCache) {
5028 if (result != NULL) *info_->cached_data() = recorder.GetScriptData(); 5030 if (result != NULL) *info_->cached_data() = recorder.GetScriptData();
5029 log_ = NULL; 5031 log_ = NULL;
5030 } 5032 }
5031 } 5033 }
5034
5035
5036 ParserTraits::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) {
5037 return new (zone()) ParserTraits::TemplateLiteral(zone(), pos);
5038 }
5039
5040
5041 void Parser::AddTemplateSpan(TemplateLiteralState* state, bool tail) {
5042 int pos = scanner()->location().beg_pos;
5043 int end = scanner()->location().end_pos - (tail ? 1 : 2);
5044 const AstRawString* tv = scanner()->CurrentSymbol(ast_value_factory());
5045 Literal* cooked = factory()->NewStringLiteral(tv, pos);
5046 (*state)->AddTemplateSpan(cooked, end, zone());
5047 }
5048
5049
5050 void Parser::AddTemplateExpression(TemplateLiteralState* state,
5051 Expression* expression) {
5052 (*state)->AddExpression(expression, zone());
5053 }
5054
5055
5056 Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state,
5057 int start, Expression* tag) {
5058 #define COOKED_STRING(i) cooked_strings->at(i)
5059 #define POS(i) cooked_strings->at(i)->position()
5060 #define EXPR(i) expressions->at(i)
5061 TemplateLiteral* lit = *state;
5062 int pos = lit->position();
5063 const ZoneList<Expression*>* cooked_strings = lit->cooked();
5064 const ZoneList<Expression*>* expressions = lit->expressions();
5065 CHECK(cooked_strings->length() == (expressions->length() + 1));
5066
5067 if (!tag) {
5068 // Build tree of BinaryOps to simplify code-generation
5069 Expression* expr = NULL;
5070
5071 if (expressions->length() == 0) {
5072 // Simple case: treat as string literal
5073 expr = COOKED_STRING(0);
5074 } else {
5075 int i;
5076 expr = factory()->NewBinaryOperation(Token::ADD,
5077 COOKED_STRING(0), EXPR(0), POS(0));
5078 for (i = 1; i < expressions->length(); ++i) {
5079 expr = factory()->NewBinaryOperation(Token::ADD,
5080 expr, factory()->NewBinaryOperation(Token::ADD, COOKED_STRING(i),
5081 EXPR(i), POS(i)), POS(i));
5082 }
5083 expr = factory()->NewBinaryOperation(Token::ADD, expr, COOKED_STRING(i),
5084 POS(i));
5085 }
5086 return expr;
5087 } else {
5088 ZoneList<Expression*>* raw_strings = TemplateRawStrings(lit);
5089 Handle<String> source(String::cast(script()->source()));
5090
5091 int cooked_idx = function_state_->NextMaterializedLiteralIndex();
5092 int raw_idx = function_state_->NextMaterializedLiteralIndex();
5093
5094 // GetTemplateCallSite
5095 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(4, zone());
5096 args->Add(factory()->NewArrayLiteral(
5097 const_cast<ZoneList<Expression*>*>(cooked_strings), cooked_idx, pos),
5098 zone());
5099 args->Add(factory()->NewArrayLiteral(
5100 const_cast<ZoneList<Expression*>*>(raw_strings), raw_idx, pos), zone());
5101 this->CheckPossibleEvalCall(tag, scope_);
5102 Expression* expr = factory()->NewCallRuntime(
5103 ast_value_factory()->get_template_callsite_string(), NULL, args, start);
5104
5105 // Call TagFn
5106 ZoneList<Expression*>* call_args = new (zone()) ZoneList<Expression*>(
5107 expressions->length() + 1, zone());
5108 call_args->Add(expr, zone());
5109 call_args->AddAll(*expressions, zone());
5110 expr = factory()->NewCall(tag, call_args, pos);
5111 return expr;
5112 }
5113 #undef COOKED_STRING
5114 #undef POS
5115 #undef EXPR
5116 }
5117
5118
5119 ZoneList<Expression*>* Parser::TemplateRawStrings(const TemplateLiteral* lit) {
5120 const ZoneList<int>* lengths = lit->lengths();
5121 const ZoneList<Expression*>* cooked_strings = lit->cooked();
5122 int total = lengths->length();
5123 ZoneList<Expression*>* raw_strings;
5124 SmartArrayPointer<char> raw_chars;
5125
5126 // Given a TemplateLiteral, produce a list of raw strings, used for generating
5127 // a CallSite object for a tagged template invocations.
5128 //
5129 // A raw string will consist of the unescaped characters of a template span,
5130 // with end-of-line sequences normalized to U+000A LINE FEEDs, and without
5131 // leading or trailing template delimiters.
5132 //
5133
5134 DCHECK(total);
5135
5136 Handle<String> source(String::cast(script()->source()));
5137
5138 raw_strings = new (zone()) ZoneList<Expression*>(total, zone());
5139
5140 for (int index = 0; index < total; ++index) {
5141 int span_start = cooked_strings->at(index)->position() + 1;
5142 int span_end = lengths->at(index) - 1;
5143 int length;
5144 int to_index = 0;
5145
5146 raw_chars = source->ToCString(
5147 ALLOW_NULLS, FAST_STRING_TRAVERSAL, span_start, span_end, &length);
5148
5149 // Normalize raw line-feeds. [U+000D U+000A] (CRLF) and [U+000D] (CR) must
5150 // be translated into U+000A (LF).
5151 for (int from_index = 0; from_index < length; ++from_index) {
5152 char ch = raw_chars[from_index];
5153 if (ch == '\r') {
5154 if (raw_chars[from_index + 1] == '\n') {
5155 ++from_index;
5156 }
5157 ch = '\n';
5158 }
5159 raw_chars[to_index++] = ch;
5160 }
5161
5162 const AstRawString* raw_str = ast_value_factory()->GetOneByteString(
5163 OneByteVector(raw_chars.get(), to_index));
5164 Literal* raw_lit = factory()->NewStringLiteral(raw_str, span_start - 1);
5165 raw_strings->Add(raw_lit, zone());
5166 }
5167
5168 return raw_strings;
5169 }
5170
5032 } } // namespace v8::internal 5171 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | test/mjsunit/es6/templates.js » ('J')

Powered by Google App Engine
This is Rietveld 408576698