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