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/parsing/parser.h" | 5 #include "src/parsing/parser.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "src/api.h" | 9 #include "src/api.h" |
10 #include "src/ast/ast.h" | 10 #include "src/ast/ast.h" |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
45 flags_(0), | 45 flags_(0), |
46 source_stream_(nullptr), | 46 source_stream_(nullptr), |
47 source_stream_encoding_(ScriptCompiler::StreamedSource::ONE_BYTE), | 47 source_stream_encoding_(ScriptCompiler::StreamedSource::ONE_BYTE), |
48 character_stream_(nullptr), | 48 character_stream_(nullptr), |
49 extension_(nullptr), | 49 extension_(nullptr), |
50 compile_options_(ScriptCompiler::kNoCompileOptions), | 50 compile_options_(ScriptCompiler::kNoCompileOptions), |
51 script_scope_(nullptr), | 51 script_scope_(nullptr), |
52 unicode_cache_(nullptr), | 52 unicode_cache_(nullptr), |
53 stack_limit_(0), | 53 stack_limit_(0), |
54 hash_seed_(0), | 54 hash_seed_(0), |
| 55 compiler_hints_(0), |
| 56 start_position_(0), |
| 57 end_position_(0), |
55 isolate_(nullptr), | 58 isolate_(nullptr), |
56 cached_data_(nullptr), | 59 cached_data_(nullptr), |
57 ast_value_factory_(nullptr), | 60 ast_value_factory_(nullptr), |
58 literal_(nullptr), | 61 literal_(nullptr), |
59 scope_(nullptr) {} | 62 scope_(nullptr) {} |
60 | 63 |
61 ParseInfo::ParseInfo(Zone* zone, Handle<JSFunction> function) | 64 ParseInfo::ParseInfo(Zone* zone, Handle<JSFunction> function) |
62 : ParseInfo(zone, Handle<SharedFunctionInfo>(function->shared())) { | 65 : ParseInfo(zone, Handle<SharedFunctionInfo>(function->shared())) { |
63 set_context(Handle<Context>(function->context())); | 66 set_context(Handle<Context>(function->context())); |
64 } | 67 } |
65 | 68 |
66 | 69 |
67 ParseInfo::ParseInfo(Zone* zone, Handle<SharedFunctionInfo> shared) | 70 ParseInfo::ParseInfo(Zone* zone, Handle<SharedFunctionInfo> shared) |
68 : ParseInfo(zone) { | 71 : ParseInfo(zone) { |
69 isolate_ = shared->GetIsolate(); | 72 isolate_ = shared->GetIsolate(); |
70 | 73 |
71 set_lazy(); | 74 set_lazy(); |
72 set_hash_seed(isolate_->heap()->HashSeed()); | 75 set_hash_seed(isolate_->heap()->HashSeed()); |
| 76 set_is_named_expression(shared->is_named_expression()); |
| 77 set_calls_eval(shared->scope_info()->CallsEval()); |
| 78 set_compiler_hints(shared->compiler_hints()); |
| 79 set_start_position(shared->start_position()); |
| 80 set_end_position(shared->end_position()); |
73 set_stack_limit(isolate_->stack_guard()->real_climit()); | 81 set_stack_limit(isolate_->stack_guard()->real_climit()); |
74 set_unicode_cache(isolate_->unicode_cache()); | 82 set_unicode_cache(isolate_->unicode_cache()); |
75 set_language_mode(shared->language_mode()); | 83 set_language_mode(shared->language_mode()); |
76 set_shared_info(shared); | 84 set_shared_info(shared); |
77 | 85 |
78 Handle<Script> script(Script::cast(shared->script())); | 86 Handle<Script> script(Script::cast(shared->script())); |
79 set_script(script); | 87 set_script(script); |
80 if (!script.is_null() && script->type() == Script::TYPE_NATIVE) { | 88 if (!script.is_null() && script->type() == Script::TYPE_NATIVE) { |
81 set_native(); | 89 set_native(); |
82 } | 90 } |
83 } | 91 } |
84 | 92 |
85 | 93 |
86 ParseInfo::ParseInfo(Zone* zone, Handle<Script> script) : ParseInfo(zone) { | 94 ParseInfo::ParseInfo(Zone* zone, Handle<Script> script) : ParseInfo(zone) { |
87 isolate_ = script->GetIsolate(); | 95 isolate_ = script->GetIsolate(); |
88 | 96 |
89 set_hash_seed(isolate_->heap()->HashSeed()); | 97 set_hash_seed(isolate_->heap()->HashSeed()); |
90 set_stack_limit(isolate_->stack_guard()->real_climit()); | 98 set_stack_limit(isolate_->stack_guard()->real_climit()); |
91 set_unicode_cache(isolate_->unicode_cache()); | 99 set_unicode_cache(isolate_->unicode_cache()); |
92 set_script(script); | 100 set_script(script); |
93 | 101 |
94 if (script->type() == Script::TYPE_NATIVE) { | 102 if (script->type() == Script::TYPE_NATIVE) { |
95 set_native(); | 103 set_native(); |
96 } | 104 } |
97 } | 105 } |
98 | 106 |
| 107 bool ParseInfo::is_declaration() const { |
| 108 return (compiler_hints_ & (1 << SharedFunctionInfo::kIsDeclaration)) != 0; |
| 109 } |
| 110 |
| 111 bool ParseInfo::is_arrow() const { |
| 112 return (compiler_hints_ & (1 << SharedFunctionInfo::kIsArrow)) != 0; |
| 113 } |
| 114 |
| 115 bool ParseInfo::is_async() const { |
| 116 return (compiler_hints_ & (1 << SharedFunctionInfo::kIsAsyncFunction)) != 0; |
| 117 } |
| 118 |
| 119 bool ParseInfo::is_default_constructor() const { |
| 120 return (compiler_hints_ & (1 << SharedFunctionInfo::kIsDefaultConstructor)) != |
| 121 0; |
| 122 } |
| 123 |
| 124 FunctionKind ParseInfo::function_kind() const { |
| 125 return SharedFunctionInfo::FunctionKindBits::decode(compiler_hints_); |
| 126 } |
99 | 127 |
100 FunctionEntry ParseData::GetFunctionEntry(int start) { | 128 FunctionEntry ParseData::GetFunctionEntry(int start) { |
101 // The current pre-data entry must be a FunctionEntry with the given | 129 // The current pre-data entry must be a FunctionEntry with the given |
102 // start position. | 130 // start position. |
103 if ((function_index_ + FunctionEntry::kSize <= Length()) && | 131 if ((function_index_ + FunctionEntry::kSize <= Length()) && |
104 (static_cast<int>(Data()[function_index_]) == start)) { | 132 (static_cast<int>(Data()[function_index_]) == start)) { |
105 int index = function_index_; | 133 int index = function_index_; |
106 function_index_ += FunctionEntry::kSize; | 134 function_index_ += FunctionEntry::kSize; |
107 Vector<unsigned> subvector(&(Data()[index]), FunctionEntry::kSize); | 135 Vector<unsigned> subvector(&(Data()[index]), FunctionEntry::kSize); |
108 return FunctionEntry(subvector); | 136 return FunctionEntry(subvector); |
(...skipping 964 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1073 Handle<ExternalTwoByteString>::cast(source), | 1101 Handle<ExternalTwoByteString>::cast(source), |
1074 shared_info->start_position(), shared_info->end_position())); | 1102 shared_info->start_position(), shared_info->end_position())); |
1075 } else if (source->IsExternalOneByteString()) { | 1103 } else if (source->IsExternalOneByteString()) { |
1076 stream.reset(new ExternalOneByteStringUtf16CharacterStream( | 1104 stream.reset(new ExternalOneByteStringUtf16CharacterStream( |
1077 Handle<ExternalOneByteString>::cast(source), | 1105 Handle<ExternalOneByteString>::cast(source), |
1078 shared_info->start_position(), shared_info->end_position())); | 1106 shared_info->start_position(), shared_info->end_position())); |
1079 } else { | 1107 } else { |
1080 stream.reset(new GenericStringUtf16CharacterStream( | 1108 stream.reset(new GenericStringUtf16CharacterStream( |
1081 source, shared_info->start_position(), shared_info->end_position())); | 1109 source, shared_info->start_position(), shared_info->end_position())); |
1082 } | 1110 } |
1083 result = DoParseLazy(isolate, info, stream.get()); | 1111 Handle<String> name(String::cast(shared_info->name())); |
| 1112 result = DoParseLazy(isolate, info, ast_value_factory()->GetString(name), |
| 1113 stream.get()); |
| 1114 if (result != nullptr) { |
| 1115 Handle<String> inferred_name(shared_info->inferred_name()); |
| 1116 result->set_inferred_name(inferred_name); |
| 1117 } |
1084 } | 1118 } |
1085 | 1119 |
1086 if (FLAG_trace_parse && result != NULL) { | 1120 if (FLAG_trace_parse && result != NULL) { |
1087 double ms = timer.Elapsed().InMillisecondsF(); | 1121 double ms = timer.Elapsed().InMillisecondsF(); |
1088 std::unique_ptr<char[]> name_chars = result->debug_name()->ToCString(); | 1122 std::unique_ptr<char[]> name_chars = result->debug_name()->ToCString(); |
1089 PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms); | 1123 PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms); |
1090 } | 1124 } |
1091 return result; | 1125 return result; |
1092 } | 1126 } |
1093 | 1127 |
1094 static FunctionLiteral::FunctionType ComputeFunctionType( | 1128 static FunctionLiteral::FunctionType ComputeFunctionType(ParseInfo* info) { |
1095 Handle<SharedFunctionInfo> shared_info) { | 1129 if (info->is_declaration()) { |
1096 if (shared_info->is_declaration()) { | |
1097 return FunctionLiteral::kDeclaration; | 1130 return FunctionLiteral::kDeclaration; |
1098 } else if (shared_info->is_named_expression()) { | 1131 } else if (info->is_named_expression()) { |
1099 return FunctionLiteral::kNamedExpression; | 1132 return FunctionLiteral::kNamedExpression; |
1100 } else if (IsConciseMethod(shared_info->kind()) || | 1133 } else if (IsConciseMethod(info->function_kind()) || |
1101 IsAccessorFunction(shared_info->kind())) { | 1134 IsAccessorFunction(info->function_kind())) { |
1102 return FunctionLiteral::kAccessorOrMethod; | 1135 return FunctionLiteral::kAccessorOrMethod; |
1103 } | 1136 } |
1104 return FunctionLiteral::kAnonymousExpression; | 1137 return FunctionLiteral::kAnonymousExpression; |
1105 } | 1138 } |
1106 | 1139 |
1107 FunctionLiteral* Parser::DoParseLazy(Isolate* isolate, ParseInfo* info, | 1140 FunctionLiteral* Parser::DoParseLazy(Isolate* isolate, ParseInfo* info, |
| 1141 const AstRawString* raw_name, |
1108 Utf16CharacterStream* source) { | 1142 Utf16CharacterStream* source) { |
1109 Handle<SharedFunctionInfo> shared_info = info->shared_info(); | |
1110 scanner_.Initialize(source); | 1143 scanner_.Initialize(source); |
1111 DCHECK_NULL(scope_state_); | 1144 DCHECK_NULL(scope_state_); |
1112 DCHECK_NULL(target_stack_); | 1145 DCHECK_NULL(target_stack_); |
1113 | 1146 |
1114 Handle<String> name(String::cast(shared_info->name())); | |
1115 DCHECK(ast_value_factory()); | 1147 DCHECK(ast_value_factory()); |
1116 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); | 1148 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); |
1117 const AstRawString* raw_name = ast_value_factory()->GetString(name); | |
1118 fni_->PushEnclosingName(raw_name); | 1149 fni_->PushEnclosingName(raw_name); |
1119 | 1150 |
1120 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 1151 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
1121 | 1152 |
1122 // Place holder for the result. | 1153 // Place holder for the result. |
1123 FunctionLiteral* result = nullptr; | 1154 FunctionLiteral* result = nullptr; |
1124 | 1155 |
1125 { | 1156 { |
1126 // Parse the function literal. | 1157 // Parse the function literal. |
1127 Scope* scope = original_scope_; | 1158 Scope* scope = original_scope_; |
1128 DCHECK(scope); | 1159 DCHECK(scope); |
1129 FunctionState function_state(&function_state_, &scope_state_, scope, | 1160 FunctionState function_state(&function_state_, &scope_state_, scope, |
1130 shared_info->kind()); | 1161 info->function_kind()); |
1131 DCHECK(is_sloppy(scope->language_mode()) || | 1162 DCHECK(is_sloppy(scope->language_mode()) || |
1132 is_strict(info->language_mode())); | 1163 is_strict(info->language_mode())); |
1133 DCHECK(info->language_mode() == shared_info->language_mode()); | 1164 FunctionLiteral::FunctionType function_type = ComputeFunctionType(info); |
1134 FunctionLiteral::FunctionType function_type = | |
1135 ComputeFunctionType(shared_info); | |
1136 bool ok = true; | 1165 bool ok = true; |
1137 | 1166 |
1138 if (shared_info->is_arrow()) { | 1167 if (info->is_arrow()) { |
1139 bool is_async = allow_harmony_async_await() && shared_info->is_async(); | 1168 bool is_async = allow_harmony_async_await() && info->is_async(); |
1140 if (is_async) { | 1169 if (is_async) { |
1141 DCHECK(!scanner()->HasAnyLineTerminatorAfterNext()); | 1170 DCHECK(!scanner()->HasAnyLineTerminatorAfterNext()); |
1142 if (!Check(Token::ASYNC)) { | 1171 if (!Check(Token::ASYNC)) { |
1143 CHECK(stack_overflow()); | 1172 CHECK(stack_overflow()); |
1144 return nullptr; | 1173 return nullptr; |
1145 } | 1174 } |
1146 if (!(peek_any_identifier() || peek() == Token::LPAREN)) { | 1175 if (!(peek_any_identifier() || peek() == Token::LPAREN)) { |
1147 CHECK(stack_overflow()); | 1176 CHECK(stack_overflow()); |
1148 return nullptr; | 1177 return nullptr; |
1149 } | 1178 } |
1150 } | 1179 } |
1151 | 1180 |
1152 // TODO(adamk): We should construct this scope from the ScopeInfo. | 1181 // TODO(adamk): We should construct this scope from the ScopeInfo. |
1153 Scope* scope = NewFunctionScope(FunctionKind::kArrowFunction); | 1182 Scope* scope = NewFunctionScope(FunctionKind::kArrowFunction); |
1154 | 1183 |
1155 // These two bits only need to be explicitly set because we're | 1184 // These two bits only need to be explicitly set because we're |
1156 // not passing the ScopeInfo to the Scope constructor. | 1185 // not passing the ScopeInfo to the Scope constructor. |
1157 // TODO(adamk): Remove these calls once the above NewScope call | 1186 // TODO(adamk): Remove these calls once the above NewScope call |
1158 // passes the ScopeInfo. | 1187 // passes the ScopeInfo. |
1159 if (shared_info->scope_info()->CallsEval()) { | 1188 if (info->calls_eval()) { |
1160 scope->RecordEvalCall(); | 1189 scope->RecordEvalCall(); |
1161 } | 1190 } |
1162 SetLanguageMode(scope, shared_info->language_mode()); | 1191 SetLanguageMode(scope, info->language_mode()); |
1163 | 1192 |
1164 scope->set_start_position(shared_info->start_position()); | 1193 scope->set_start_position(info->start_position()); |
1165 ExpressionClassifier formals_classifier(this); | 1194 ExpressionClassifier formals_classifier(this); |
1166 ParserFormalParameters formals(scope); | 1195 ParserFormalParameters formals(scope); |
1167 Checkpoint checkpoint(this); | 1196 Checkpoint checkpoint(this); |
1168 { | 1197 { |
1169 // Parsing patterns as variable reference expression creates | 1198 // Parsing patterns as variable reference expression creates |
1170 // NewUnresolved references in current scope. Entrer arrow function | 1199 // NewUnresolved references in current scope. Entrer arrow function |
1171 // scope for formal parameter parsing. | 1200 // scope for formal parameter parsing. |
1172 BlockState block_state(&scope_state_, scope); | 1201 BlockState block_state(&scope_state_, scope); |
1173 if (Check(Token::LPAREN)) { | 1202 if (Check(Token::LPAREN)) { |
1174 // '(' StrictFormalParameters ')' | 1203 // '(' StrictFormalParameters ')' |
(...skipping 15 matching lines...) Expand all Loading... |
1190 // not be observable, or else the preparser would have failed. | 1219 // not be observable, or else the preparser would have failed. |
1191 Expression* expression = ParseArrowFunctionLiteral( | 1220 Expression* expression = ParseArrowFunctionLiteral( |
1192 true, formals, is_async, formals_classifier, &ok); | 1221 true, formals, is_async, formals_classifier, &ok); |
1193 if (ok) { | 1222 if (ok) { |
1194 // Scanning must end at the same position that was recorded | 1223 // Scanning must end at the same position that was recorded |
1195 // previously. If not, parsing has been interrupted due to a stack | 1224 // previously. If not, parsing has been interrupted due to a stack |
1196 // overflow, at which point the partially parsed arrow function | 1225 // overflow, at which point the partially parsed arrow function |
1197 // concise body happens to be a valid expression. This is a problem | 1226 // concise body happens to be a valid expression. This is a problem |
1198 // only for arrow functions with single expression bodies, since there | 1227 // only for arrow functions with single expression bodies, since there |
1199 // is no end token such as "}" for normal functions. | 1228 // is no end token such as "}" for normal functions. |
1200 if (scanner()->location().end_pos == shared_info->end_position()) { | 1229 if (scanner()->location().end_pos == info->end_position()) { |
1201 // The pre-parser saw an arrow function here, so the full parser | 1230 // The pre-parser saw an arrow function here, so the full parser |
1202 // must produce a FunctionLiteral. | 1231 // must produce a FunctionLiteral. |
1203 DCHECK(expression->IsFunctionLiteral()); | 1232 DCHECK(expression->IsFunctionLiteral()); |
1204 result = expression->AsFunctionLiteral(); | 1233 result = expression->AsFunctionLiteral(); |
1205 } else { | 1234 } else { |
1206 ok = false; | 1235 ok = false; |
1207 } | 1236 } |
1208 } | 1237 } |
1209 } | 1238 } |
1210 } else if (shared_info->is_default_constructor()) { | 1239 } else if (info->is_default_constructor()) { |
1211 DCHECK_EQ(this->scope(), scope); | 1240 DCHECK_EQ(this->scope(), scope); |
1212 result = DefaultConstructor( | 1241 result = DefaultConstructor( |
1213 raw_name, IsSubclassConstructor(shared_info->kind()), | 1242 raw_name, IsSubclassConstructor(info->function_kind()), |
1214 shared_info->start_position(), shared_info->end_position(), | 1243 info->start_position(), info->end_position(), info->language_mode()); |
1215 shared_info->language_mode()); | |
1216 } else { | 1244 } else { |
1217 result = ParseFunctionLiteral(raw_name, Scanner::Location::invalid(), | 1245 result = ParseFunctionLiteral(raw_name, Scanner::Location::invalid(), |
1218 kSkipFunctionNameCheck, shared_info->kind(), | 1246 kSkipFunctionNameCheck, |
1219 kNoSourcePosition, function_type, | 1247 info->function_kind(), kNoSourcePosition, |
1220 shared_info->language_mode(), &ok); | 1248 function_type, info->language_mode(), &ok); |
1221 } | 1249 } |
1222 // Make sure the results agree. | 1250 // Make sure the results agree. |
1223 DCHECK(ok == (result != nullptr)); | 1251 DCHECK(ok == (result != nullptr)); |
1224 } | 1252 } |
1225 | 1253 |
1226 // Make sure the target stack is empty. | 1254 // Make sure the target stack is empty. |
1227 DCHECK_NULL(target_stack_); | 1255 DCHECK_NULL(target_stack_); |
1228 | |
1229 if (result != nullptr) { | |
1230 Handle<String> inferred_name(shared_info->inferred_name()); | |
1231 result->set_inferred_name(inferred_name); | |
1232 } | |
1233 return result; | 1256 return result; |
1234 } | 1257 } |
1235 | 1258 |
1236 | 1259 |
1237 void Parser::ParseStatementList(ZoneList<Statement*>* body, int end_token, | 1260 void Parser::ParseStatementList(ZoneList<Statement*>* body, int end_token, |
1238 bool* ok) { | 1261 bool* ok) { |
1239 // StatementList :: | 1262 // StatementList :: |
1240 // (StatementListItem)* <end_token> | 1263 // (StatementListItem)* <end_token> |
1241 | 1264 |
1242 // Allocate a target stack to use for this set of source | 1265 // Allocate a target stack to use for this set of source |
(...skipping 5855 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7098 node->Print(Isolate::Current()); | 7121 node->Print(Isolate::Current()); |
7099 } | 7122 } |
7100 #endif // DEBUG | 7123 #endif // DEBUG |
7101 | 7124 |
7102 #undef CHECK_OK | 7125 #undef CHECK_OK |
7103 #undef CHECK_OK_VOID | 7126 #undef CHECK_OK_VOID |
7104 #undef CHECK_FAILED | 7127 #undef CHECK_FAILED |
7105 | 7128 |
7106 } // namespace internal | 7129 } // namespace internal |
7107 } // namespace v8 | 7130 } // namespace v8 |
OLD | NEW |