| 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 |