Commit 62630927 authored by nikolaos's avatar nikolaos Committed by Commit bot

[parser] Clean up (pre)parser traits, part 2

This patch moves the following methods from the traits objects to
the (pre)parser implementation objects:

- AsIdentifier
- CheckAssigningFunctionLiteralToProperty
- GetPropertyValue
- InferFunctionName
- IsArguments
- IsArrayIndex
- IsBoilerplateProperty
- IsConstructor
- IsDirectEvalCall
- IsEval
- IsEvalOrArguments
- IsFutureStrictReserved
- IsIdentifier
- IsPrototype
- IsThisProperty
- IsUndefined
- MarkExpressionAsAssigned
- PushLiteralName
- PushPropertyName
- ShortcutNumericLiteralBinaryExpression

R=adamk@chromium.org, marja@chromium.org
BUG=
LOG=N

Review-Url: https://codereview.chromium.org/2273693002
Cr-Commit-Position: refs/heads/master@{#38861}
parent b5629a10
This diff is collapsed.
......@@ -297,76 +297,9 @@ class TargetScope BASE_EMBEDDED {
// ----------------------------------------------------------------------------
// Implementation of Parser
bool ParserBaseTraits<Parser>::IsEval(const AstRawString* identifier) const {
return identifier == delegate()->ast_value_factory()->eval_string();
}
bool ParserBaseTraits<Parser>::IsArguments(
const AstRawString* identifier) const {
return identifier == delegate()->ast_value_factory()->arguments_string();
}
bool ParserBaseTraits<Parser>::IsEvalOrArguments(
const AstRawString* identifier) const {
return IsEval(identifier) || IsArguments(identifier);
}
bool ParserBaseTraits<Parser>::IsUndefined(
const AstRawString* identifier) const {
return identifier == delegate()->ast_value_factory()->undefined_string();
}
bool ParserBaseTraits<Parser>::IsPrototype(
const AstRawString* identifier) const {
return identifier == delegate()->ast_value_factory()->prototype_string();
}
bool ParserBaseTraits<Parser>::IsConstructor(
const AstRawString* identifier) const {
return identifier == delegate()->ast_value_factory()->constructor_string();
}
bool ParserBaseTraits<Parser>::IsThisProperty(Expression* expression) {
DCHECK(expression != NULL);
Property* property = expression->AsProperty();
return property != NULL && property->obj()->IsVariableProxy() &&
property->obj()->AsVariableProxy()->is_this();
}
bool ParserBaseTraits<Parser>::IsIdentifier(Expression* expression) {
VariableProxy* operand = expression->AsVariableProxy();
return operand != NULL && !operand->is_this();
}
void ParserBaseTraits<Parser>::PushPropertyName(FuncNameInferrer* fni,
Expression* expression) {
if (expression->IsPropertyName()) {
fni->PushLiteralName(expression->AsLiteral()->AsRawPropertyName());
} else {
fni->PushLiteralName(
delegate()->ast_value_factory()->anonymous_function_string());
}
}
void ParserBaseTraits<Parser>::CheckAssigningFunctionLiteralToProperty(
Expression* left, Expression* right) {
DCHECK(left != NULL);
if (left->IsProperty() && right->IsFunctionLiteral()) {
right->AsFunctionLiteral()->set_pretenure();
}
}
Expression* ParserBaseTraits<Parser>::MarkExpressionAsAssigned(
Expression* expression) {
VariableProxy* proxy =
expression != NULL ? expression->AsVariableProxy() : NULL;
if (proxy != NULL) proxy->set_is_assigned();
return expression;
}
bool ParserBaseTraits<Parser>::ShortcutNumericLiteralBinaryExpression(
Expression** x, Expression* y, Token::Value op, int pos,
AstNodeFactory* factory) {
bool Parser::ShortcutNumericLiteralBinaryExpression(Expression** x,
Expression* y,
Token::Value op, int pos) {
if ((*x)->AsLiteral() && (*x)->AsLiteral()->raw_value()->IsNumber() &&
y->AsLiteral() && y->AsLiteral()->raw_value()->IsNumber()) {
double x_val = (*x)->AsLiteral()->raw_value()->AsNumber();
......@@ -376,53 +309,53 @@ bool ParserBaseTraits<Parser>::ShortcutNumericLiteralBinaryExpression(
bool has_dot = x_has_dot || y_has_dot;
switch (op) {
case Token::ADD:
*x = factory->NewNumberLiteral(x_val + y_val, pos, has_dot);
*x = factory()->NewNumberLiteral(x_val + y_val, pos, has_dot);
return true;
case Token::SUB:
*x = factory->NewNumberLiteral(x_val - y_val, pos, has_dot);
*x = factory()->NewNumberLiteral(x_val - y_val, pos, has_dot);
return true;
case Token::MUL:
*x = factory->NewNumberLiteral(x_val * y_val, pos, has_dot);
*x = factory()->NewNumberLiteral(x_val * y_val, pos, has_dot);
return true;
case Token::DIV:
*x = factory->NewNumberLiteral(x_val / y_val, pos, has_dot);
*x = factory()->NewNumberLiteral(x_val / y_val, pos, has_dot);
return true;
case Token::BIT_OR: {
int value = DoubleToInt32(x_val) | DoubleToInt32(y_val);
*x = factory->NewNumberLiteral(value, pos, has_dot);
*x = factory()->NewNumberLiteral(value, pos, has_dot);
return true;
}
case Token::BIT_AND: {
int value = DoubleToInt32(x_val) & DoubleToInt32(y_val);
*x = factory->NewNumberLiteral(value, pos, has_dot);
*x = factory()->NewNumberLiteral(value, pos, has_dot);
return true;
}
case Token::BIT_XOR: {
int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val);
*x = factory->NewNumberLiteral(value, pos, has_dot);
*x = factory()->NewNumberLiteral(value, pos, has_dot);
return true;
}
case Token::SHL: {
int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f);
*x = factory->NewNumberLiteral(value, pos, has_dot);
*x = factory()->NewNumberLiteral(value, pos, has_dot);
return true;
}
case Token::SHR: {
uint32_t shift = DoubleToInt32(y_val) & 0x1f;
uint32_t value = DoubleToUint32(x_val) >> shift;
*x = factory->NewNumberLiteral(value, pos, has_dot);
*x = factory()->NewNumberLiteral(value, pos, has_dot);
return true;
}
case Token::SAR: {
uint32_t shift = DoubleToInt32(y_val) & 0x1f;
int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
*x = factory->NewNumberLiteral(value, pos, has_dot);
*x = factory()->NewNumberLiteral(value, pos, has_dot);
return true;
}
case Token::EXP: {
double value = Pow(x_val, y_val);
int int_value = static_cast<int>(value);
*x = factory->NewNumberLiteral(
*x = factory()->NewNumberLiteral(
int_value == value && value != -0.0 ? int_value : value, pos,
has_dot);
return true;
......
......@@ -175,74 +175,6 @@ class ParserBaseTraits<Parser> {
return reinterpret_cast<const Parser*>(this);
}
// Helper functions for recursive descent.
bool IsEval(const AstRawString* identifier) const;
bool IsArguments(const AstRawString* identifier) const;
bool IsEvalOrArguments(const AstRawString* identifier) const;
bool IsUndefined(const AstRawString* identifier) const;
V8_INLINE bool IsFutureStrictReserved(const AstRawString* identifier) const;
// Returns true if the expression is of type "this.foo".
static bool IsThisProperty(Expression* expression);
static bool IsIdentifier(Expression* expression);
static const AstRawString* AsIdentifier(Expression* expression) {
DCHECK(IsIdentifier(expression));
return expression->AsVariableProxy()->raw_name();
}
bool IsPrototype(const AstRawString* identifier) const;
bool IsConstructor(const AstRawString* identifier) const;
bool IsDirectEvalCall(Expression* expression) const {
if (!expression->IsCall()) return false;
expression = expression->AsCall()->expression();
return IsIdentifier(expression) && IsEval(AsIdentifier(expression));
}
static bool IsBoilerplateProperty(ObjectLiteral::Property* property) {
return ObjectLiteral::IsBoilerplateProperty(property);
}
static bool IsArrayIndex(const AstRawString* string, uint32_t* index) {
return string->AsArrayIndex(index);
}
static Expression* GetPropertyValue(ObjectLiteral::Property* property) {
return property->value();
}
// Functions for encapsulating the differences between parsing and preparsing;
// operations interleaved with the recursive descent.
static void PushLiteralName(FuncNameInferrer* fni, const AstRawString* id) {
fni->PushLiteralName(id);
}
void PushPropertyName(FuncNameInferrer* fni, Expression* expression);
static void InferFunctionName(FuncNameInferrer* fni,
FunctionLiteral* func_to_infer) {
fni->AddFunction(func_to_infer);
}
// If we assign a function literal to a property we pretenure the
// literal so it can be added as a constant function property.
static void CheckAssigningFunctionLiteralToProperty(Expression* left,
Expression* right);
// Determine if the expression is a variable proxy and mark it as being used
// in an assignment or with a increment/decrement operator.
static Expression* MarkExpressionAsAssigned(Expression* expression);
// Returns true if we have a binary expression between two numeric
// literals. In that case, *x will be changed to an expression which is the
// computed value.
bool ShortcutNumericLiteralBinaryExpression(Expression** x, Expression* y,
Token::Value op, int pos,
AstNodeFactory* factory);
// Rewrites the following types of unary expressions:
// not <literal> -> true / false
// + <numeric literal> -> <numeric literal>
......@@ -892,6 +824,123 @@ class Parser : public ParserBase<Parser> {
bool* ok);
void SetFunctionName(Expression* value, const AstRawString* name);
// Helper functions for recursive descent.
V8_INLINE bool IsEval(const AstRawString* identifier) const {
return identifier == ast_value_factory()->eval_string();
}
V8_INLINE bool IsArguments(const AstRawString* identifier) const {
return identifier == ast_value_factory()->arguments_string();
}
V8_INLINE bool IsEvalOrArguments(const AstRawString* identifier) const {
return IsEval(identifier) || IsArguments(identifier);
}
V8_INLINE bool IsUndefined(const AstRawString* identifier) const {
return identifier == ast_value_factory()->undefined_string();
}
V8_INLINE bool IsFutureStrictReserved(const AstRawString* identifier) const {
return scanner()->IdentifierIsFutureStrictReserved(identifier);
}
// Returns true if the expression is of type "this.foo".
V8_INLINE static bool IsThisProperty(Expression* expression) {
DCHECK(expression != NULL);
Property* property = expression->AsProperty();
return property != NULL && property->obj()->IsVariableProxy() &&
property->obj()->AsVariableProxy()->is_this();
}
V8_INLINE static bool IsIdentifier(Expression* expression) {
VariableProxy* operand = expression->AsVariableProxy();
return operand != NULL && !operand->is_this();
}
V8_INLINE static const AstRawString* AsIdentifier(Expression* expression) {
DCHECK(IsIdentifier(expression));
return expression->AsVariableProxy()->raw_name();
}
V8_INLINE bool IsPrototype(const AstRawString* identifier) const {
return identifier == ast_value_factory()->prototype_string();
}
V8_INLINE bool IsConstructor(const AstRawString* identifier) const {
return identifier == ast_value_factory()->constructor_string();
}
V8_INLINE bool IsDirectEvalCall(Expression* expression) const {
if (!expression->IsCall()) return false;
expression = expression->AsCall()->expression();
return IsIdentifier(expression) && IsEval(AsIdentifier(expression));
}
V8_INLINE static bool IsBoilerplateProperty(
ObjectLiteral::Property* property) {
return ObjectLiteral::IsBoilerplateProperty(property);
}
V8_INLINE static bool IsArrayIndex(const AstRawString* string,
uint32_t* index) {
return string->AsArrayIndex(index);
}
V8_INLINE static Expression* GetPropertyValue(
ObjectLiteral::Property* property) {
return property->value();
}
// Functions for encapsulating the differences between parsing and preparsing;
// operations interleaved with the recursive descent.
V8_INLINE static void PushLiteralName(FuncNameInferrer* fni,
const AstRawString* id) {
fni->PushLiteralName(id);
}
V8_INLINE void PushPropertyName(FuncNameInferrer* fni,
Expression* expression) {
if (expression->IsPropertyName()) {
fni->PushLiteralName(expression->AsLiteral()->AsRawPropertyName());
} else {
fni->PushLiteralName(ast_value_factory()->anonymous_function_string());
}
}
V8_INLINE static void InferFunctionName(FuncNameInferrer* fni,
FunctionLiteral* func_to_infer) {
fni->AddFunction(func_to_infer);
}
// If we assign a function literal to a property we pretenure the
// literal so it can be added as a constant function property.
V8_INLINE static void CheckAssigningFunctionLiteralToProperty(
Expression* left, Expression* right) {
DCHECK(left != NULL);
if (left->IsProperty() && right->IsFunctionLiteral()) {
right->AsFunctionLiteral()->set_pretenure();
}
}
// Determine if the expression is a variable proxy and mark it as being used
// in an assignment or with a increment/decrement operator.
V8_INLINE static Expression* MarkExpressionAsAssigned(
Expression* expression) {
VariableProxy* proxy =
expression != NULL ? expression->AsVariableProxy() : NULL;
if (proxy != NULL) proxy->set_is_assigned();
return expression;
}
// Returns true if we have a binary expression between two numeric
// literals. In that case, *x will be changed to an expression which is the
// computed value.
bool ShortcutNumericLiteralBinaryExpression(Expression** x, Expression* y,
Token::Value op, int pos);
// Parser's private field members.
Scanner scanner_;
PreParser* reusable_preparser_;
Scope* original_scope_; // for ES5 function declarations in sloppy eval
......@@ -914,11 +963,6 @@ class Parser : public ParserBase<Parser> {
#endif // DEBUG
};
bool ParserBaseTraits<Parser>::IsFutureStrictReserved(
const AstRawString* identifier) const {
return delegate()->scanner()->IdentifierIsFutureStrictReserved(identifier);
}
const AstRawString* ParserBaseTraits<Parser>::EmptyIdentifierString() const {
return delegate()->ast_value_factory()->empty_string();
}
......
......@@ -624,104 +624,6 @@ class ParserBaseTraits<PreParser> {
return reinterpret_cast<const PreParser*>(this);
}
// Helper functions for recursive descent.
bool IsEval(PreParserIdentifier identifier) const {
return identifier.IsEval();
}
bool IsArguments(PreParserIdentifier identifier) const {
return identifier.IsArguments();
}
bool IsEvalOrArguments(PreParserIdentifier identifier) const {
return identifier.IsEvalOrArguments();
}
bool IsUndefined(PreParserIdentifier identifier) const {
return identifier.IsUndefined();
}
bool IsAwait(PreParserIdentifier identifier) const {
return identifier.IsAwait();
}
bool IsFutureStrictReserved(PreParserIdentifier identifier) const {
return identifier.IsFutureStrictReserved();
}
// Returns true if the expression is of type "this.foo".
static bool IsThisProperty(PreParserExpression expression) {
return expression.IsThisProperty();
}
static bool IsIdentifier(PreParserExpression expression) {
return expression.IsIdentifier();
}
static PreParserIdentifier AsIdentifier(PreParserExpression expression) {
return expression.AsIdentifier();
}
bool IsPrototype(PreParserIdentifier identifier) const {
return identifier.IsPrototype();
}
bool IsConstructor(PreParserIdentifier identifier) const {
return identifier.IsConstructor();
}
bool IsDirectEvalCall(PreParserExpression expression) const {
return expression.IsDirectEvalCall();
}
static bool IsBoilerplateProperty(PreParserExpression property) {
// PreParser doesn't count boilerplate properties.
return false;
}
static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) {
return false;
}
static PreParserExpression GetPropertyValue(PreParserExpression property) {
return PreParserExpression::Default();
}
// Functions for encapsulating the differences between parsing and preparsing;
// operations interleaved with the recursive descent.
static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) {
// PreParser should not use FuncNameInferrer.
UNREACHABLE();
}
void PushPropertyName(FuncNameInferrer* fni, PreParserExpression expression) {
// PreParser should not use FuncNameInferrer.
UNREACHABLE();
}
static void InferFunctionName(FuncNameInferrer* fni,
PreParserExpression expression) {
// PreParser should not use FuncNameInferrer.
UNREACHABLE();
}
static void CheckAssigningFunctionLiteralToProperty(
PreParserExpression left, PreParserExpression right) {}
static PreParserExpression MarkExpressionAsAssigned(
PreParserExpression expression) {
// TODO(marja): To be able to produce the same errors, the preparser needs
// to start tracking which expressions are variables and which are assigned.
return expression;
}
bool ShortcutNumericLiteralBinaryExpression(PreParserExpression* x,
PreParserExpression y,
Token::Value op, int pos,
PreParserFactory* factory) {
return false;
}
PreParserExpression BuildUnaryExpression(PreParserExpression expression,
Token::Value op, int pos,
PreParserFactory* factory) {
......@@ -1136,6 +1038,111 @@ class PreParser : public ParserBase<PreParser> {
V8_INLINE void QueueNonPatternForRewriting(PreParserExpression expr,
bool* ok) {}
// Helper functions for recursive descent.
V8_INLINE bool IsEval(PreParserIdentifier identifier) const {
return identifier.IsEval();
}
V8_INLINE bool IsArguments(PreParserIdentifier identifier) const {
return identifier.IsArguments();
}
V8_INLINE bool IsEvalOrArguments(PreParserIdentifier identifier) const {
return identifier.IsEvalOrArguments();
}
V8_INLINE bool IsUndefined(PreParserIdentifier identifier) const {
return identifier.IsUndefined();
}
V8_INLINE bool IsAwait(PreParserIdentifier identifier) const {
return identifier.IsAwait();
}
V8_INLINE bool IsFutureStrictReserved(PreParserIdentifier identifier) const {
return identifier.IsFutureStrictReserved();
}
// Returns true if the expression is of type "this.foo".
V8_INLINE static bool IsThisProperty(PreParserExpression expression) {
return expression.IsThisProperty();
}
V8_INLINE static bool IsIdentifier(PreParserExpression expression) {
return expression.IsIdentifier();
}
V8_INLINE static PreParserIdentifier AsIdentifier(
PreParserExpression expression) {
return expression.AsIdentifier();
}
V8_INLINE bool IsPrototype(PreParserIdentifier identifier) const {
return identifier.IsPrototype();
}
V8_INLINE bool IsConstructor(PreParserIdentifier identifier) const {
return identifier.IsConstructor();
}
V8_INLINE bool IsDirectEvalCall(PreParserExpression expression) const {
return expression.IsDirectEvalCall();
}
V8_INLINE static bool IsBoilerplateProperty(PreParserExpression property) {
// PreParser doesn't count boilerplate properties.
return false;
}
V8_INLINE static bool IsArrayIndex(PreParserIdentifier string,
uint32_t* index) {
return false;
}
V8_INLINE static PreParserExpression GetPropertyValue(
PreParserExpression property) {
return PreParserExpression::Default();
}
// Functions for encapsulating the differences between parsing and preparsing;
// operations interleaved with the recursive descent.
V8_INLINE static void PushLiteralName(FuncNameInferrer* fni,
PreParserIdentifier id) {
// PreParser should not use FuncNameInferrer.
UNREACHABLE();
}
V8_INLINE void PushPropertyName(FuncNameInferrer* fni,
PreParserExpression expression) {
// PreParser should not use FuncNameInferrer.
UNREACHABLE();
}
V8_INLINE static void InferFunctionName(FuncNameInferrer* fni,
PreParserExpression expression) {
// PreParser should not use FuncNameInferrer.
UNREACHABLE();
}
V8_INLINE static void CheckAssigningFunctionLiteralToProperty(
PreParserExpression left, PreParserExpression right) {}
V8_INLINE static PreParserExpression MarkExpressionAsAssigned(
PreParserExpression expression) {
// TODO(marja): To be able to produce the same errors, the preparser needs
// to start tracking which expressions are variables and which are assigned.
return expression;
}
V8_INLINE bool ShortcutNumericLiteralBinaryExpression(PreParserExpression* x,
PreParserExpression y,
Token::Value op,
int pos) {
return false;
}
// Preparser's private field members.
int* use_counts_;
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment