[parsing] Refactor MessageDetails arguments

.. to consistently support more than a single argument.

Each argument is now a tagged union that may contain an AST string, a
C string, or a JS string handle.

Change-Id: Iac8e40b717dea95a2bc2903449dab56c181702d6
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3122086
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Auto-Submit: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/main@{#76559}
This commit is contained in:
Jakob Gruber 2021-08-30 09:49:07 +02:00 committed by V8 LUCI CQ
parent 95885659dc
commit 8455b98be3
2 changed files with 76 additions and 68 deletions

View File

@ -19,49 +19,52 @@ namespace internal {
void PendingCompilationErrorHandler::MessageDetails::SetString( void PendingCompilationErrorHandler::MessageDetails::SetString(
Handle<String> string, Isolate* isolate) { Handle<String> string, Isolate* isolate) {
DCHECK_NE(arg0_type_, kMainThreadHandle); DCHECK_NE(args_[0].type, kMainThreadHandle);
arg0_type_ = kMainThreadHandle; args_[0].type = kMainThreadHandle;
arg0_handle_ = string; args_[0].js_string = string;
} }
void PendingCompilationErrorHandler::MessageDetails::SetString( void PendingCompilationErrorHandler::MessageDetails::SetString(
Handle<String> string, LocalIsolate* isolate) { Handle<String> string, LocalIsolate* isolate) {
DCHECK_NE(arg0_type_, kMainThreadHandle); DCHECK_NE(args_[0].type, kMainThreadHandle);
arg0_type_ = kMainThreadHandle; args_[0].type = kMainThreadHandle;
arg0_handle_ = isolate->heap()->NewPersistentHandle(string); args_[0].js_string = isolate->heap()->NewPersistentHandle(string);
} }
template <typename IsolateT> template <typename IsolateT>
void PendingCompilationErrorHandler::MessageDetails::Prepare( void PendingCompilationErrorHandler::MessageDetails::Prepare(
IsolateT* isolate) { IsolateT* isolate) {
switch (arg0_type_) { for (int i = 0; i < kMaxArgumentCount; i++) {
case kAstRawString: switch (args_[i].type) {
return SetString(arg0_->string(), isolate); case kAstRawString:
return SetString(args_[i].ast_string->string(), isolate);
case kNone: case kNone:
case kConstCharString: case kConstCharString:
// We can delay allocation until Arg0String(isolate). // We can delay allocation until ArgString(isolate).
// TODO(leszeks): We don't actually have to transfer this string, since return;
// it's a root.
return;
case kMainThreadHandle: case kMainThreadHandle:
// The message details might already be prepared, so skip them if this is // The message details might already be prepared, so skip them if this
// the case. // is the case.
return; return;
}
} }
} }
Handle<String> PendingCompilationErrorHandler::MessageDetails::Arg0String( Handle<String> PendingCompilationErrorHandler::MessageDetails::ArgString(
Isolate* isolate) const { Isolate* isolate, int index) const {
switch (arg0_type_) { // `index` may be >= argc; in that case we return a default value to pass on
// elsewhere.
DCHECK_LT(index, kMaxArgumentCount);
switch (args_[index].type) {
case kMainThreadHandle: case kMainThreadHandle:
return arg0_handle_; return args_[index].js_string;
case kNone: case kNone:
return isolate->factory()->undefined_string(); return Handle<String>::null();
case kConstCharString: case kConstCharString:
return isolate->factory() return isolate->factory()
->NewStringFromUtf8(base::CStrVector(char_arg0_), ->NewStringFromUtf8(base::CStrVector(args_[index].c_string),
AllocationType::kOld) AllocationType::kOld)
.ToHandleChecked(); .ToHandleChecked();
case kAstRawString: case kAstRawString:
@ -69,14 +72,6 @@ Handle<String> PendingCompilationErrorHandler::MessageDetails::Arg0String(
} }
} }
Handle<String> PendingCompilationErrorHandler::MessageDetails::Arg1String(
Isolate* isolate) const {
if (arg1_ == nullptr) return Handle<String>::null();
return isolate->factory()
->NewStringFromUtf8(base::CStrVector(arg1_), AllocationType::kOld)
.ToHandleChecked();
}
MessageLocation PendingCompilationErrorHandler::MessageDetails::GetLocation( MessageLocation PendingCompilationErrorHandler::MessageDetails::GetLocation(
Handle<Script> script) const { Handle<Script> script) const {
return MessageLocation(script, start_position_, end_position_); return MessageLocation(script, start_position_, end_position_);
@ -139,8 +134,8 @@ void PendingCompilationErrorHandler::ReportWarnings(
for (const MessageDetails& warning : warning_messages_) { for (const MessageDetails& warning : warning_messages_) {
MessageLocation location = warning.GetLocation(script); MessageLocation location = warning.GetLocation(script);
Handle<String> argument = warning.Arg0String(isolate); Handle<String> argument = warning.ArgString(isolate, 0);
DCHECK(warning.Arg1String(isolate).is_null()); // Only used for errors. DCHECK_LT(warning.ArgCount(), 2); // Arg1 is only used for errors.
Handle<JSMessageObject> message = Handle<JSMessageObject> message =
MessageHandler::MakeMessageObject(isolate, warning.message(), &location, MessageHandler::MakeMessageObject(isolate, warning.message(), &location,
argument, Handle<FixedArray>::null()); argument, Handle<FixedArray>::null());
@ -181,8 +176,8 @@ void PendingCompilationErrorHandler::ThrowPendingError(
if (!has_pending_error_) return; if (!has_pending_error_) return;
MessageLocation location = error_details_.GetLocation(script); MessageLocation location = error_details_.GetLocation(script);
Handle<String> arg0 = error_details_.Arg0String(isolate); Handle<String> arg0 = error_details_.ArgString(isolate, 0);
Handle<String> arg1 = error_details_.Arg1String(isolate); Handle<String> arg1 = error_details_.ArgString(isolate, 1);
isolate->debug()->OnCompileError(script); isolate->debug()->OnCompileError(script);
Factory* factory = isolate->factory(); Factory* factory = isolate->factory();
@ -195,8 +190,8 @@ Handle<String> PendingCompilationErrorHandler::FormatErrorMessageForTest(
Isolate* isolate) { Isolate* isolate) {
error_details_.Prepare(isolate); error_details_.Prepare(isolate);
return MessageFormatter::Format(isolate, error_details_.message(), return MessageFormatter::Format(isolate, error_details_.message(),
error_details_.Arg0String(isolate), error_details_.ArgString(isolate, 0),
error_details_.Arg1String(isolate)); error_details_.ArgString(isolate, 1));
} }
} // namespace internal } // namespace internal

View File

@ -25,9 +25,7 @@ class Script;
// compilation phases. // compilation phases.
class PendingCompilationErrorHandler { class PendingCompilationErrorHandler {
public: public:
PendingCompilationErrorHandler() PendingCompilationErrorHandler() = default;
: has_pending_error_(false), stack_overflow_(false) {}
PendingCompilationErrorHandler(const PendingCompilationErrorHandler&) = PendingCompilationErrorHandler(const PendingCompilationErrorHandler&) =
delete; delete;
PendingCompilationErrorHandler& operator=( PendingCompilationErrorHandler& operator=(
@ -89,40 +87,45 @@ class PendingCompilationErrorHandler {
MessageDetails() MessageDetails()
: start_position_(-1), : start_position_(-1),
end_position_(-1), end_position_(-1),
message_(MessageTemplate::kNone), message_(MessageTemplate::kNone) {}
arg1_(nullptr),
arg0_type_(kNone) {}
MessageDetails(int start_position, int end_position, MessageDetails(int start_position, int end_position,
MessageTemplate message, const AstRawString* arg) MessageTemplate message, const AstRawString* arg0)
: start_position_(start_position), : start_position_(start_position),
end_position_(end_position), end_position_(end_position),
message_(message), message_(message),
arg0_(arg), args_{MessageArgument{arg0}, MessageArgument{}} {}
arg1_(nullptr),
arg0_type_(arg ? kAstRawString : kNone) {}
MessageDetails(int start_position, int end_position, MessageDetails(int start_position, int end_position,
MessageTemplate message, const AstRawString* arg0, MessageTemplate message, const AstRawString* arg0,
const char* arg1) const char* arg1)
: start_position_(start_position), : start_position_(start_position),
end_position_(end_position), end_position_(end_position),
message_(message), message_(message),
arg0_(arg0), args_{MessageArgument{arg0}, MessageArgument{arg1}} {
arg1_(arg1),
arg0_type_(kAstRawString) {
DCHECK_NOT_NULL(arg0); DCHECK_NOT_NULL(arg0);
DCHECK_NOT_NULL(arg1); DCHECK_NOT_NULL(arg1);
} }
MessageDetails(int start_position, int end_position, MessageDetails(int start_position, int end_position,
MessageTemplate message, const char* char_arg) MessageTemplate message, const char* arg0)
: start_position_(start_position), : start_position_(start_position),
end_position_(end_position), end_position_(end_position),
message_(message), message_(message),
char_arg0_(char_arg), args_{MessageArgument{arg0}, MessageArgument{}} {}
arg1_(nullptr),
arg0_type_(char_arg0_ ? kConstCharString : kNone) {} Handle<String> ArgString(Isolate* isolate, int index) const;
int ArgCount() const {
int argc = 0;
for (int i = 0; i < kMaxArgumentCount; i++) {
if (args_[i].type == kNone) break;
argc++;
}
#ifdef DEBUG
for (int i = argc; i < kMaxArgumentCount; i++) {
DCHECK_EQ(args_[i].type, kNone);
}
#endif // DEBUG
return argc;
}
Handle<String> Arg0String(Isolate* isolate) const;
Handle<String> Arg1String(Isolate* isolate) const;
MessageLocation GetLocation(Handle<Script> script) const; MessageLocation GetLocation(Handle<Script> script) const;
MessageTemplate message() const { return message_; } MessageTemplate message() const { return message_; }
@ -137,22 +140,32 @@ class PendingCompilationErrorHandler {
int start_position_; int start_position_;
int end_position_; int end_position_;
MessageTemplate message_; MessageTemplate message_;
union {
const AstRawString* arg0_; struct MessageArgument final {
const char* char_arg0_; constexpr MessageArgument() : ast_string(nullptr), type(kNone) {}
Handle<String> arg0_handle_; explicit constexpr MessageArgument(const AstRawString* s)
: ast_string(s), type(s == nullptr ? kNone : kAstRawString) {}
explicit constexpr MessageArgument(const char* s)
: c_string(s), type(s == nullptr ? kNone : kConstCharString) {}
union {
const AstRawString* ast_string;
const char* c_string;
Handle<String> js_string;
};
Type type;
}; };
// TODO(jgruber): If we ever extend functionality of arg1, refactor it to
// be more consistent with arg0. static constexpr int kMaxArgumentCount = 2;
const char* arg1_; MessageArgument args_[kMaxArgumentCount];
Type arg0_type_;
}; };
void ThrowPendingError(Isolate* isolate, Handle<Script> script) const; void ThrowPendingError(Isolate* isolate, Handle<Script> script) const;
bool has_pending_error_; bool has_pending_error_ = false;
bool stack_overflow_; bool stack_overflow_ = false;
bool unidentifiable_error_ = false; bool unidentifiable_error_ = false;
MessageDetails error_details_; MessageDetails error_details_;