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