Replace is_reference_error bool argument with ParseErrorType enum

This avoids accidental coercion-to-bool when calling ReportMessage()
in the parser (e.g., from pointer types), and as a bonus makes callsites
easier to read.

Review URL: https://codereview.chromium.org/939303002

Cr-Commit-Position: refs/heads/master@{#26788}
This commit is contained in:
adamk 2015-02-20 13:19:43 -08:00 committed by Commit bot
parent 925364f5b4
commit 82368b17e9
8 changed files with 76 additions and 90 deletions

View File

@ -802,6 +802,10 @@ enum InitializationFlag {
enum MaybeAssignedFlag { kNotAssigned, kMaybeAssigned };
// Serialized in PreparseData, so numeric values should not be changed.
enum ParseErrorType { kSyntaxError = 0, kReferenceError = 1 };
enum ClearExceptionFlag {
KEEP_EXCEPTION,
CLEAR_EXCEPTION

View File

@ -600,9 +600,8 @@ Expression* ParserTraits::NewThrowError(
void ParserTraits::ReportMessageAt(Scanner::Location source_location,
const char* message,
const char* arg,
bool is_reference_error) {
const char* message, const char* arg,
ParseErrorType error_type) {
if (parser_->stack_overflow()) {
// Suppress the error message (syntax error or such) in the presence of a
// stack overflow. The isolate allows only one pending exception at at time
@ -614,30 +613,27 @@ void ParserTraits::ReportMessageAt(Scanner::Location source_location,
parser_->pending_error_message_ = message;
parser_->pending_error_char_arg_ = arg;
parser_->pending_error_arg_ = NULL;
parser_->pending_error_is_reference_error_ = is_reference_error;
parser_->pending_error_type_ = error_type;
}
void ParserTraits::ReportMessage(const char* message,
const char* arg,
bool is_reference_error) {
void ParserTraits::ReportMessage(const char* message, const char* arg,
ParseErrorType error_type) {
Scanner::Location source_location = parser_->scanner()->location();
ReportMessageAt(source_location, message, arg, is_reference_error);
ReportMessageAt(source_location, message, arg, error_type);
}
void ParserTraits::ReportMessage(const char* message,
const AstRawString* arg,
bool is_reference_error) {
void ParserTraits::ReportMessage(const char* message, const AstRawString* arg,
ParseErrorType error_type) {
Scanner::Location source_location = parser_->scanner()->location();
ReportMessageAt(source_location, message, arg, is_reference_error);
ReportMessageAt(source_location, message, arg, error_type);
}
void ParserTraits::ReportMessageAt(Scanner::Location source_location,
const char* message,
const AstRawString* arg,
bool is_reference_error) {
const char* message, const AstRawString* arg,
ParseErrorType error_type) {
if (parser_->stack_overflow()) {
// Suppress the error message (syntax error or such) in the presence of a
// stack overflow. The isolate allows only one pending exception at at time
@ -649,7 +645,7 @@ void ParserTraits::ReportMessageAt(Scanner::Location source_location,
parser_->pending_error_message_ = message;
parser_->pending_error_char_arg_ = NULL;
parser_->pending_error_arg_ = arg;
parser_->pending_error_is_reference_error_ = is_reference_error;
parser_->pending_error_type_ = error_type;
}
@ -797,6 +793,7 @@ Parser::Parser(CompilationInfo* info, uintptr_t stack_limit, uint32_t hash_seed,
pending_error_message_(NULL),
pending_error_arg_(NULL),
pending_error_char_arg_(NULL),
pending_error_type_(kSyntaxError),
total_preparse_skipped_(0),
pre_parse_timer_(NULL),
parsing_on_main_thread_(true) {
@ -3888,7 +3885,7 @@ void Parser::SkipLazyFunctionBody(const AstRawString* function_name,
if (logger.has_error()) {
ParserTraits::ReportMessageAt(
Scanner::Location(logger.start(), logger.end()), logger.message(),
logger.argument_opt(), logger.is_reference_error());
logger.argument_opt(), logger.error_type());
*ok = false;
return;
}
@ -4292,10 +4289,16 @@ void Parser::ThrowPendingError(Isolate* isolate, Handle<Script> script) {
Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
Handle<Object> error;
MaybeHandle<Object> maybe_error =
pending_error_is_reference_error_
? factory->NewReferenceError(pending_error_message_, array)
: factory->NewSyntaxError(pending_error_message_, array);
MaybeHandle<Object> maybe_error;
switch (pending_error_type_) {
case kReferenceError:
maybe_error = factory->NewReferenceError(pending_error_message_, array);
break;
case kSyntaxError:
maybe_error = factory->NewSyntaxError(pending_error_message_, array);
break;
}
DCHECK(!maybe_error.is_null() || isolate->has_pending_exception());
if (maybe_error.ToHandle(&error)) {
Handle<JSObject> jserror = Handle<JSObject>::cast(error);

View File

@ -492,20 +492,16 @@ class ParserTraits {
const AstRawString* arg, int pos);
// Reporting errors.
void ReportMessageAt(Scanner::Location source_location,
const char* message,
void ReportMessageAt(Scanner::Location source_location, const char* message,
const char* arg = NULL,
bool is_reference_error = false);
void ReportMessage(const char* message,
const char* arg = NULL,
bool is_reference_error = false);
void ReportMessage(const char* message,
const AstRawString* arg,
bool is_reference_error = false);
void ReportMessageAt(Scanner::Location source_location,
const char* message,
ParseErrorType error_type = kSyntaxError);
void ReportMessage(const char* message, const char* arg = NULL,
ParseErrorType error_type = kSyntaxError);
void ReportMessage(const char* message, const AstRawString* arg,
ParseErrorType error_type = kSyntaxError);
void ReportMessageAt(Scanner::Location source_location, const char* message,
const AstRawString* arg,
bool is_reference_error = false);
ParseErrorType error_type = kSyntaxError);
// "null" return type creators.
static const AstRawString* EmptyIdentifier() {
@ -853,7 +849,7 @@ class Parser : public ParserBase<ParserTraits> {
const char* pending_error_message_;
const AstRawString* pending_error_arg_;
const char* pending_error_char_arg_;
bool pending_error_is_reference_error_;
ParseErrorType pending_error_type_;
// Other information which will be stored in Parser and moved to Isolate after
// parsing.

View File

@ -27,7 +27,7 @@ struct PreparseDataConstants {
static const int kMessageStartPos = 0;
static const int kMessageEndPos = 1;
static const int kMessageArgCountPos = 2;
static const int kIsReferenceErrorPos = 3;
static const int kParseErrorTypePos = 3;
static const int kMessageTextPos = 4;
static const unsigned char kNumberTerminator = 0x80u;

View File

@ -28,11 +28,10 @@ CompleteParserRecorder::CompleteParserRecorder() {
}
void CompleteParserRecorder::LogMessage(int start_pos,
int end_pos,
void CompleteParserRecorder::LogMessage(int start_pos, int end_pos,
const char* message,
const char* arg_opt,
bool is_reference_error) {
ParseErrorType error_type) {
if (HasError()) return;
preamble_[PreparseDataConstants::kHasErrorOffset] = true;
function_store_.Reset();
@ -42,8 +41,8 @@ void CompleteParserRecorder::LogMessage(int start_pos,
function_store_.Add(end_pos);
STATIC_ASSERT(PreparseDataConstants::kMessageArgCountPos == 2);
function_store_.Add((arg_opt == NULL) ? 0 : 1);
STATIC_ASSERT(PreparseDataConstants::kIsReferenceErrorPos == 3);
function_store_.Add(is_reference_error ? 1 : 0);
STATIC_ASSERT(PreparseDataConstants::kParseErrorTypePos == 3);
function_store_.Add(error_type);
STATIC_ASSERT(PreparseDataConstants::kMessageTextPos == 4);
WriteString(CStrVector(message));
if (arg_opt != NULL) WriteString(CStrVector(arg_opt));

View File

@ -30,11 +30,10 @@ class ParserRecorder {
// Logs an error message and marks the log as containing an error.
// Further logging will be ignored, and ExtractData will return a vector
// representing the error only.
virtual void LogMessage(int start,
int end,
const char* message,
virtual void LogMessage(int start, int end, const char* message,
const char* argument_opt,
bool is_reference_error) = 0;
ParseErrorType error_type) = 0;
private:
DISALLOW_COPY_AND_ASSIGN(ParserRecorder);
};
@ -43,7 +42,7 @@ class ParserRecorder {
class SingletonLogger : public ParserRecorder {
public:
SingletonLogger()
: has_error_(false), start_(-1), end_(-1), is_reference_error_(false) {}
: has_error_(false), start_(-1), end_(-1), error_type_(kSyntaxError) {}
virtual ~SingletonLogger() {}
void Reset() { has_error_ = false; }
@ -63,18 +62,15 @@ class SingletonLogger : public ParserRecorder {
// Logs an error message and marks the log as containing an error.
// Further logging will be ignored, and ExtractData will return a vector
// representing the error only.
virtual void LogMessage(int start,
int end,
const char* message,
const char* argument_opt,
bool is_reference_error) {
virtual void LogMessage(int start, int end, const char* message,
const char* argument_opt, ParseErrorType error_type) {
if (has_error_) return;
has_error_ = true;
start_ = start;
end_ = end;
message_ = message;
argument_opt_ = argument_opt;
is_reference_error_ = is_reference_error;
error_type_ = error_type;
}
bool has_error() const { return has_error_; }
@ -97,7 +93,10 @@ class SingletonLogger : public ParserRecorder {
DCHECK(!has_error_);
return scope_uses_super_property_;
}
int is_reference_error() const { return is_reference_error_; }
ParseErrorType error_type() const {
DCHECK(has_error_);
return error_type_;
}
const char* message() {
DCHECK(has_error_);
return message_;
@ -119,7 +118,7 @@ class SingletonLogger : public ParserRecorder {
// For error messages.
const char* message_;
const char* argument_opt_;
bool is_reference_error_;
ParseErrorType error_type_;
};
@ -147,11 +146,8 @@ class CompleteParserRecorder : public ParserRecorder {
// Logs an error message and marks the log as containing an error.
// Further logging will be ignored, and ExtractData will return a vector
// representing the error only.
virtual void LogMessage(int start,
int end,
const char* message,
const char* argument_opt,
bool is_reference_error_);
virtual void LogMessage(int start, int end, const char* message,
const char* argument_opt, ParseErrorType error_type);
ScriptData* GetScriptData();
bool HasError() {

View File

@ -21,24 +21,16 @@ namespace v8 {
namespace internal {
void PreParserTraits::ReportMessageAt(Scanner::Location location,
const char* message,
const char* arg,
bool is_reference_error) {
ReportMessageAt(location.beg_pos,
location.end_pos,
message,
arg,
is_reference_error);
const char* message, const char* arg,
ParseErrorType error_type) {
ReportMessageAt(location.beg_pos, location.end_pos, message, arg, error_type);
}
void PreParserTraits::ReportMessageAt(int start_pos,
int end_pos,
const char* message,
const char* arg,
bool is_reference_error) {
pre_parser_->log_->LogMessage(start_pos, end_pos, message, arg,
is_reference_error);
void PreParserTraits::ReportMessageAt(int start_pos, int end_pos,
const char* message, const char* arg,
ParseErrorType error_type) {
pre_parser_->log_->LogMessage(start_pos, end_pos, message, arg, error_type);
}

View File

@ -527,16 +527,15 @@ class ParserBase : public Traits {
// Report syntax errors.
void ReportMessage(const char* message, const char* arg = NULL,
bool is_reference_error = false) {
ParseErrorType error_type = kSyntaxError) {
Scanner::Location source_location = scanner()->location();
Traits::ReportMessageAt(source_location, message, arg, is_reference_error);
Traits::ReportMessageAt(source_location, message, arg, error_type);
}
void ReportMessageAt(Scanner::Location location, const char* message,
bool is_reference_error = false) {
Traits::ReportMessageAt(location, message,
reinterpret_cast<const char*>(0),
is_reference_error);
ParseErrorType error_type = kSyntaxError) {
Traits::ReportMessageAt(location, message, reinterpret_cast<const char*>(0),
error_type);
}
void ReportUnexpectedToken(Token::Value token);
@ -1345,15 +1344,12 @@ class PreParserTraits {
}
// Reporting errors.
void ReportMessageAt(Scanner::Location location,
const char* message,
void ReportMessageAt(Scanner::Location location, const char* message,
const char* arg = NULL,
bool is_reference_error = false);
void ReportMessageAt(int start_pos,
int end_pos,
const char* message,
ParseErrorType error_type = kSyntaxError);
void ReportMessageAt(int start_pos, int end_pos, const char* message,
const char* arg = NULL,
bool is_reference_error = false);
ParseErrorType error_type = kSyntaxError);
// "null" return type creators.
static PreParserIdentifier EmptyIdentifier() {
@ -2988,7 +2984,7 @@ ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start, bool* ok) {
} else if (next == Token::ILLEGAL) {
Traits::ReportMessageAt(
Scanner::Location(position() + 1, peek_position()),
"unexpected_token", "ILLEGAL", false);
"unexpected_token", "ILLEGAL", kSyntaxError);
*ok = false;
return Traits::EmptyExpression();
}
@ -3017,7 +3013,7 @@ ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start, bool* ok) {
} else if (next == Token::ILLEGAL) {
Traits::ReportMessageAt(
Scanner::Location(position() + 1, peek_position()),
"unexpected_token", "ILLEGAL", false);
"unexpected_token", "ILLEGAL", kSyntaxError);
*ok = false;
return Traits::EmptyExpression();
}
@ -3039,7 +3035,7 @@ typename ParserBase<Traits>::ExpressionT ParserBase<
const char* message, bool* ok) {
if (is_strict(language_mode()) && this->IsIdentifier(expression) &&
this->IsEvalOrArguments(this->AsIdentifier(expression))) {
this->ReportMessageAt(location, "strict_eval_arguments", false);
this->ReportMessageAt(location, "strict_eval_arguments", kSyntaxError);
*ok = false;
return this->EmptyExpression();
} else if (expression->IsValidReferenceExpression()) {
@ -3051,7 +3047,7 @@ typename ParserBase<Traits>::ExpressionT ParserBase<
ExpressionT error = this->NewThrowReferenceError(message, pos);
return factory()->NewProperty(expression, error, pos);
} else {
this->ReportMessageAt(location, message, true);
this->ReportMessageAt(location, message, kReferenceError);
*ok = false;
return this->EmptyExpression();
}