Commit eecaef41 authored by marja@chromium.org's avatar marja@chromium.org

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
parent d93c906a
...@@ -304,20 +304,25 @@ const char* ScriptDataImpl::ReadString(unsigned* start, int* chars) { ...@@ -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 beg_pos = Read(PreparseDataConstants::kMessageStartPos);
int end_pos = Read(PreparseDataConstants::kMessageEndPos); int end_pos = Read(PreparseDataConstants::kMessageEndPos);
return Scanner::Location(beg_pos, end_pos); 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); unsigned* start = ReadAddress(PreparseDataConstants::kMessageTextPos);
return ReadString(start, NULL); return ReadString(start, NULL);
} }
Vector<const char*> ScriptDataImpl::BuildArgs() { Vector<const char*> ScriptDataImpl::BuildArgs() const {
int arg_count = Read(PreparseDataConstants::kMessageArgCountPos); int arg_count = Read(PreparseDataConstants::kMessageArgCountPos);
const char** array = NewArray<const char*>(arg_count); const char** array = NewArray<const char*>(arg_count);
// Position after text found by skipping past length field and // Position after text found by skipping past length field and
...@@ -333,12 +338,12 @@ Vector<const char*> ScriptDataImpl::BuildArgs() { ...@@ -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]; return store_[PreparseDataConstants::kHeaderSize + position];
} }
unsigned* ScriptDataImpl::ReadAddress(int position) { unsigned* ScriptDataImpl::ReadAddress(int position) const {
return &store_[PreparseDataConstants::kHeaderSize + position]; return &store_[PreparseDataConstants::kHeaderSize + position];
} }
...@@ -3385,8 +3390,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral( ...@@ -3385,8 +3390,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
} }
ParserTraits::ReportMessageAt( ParserTraits::ReportMessageAt(
Scanner::Location(logger.start(), logger.end()), Scanner::Location(logger.start(), logger.end()),
logger.message(), logger.message(), args, logger.is_reference_error());
args);
*ok = false; *ok = false;
return NULL; return NULL;
} }
...@@ -4688,7 +4692,8 @@ bool Parser::Parse() { ...@@ -4688,7 +4692,8 @@ bool Parser::Parse() {
Scanner::Location loc = cached_data->MessageLocation(); Scanner::Location loc = cached_data->MessageLocation();
const char* message = cached_data->BuildMessage(); const char* message = cached_data->BuildMessage();
Vector<const char*> args = cached_data->BuildArgs(); Vector<const char*> args = cached_data->BuildArgs();
ParserTraits::ReportMessageAt(loc, message, args); ParserTraits::ReportMessageAt(loc, message, args,
cached_data->IsReferenceError());
DeleteArray(message); DeleteArray(message);
for (int i = 0; i < args.length(); i++) { for (int i = 0; i < args.length(); i++) {
DeleteArray(args[i]); DeleteArray(args[i]);
......
...@@ -104,9 +104,10 @@ class ScriptDataImpl : public ScriptData { ...@@ -104,9 +104,10 @@ class ScriptDataImpl : public ScriptData {
int GetSymbolIdentifier(); int GetSymbolIdentifier();
bool SanityCheck(); bool SanityCheck();
Scanner::Location MessageLocation(); Scanner::Location MessageLocation() const;
const char* BuildMessage(); bool IsReferenceError() const;
Vector<const char*> BuildArgs(); const char* BuildMessage() const;
Vector<const char*> BuildArgs() const;
int symbol_count() { int symbol_count() {
return (store_.length() > PreparseDataConstants::kHeaderSize) return (store_.length() > PreparseDataConstants::kHeaderSize)
...@@ -127,8 +128,8 @@ class ScriptDataImpl : public ScriptData { ...@@ -127,8 +128,8 @@ class ScriptDataImpl : public ScriptData {
int function_index_; int function_index_;
bool owns_store_; bool owns_store_;
unsigned Read(int position); unsigned Read(int position) const;
unsigned* ReadAddress(int position); unsigned* ReadAddress(int position) const;
// Reads a number from the current symbols // Reads a number from the current symbols
int ReadNumber(byte** source); int ReadNumber(byte** source);
......
...@@ -51,7 +51,8 @@ struct PreparseDataConstants { ...@@ -51,7 +51,8 @@ struct PreparseDataConstants {
static const int kMessageStartPos = 0; static const int kMessageStartPos = 0;
static const int kMessageEndPos = 1; static const int kMessageEndPos = 1;
static const int kMessageArgCountPos = 2; 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; static const unsigned char kNumberTerminator = 0x80u;
}; };
......
...@@ -88,9 +88,10 @@ CompleteParserRecorder::CompleteParserRecorder() ...@@ -88,9 +88,10 @@ CompleteParserRecorder::CompleteParserRecorder()
void CompleteParserRecorder::LogMessage(int start_pos, void CompleteParserRecorder::LogMessage(int start_pos,
int end_pos, int end_pos,
const char* message, const char* message,
const char* arg_opt) { const char* arg_opt,
bool is_reference_error) {
if (has_error()) return; if (has_error()) return;
preamble_[PreparseDataConstants::kHasErrorOffset] = true; preamble_[PreparseDataConstants::kHasErrorOffset] = true;
function_store_.Reset(); function_store_.Reset();
...@@ -100,7 +101,9 @@ void CompleteParserRecorder::LogMessage(int start_pos, ...@@ -100,7 +101,9 @@ void CompleteParserRecorder::LogMessage(int start_pos,
function_store_.Add(end_pos); function_store_.Add(end_pos);
STATIC_ASSERT(PreparseDataConstants::kMessageArgCountPos == 2); STATIC_ASSERT(PreparseDataConstants::kMessageArgCountPos == 2);
function_store_.Add((arg_opt == NULL) ? 0 : 1); 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)); WriteString(CStrVector(message));
if (arg_opt != NULL) WriteString(CStrVector(arg_opt)); if (arg_opt != NULL) WriteString(CStrVector(arg_opt));
should_log_symbols_ = false; should_log_symbols_ = false;
......
...@@ -55,7 +55,8 @@ class ParserRecorder { ...@@ -55,7 +55,8 @@ class ParserRecorder {
virtual void LogMessage(int start, virtual void LogMessage(int start,
int end, int end,
const char* message, 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. // Logs a symbol creation of a literal or identifier.
bool ShouldLogSymbols() { return should_log_symbols_; } bool ShouldLogSymbols() { return should_log_symbols_; }
...@@ -80,8 +81,9 @@ class ParserRecorder { ...@@ -80,8 +81,9 @@ class ParserRecorder {
class SingletonLogger : public ParserRecorder { class SingletonLogger : public ParserRecorder {
public: public:
SingletonLogger() : has_error_(false), start_(-1), end_(-1) { } SingletonLogger()
virtual ~SingletonLogger() { } : has_error_(false), start_(-1), end_(-1), is_reference_error_(false) {}
virtual ~SingletonLogger() {}
void Reset() { has_error_ = false; } void Reset() { has_error_ = false; }
...@@ -104,36 +106,39 @@ class SingletonLogger : public ParserRecorder { ...@@ -104,36 +106,39 @@ class SingletonLogger : public ParserRecorder {
virtual void LogMessage(int start, virtual void LogMessage(int start,
int end, int end,
const char* message, const char* message,
const char* argument_opt) { const char* argument_opt,
bool is_reference_error) {
if (has_error_) return; if (has_error_) return;
has_error_ = true; has_error_ = true;
start_ = start; start_ = start;
end_ = end; end_ = end;
message_ = message; message_ = message;
argument_opt_ = argument_opt; 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 start() const { return start_; }
int end() { return end_; } int end() const { return end_; }
int literals() { int literals() const {
ASSERT(!has_error_); ASSERT(!has_error_);
return literals_; return literals_;
} }
int properties() { int properties() const {
ASSERT(!has_error_); ASSERT(!has_error_);
return properties_; return properties_;
} }
StrictMode strict_mode() { StrictMode strict_mode() const {
ASSERT(!has_error_); ASSERT(!has_error_);
return strict_mode_; return strict_mode_;
} }
int is_reference_error() const { return is_reference_error_; }
const char* message() { const char* message() {
ASSERT(has_error_); ASSERT(has_error_);
return message_; return message_;
} }
const char* argument_opt() { const char* argument_opt() const {
ASSERT(has_error_); ASSERT(has_error_);
return argument_opt_; return argument_opt_;
} }
...@@ -149,6 +154,7 @@ class SingletonLogger : public ParserRecorder { ...@@ -149,6 +154,7 @@ class SingletonLogger : public ParserRecorder {
// For error messages. // For error messages.
const char* message_; const char* message_;
const char* argument_opt_; const char* argument_opt_;
bool is_reference_error_;
}; };
...@@ -180,7 +186,8 @@ class CompleteParserRecorder : public ParserRecorder { ...@@ -180,7 +186,8 @@ class CompleteParserRecorder : public ParserRecorder {
virtual void LogMessage(int start, virtual void LogMessage(int start,
int end, int end,
const char* message, const char* message,
const char* argument_opt); const char* argument_opt,
bool is_reference_error_);
virtual void PauseRecording() { virtual void PauseRecording() {
ASSERT(should_log_symbols_); ASSERT(should_log_symbols_);
......
...@@ -83,8 +83,8 @@ void PreParserTraits::ReportMessageAt(Scanner::Location location, ...@@ -83,8 +83,8 @@ void PreParserTraits::ReportMessageAt(Scanner::Location location,
const char* type, const char* type,
const char* name_opt, const char* name_opt,
bool is_reference_error) { bool is_reference_error) {
pre_parser_->log_ pre_parser_->log_->LogMessage(location.beg_pos, location.end_pos, type,
->LogMessage(location.beg_pos, location.end_pos, type, name_opt); name_opt, is_reference_error);
} }
...@@ -93,7 +93,8 @@ void PreParserTraits::ReportMessageAt(int start_pos, ...@@ -93,7 +93,8 @@ void PreParserTraits::ReportMessageAt(int start_pos,
const char* type, const char* type,
const char* name_opt, const char* name_opt,
bool is_reference_error) { 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);
} }
......
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