v8/src/pending-compilation-error-handler.cc
Jakob Kummerow cfb5bb726f [ubsan] Port JSReceiver and subclasses to the new design
Bug: v8:3770
Change-Id: I1d74ffe9e5478b4b8bc0acbf088d20919d458d50
Reviewed-on: https://chromium-review.googlesource.com/c/1363822
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: Andreas Haas <ahaas@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58112}
2018-12-08 04:05:50 +00:00

149 lines
5.0 KiB
C++

// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/pending-compilation-error-handler.h"
#include "src/ast/ast-value-factory.h"
#include "src/debug/debug.h"
#include "src/handles.h"
#include "src/isolate.h"
#include "src/messages.h"
#include "src/objects-inl.h"
namespace v8 {
namespace internal {
Handle<String> PendingCompilationErrorHandler::MessageDetails::ArgumentString(
Isolate* isolate) const {
if (arg_ != nullptr) return arg_->string();
if (char_arg_ != nullptr) {
return isolate->factory()
->NewStringFromUtf8(CStrVector(char_arg_))
.ToHandleChecked();
}
return isolate->factory()->undefined_string();
}
MessageLocation PendingCompilationErrorHandler::MessageDetails::GetLocation(
Handle<Script> script) const {
return MessageLocation(script, start_position_, end_position_);
}
void PendingCompilationErrorHandler::ReportMessageAt(
int start_position, int end_position, MessageTemplate message,
const char* arg, ParseErrorType error_type) {
if (has_pending_error_) return;
has_pending_error_ = true;
error_details_ =
MessageDetails(start_position, end_position, message, nullptr, arg);
error_type_ = error_type;
}
void PendingCompilationErrorHandler::ReportMessageAt(
int start_position, int end_position, MessageTemplate message,
const AstRawString* arg, ParseErrorType error_type) {
if (has_pending_error_) return;
has_pending_error_ = true;
error_details_ =
MessageDetails(start_position, end_position, message, arg, nullptr);
error_type_ = error_type;
}
void PendingCompilationErrorHandler::ReportWarningAt(int start_position,
int end_position,
MessageTemplate message,
const char* arg) {
warning_messages_.emplace_front(
MessageDetails(start_position, end_position, message, nullptr, arg));
}
void PendingCompilationErrorHandler::ReportWarnings(Isolate* isolate,
Handle<Script> script) {
DCHECK(!has_pending_error());
for (const MessageDetails& warning : warning_messages_) {
MessageLocation location = warning.GetLocation(script);
Handle<String> argument = warning.ArgumentString(isolate);
Handle<JSMessageObject> message =
MessageHandler::MakeMessageObject(isolate, warning.message(), &location,
argument, Handle<FixedArray>::null());
message->set_error_level(v8::Isolate::kMessageWarning);
MessageHandler::ReportMessage(isolate, &location, message);
}
}
void PendingCompilationErrorHandler::ReportErrors(
Isolate* isolate, Handle<Script> script,
AstValueFactory* ast_value_factory) {
if (stack_overflow()) {
isolate->StackOverflow();
} else {
DCHECK(has_pending_error());
// Internalize ast values for throwing the pending error.
ast_value_factory->Internalize(isolate);
ThrowPendingError(isolate, script);
}
}
void PendingCompilationErrorHandler::ThrowPendingError(Isolate* isolate,
Handle<Script> script) {
if (!has_pending_error_) return;
MessageLocation location = error_details_.GetLocation(script);
Handle<String> argument = error_details_.ArgumentString(isolate);
isolate->debug()->OnCompileError(script);
Factory* factory = isolate->factory();
Handle<Object> error;
switch (error_type_) {
case kReferenceError:
error = factory->NewReferenceError(error_details_.message(), argument);
break;
case kSyntaxError:
error = factory->NewSyntaxError(error_details_.message(), argument);
break;
default:
UNREACHABLE();
break;
}
if (!error->IsJSObject()) {
isolate->Throw(*error, &location);
return;
}
Handle<JSObject> jserror = Handle<JSObject>::cast(error);
Handle<Name> key_start_pos = factory->error_start_pos_symbol();
Object::SetProperty(isolate, jserror, key_start_pos,
handle(Smi::FromInt(location.start_pos()), isolate),
LanguageMode::kSloppy)
.Check();
Handle<Name> key_end_pos = factory->error_end_pos_symbol();
Object::SetProperty(isolate, jserror, key_end_pos,
handle(Smi::FromInt(location.end_pos()), isolate),
LanguageMode::kSloppy)
.Check();
Handle<Name> key_script = factory->error_script_symbol();
Object::SetProperty(isolate, jserror, key_script, script,
LanguageMode::kSloppy)
.Check();
isolate->Throw(*error, &location);
}
Handle<String> PendingCompilationErrorHandler::FormatErrorMessageForTest(
Isolate* isolate) const {
return MessageFormatter::FormatMessage(
isolate, error_details_.message(),
error_details_.ArgumentString(isolate));
}
} // namespace internal
} // namespace v8