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 784 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |