PreParser fix: propagate reference erros properly.

For example, invalid left hand sides are reference errors. PreParser didn't use
to produce this error ever, so the code for propagating reference errors
properly was missing, and reference errors turned into syntax errors.

R=rossberg@chromium.org
BUG=

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20408 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
marja@chromium.org 2014-04-01 14:17:43 +00:00
parent d93c906acc
commit eecaef41d9
6 changed files with 51 additions and 33 deletions

View File

@ -304,20 +304,25 @@ const char* ScriptDataImpl::ReadString(unsigned* start, int* chars) {
}
Scanner::Location ScriptDataImpl::MessageLocation() {
Scanner::Location ScriptDataImpl::MessageLocation() const {
int beg_pos = Read(PreparseDataConstants::kMessageStartPos);
int end_pos = Read(PreparseDataConstants::kMessageEndPos);
return Scanner::Location(beg_pos, end_pos);
}
const char* ScriptDataImpl::BuildMessage() {
bool ScriptDataImpl::IsReferenceError() const {
return Read(PreparseDataConstants::kIsReferenceErrorPos);
}
const char* ScriptDataImpl::BuildMessage() const {
unsigned* start = ReadAddress(PreparseDataConstants::kMessageTextPos);
return ReadString(start, NULL);
}
Vector<const char*> ScriptDataImpl::BuildArgs() {
Vector<const char*> ScriptDataImpl::BuildArgs() const {
int arg_count = Read(PreparseDataConstants::kMessageArgCountPos);
const char** array = NewArray<const char*>(arg_count);
// Position after text found by skipping past length field and
@ -333,12 +338,12 @@ Vector<const char*> ScriptDataImpl::BuildArgs() {
}
unsigned ScriptDataImpl::Read(int position) {
unsigned ScriptDataImpl::Read(int position) const {
return store_[PreparseDataConstants::kHeaderSize + position];
}
unsigned* ScriptDataImpl::ReadAddress(int position) {
unsigned* ScriptDataImpl::ReadAddress(int position) const {
return &store_[PreparseDataConstants::kHeaderSize + position];
}
@ -3385,8 +3390,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
}
ParserTraits::ReportMessageAt(
Scanner::Location(logger.start(), logger.end()),
logger.message(),
args);
logger.message(), args, logger.is_reference_error());
*ok = false;
return NULL;
}
@ -4688,7 +4692,8 @@ bool Parser::Parse() {
Scanner::Location loc = cached_data->MessageLocation();
const char* message = cached_data->BuildMessage();
Vector<const char*> args = cached_data->BuildArgs();
ParserTraits::ReportMessageAt(loc, message, args);
ParserTraits::ReportMessageAt(loc, message, args,
cached_data->IsReferenceError());
DeleteArray(message);
for (int i = 0; i < args.length(); i++) {
DeleteArray(args[i]);

View File

@ -104,9 +104,10 @@ class ScriptDataImpl : public ScriptData {
int GetSymbolIdentifier();
bool SanityCheck();
Scanner::Location MessageLocation();
const char* BuildMessage();
Vector<const char*> BuildArgs();
Scanner::Location MessageLocation() const;
bool IsReferenceError() const;
const char* BuildMessage() const;
Vector<const char*> BuildArgs() const;
int symbol_count() {
return (store_.length() > PreparseDataConstants::kHeaderSize)
@ -127,8 +128,8 @@ class ScriptDataImpl : public ScriptData {
int function_index_;
bool owns_store_;
unsigned Read(int position);
unsigned* ReadAddress(int position);
unsigned Read(int position) const;
unsigned* ReadAddress(int position) const;
// Reads a number from the current symbols
int ReadNumber(byte** source);

View File

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

View File

@ -90,7 +90,8 @@ CompleteParserRecorder::CompleteParserRecorder()
void CompleteParserRecorder::LogMessage(int start_pos,
int end_pos,
const char* message,
const char* arg_opt) {
const char* arg_opt,
bool is_reference_error) {
if (has_error()) return;
preamble_[PreparseDataConstants::kHasErrorOffset] = true;
function_store_.Reset();
@ -100,7 +101,9 @@ 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::kMessageTextPos == 3);
STATIC_ASSERT(PreparseDataConstants::kIsReferenceErrorPos == 3);
function_store_.Add(is_reference_error ? 1 : 0);
STATIC_ASSERT(PreparseDataConstants::kMessageTextPos == 4);
WriteString(CStrVector(message));
if (arg_opt != NULL) WriteString(CStrVector(arg_opt));
should_log_symbols_ = false;

View File

@ -55,7 +55,8 @@ class ParserRecorder {
virtual void LogMessage(int start,
int end,
const char* message,
const char* argument_opt) = 0;
const char* argument_opt,
bool is_reference_error) = 0;
// Logs a symbol creation of a literal or identifier.
bool ShouldLogSymbols() { return should_log_symbols_; }
@ -80,8 +81,9 @@ class ParserRecorder {
class SingletonLogger : public ParserRecorder {
public:
SingletonLogger() : has_error_(false), start_(-1), end_(-1) { }
virtual ~SingletonLogger() { }
SingletonLogger()
: has_error_(false), start_(-1), end_(-1), is_reference_error_(false) {}
virtual ~SingletonLogger() {}
void Reset() { has_error_ = false; }
@ -104,36 +106,39 @@ class SingletonLogger : public ParserRecorder {
virtual void LogMessage(int start,
int end,
const char* message,
const char* argument_opt) {
const char* argument_opt,
bool is_reference_error) {
if (has_error_) return;
has_error_ = true;
start_ = start;
end_ = end;
message_ = message;
argument_opt_ = argument_opt;
is_reference_error_ = is_reference_error;
}
bool has_error() { return has_error_; }
bool has_error() const { return has_error_; }
int start() { return start_; }
int end() { return end_; }
int literals() {
int start() const { return start_; }
int end() const { return end_; }
int literals() const {
ASSERT(!has_error_);
return literals_;
}
int properties() {
int properties() const {
ASSERT(!has_error_);
return properties_;
}
StrictMode strict_mode() {
StrictMode strict_mode() const {
ASSERT(!has_error_);
return strict_mode_;
}
int is_reference_error() const { return is_reference_error_; }
const char* message() {
ASSERT(has_error_);
return message_;
}
const char* argument_opt() {
const char* argument_opt() const {
ASSERT(has_error_);
return argument_opt_;
}
@ -149,6 +154,7 @@ class SingletonLogger : public ParserRecorder {
// For error messages.
const char* message_;
const char* argument_opt_;
bool is_reference_error_;
};
@ -180,7 +186,8 @@ class CompleteParserRecorder : public ParserRecorder {
virtual void LogMessage(int start,
int end,
const char* message,
const char* argument_opt);
const char* argument_opt,
bool is_reference_error_);
virtual void PauseRecording() {
ASSERT(should_log_symbols_);

View File

@ -83,8 +83,8 @@ void PreParserTraits::ReportMessageAt(Scanner::Location location,
const char* type,
const char* name_opt,
bool is_reference_error) {
pre_parser_->log_
->LogMessage(location.beg_pos, location.end_pos, type, name_opt);
pre_parser_->log_->LogMessage(location.beg_pos, location.end_pos, type,
name_opt, is_reference_error);
}
@ -93,7 +93,8 @@ void PreParserTraits::ReportMessageAt(int start_pos,
const char* type,
const char* name_opt,
bool is_reference_error) {
pre_parser_->log_->LogMessage(start_pos, end_pos, type, name_opt);
pre_parser_->log_->LogMessage(start_pos, end_pos, type, name_opt,
is_reference_error);
}