Index: src/preparser.h |
diff --git a/src/preparser.h b/src/preparser.h |
index b34b04e15252ee30774e2f6ebfd339f88fd646a0..f3bb292e2c5ca56afd33939d0e860091f4c0176e 100644 |
--- a/src/preparser.h |
+++ b/src/preparser.h |
@@ -639,6 +639,12 @@ class PreParserIdentifier { |
return type_ == kFutureStrictReservedIdentifier; |
} |
bool IsValidStrictVariable() const { return type_ == kUnknownIdentifier; } |
+ V8_INLINE bool IsValidArrowParam() const { |
+ // A valid identifier can be an arrow function parameter |
+ // except for eval, arguments, yield, and reserved keywords. |
+ return !(IsEval() || IsArguments() || IsYield() || |
+ IsFutureStrictReserved()); |
+ } |
// Allow identifier->name()[->length()] to work. The preparser |
// does not need the actual positions/lengths of the identifiers. |
@@ -668,30 +674,27 @@ class PreParserIdentifier { |
}; |
-// Bits 0 and 1 are used to identify the type of expression: |
-// If bit 0 is set, it's an identifier. |
-// if bit 1 is set, it's a string literal. |
-// If neither is set, it's no particular type, and both set isn't |
-// use yet. |
class PreParserExpression { |
public: |
static PreParserExpression Default() { |
- return PreParserExpression(kUnknownExpression); |
+ return PreParserExpression(TypeField::encode(kExpression)); |
} |
static PreParserExpression FromIdentifier(PreParserIdentifier id) { |
- return PreParserExpression(kTypeIdentifier | |
- (id.type_ << kIdentifierShift)); |
+ return PreParserExpression(TypeField::encode(kIdentifierExpression) | |
+ IdentifierTypeField::encode(id.type_)); |
} |
static PreParserExpression BinaryOperation(PreParserExpression left, |
Token::Value op, |
PreParserExpression right) { |
- int code = ((op == Token::COMMA) && !left.is_parenthesized() && |
- !right.is_parenthesized()) |
- ? left.ArrowParamListBit() & right.ArrowParamListBit() |
- : 0; |
- return PreParserExpression(kTypeBinaryOperation | code); |
+ bool valid_arrow_param_list = |
+ op == Token::COMMA && !left.is_parenthesized() && |
+ !right.is_parenthesized() && left.IsValidArrowParams() && |
+ right.IsValidArrowParams(); |
+ return PreParserExpression( |
+ TypeField::encode(kBinaryOperationExpression) | |
+ IsValidArrowParamListField::encode(valid_arrow_param_list)); |
} |
static PreParserExpression EmptyArrowParamList() { |
@@ -701,69 +704,89 @@ class PreParserExpression { |
} |
static PreParserExpression StringLiteral() { |
- return PreParserExpression(kUnknownStringLiteral); |
+ return PreParserExpression(TypeField::encode(kStringLiteralExpression) | |
+ IsUseStrictField::encode(false)); |
} |
static PreParserExpression UseStrictStringLiteral() { |
- return PreParserExpression(kUseStrictString); |
+ return PreParserExpression(TypeField::encode(kStringLiteralExpression) | |
+ IsUseStrictField::encode(true)); |
} |
static PreParserExpression This() { |
- return PreParserExpression(kThisExpression); |
+ return PreParserExpression(TypeField::encode(kExpression) | |
+ ExpressionTypeField::encode(kThisExpression)); |
} |
static PreParserExpression Super() { |
- return PreParserExpression(kSuperExpression); |
+ return PreParserExpression(TypeField::encode(kExpression) | |
+ ExpressionTypeField::encode(kSuperExpression)); |
} |
static PreParserExpression ThisProperty() { |
- return PreParserExpression(kThisPropertyExpression); |
+ return PreParserExpression( |
+ TypeField::encode(kExpression) | |
+ ExpressionTypeField::encode(kThisPropertyExpression)); |
} |
static PreParserExpression Property() { |
- return PreParserExpression(kPropertyExpression); |
+ return PreParserExpression( |
+ TypeField::encode(kExpression) | |
+ ExpressionTypeField::encode(kPropertyExpression)); |
} |
static PreParserExpression Call() { |
- return PreParserExpression(kCallExpression); |
+ return PreParserExpression(TypeField::encode(kExpression) | |
+ ExpressionTypeField::encode(kCallExpression)); |
} |
- bool IsIdentifier() const { return (code_ & kTypeMask) == kTypeIdentifier; } |
+ bool IsIdentifier() const { |
+ return TypeField::decode(code_) == kIdentifierExpression; |
+ } |
PreParserIdentifier AsIdentifier() const { |
DCHECK(IsIdentifier()); |
- return PreParserIdentifier( |
- static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift)); |
+ return PreParserIdentifier(IdentifierTypeField::decode(code_)); |
} |
bool IsStringLiteral() const { |
- return (code_ & kTypeMask) == kTypeStringLiteral; |
+ return TypeField::decode(code_) == kStringLiteralExpression; |
} |
bool IsUseStrictLiteral() const { |
- return (code_ & kUseStrictString) == kUseStrictString; |
+ return TypeField::decode(code_) == kStringLiteralExpression && |
+ IsUseStrictField::decode(code_); |
} |
- bool IsThis() const { return (code_ & kThisExpression) == kThisExpression; } |
+ bool IsThis() const { |
+ return TypeField::decode(code_) == kExpression && |
+ ExpressionTypeField::decode(code_) == kThisExpression; |
+ } |
bool IsThisProperty() const { |
- return (code_ & kThisPropertyExpression) == kThisPropertyExpression; |
+ return TypeField::decode(code_) == kExpression && |
+ ExpressionTypeField::decode(code_) == kThisPropertyExpression; |
} |
bool IsProperty() const { |
- return (code_ & kPropertyExpression) == kPropertyExpression || |
- (code_ & kThisPropertyExpression) == kThisPropertyExpression; |
+ return TypeField::decode(code_) == kExpression && |
+ (ExpressionTypeField::decode(code_) == kPropertyExpression || |
+ ExpressionTypeField::decode(code_) == kThisPropertyExpression); |
} |
- bool IsCall() const { return (code_ & kCallExpression) == kCallExpression; } |
+ bool IsCall() const { |
+ return TypeField::decode(code_) == kExpression && |
+ ExpressionTypeField::decode(code_) == kCallExpression; |
+ } |
bool IsValidReferenceExpression() const { |
return IsIdentifier() || IsProperty(); |
} |
bool IsValidArrowParamList() const { |
- return (ArrowParamListBit() & kBinaryOperationArrowParamList) != 0 && |
- (code_ & kMultiParenthesizedExpression) == 0; |
+ return IsValidArrowParams() && |
+ ParenthesizationField::decode(code_) != |
+ kMultiParenthesizedExpression; |
} |
// At the moment PreParser doesn't track these expression types. |
@@ -773,16 +796,17 @@ class PreParserExpression { |
PreParserExpression AsFunctionLiteral() { return *this; } |
bool IsBinaryOperation() const { |
- return (code_ & kTypeMask) == kTypeBinaryOperation; |
+ return TypeField::decode(code_) == kBinaryOperationExpression; |
} |
bool is_parenthesized() const { |
- return (code_ & kParenthesizedExpression) != 0; |
+ return ParenthesizationField::decode(code_) != kNotParenthesized; |
} |
void increase_parenthesization_level() { |
- code_ |= is_parenthesized() ? kMultiParenthesizedExpression |
- : kParenthesizedExpression; |
+ code_ = ParenthesizationField::update( |
+ code_, is_parenthesized() ? kMultiParenthesizedExpression |
+ : kParanthesizedExpression); |
} |
// Dummy implementation for making expression->somefunc() work in both Parser |
@@ -798,66 +822,52 @@ class PreParserExpression { |
void set_ast_properties(int* ast_properties) {} |
void set_dont_optimize_reason(BailoutReason dont_optimize_reason) {} |
- bool operator==(const PreParserExpression& other) const { |
- return code_ == other.code_; |
- } |
- bool operator!=(const PreParserExpression& other) const { |
- return code_ != other.code_; |
- } |
- |
private: |
- // Least significant 2 bits are used as expression type. The third least |
- // significant bit tracks whether an expression is parenthesized. If the |
- // expression is an identifier or a string literal, the other bits |
- // describe the type/ (see PreParserIdentifier::Type and string literal |
- // constants below). For binary operations, the other bits are flags |
- // which further describe the contents of the expression. |
- enum { |
- kUnknownExpression = 0, |
- kTypeMask = 1 | 2, |
- kParenthesizedExpression = (1 << 2), |
- kMultiParenthesizedExpression = (1 << 3), |
- |
- // Identifiers |
- kTypeIdentifier = 1, // Used to detect labels. |
- kIdentifierShift = 5, |
- kTypeStringLiteral = 2, // Used to detect directive prologue. |
- kUnknownStringLiteral = kTypeStringLiteral, |
- kUseStrictString = kTypeStringLiteral | 32, |
- kStringLiteralMask = kUseStrictString, |
+ enum Type { |
marja
2015/03/10 08:45:40
Type and ExpressionType both??? What's up with tha
|
+ kExpression, |
+ kIdentifierExpression, |
+ kStringLiteralExpression, |
+ kBinaryOperationExpression |
+ }; |
- // Binary operations. Those are needed to detect certain keywords and |
- // duplicated identifier in parameter lists for arrow functions, because |
- // they are initially parsed as comma-separated expressions. |
- kTypeBinaryOperation = 3, |
- kBinaryOperationArrowParamList = (1 << 4), |
+ enum Parenthesization { |
+ kNotParenthesized, |
+ kParanthesizedExpression, |
+ kMultiParenthesizedExpression |
+ }; |
- // Below here applies if neither identifier nor string literal. Reserve the |
- // 2 least significant bits for flags. |
- kThisExpression = (1 << 4), |
- kThisPropertyExpression = (2 << 4), |
- kPropertyExpression = (3 << 4), |
- kCallExpression = (4 << 4), |
- kSuperExpression = (5 << 4) |
+ enum ExpressionType { |
+ kThisExpression, |
+ kThisPropertyExpression, |
+ kPropertyExpression, |
+ kCallExpression, |
+ kSuperExpression |
}; |
- explicit PreParserExpression(int expression_code) : code_(expression_code) {} |
+ explicit PreParserExpression(uint32_t expression_code) |
+ : code_(expression_code) {} |
- V8_INLINE int ArrowParamListBit() const { |
- if (IsBinaryOperation()) return code_ & kBinaryOperationArrowParamList; |
- if (IsIdentifier()) { |
- const PreParserIdentifier ident = AsIdentifier(); |
- // A valid identifier can be an arrow function parameter list |
- // except for eval, arguments, yield, and reserved keywords. |
- if (ident.IsEval() || ident.IsArguments() || ident.IsYield() || |
- ident.IsFutureStrictReserved()) |
- return 0; |
- return kBinaryOperationArrowParamList; |
- } |
- return 0; |
+ V8_INLINE bool IsValidArrowParams() const { |
+ return IsBinaryOperation() |
+ ? IsValidArrowParamListField::decode(code_) |
+ : (IsIdentifier() && AsIdentifier().IsValidArrowParam()); |
} |
- int code_; |
+ // The first four bits are for the Type and Parenthesization. |
+ typedef BitField<Type, 0, 2> TypeField; |
+ typedef BitField<Parenthesization, TypeField::kNext, 2> ParenthesizationField; |
+ |
+ // The rest of the bits are interpreted depending on the value |
+ // of the Type field, so they can share the storage. |
+ typedef BitField<ExpressionType, ParenthesizationField::kNext, 3> |
+ ExpressionTypeField; |
+ typedef BitField<bool, ParenthesizationField::kNext, 1> IsUseStrictField; |
+ typedef BitField<bool, ParenthesizationField::kNext, 1> |
+ IsValidArrowParamListField; |
+ typedef BitField<PreParserIdentifier::Type, ParenthesizationField::kNext, 10> |
+ IdentifierTypeField; |
+ |
+ uint32_t code_; |
}; |