Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(144)

Side by Side Diff: src/parsing/parser-base.h

Issue 2156303002: Implement new Function.prototype.toString and fix CreateDynamicFunction parsing (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: rebase Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/parsing/parser.cc ('k') | src/parsing/preparser.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #ifndef V8_PARSING_PARSER_BASE_H 5 #ifndef V8_PARSING_PARSER_BASE_H
6 #define V8_PARSING_PARSER_BASE_H 6 #define V8_PARSING_PARSER_BASE_H
7 7
8 #include "src/ast/ast.h" 8 #include "src/ast/ast.h"
9 #include "src/ast/scopes.h" 9 #include "src/ast/scopes.h"
10 #include "src/bailout-reason.h" 10 #include "src/bailout-reason.h"
(...skipping 2173 matching lines...) Expand 10 before | Expand all | Expand 10 after
2184 bool is_get = false; 2184 bool is_get = false;
2185 bool is_set = false; 2185 bool is_set = false;
2186 bool is_generator = false; 2186 bool is_generator = false;
2187 bool is_async = false; 2187 bool is_async = false;
2188 *is_static = false; 2188 *is_static = false;
2189 *property_kind = ClassLiteralProperty::METHOD; 2189 *property_kind = ClassLiteralProperty::METHOD;
2190 PropertyKind kind = PropertyKind::kNotSet; 2190 PropertyKind kind = PropertyKind::kNotSet;
2191 2191
2192 Token::Value name_token = peek(); 2192 Token::Value name_token = peek();
2193 2193
2194 int function_token_position = scanner()->peek_location().beg_pos;
2194 IdentifierT name = impl()->EmptyIdentifier(); 2195 IdentifierT name = impl()->EmptyIdentifier();
2195 ExpressionT name_expression; 2196 ExpressionT name_expression;
2196 if (name_token == Token::STATIC) { 2197 if (name_token == Token::STATIC) {
2197 Consume(Token::STATIC); 2198 Consume(Token::STATIC);
2199 function_token_position = scanner()->peek_location().beg_pos;
2198 if (peek() == Token::LPAREN) { 2200 if (peek() == Token::LPAREN) {
2199 kind = PropertyKind::kMethodProperty; 2201 kind = PropertyKind::kMethodProperty;
2200 name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'static' 2202 name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'static'
2201 name_expression = factory()->NewStringLiteral(name, position()); 2203 name_expression = factory()->NewStringLiteral(name, position());
2202 } else if (peek() == Token::ASSIGN || peek() == Token::SEMICOLON || 2204 } else if (peek() == Token::ASSIGN || peek() == Token::SEMICOLON ||
2203 peek() == Token::RBRACE) { 2205 peek() == Token::RBRACE) {
2204 name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'static' 2206 name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'static'
2205 name_expression = factory()->NewStringLiteral(name, position()); 2207 name_expression = factory()->NewStringLiteral(name, position());
2206 } else { 2208 } else {
2207 *is_static = true; 2209 *is_static = true;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2264 : FunctionKind::kConciseMethod; 2266 : FunctionKind::kConciseMethod;
2265 2267
2266 if (!*is_static && impl()->IsConstructor(name)) { 2268 if (!*is_static && impl()->IsConstructor(name)) {
2267 *has_seen_constructor = true; 2269 *has_seen_constructor = true;
2268 kind = has_extends ? FunctionKind::kDerivedConstructor 2270 kind = has_extends ? FunctionKind::kDerivedConstructor
2269 : FunctionKind::kBaseConstructor; 2271 : FunctionKind::kBaseConstructor;
2270 } 2272 }
2271 2273
2272 ExpressionT value = impl()->ParseFunctionLiteral( 2274 ExpressionT value = impl()->ParseFunctionLiteral(
2273 name, scanner()->location(), kSkipFunctionNameCheck, kind, 2275 name, scanner()->location(), kSkipFunctionNameCheck, kind,
2274 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, 2276 FLAG_harmony_function_tostring ? function_token_position
2275 language_mode(), CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); 2277 : kNoSourcePosition,
2278 FunctionLiteral::kAccessorOrMethod, language_mode(),
2279 CHECK_OK_CUSTOM(EmptyClassLiteralProperty));
2276 2280
2277 *property_kind = ClassLiteralProperty::METHOD; 2281 *property_kind = ClassLiteralProperty::METHOD;
2278 return factory()->NewClassLiteralProperty(name_expression, value, 2282 return factory()->NewClassLiteralProperty(name_expression, value,
2279 *property_kind, *is_static, 2283 *property_kind, *is_static,
2280 *is_computed_name); 2284 *is_computed_name);
2281 } 2285 }
2282 2286
2283 case PropertyKind::kAccessorProperty: { 2287 case PropertyKind::kAccessorProperty: {
2284 DCHECK((is_get || is_set) && !is_generator && !is_async); 2288 DCHECK((is_get || is_set) && !is_generator && !is_async);
2285 2289
2286 if (!*is_computed_name) { 2290 if (!*is_computed_name) {
2287 checker->CheckClassMethodName( 2291 checker->CheckClassMethodName(
2288 name_token, PropertyKind::kAccessorProperty, false, false, 2292 name_token, PropertyKind::kAccessorProperty, false, false,
2289 *is_static, CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); 2293 *is_static, CHECK_OK_CUSTOM(EmptyClassLiteralProperty));
2290 // Make sure the name expression is a string since we need a Name for 2294 // Make sure the name expression is a string since we need a Name for
2291 // Runtime_DefineAccessorPropertyUnchecked and since we can determine 2295 // Runtime_DefineAccessorPropertyUnchecked and since we can determine
2292 // this statically we can skip the extra runtime check. 2296 // this statically we can skip the extra runtime check.
2293 name_expression = 2297 name_expression =
2294 factory()->NewStringLiteral(name, name_expression->position()); 2298 factory()->NewStringLiteral(name, name_expression->position());
2295 } 2299 }
2296 2300
2297 FunctionKind kind = is_get ? FunctionKind::kGetterFunction 2301 FunctionKind kind = is_get ? FunctionKind::kGetterFunction
2298 : FunctionKind::kSetterFunction; 2302 : FunctionKind::kSetterFunction;
2299 2303
2300 FunctionLiteralT value = impl()->ParseFunctionLiteral( 2304 FunctionLiteralT value = impl()->ParseFunctionLiteral(
2301 name, scanner()->location(), kSkipFunctionNameCheck, kind, 2305 name, scanner()->location(), kSkipFunctionNameCheck, kind,
2302 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, 2306 FLAG_harmony_function_tostring ? function_token_position
2303 language_mode(), CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); 2307 : kNoSourcePosition,
2308 FunctionLiteral::kAccessorOrMethod, language_mode(),
2309 CHECK_OK_CUSTOM(EmptyClassLiteralProperty));
2304 2310
2305 if (!*is_computed_name) { 2311 if (!*is_computed_name) {
2306 impl()->AddAccessorPrefixToFunctionName(is_get, value, name); 2312 impl()->AddAccessorPrefixToFunctionName(is_get, value, name);
2307 } 2313 }
2308 2314
2309 *property_kind = 2315 *property_kind =
2310 is_get ? ClassLiteralProperty::GETTER : ClassLiteralProperty::SETTER; 2316 is_get ? ClassLiteralProperty::GETTER : ClassLiteralProperty::SETTER;
2311 return factory()->NewClassLiteralProperty(name_expression, value, 2317 return factory()->NewClassLiteralProperty(name_expression, value,
2312 *property_kind, *is_static, 2318 *property_kind, *is_static,
2313 *is_computed_name); 2319 *is_computed_name);
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
2487 Scanner::Location(next_beg_pos, scanner()->location().end_pos), 2493 Scanner::Location(next_beg_pos, scanner()->location().end_pos),
2488 MessageTemplate::kInvalidDestructuringTarget); 2494 MessageTemplate::kInvalidDestructuringTarget);
2489 2495
2490 FunctionKind kind = is_generator 2496 FunctionKind kind = is_generator
2491 ? FunctionKind::kConciseGeneratorMethod 2497 ? FunctionKind::kConciseGeneratorMethod
2492 : is_async ? FunctionKind::kAsyncConciseMethod 2498 : is_async ? FunctionKind::kAsyncConciseMethod
2493 : FunctionKind::kConciseMethod; 2499 : FunctionKind::kConciseMethod;
2494 2500
2495 ExpressionT value = impl()->ParseFunctionLiteral( 2501 ExpressionT value = impl()->ParseFunctionLiteral(
2496 name, scanner()->location(), kSkipFunctionNameCheck, kind, 2502 name, scanner()->location(), kSkipFunctionNameCheck, kind,
2497 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, 2503 FLAG_harmony_function_tostring ? next_beg_pos : kNoSourcePosition,
2498 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2504 FunctionLiteral::kAccessorOrMethod, language_mode(),
2505 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2499 2506
2500 return factory()->NewObjectLiteralProperty( 2507 return factory()->NewObjectLiteralProperty(
2501 name_expression, value, ObjectLiteralProperty::COMPUTED, 2508 name_expression, value, ObjectLiteralProperty::COMPUTED,
2502 *is_computed_name); 2509 *is_computed_name);
2503 } 2510 }
2504 2511
2505 case PropertyKind::kAccessorProperty: { 2512 case PropertyKind::kAccessorProperty: {
2506 DCHECK((is_get || is_set) && !(is_set && is_get) && !is_generator && 2513 DCHECK((is_get || is_set) && !(is_set && is_get) && !is_generator &&
2507 !is_async); 2514 !is_async);
2508 2515
2509 classifier()->RecordPatternError( 2516 classifier()->RecordPatternError(
2510 Scanner::Location(next_beg_pos, scanner()->location().end_pos), 2517 Scanner::Location(next_beg_pos, scanner()->location().end_pos),
2511 MessageTemplate::kInvalidDestructuringTarget); 2518 MessageTemplate::kInvalidDestructuringTarget);
2512 2519
2513 if (!*is_computed_name) { 2520 if (!*is_computed_name) {
2514 // Make sure the name expression is a string since we need a Name for 2521 // Make sure the name expression is a string since we need a Name for
2515 // Runtime_DefineAccessorPropertyUnchecked and since we can determine 2522 // Runtime_DefineAccessorPropertyUnchecked and since we can determine
2516 // this statically we can skip the extra runtime check. 2523 // this statically we can skip the extra runtime check.
2517 name_expression = 2524 name_expression =
2518 factory()->NewStringLiteral(name, name_expression->position()); 2525 factory()->NewStringLiteral(name, name_expression->position());
2519 } 2526 }
2520 2527
2521 FunctionKind kind = is_get ? FunctionKind::kGetterFunction 2528 FunctionKind kind = is_get ? FunctionKind::kGetterFunction
2522 : FunctionKind::kSetterFunction; 2529 : FunctionKind::kSetterFunction;
2523 2530
2524 FunctionLiteralT value = impl()->ParseFunctionLiteral( 2531 FunctionLiteralT value = impl()->ParseFunctionLiteral(
2525 name, scanner()->location(), kSkipFunctionNameCheck, kind, 2532 name, scanner()->location(), kSkipFunctionNameCheck, kind,
2526 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, 2533 FLAG_harmony_function_tostring ? next_beg_pos : kNoSourcePosition,
2527 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2534 FunctionLiteral::kAccessorOrMethod, language_mode(),
2535 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2528 2536
2529 if (!*is_computed_name) { 2537 if (!*is_computed_name) {
2530 impl()->AddAccessorPrefixToFunctionName(is_get, value, name); 2538 impl()->AddAccessorPrefixToFunctionName(is_get, value, name);
2531 } 2539 }
2532 2540
2533 return factory()->NewObjectLiteralProperty( 2541 return factory()->NewObjectLiteralProperty(
2534 name_expression, value, is_get ? ObjectLiteralProperty::GETTER 2542 name_expression, value, is_get ? ObjectLiteralProperty::GETTER
2535 : ObjectLiteralProperty::SETTER, 2543 : ObjectLiteralProperty::SETTER,
2536 *is_computed_name); 2544 *is_computed_name);
2537 } 2545 }
(...skipping 818 matching lines...) Expand 10 before | Expand all | Expand 10 after
3356 } 3364 }
3357 3365
3358 FunctionKind function_kind = Check(Token::MUL) 3366 FunctionKind function_kind = Check(Token::MUL)
3359 ? FunctionKind::kGeneratorFunction 3367 ? FunctionKind::kGeneratorFunction
3360 : FunctionKind::kNormalFunction; 3368 : FunctionKind::kNormalFunction;
3361 IdentifierT name = impl()->EmptyIdentifier(); 3369 IdentifierT name = impl()->EmptyIdentifier();
3362 bool is_strict_reserved_name = false; 3370 bool is_strict_reserved_name = false;
3363 Scanner::Location function_name_location = Scanner::Location::invalid(); 3371 Scanner::Location function_name_location = Scanner::Location::invalid();
3364 FunctionLiteral::FunctionType function_type = 3372 FunctionLiteral::FunctionType function_type =
3365 FunctionLiteral::kAnonymousExpression; 3373 FunctionLiteral::kAnonymousExpression;
3366 if (peek_any_identifier()) { 3374 if (impl()->ParsingDynamicFunctionDeclaration()) {
3375 // We don't want dynamic functions to actually declare their name
3376 // "anonymous". We just want that name in the toString().
3377 Consume(Token::IDENTIFIER);
3378 DCHECK(scanner()->UnescapedLiteralMatches("anonymous", 9));
3379 } else if (peek_any_identifier()) {
3367 name = ParseIdentifierOrStrictReservedWord( 3380 name = ParseIdentifierOrStrictReservedWord(
3368 function_kind, &is_strict_reserved_name, CHECK_OK); 3381 function_kind, &is_strict_reserved_name, CHECK_OK);
3369 function_name_location = scanner()->location(); 3382 function_name_location = scanner()->location();
3370 function_type = FunctionLiteral::kNamedExpression; 3383 function_type = FunctionLiteral::kNamedExpression;
3371 } 3384 }
3372 result = impl()->ParseFunctionLiteral( 3385 result = impl()->ParseFunctionLiteral(
3373 name, function_name_location, 3386 name, function_name_location,
3374 is_strict_reserved_name ? kFunctionNameIsStrictReserved 3387 is_strict_reserved_name ? kFunctionNameIsStrictReserved
3375 : kFunctionNameValidityUnknown, 3388 : kFunctionNameValidityUnknown,
3376 function_kind, function_token_position, function_type, language_mode(), 3389 function_kind, function_token_position, function_type, language_mode(),
(...skipping 992 matching lines...) Expand 10 before | Expand all | Expand 10 after
4369 // 4382 //
4370 // async [no LineTerminator here] function BindingIdentifier[Await] 4383 // async [no LineTerminator here] function BindingIdentifier[Await]
4371 // ( FormalParameters[Await] ) { AsyncFunctionBody } 4384 // ( FormalParameters[Await] ) { AsyncFunctionBody }
4372 DCHECK_EQ(scanner()->current_token(), Token::ASYNC); 4385 DCHECK_EQ(scanner()->current_token(), Token::ASYNC);
4373 int pos = position(); 4386 int pos = position();
4374 Expect(Token::FUNCTION, CHECK_OK); 4387 Expect(Token::FUNCTION, CHECK_OK);
4375 bool is_strict_reserved = false; 4388 bool is_strict_reserved = false;
4376 IdentifierT name = impl()->EmptyIdentifier(); 4389 IdentifierT name = impl()->EmptyIdentifier();
4377 FunctionLiteral::FunctionType type = FunctionLiteral::kAnonymousExpression; 4390 FunctionLiteral::FunctionType type = FunctionLiteral::kAnonymousExpression;
4378 4391
4379 if (peek_any_identifier()) { 4392 if (impl()->ParsingDynamicFunctionDeclaration()) {
4393 // We don't want dynamic functions to actually declare their name
4394 // "anonymous". We just want that name in the toString().
4395 Consume(Token::IDENTIFIER);
4396 DCHECK(scanner()->UnescapedLiteralMatches("anonymous", 9));
4397 } else if (peek_any_identifier()) {
4380 type = FunctionLiteral::kNamedExpression; 4398 type = FunctionLiteral::kNamedExpression;
4381 name = ParseIdentifierOrStrictReservedWord(FunctionKind::kAsyncFunction, 4399 name = ParseIdentifierOrStrictReservedWord(FunctionKind::kAsyncFunction,
4382 &is_strict_reserved, CHECK_OK); 4400 &is_strict_reserved, CHECK_OK);
4383 } 4401 }
4384 return impl()->ParseFunctionLiteral( 4402 return impl()->ParseFunctionLiteral(
4385 name, scanner()->location(), 4403 name, scanner()->location(),
4386 is_strict_reserved ? kFunctionNameIsStrictReserved 4404 is_strict_reserved ? kFunctionNameIsStrictReserved
4387 : kFunctionNameValidityUnknown, 4405 : kFunctionNameValidityUnknown,
4388 FunctionKind::kAsyncFunction, pos, type, language_mode(), CHECK_OK); 4406 FunctionKind::kAsyncFunction, pos, type, language_mode(), CHECK_OK);
4389 } 4407 }
(...skipping 1457 matching lines...) Expand 10 before | Expand all | Expand 10 after
5847 } 5865 }
5848 5866
5849 #undef CHECK_OK 5867 #undef CHECK_OK
5850 #undef CHECK_OK_CUSTOM 5868 #undef CHECK_OK_CUSTOM
5851 #undef CHECK_OK_VOID 5869 #undef CHECK_OK_VOID
5852 5870
5853 } // namespace internal 5871 } // namespace internal
5854 } // namespace v8 5872 } // namespace v8
5855 5873
5856 #endif // V8_PARSING_PARSER_BASE_H 5874 #endif // V8_PARSING_PARSER_BASE_H
OLDNEW
« no previous file with comments | « src/parsing/parser.cc ('k') | src/parsing/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698