aboutsummaryrefslogtreecommitdiff
path: root/src/messages.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/messages.cc')
-rw-r--r--src/messages.cc359
1 files changed, 201 insertions, 158 deletions
diff --git a/src/messages.cc b/src/messages.cc
index eea77e34..b5150ef4 100644
--- a/src/messages.cc
+++ b/src/messages.cc
@@ -21,11 +21,11 @@ MessageLocation::MessageLocation(Handle<Script> script, int start_pos,
int end_pos)
: script_(script), start_pos_(start_pos), end_pos_(end_pos) {}
MessageLocation::MessageLocation(Handle<Script> script, int start_pos,
- int end_pos, Handle<JSFunction> function)
+ int end_pos, Handle<SharedFunctionInfo> shared)
: script_(script),
start_pos_(start_pos),
end_pos_(end_pos),
- function_(function) {}
+ shared_(shared) {}
MessageLocation::MessageLocation() : start_pos_(-1), end_pos_(-1) {}
// If no message listeners have been registered this one is called
@@ -47,10 +47,9 @@ void MessageHandler::DefaultMessageReport(Isolate* isolate,
}
}
-
Handle<JSMessageObject> MessageHandler::MakeMessageObject(
Isolate* isolate, MessageTemplate::Template message,
- MessageLocation* location, Handle<Object> argument,
+ const MessageLocation* location, Handle<Object> argument,
Handle<JSArray> stack_frames) {
Factory* factory = isolate->factory();
@@ -75,50 +74,63 @@ Handle<JSMessageObject> MessageHandler::MakeMessageObject(
return message_obj;
}
-
-void MessageHandler::ReportMessage(Isolate* isolate, MessageLocation* loc,
+void MessageHandler::ReportMessage(Isolate* isolate, const MessageLocation* loc,
Handle<JSMessageObject> message) {
- // We are calling into embedder's code which can throw exceptions.
- // Thus we need to save current exception state, reset it to the clean one
- // and ignore scheduled exceptions callbacks can throw.
-
- // We pass the exception object into the message handler callback though.
- Object* exception_object = isolate->heap()->undefined_value();
- if (isolate->has_pending_exception()) {
- exception_object = isolate->pending_exception();
- }
- Handle<Object> exception(exception_object, isolate);
+ v8::Local<v8::Message> api_message_obj = v8::Utils::MessageToLocal(message);
- Isolate::ExceptionScope exception_scope(isolate);
- isolate->clear_pending_exception();
- isolate->set_external_caught_exception(false);
+ if (api_message_obj->ErrorLevel() == v8::Isolate::kMessageError) {
+ // We are calling into embedder's code which can throw exceptions.
+ // Thus we need to save current exception state, reset it to the clean one
+ // and ignore scheduled exceptions callbacks can throw.
- // Turn the exception on the message into a string if it is an object.
- if (message->argument()->IsJSObject()) {
- HandleScope scope(isolate);
- Handle<Object> argument(message->argument(), isolate);
+ // We pass the exception object into the message handler callback though.
+ Object* exception_object = isolate->heap()->undefined_value();
+ if (isolate->has_pending_exception()) {
+ exception_object = isolate->pending_exception();
+ }
+ Handle<Object> exception(exception_object, isolate);
- MaybeHandle<Object> maybe_stringified;
- Handle<Object> stringified;
- // Make sure we don't leak uncaught internally generated Error objects.
- if (argument->IsJSError()) {
- maybe_stringified = Object::NoSideEffectsToString(isolate, argument);
- } else {
- v8::TryCatch catcher(reinterpret_cast<v8::Isolate*>(isolate));
- catcher.SetVerbose(false);
- catcher.SetCaptureMessage(false);
+ Isolate::ExceptionScope exception_scope(isolate);
+ isolate->clear_pending_exception();
+ isolate->set_external_caught_exception(false);
- maybe_stringified = Object::ToString(isolate, argument);
- }
+ // Turn the exception on the message into a string if it is an object.
+ if (message->argument()->IsJSObject()) {
+ HandleScope scope(isolate);
+ Handle<Object> argument(message->argument(), isolate);
+
+ MaybeHandle<Object> maybe_stringified;
+ Handle<Object> stringified;
+ // Make sure we don't leak uncaught internally generated Error objects.
+ if (argument->IsJSError()) {
+ maybe_stringified = Object::NoSideEffectsToString(isolate, argument);
+ } else {
+ v8::TryCatch catcher(reinterpret_cast<v8::Isolate*>(isolate));
+ catcher.SetVerbose(false);
+ catcher.SetCaptureMessage(false);
- if (!maybe_stringified.ToHandle(&stringified)) {
- stringified = isolate->factory()->NewStringFromAsciiChecked("exception");
+ maybe_stringified = Object::ToString(isolate, argument);
+ }
+
+ if (!maybe_stringified.ToHandle(&stringified)) {
+ stringified =
+ isolate->factory()->NewStringFromAsciiChecked("exception");
+ }
+ message->set_argument(*stringified);
}
- message->set_argument(*stringified);
+
+ v8::Local<v8::Value> api_exception_obj = v8::Utils::ToLocal(exception);
+ ReportMessageNoExceptions(isolate, loc, message, api_exception_obj);
+ } else {
+ ReportMessageNoExceptions(isolate, loc, message, v8::Local<v8::Value>());
}
+}
+void MessageHandler::ReportMessageNoExceptions(
+ Isolate* isolate, const MessageLocation* loc, Handle<Object> message,
+ v8::Local<v8::Value> api_exception_obj) {
v8::Local<v8::Message> api_message_obj = v8::Utils::MessageToLocal(message);
- v8::Local<v8::Value> api_exception_obj = v8::Utils::ToLocal(exception);
+ int error_level = api_message_obj->ErrorLevel();
Handle<TemplateList> global_listeners =
isolate->factory()->message_listeners();
@@ -134,6 +146,11 @@ void MessageHandler::ReportMessage(Isolate* isolate, MessageLocation* loc,
if (global_listeners->get(i)->IsUndefined(isolate)) continue;
FixedArray* listener = FixedArray::cast(global_listeners->get(i));
Foreign* callback_obj = Foreign::cast(listener->get(0));
+ int32_t message_levels =
+ static_cast<int32_t>(Smi::cast(listener->get(2))->value());
+ if (!(message_levels & error_level)) {
+ continue;
+ }
v8::MessageCallback callback =
FUNCTION_CAST<v8::MessageCallback>(callback_obj->foreign_address());
Handle<Object> callback_data(listener->get(1), isolate);
@@ -165,6 +182,115 @@ std::unique_ptr<char[]> MessageHandler::GetLocalizedMessage(
return GetMessage(isolate, data)->ToCString(DISALLOW_NULLS);
}
+namespace {
+
+Object* EvalFromFunctionName(Isolate* isolate, Handle<Script> script) {
+ if (script->eval_from_shared()->IsUndefined(isolate))
+ return isolate->heap()->undefined_value();
+
+ Handle<SharedFunctionInfo> shared(
+ SharedFunctionInfo::cast(script->eval_from_shared()));
+ // Find the name of the function calling eval.
+ if (shared->name()->BooleanValue()) {
+ return shared->name();
+ }
+
+ return shared->inferred_name();
+}
+
+Object* EvalFromScript(Isolate* isolate, Handle<Script> script) {
+ if (script->eval_from_shared()->IsUndefined(isolate))
+ return isolate->heap()->undefined_value();
+
+ Handle<SharedFunctionInfo> eval_from_shared(
+ SharedFunctionInfo::cast(script->eval_from_shared()));
+ return eval_from_shared->script()->IsScript()
+ ? eval_from_shared->script()
+ : isolate->heap()->undefined_value();
+}
+
+MaybeHandle<String> FormatEvalOrigin(Isolate* isolate, Handle<Script> script) {
+ Handle<Object> sourceURL(script->GetNameOrSourceURL(), isolate);
+ if (!sourceURL->IsUndefined(isolate)) {
+ DCHECK(sourceURL->IsString());
+ return Handle<String>::cast(sourceURL);
+ }
+
+ IncrementalStringBuilder builder(isolate);
+ builder.AppendCString("eval at ");
+
+ Handle<Object> eval_from_function_name =
+ handle(EvalFromFunctionName(isolate, script), isolate);
+ if (eval_from_function_name->BooleanValue()) {
+ Handle<String> str;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, str, Object::ToString(isolate, eval_from_function_name),
+ String);
+ builder.AppendString(str);
+ } else {
+ builder.AppendCString("<anonymous>");
+ }
+
+ Handle<Object> eval_from_script_obj =
+ handle(EvalFromScript(isolate, script), isolate);
+ if (eval_from_script_obj->IsScript()) {
+ Handle<Script> eval_from_script =
+ Handle<Script>::cast(eval_from_script_obj);
+ builder.AppendCString(" (");
+ if (eval_from_script->compilation_type() == Script::COMPILATION_TYPE_EVAL) {
+ // Eval script originated from another eval.
+ Handle<String> str;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, str, FormatEvalOrigin(isolate, eval_from_script), String);
+ builder.AppendString(str);
+ } else {
+ DCHECK(eval_from_script->compilation_type() !=
+ Script::COMPILATION_TYPE_EVAL);
+ // eval script originated from "real" source.
+ Handle<Object> name_obj = handle(eval_from_script->name(), isolate);
+ if (eval_from_script->name()->IsString()) {
+ builder.AppendString(Handle<String>::cast(name_obj));
+
+ Script::PositionInfo info;
+ if (Script::GetPositionInfo(eval_from_script, script->GetEvalPosition(),
+ &info, Script::NO_OFFSET)) {
+ builder.AppendCString(":");
+
+ Handle<String> str = isolate->factory()->NumberToString(
+ handle(Smi::FromInt(info.line + 1), isolate));
+ builder.AppendString(str);
+
+ builder.AppendCString(":");
+
+ str = isolate->factory()->NumberToString(
+ handle(Smi::FromInt(info.column + 1), isolate));
+ builder.AppendString(str);
+ }
+ } else {
+ DCHECK(!eval_from_script->name()->IsString());
+ builder.AppendCString("unknown source");
+ }
+ }
+ builder.AppendCString(")");
+ }
+
+ Handle<String> result;
+ ASSIGN_RETURN_ON_EXCEPTION(isolate, result, builder.Finish(), String);
+ return result;
+}
+
+} // namespace
+
+Handle<Object> StackFrameBase::GetEvalOrigin() {
+ if (!HasScript()) return isolate_->factory()->undefined_value();
+ return FormatEvalOrigin(isolate_, GetScript()).ToHandleChecked();
+}
+
+bool StackFrameBase::IsEval() {
+ return HasScript() &&
+ GetScript()->compilation_type() == Script::COMPILATION_TYPE_EVAL;
+}
+
void JSStackFrame::FromFrameArray(Isolate* isolate, Handle<FrameArray> array,
int frame_ix) {
DCHECK(!array->IsWasmFrame(frame_ix));
@@ -179,10 +305,12 @@ void JSStackFrame::FromFrameArray(Isolate* isolate, Handle<FrameArray> array,
is_strict_ = (flags & FrameArray::kIsStrict) != 0;
}
+JSStackFrame::JSStackFrame() {}
+
JSStackFrame::JSStackFrame(Isolate* isolate, Handle<Object> receiver,
Handle<JSFunction> function,
Handle<AbstractCode> code, int offset)
- : isolate_(isolate),
+ : StackFrameBase(isolate),
receiver_(receiver),
function_(function),
code_(code),
@@ -190,8 +318,6 @@ JSStackFrame::JSStackFrame(Isolate* isolate, Handle<Object> receiver,
force_constructor_(false),
is_strict_(false) {}
-JSStackFrame::JSStackFrame() {}
-
Handle<Object> JSStackFrame::GetFunction() const {
return Handle<Object>::cast(function_);
}
@@ -245,7 +371,7 @@ Handle<Object> JSStackFrame::GetScriptNameOrSourceUrl() {
}
Handle<Object> JSStackFrame::GetMethodName() {
- if (receiver_->IsNull(isolate_) || receiver_->IsUndefined(isolate_)) {
+ if (receiver_->IsNullOrUndefined(isolate_)) {
return isolate_->factory()->null_value();
}
@@ -298,110 +424,11 @@ Handle<Object> JSStackFrame::GetMethodName() {
return isolate_->factory()->null_value();
}
-namespace {
-
-Object* EvalFromFunctionName(Isolate* isolate, Handle<Script> script) {
- if (script->eval_from_shared()->IsUndefined(isolate))
- return isolate->heap()->undefined_value();
-
- Handle<SharedFunctionInfo> shared(
- SharedFunctionInfo::cast(script->eval_from_shared()));
- // Find the name of the function calling eval.
- if (shared->name()->BooleanValue()) {
- return shared->name();
- }
-
- return shared->inferred_name();
-}
-
-Object* EvalFromScript(Isolate* isolate, Handle<Script> script) {
- if (script->eval_from_shared()->IsUndefined(isolate))
- return isolate->heap()->undefined_value();
-
- Handle<SharedFunctionInfo> eval_from_shared(
- SharedFunctionInfo::cast(script->eval_from_shared()));
- return eval_from_shared->script()->IsScript()
- ? eval_from_shared->script()
- : isolate->heap()->undefined_value();
-}
-
-MaybeHandle<String> FormatEvalOrigin(Isolate* isolate, Handle<Script> script) {
- Handle<Object> sourceURL = Script::GetNameOrSourceURL(script);
- if (!sourceURL->IsUndefined(isolate)) {
- DCHECK(sourceURL->IsString());
- return Handle<String>::cast(sourceURL);
- }
-
- IncrementalStringBuilder builder(isolate);
- builder.AppendCString("eval at ");
-
- Handle<Object> eval_from_function_name =
- handle(EvalFromFunctionName(isolate, script), isolate);
- if (eval_from_function_name->BooleanValue()) {
- Handle<String> str;
- ASSIGN_RETURN_ON_EXCEPTION(
- isolate, str, Object::ToString(isolate, eval_from_function_name),
- String);
- builder.AppendString(str);
- } else {
- builder.AppendCString("<anonymous>");
- }
-
- Handle<Object> eval_from_script_obj =
- handle(EvalFromScript(isolate, script), isolate);
- if (eval_from_script_obj->IsScript()) {
- Handle<Script> eval_from_script =
- Handle<Script>::cast(eval_from_script_obj);
- builder.AppendCString(" (");
- if (eval_from_script->compilation_type() == Script::COMPILATION_TYPE_EVAL) {
- // Eval script originated from another eval.
- Handle<String> str;
- ASSIGN_RETURN_ON_EXCEPTION(
- isolate, str, FormatEvalOrigin(isolate, eval_from_script), String);
- builder.AppendString(str);
- } else {
- DCHECK(eval_from_script->compilation_type() !=
- Script::COMPILATION_TYPE_EVAL);
- // eval script originated from "real" source.
- Handle<Object> name_obj = handle(eval_from_script->name(), isolate);
- if (eval_from_script->name()->IsString()) {
- builder.AppendString(Handle<String>::cast(name_obj));
-
- Script::PositionInfo info;
- if (Script::GetPositionInfo(eval_from_script, script->GetEvalPosition(),
- &info, Script::NO_OFFSET)) {
- builder.AppendCString(":");
-
- Handle<String> str = isolate->factory()->NumberToString(
- handle(Smi::FromInt(info.line + 1), isolate));
- builder.AppendString(str);
-
- builder.AppendCString(":");
-
- str = isolate->factory()->NumberToString(
- handle(Smi::FromInt(info.column + 1), isolate));
- builder.AppendString(str);
- }
- } else {
- DCHECK(!eval_from_script->name()->IsString());
- builder.AppendCString("unknown source");
- }
- }
- builder.AppendCString(")");
- }
-
- Handle<String> result;
- ASSIGN_RETURN_ON_EXCEPTION(isolate, result, builder.Finish(), String);
- return result;
-}
-
-} // namespace
-
Handle<Object> JSStackFrame::GetTypeName() {
// TODO(jgruber): Check for strict/constructor here as in
// CallSitePrototypeGetThis.
- if (receiver_->IsNull(isolate_) || receiver_->IsUndefined(isolate_))
+ if (receiver_->IsNullOrUndefined(isolate_))
return isolate_->factory()->null_value();
if (receiver_->IsJSProxy()) return isolate_->factory()->Proxy_string();
@@ -411,11 +438,6 @@ Handle<Object> JSStackFrame::GetTypeName() {
return JSReceiver::GetConstructorName(receiver_object);
}
-Handle<Object> JSStackFrame::GetEvalOrigin() {
- if (!HasScript()) return isolate_->factory()->undefined_value();
- return FormatEvalOrigin(isolate_, GetScript()).ToHandleChecked();
-}
-
int JSStackFrame::GetLineNumber() {
DCHECK_LE(0, GetPosition());
if (HasScript()) return Script::GetLineNumber(GetScript(), GetPosition()) + 1;
@@ -435,13 +457,7 @@ bool JSStackFrame::IsNative() {
}
bool JSStackFrame::IsToplevel() {
- return receiver_->IsJSGlobalProxy() || receiver_->IsNull(isolate_) ||
- receiver_->IsUndefined(isolate_);
-}
-
-bool JSStackFrame::IsEval() {
- return HasScript() &&
- GetScript()->compilation_type() == Script::COMPILATION_TYPE_EVAL;
+ return receiver_->IsJSGlobalProxy() || receiver_->IsNullOrUndefined(isolate_);
}
bool JSStackFrame::IsConstructor() {
@@ -619,6 +635,8 @@ Handle<Script> JSStackFrame::GetScript() const {
return handle(Script::cast(function_->shared()->script()), isolate_);
}
+WasmStackFrame::WasmStackFrame() {}
+
void WasmStackFrame::FromFrameArray(Isolate* isolate, Handle<FrameArray> array,
int frame_ix) {
// This function is called for both wasm and asm.js->wasm frames.
@@ -638,9 +656,10 @@ Handle<Object> WasmStackFrame::GetFunction() const {
Handle<Object> WasmStackFrame::GetFunctionName() {
Handle<Object> name;
Handle<WasmCompiledModule> compiled_module(
- Handle<WasmInstanceObject>::cast(wasm_instance_)->get_compiled_module(),
+ Handle<WasmInstanceObject>::cast(wasm_instance_)->compiled_module(),
isolate_);
- if (!WasmCompiledModule::GetFunctionName(compiled_module, wasm_func_index_)
+ if (!WasmCompiledModule::GetFunctionNameOrNull(isolate_, compiled_module,
+ wasm_func_index_)
.ToHandle(&name)) {
name = isolate_->factory()->null_value();
}
@@ -673,6 +692,7 @@ MaybeHandle<String> WasmStackFrame::ToString() {
}
int WasmStackFrame::GetPosition() const {
+ // TODO(wasm): Clean this up (bug 5007).
return (offset_ < 0) ? (-1 - offset_) : code_->SourcePosition(offset_);
}
@@ -680,6 +700,25 @@ Handle<Object> WasmStackFrame::Null() const {
return isolate_->factory()->null_value();
}
+bool WasmStackFrame::HasScript() const { return true; }
+
+Handle<Script> WasmStackFrame::GetScript() const {
+ return handle(
+ WasmInstanceObject::cast(*wasm_instance_)->compiled_module()->script(),
+ isolate_);
+}
+
+AsmJsWasmStackFrame::AsmJsWasmStackFrame() {}
+
+void AsmJsWasmStackFrame::FromFrameArray(Isolate* isolate,
+ Handle<FrameArray> array,
+ int frame_ix) {
+ DCHECK(array->IsAsmJsWasmFrame(frame_ix));
+ WasmStackFrame::FromFrameArray(isolate, array, frame_ix);
+ is_at_number_conversion_ =
+ array->Flags(frame_ix)->value() & FrameArray::kAsmJsAtNumberConversion;
+}
+
Handle<Object> AsmJsWasmStackFrame::GetReceiver() const {
return isolate_->global_proxy();
}
@@ -706,8 +745,12 @@ Handle<Object> AsmJsWasmStackFrame::GetScriptNameOrSourceUrl() {
int AsmJsWasmStackFrame::GetPosition() const {
DCHECK_LE(0, offset_);
int byte_offset = code_->SourcePosition(offset_);
- return wasm::GetAsmWasmSourcePosition(Handle<JSObject>::cast(wasm_instance_),
- wasm_func_index_, byte_offset);
+ Handle<WasmCompiledModule> compiled_module(
+ WasmInstanceObject::cast(*wasm_instance_)->compiled_module(), isolate_);
+ DCHECK_LE(0, byte_offset);
+ return WasmCompiledModule::GetAsmJsSourcePosition(
+ compiled_module, wasm_func_index_, static_cast<uint32_t>(byte_offset),
+ is_at_number_conversion_);
}
int AsmJsWasmStackFrame::GetLineNumber() {