Exemplo n.º 1
0
void
AutoJSAPI::ReportException()
{
  MOZ_ASSERT(OwnsErrorReporting(), "This is not our exception to report!");
  if (!HasException()) {
    return;
  }

  // AutoJSAPI uses a JSAutoNullableCompartment, and may be in a null
  // compartment when the destructor is called. However, the JS engine
  // requires us to be in a compartment when we fetch the pending exception.
  // In this case, we enter the privileged junk scope and don't dispatch any
  // error events.
  JS::Rooted<JSObject*> errorGlobal(cx(), JS::CurrentGlobalOrNull(cx()));
  if (!errorGlobal)
    errorGlobal = xpc::PrivilegedJunkScope();
  JSAutoCompartment ac(cx(), errorGlobal);
  nsCOMPtr<nsPIDOMWindow> win = xpc::WindowGlobalOrNull(errorGlobal);
  JS::Rooted<JS::Value> exn(cx());
  js::ErrorReport jsReport(cx());
  if (StealException(&exn) && jsReport.init(cx(), exn)) {
    nsRefPtr<xpc::ErrorReport> xpcReport = new xpc::ErrorReport();
    xpcReport->Init(jsReport.report(), jsReport.message(),
                    nsContentUtils::IsCallerChrome(),
                    win ? win->WindowID() : 0);
    if (win) {
      DispatchScriptErrorEvent(win, JS_GetRuntime(cx()), xpcReport, exn);
    } else {
      xpcReport->LogToConsole();
    }
  } else {
    NS_WARNING("OOMed while acquiring uncaught exception from JSAPI");
  }
}
Exemplo n.º 2
0
void
AutoJSAPI::ReportException()
{
  MOZ_ASSERT(OwnsErrorReporting(), "This is not our exception to report!");
  if (!HasException()) {
    return;
  }

  // AutoJSAPI uses a JSAutoNullableCompartment, and may be in a null
  // compartment when the destructor is called. However, the JS engine
  // requires us to be in a compartment when we fetch the pending exception.
  // In this case, we enter the privileged junk scope and don't dispatch any
  // error events.
  JS::Rooted<JSObject*> errorGlobal(cx(), JS::CurrentGlobalOrNull(cx()));
  if (!errorGlobal) {
    if (mIsMainThread) {
      errorGlobal = xpc::PrivilegedJunkScope();
    } else {
      errorGlobal = workers::GetCurrentThreadWorkerGlobal();
    }
  }
  JSAutoCompartment ac(cx(), errorGlobal);
  JS::Rooted<JS::Value> exn(cx());
  js::ErrorReport jsReport(cx());
  if (StealException(&exn) && jsReport.init(cx(), exn)) {
    if (mIsMainThread) {
      RefPtr<xpc::ErrorReport> xpcReport = new xpc::ErrorReport();
      RefPtr<nsGlobalWindow> win = xpc::WindowGlobalOrNull(errorGlobal);
      nsPIDOMWindowInner* inner = win ? win->AsInner() : nullptr;
      xpcReport->Init(jsReport.report(), jsReport.message(),
                      nsContentUtils::IsCallerChrome(),
                      inner ? inner->WindowID() : 0);
      if (inner) {
        DispatchScriptErrorEvent(inner, JS_GetRuntime(cx()), xpcReport, exn);
      } else {
        xpcReport->LogToConsole();
      }
    } else {
      // On a worker, we just use the worker error reporting mechanism and don't
      // bother with xpc::ErrorReport.  This will ensure that all the right
      // events (which are a lot more complicated than in the window case) get
      // fired.
      workers::WorkerPrivate* worker = workers::GetCurrentThreadWorkerPrivate();
      MOZ_ASSERT(worker);
      MOZ_ASSERT(worker->GetJSContext() == cx());
      // Before invoking ReportError, put the exception back on the context,
      // because it may want to put it in its error events and has no other way
      // to get hold of it.  After we invoke ReportError, clear the exception on
      // cx(), just in case ReportError didn't.
      JS_SetPendingException(cx(), exn);
      worker->ReportError(cx(), jsReport.message(), jsReport.report());
      ClearException();
    }
  } else {
    NS_WARNING("OOMed while acquiring uncaught exception from JSAPI");
    ClearException();
  }
}