Commit 2fee5a16 authored by marja@chromium.org's avatar marja@chromium.org

Parser: delay throwing errors.

This makes Parser a bit more independent of Isolate during the recursive descent
phase. That is necessary for making it possible to run Parser on a non-main
thread in the future.

Proof of concept CL for the the "Parser independent of Isolate" work is here:
https://codereview.chromium.org/231073002/

BUG=
R=rossberg@chromium.org

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21385 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent fd4da6bf
......@@ -630,21 +630,12 @@ void ParserTraits::ReportMessageAt(Scanner::Location source_location,
// and we want to report the stack overflow later.
return;
}
MessageLocation location(parser_->script_,
source_location.beg_pos,
source_location.end_pos);
Factory* factory = parser_->isolate()->factory();
Handle<FixedArray> elements = factory->NewFixedArray(arg == NULL ? 0 : 1);
if (arg != NULL) {
Handle<String> arg_string =
factory->NewStringFromUtf8(CStrVector(arg)).ToHandleChecked();
elements->set(0, *arg_string);
}
Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
Handle<Object> result = is_reference_error
? factory->NewReferenceError(message, array)
: factory->NewSyntaxError(message, array);
parser_->isolate()->Throw(*result, &location);
parser_->has_pending_error_ = true;
parser_->pending_error_location_ = source_location;
parser_->pending_error_message_ = message;
parser_->pending_error_char_arg_ = arg;
parser_->pending_error_arg_ = Handle<String>();
parser_->pending_error_is_reference_error_ = is_reference_error;
}
......@@ -666,19 +657,12 @@ void ParserTraits::ReportMessageAt(Scanner::Location source_location,
// and we want to report the stack overflow later.
return;
}
MessageLocation location(parser_->script_,
source_location.beg_pos,
source_location.end_pos);
Factory* factory = parser_->isolate()->factory();
Handle<FixedArray> elements = factory->NewFixedArray(arg.is_null() ? 0 : 1);
if (!arg.is_null()) {
elements->set(0, *(arg.ToHandleChecked()));
}
Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
Handle<Object> result = is_reference_error
? factory->NewReferenceError(message, array)
: factory->NewSyntaxError(message, array);
parser_->isolate()->Throw(*result, &location);
parser_->has_pending_error_ = true;
parser_->pending_error_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;
}
......@@ -790,7 +774,10 @@ Parser::Parser(CompilationInfo* info)
target_stack_(NULL),
cached_data_(NULL),
cached_data_mode_(NO_CACHED_DATA),
info_(info) {
info_(info),
has_pending_error_(false),
pending_error_message_(NULL),
pending_error_char_arg_(NULL) {
ASSERT(!script_.is_null());
isolate_->set_ast_node_id(0);
set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping);
......@@ -942,6 +929,8 @@ FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info,
factory()->visitor()->dont_optimize_reason());
} else if (stack_overflow()) {
isolate()->StackOverflow();
} else {
ThrowPendingError();
}
}
......@@ -1036,7 +1025,11 @@ FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) {
ASSERT(target_stack_ == NULL);
if (result == NULL) {
if (stack_overflow()) isolate()->StackOverflow();
if (stack_overflow()) {
isolate()->StackOverflow();
} else {
ThrowPendingError();
}
} else {
Handle<String> inferred_name(shared_info->inferred_name());
result->set_inferred_name(inferred_name);
......@@ -3679,6 +3672,32 @@ void Parser::RegisterTargetUse(Label* target, Target* stop) {
}
void Parser::ThrowPendingError() {
if (has_pending_error_) {
MessageLocation location(script_,
pending_error_location_.beg_pos,
pending_error_location_.end_pos);
Factory* factory = isolate()->factory();
bool has_arg =
!pending_error_arg_.is_null() || pending_error_char_arg_ != NULL;
Handle<FixedArray> elements = factory->NewFixedArray(has_arg ? 1 : 0);
if (!pending_error_arg_.is_null()) {
elements->set(0, *(pending_error_arg_.ToHandleChecked()));
} else if (pending_error_char_arg_ != NULL) {
Handle<String> arg_string =
factory->NewStringFromUtf8(CStrVector(pending_error_char_arg_))
.ToHandleChecked();
elements->set(0, *arg_string);
}
Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
Handle<Object> result = pending_error_is_reference_error_
? factory->NewReferenceError(pending_error_message_, array)
: factory->NewSyntaxError(pending_error_message_, array);
isolate()->Throw(*result, &location);
}
}
// ----------------------------------------------------------------------------
// Regular expressions
......
......@@ -781,6 +781,8 @@ class Parser : public ParserBase<ParserTraits> {
bool is_generator,
bool* ok);
void ThrowPendingError();
Isolate* isolate_;
Handle<Script> script_;
......@@ -792,6 +794,14 @@ class Parser : public ParserBase<ParserTraits> {
CachedDataMode cached_data_mode_;
CompilationInfo* info_;
// Pending errors.
bool has_pending_error_;
Scanner::Location pending_error_location_;
const char* pending_error_message_;
MaybeHandle<String> pending_error_arg_;
const char* pending_error_char_arg_;
bool pending_error_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