Exemple #1
0
void node_t::calc_bounds( const render::render_context_t& context)
{
    if( is_valid_ && !ignored())
    {
	do_calc_bounds( context);
	return;
    }

    if( ignored() && ( num_inputs() != 0) && input())
    {
	set_bounds( input()->bounds());
	return;
    }

    set_bounds( domain());
}
void parseBlackList()
{
    QString filename = QTest::qFindTestData(QStringLiteral("BLACKLIST"));
    if (filename.isEmpty())
        return;
    QFile ignored(filename);
    if (!ignored.open(QIODevice::ReadOnly))
        return;

    QByteArray function;

    while (!ignored.atEnd()) {
        QByteArray line = ignored.readLine().simplified();
        if (line.isEmpty() || line.startsWith('#'))
            continue;
        if (line.startsWith('[')) {
            function = line.mid(1, line.length() - 2);
            continue;
        }
        bool condition = checkCondition(line);
        if (condition) {
            if (!function.size()) {
                ignoreAll = true;
            } else {
                if (!ignoredTests)
                    ignoredTests = new std::set<QByteArray>;
                ignoredTests->insert(function);
            }
        }
    }
}
Exemple #3
0
static void *SigThread (void *data)
{
    intf_thread_t *obj = data;
    sigset_t set;
    int signum;

    sigemptyset (&set);
    if (!ignored (SIGHUP)) /* <- needed to handle nohup properly */
        sigaddset (&set, SIGHUP);
    sigaddset (&set, SIGINT);
    sigaddset (&set, SIGQUIT);
    sigaddset (&set, SIGTERM);

    sigaddset (&set, SIGCHLD);

    do
    {
        while (sigwait (&set, &signum));

#ifdef __APPLE__
        /* In Mac OS X up to 10.5 sigwait (among others) is not a pthread
         * cancellation point */
        vlc_testcancel();
#endif

       /* Hack for Qt QProcess */
       if (signum == SIGCHLD)
       {
           struct sigaction act;

           sigaction (signum, NULL, &act);
           if ((act.sa_flags & SA_SIGINFO) || (act.sa_handler != SIG_DFL))
           {
               msg_Err (obj, "signal %d overriden (%p)", signum,
                        act.sa_handler);
#ifdef __GLIBC__
               Dl_info info;

               if (dladdr (act.sa_handler, &info))
                   msg_Err (obj, " %s(%s)[%p]",
                            info.dli_fname ? info.dli_fname : "?",
                            info.dli_sname ? info.dli_sname : "?",
                            info.dli_saddr);
#endif
               if (!(act.sa_flags & SA_SIGINFO) && (act.sa_handler != SIG_IGN))
                   act.sa_handler (signum);
           }
       }
    }
    while (signum == SIGCHLD);

    msg_Err (obj, "Caught %s signal, exiting...", strsignal (signum));
    libvlc_Quit (obj->p_libvlc);

    /* After 3 seconds, fallback to normal signal handling */
    msleep (3 * CLOCK_FREQ);
    pthread_sigmask (SIG_UNBLOCK, &set, NULL);
    for (;;)
        pause ();
}
Exemple #4
0
void PlanExecutor::integrityCheckFinished(KJob *pJob) {
	endSleepInhibit();
	discardIntegrityNotification();
	mIntegrityNotification = new KNotification(QStringLiteral("IntegrityCheckCompleted"), KNotification::Persistent);
	mIntegrityNotification->setTitle(xi18nc("@title:window", "Integrity Check Completed"));
	mIntegrityNotification->setText(pJob->errorText());
	QStringList lAnswers;
	if(pJob->error() == BackupJob::ErrorWithLog) {
		lAnswers << xi18nc("@action:button", "Show log file");
		connect(mIntegrityNotification, SIGNAL(action1Activated()), SLOT(showLog()));
	} else if(pJob->error() == BackupJob::ErrorSuggestRepair) {
		lAnswers << xi18nc("@action:button", "Yes");
		lAnswers << xi18nc("@action:button", "No");
		connect(mIntegrityNotification, SIGNAL(action1Activated()), SLOT(startRepairJob()));
	}
	mIntegrityNotification->setActions(lAnswers);

	connect(mIntegrityNotification, SIGNAL(action2Activated()), SLOT(discardIntegrityNotification()));
	connect(mIntegrityNotification, SIGNAL(closed()), SLOT(discardIntegrityNotification()));
	connect(mIntegrityNotification, SIGNAL(ignored()), SLOT(discardIntegrityNotification()));
	mIntegrityNotification->sendEvent();

	if(mState == INTEGRITY_TESTING) { //only restore if nothing has changed during the run
		mState = mLastState;
	}
	emit stateChanged();
}
Exemple #5
0
bool
AddonWrapper<Base>::set(JSContext* cx, JS::HandleObject wrapper, JS::HandleId id, JS::HandleValue v,
                        JS::HandleValue receiver, JS::ObjectOpResult& result) const
{
    Rooted<JSPropertyDescriptor> desc(cx);
    if (!InterposeProperty(cx, wrapper, nullptr, id, &desc))
        return false;

    if (!desc.object())
        return Base::set(cx, wrapper, id, v, receiver, result);

    if (desc.setter()) {
        MOZ_ASSERT(desc.hasSetterObject());
        JS::AutoValueVector args(cx);
        if (!args.append(v))
            return false;
        RootedValue fval(cx, ObjectValue(*desc.setterObject()));
        RootedValue ignored(cx);
        if (!JS::Call(cx, receiver, fval, args, &ignored))
            return false;
        return result.succeed();
    }

    return result.failCantSetInterposed();
}
void 
ChemistryMulti::check_ignore (const symbol chem, Treelog& msg)
{
  if (ignored (chem))
    return;
  
  msg.message ("Fate of '" + chem.name () + "' will not be traced");
  ignore.push_back (chem);
}
/*****************************************************************************
 * ARP-VELOCITY-MAP-ADDON
 *****************************************************************************/
void ArpVelocityMapAddOn::LongDescription(BString& name, BString& str) const
{
	AmFilterAddOn::LongDescription(name, str);
	str << "<p>I take a range of velocities and transform it into a
	new range.  Any velocities out of range are ignored (so use multiple
	maps to get multiple bands of transformation).  I can be used to compress
	(by setting the To values to a wider range than the From values) or expand
	(by doing the opposite).</p>";
}
Exemple #8
0
void node_t::calc_domain( const render::render_context_t& context)
{
    is_valid_ = is_valid();

    if( is_valid_ && !ignored())
    {
	do_calc_domain( context);
	return;
    }

    if( ignored() && ( num_inputs() != 0) && input())
    {
	set_domain( input()->domain());
	return;
    }

    set_domain( Imath::Box2i( Imath::V2i( 0, 0), Imath::V2i( context.default_format.area().max.x - 1, context.default_format.area().max.y - 1)));
}
void EmoticonSetInstaller::showRequest()
{
    kDebug();

    KNotification *notification = new KNotification(QLatin1String("emoticonsRequest"), NULL, KNotification::Persistent);
    notification->setText( i18n("Install Emoticonset %1", this->bundleName()) );
    notification->setActions( QStringList() << i18n("Install") << i18n("Cancel") );

    QObject::connect(notification, SIGNAL(action1Activated()), this, SLOT(install()));
    QObject::connect(notification, SIGNAL(action1Activated()), notification, SLOT(close()));

    QObject::connect(notification, SIGNAL(ignored()), this, SLOT(ignoreRequest()));
    QObject::connect(notification, SIGNAL(ignored()), notification, SLOT(close()));

    QObject::connect(notification, SIGNAL(action2Activated()), this, SLOT(ignoreRequest()));
    QObject::connect(notification, SIGNAL(action2Activated()), notification, SLOT(close()));

    notification->sendEvent();
}
Exemple #10
0
void PythonBridge::initializePython()
{
	Py_Initialize();
	main_module.reset( new object(  handle<> ( borrowed( PyImport_AddModule( "__main__" ) ) ) ) );
	main_namespace.reset( new object ( main_module->attr( "__dict__" ) ) );
	handle<> ignored( ( PyRun_String( "from isis import util; from isis import data", Py_file_input, main_namespace->ptr(), main_namespace->ptr() ) ) );

	//redirect stdio
	( *main_namespace )["PythonStdIoRedirect"] = class_<PythonStdIoRedirect>( "PythonStdIoRedirect", init<>() )
			.def( "write", &PythonStdIoRedirect::Write );

	boost::python::import( "sys" ).attr( "stderr" ) = python_stdio_redirector;
	boost::python::import( "sys" ).attr( "stdout" ) = python_stdio_redirector;
}
Exemple #11
0
void node_t::calc_inputs_interest( const render::render_context_t& context)
{
    if( is_valid_ && !ignored())
	do_calc_inputs_interest( context);
    else
    {
	// just pass the interest area to the inputs
        BOOST_FOREACH( input_plug_type& i, input_plugs())
	{
	    if( i.connected())
		i.input()->add_interest( interest_);
	}
    }
}
void EmoticonSetInstaller::showResult()
{
    kDebug();

    KNotification *notification = new KNotification(QLatin1String("emoticonsSuccess"), NULL, KNotification::Persistent);
    notification->setText( i18n("Installed Emoticonset %1 successfully.", this->bundleName()) );

    notification->setActions( QStringList() << i18n("OK") );
    QObject::connect(notification, SIGNAL(action1Activated()), notification, SLOT(close()));
    QObject::connect(notification, SIGNAL(ignored()), notification, SLOT(close()));

    notification->sendEvent();

    Q_EMIT showedResult();
}
Exemple #13
0
std::string PythonBridge::run( const std::string &code ) const
{
	if( m_ViewerCore->hasImage() ) {
		( *main_namespace )["ci"] = m_ViewerCore->getCurrentImage()->getISISImage().get();
	}


	try {
		handle<> ignored( ( PyRun_String( code.c_str(), Py_file_input, main_namespace->ptr(), main_namespace->ptr() ) ) );
	} catch( error_already_set ) {
		PyErr_Print();
	}

	return python_stdio_redirector.GetOutput();
}
Exemple #14
0
void PlanExecutor::askUser(const QString &pQuestion) {
	mQuestion = new KNotification(QLatin1String("StartBackup"), KNotification::Persistent);
	mQuestion->setTitle(i18nc("@title:window", "Backup Device Available - %1", mPlan->mDescription));
	mQuestion->setText(pQuestion);
	QStringList lAnswers;
	lAnswers << i18nc("@action:button", "Yes") << i18nc("@action:button", "No");
	mQuestion->setActions(lAnswers);
	connect(mQuestion, SIGNAL(action1Activated()), SLOT(enterBackupRunningState()));
	connect(mQuestion, SIGNAL(action2Activated()), SLOT(discardUserQuestion()));
	connect(mQuestion, SIGNAL(closed()), SLOT(discardUserQuestion()));
	connect(mQuestion, SIGNAL(ignored()), SLOT(discardUserQuestion()));
	// enter this "do nothing" state, if user answers "no" or ignores, remain there
	mState = WAITING_FOR_MANUAL_BACKUP;
	emit stateChanged();
	mQuestion->sendEvent();
}
JSBool
JetpackChild::EvalInSandbox(JSContext* cx, uintN argc, jsval* vp)
{
  if (argc != 2) {
    JS_ReportError(cx, "evalInSandbox takes two arguments");
    return JS_FALSE;
  }

  jsval* argv = JS_ARGV(cx, vp);

  JSObject* obj;
  if (!JSVAL_IS_OBJECT(argv[0]) ||
      !(obj = JSVAL_TO_OBJECT(argv[0]))) {
    JS_ReportError(cx, "The first argument to evalInSandbox must be a global object created using createSandbox.");
    JS_ASSERT(JS_FALSE);
    return JS_FALSE;
  }

  // Unwrap, and switch compartments
  obj = js::UnwrapObject(obj);

  JSAutoEnterCompartment ac;
  if (!ac.enter(cx, obj))
    return JS_FALSE;

  if (&sGlobalClass != JS_GetClass(cx, obj) ||
      obj == JS_GetGlobalObject(cx)) {
    JS_ReportError(cx, "The first argument to evalInSandbox must be a global object created using createSandbox.");
    JS_ASSERT(JS_FALSE);
    return JS_FALSE;
  }

  if (!JS_WrapValue(cx, &argv[1]))
    return JS_FALSE;

  JSString* str = JS_ValueToString(cx, argv[1]);
  if (!str)
    return JS_FALSE;

  size_t length;
  const jschar* chars = JS_GetStringCharsAndLength(cx, str, &length);
  if (!chars)
      return JS_FALSE;

  js::AutoValueRooter ignored(cx);
  return JS_EvaluateUCScript(cx, obj, chars, length, "", 1, ignored.jsval_addr());
}
Exemple #16
0
void PlanExecutor::askUser(const QString &pQuestion) {
	discardUserQuestion();
	mQuestion = new KNotification(QStringLiteral("StartBackup"), KNotification::Persistent);
	mQuestion->setTitle(mPlan->mDescription);
	mQuestion->setText(pQuestion);
	QStringList lAnswers;
	lAnswers << xi18nc("@action:button", "Yes") << xi18nc("@action:button", "No");
	mQuestion->setActions(lAnswers);
	connect(mQuestion, SIGNAL(action1Activated()), SLOT(startBackupSaveJob()));
	connect(mQuestion, SIGNAL(action2Activated()), SLOT(discardUserQuestion()));
	connect(mQuestion, SIGNAL(closed()), SLOT(discardUserQuestion()));
	connect(mQuestion, SIGNAL(ignored()), SLOT(discardUserQuestion()));
	// enter this "do nothing" state, if user answers "no" or ignores, remain there
	mState = WAITING_FOR_MANUAL_BACKUP;
	emit stateChanged();
	mQuestion->sendEvent();
}
Exemple #17
0
void PlanExecutor::repairFinished(KJob *pJob) {
	endSleepInhibit();
	discardRepairNotification();
	mRepairNotification = new KNotification(QStringLiteral("RepairCompleted"), KNotification::Persistent);
	mRepairNotification->setTitle(xi18nc("@title:window", "Repair Completed"));
	mRepairNotification->setText(pJob->errorText());
	QStringList lAnswers;
	lAnswers << xi18nc("@action:button", "Show log file");
	mRepairNotification->setActions(lAnswers);
	connect(mRepairNotification, SIGNAL(action1Activated()), SLOT(showLog()));
	connect(mRepairNotification, SIGNAL(closed()), SLOT(discardRepairNotification()));
	connect(mRepairNotification, SIGNAL(ignored()), SLOT(discardRepairNotification()));
	mRepairNotification->sendEvent();

	if(mState == REPAIRING) { //only restore if nothing has changed during the run
		mState = mLastState;
	}
	emit stateChanged();
}
Exemple #18
0
void PlanExecutor::notifyBackupFailed(KJob *pFailedJob) {
	discardFailNotification();
	mFailNotification = new KNotification(QStringLiteral("BackupFailed"), KNotification::Persistent);
	mFailNotification->setTitle(xi18nc("@title:window", "Saving of Backup Failed"));
	mFailNotification->setText(pFailedJob->errorText());

	QStringList lAnswers;
	if(pFailedJob->error() == BackupJob::ErrorWithLog) {
		lAnswers << xi18nc("@action:button", "Show log file");
		connect(mFailNotification, SIGNAL(action1Activated()), SLOT(showLog()));
	} else if(pFailedJob->error() == BackupJob::ErrorSuggestRepair) {
		lAnswers << xi18nc("@action:button", "Yes");
		lAnswers << xi18nc("@action:button", "No");
		connect(mFailNotification, SIGNAL(action1Activated()), SLOT(startRepairJob()));
	}
	mFailNotification->setActions(lAnswers);

	connect(mFailNotification, SIGNAL(action2Activated()), SLOT(discardFailNotification()));
	connect(mFailNotification, SIGNAL(closed()), SLOT(discardFailNotification()));
	connect(mFailNotification, SIGNAL(ignored()), SLOT(discardFailNotification()));
	mFailNotification->sendEvent();
}
nsresult
InvokePromiseFuncCallback::Call(JSContext* aCx,
                                JS::Handle<JS::Value> aValue)
{
  // Run resolver's algorithm with value and the synchronous flag set.

  JS::ExposeObjectToActiveJS(mGlobal);
  JS::ExposeValueToActiveJS(aValue);

  JSAutoCompartment ac(aCx, mGlobal);
  JS::Rooted<JS::Value> value(aCx, aValue);
  if (!JS_WrapValue(aCx, &value)) {
    NS_WARNING("Failed to wrap value into the right compartment.");
    return NS_ERROR_FAILURE;
  }

  ErrorResult rv;
  JS::Rooted<JS::Value> ignored(aCx);
  mPromiseFunc->Call(value, &ignored, rv);
  // Useful exceptions already got reported.
  rv.SuppressException();
  return NS_OK;
}
void UpdateChecker::readUpdateData(const QByteArray &data)
{
	const QStringList activeChannels = SettingsManager::getValue(QLatin1String("Updates/ActiveChannels")).toStringList();
	const QJsonObject updateData = QJsonDocument::fromJson(data).object();
	const QJsonArray channels = updateData.value(QLatin1String("channels")).toArray();
	int mainVersion = QCoreApplication::applicationVersion().remove(QChar('.')).toInt();
	int subVersion = QString(OTTER_VERSION_WEEKLY).toInt();
	QString availableVersion;
	QString availableChannel;

	for (int i = 0; i < channels.count(); ++i)
	{
		if (channels.at(i).isObject())
		{
			const QJsonObject object = channels.at(i).toObject();
			const QString identifier = object["identifier"].toString();
			const QString channelVersion = object["version"].toString();

			if (activeChannels.contains(identifier, Qt::CaseInsensitive))
			{
				const int channelMainVersion = channelVersion.trimmed().remove(QChar('.')).toInt();

				if (channelMainVersion == 0)
				{
					Console::addMessage(QCoreApplication::translate("main", "Unable to parse version number: %1").arg(channelVersion), OtherMessageCategory, ErrorMessageLevel);

					continue;
				}

				const int channelSubVersion = object["subVersion"].toString().toInt();

				if ((mainVersion < channelMainVersion) || (channelSubVersion > 0 && subVersion < channelSubVersion))
				{
					mainVersion = channelMainVersion;
					subVersion = channelSubVersion;
					availableVersion = channelVersion;
					availableChannel = identifier;
					m_detailsUrl = object["detailsUrl"].toString();
				}
			}
		}
	}

	SettingsManager::setValue(QLatin1String("Updates/LastCheck"), QDate::currentDate().toString(Qt::ISODate));

	if (!availableVersion.isEmpty())
	{
		const QString text = tr("New update %1 from %2 channel is available!").arg(availableVersion).arg(availableChannel);

		if (m_showDialog)
		{
			QMessageBox messageBox;
			messageBox.setWindowTitle(tr("New version of Otter Browser is available"));
			messageBox.setText(text);
			messageBox.setInformativeText(tr("Do you want to open a new tab with download page?"));
			messageBox.setIcon(QMessageBox::Question);
			messageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
			messageBox.setDefaultButton(QMessageBox::No);

			if (messageBox.exec() == QMessageBox::Yes)
			{
				runUpdate();
			}
			else
			{
				deleteLater();
			}
		}
		else
		{
			Notification *updateNotification = NotificationsManager::createNotification(NotificationsManager::UpdateAvailableEvent, text);

			connect(updateNotification, SIGNAL(clicked()), this, SLOT(runUpdate()));
			connect(updateNotification, SIGNAL(ignored()), this, SLOT(deleteLater()));
		}
	}
	else
	{ 
		deleteLater();
	}
}
void AdiumxtraProtocolHandler::install()
{
    if (m_url.isEmpty()) {
        Q_EMIT finished();
        return; // BundleInstaller:: xxxxx
    }

    QUrl url = QUrl::fromUserInput(m_url);
    if(url.scheme() == QLatin1String("adiumxtra")) {
        url.setScheme(QStringLiteral("http"));
    }

    QTemporaryFile *tmpFile = new QTemporaryFile();
    if (tmpFile->open()) {
        KIO::Job* getJob = KIO::file_copy(url, QUrl::fromLocalFile(tmpFile->fileName()), -1,
                                          KIO::Overwrite | KIO::HideProgressInfo);
        if (getJob->exec()) {
            qWarning() << "Download failed";
            Q_EMIT finished();
            return; // BundleInstaller::BundleCannotOpen;
        }
        getJob->deleteLater();
    }

    KArchive *archive = 0L;

    QMimeDatabase db;

    QString currentBundleMimeType =  db.mimeTypeForFile(tmpFile->fileName()).name();
    if (currentBundleMimeType == QLatin1String("application/zip")) {
        archive = new KZip(tmpFile->fileName());
    } else if (currentBundleMimeType == QLatin1String("application/x-compressed-tar") ||
               currentBundleMimeType == QLatin1String("application/x-bzip-compressed-tar") ||
               currentBundleMimeType == QLatin1String("application/x-gzip") ||
               currentBundleMimeType == QLatin1String("application/x-bzip")) {
        archive = new KTar(tmpFile->fileName());
    } else {
        KNotification *notification = new KNotification(QLatin1String("packagenotrecognized"), NULL, KNotification::Persistent);
        notification->setText( i18n("Package type not recognized or not supported") );
        notification->setActions( QStringList() << i18n("OK") );
        QObject::connect(notification, SIGNAL(action1Activated()), notification, SLOT(close()));
        QObject::connect(notification, SIGNAL(ignored()), notification, SLOT(close()));
        notification->setComponentName(ktelepathyComponentName());
        notification->sendEvent();
        qWarning() << "Unsupported file type" << currentBundleMimeType;
        Q_EMIT finished();
        return;// BundleInstaller::BundleNotValid;
    }

    if (!archive->open(QIODevice::ReadOnly)) {
        delete archive;
        qWarning() << "Cannot open theme file";
        Q_EMIT finished();
        return;// BundleInstaller::BundleCannotOpen;
    }

    ChatStyleInstaller *chatStyleInstaller = new ChatStyleInstaller(archive, tmpFile);
    if (chatStyleInstaller->validate() == BundleInstaller::BundleValid) {
        chatStyleInstaller->showRequest();

        QObject::connect(chatStyleInstaller, SIGNAL(finished(BundleInstaller::BundleStatus)),
                         chatStyleInstaller, SLOT(showResult()));
        QObject::connect(chatStyleInstaller, SIGNAL(showedResult()), this, SIGNAL(finished()));
        QObject::connect(chatStyleInstaller, SIGNAL(showedResult()),
                         chatStyleInstaller, SLOT(deleteLater()));
        QObject::connect(chatStyleInstaller, SIGNAL(ignoredRequest()), this, SIGNAL(finished()));
        QObject::connect(chatStyleInstaller, SIGNAL(ignoredRequest()),
                         chatStyleInstaller, SLOT(deleteLater()));

        return;// BundleInstaller::BundleValid;
    }
    delete chatStyleInstaller;

    EmoticonSetInstaller *emoticonSetInstaller = new EmoticonSetInstaller(archive, tmpFile);
    if(emoticonSetInstaller->validate() == BundleInstaller::BundleValid) {
        emoticonSetInstaller->showRequest();

        QObject::connect(emoticonSetInstaller, SIGNAL(finished(BundleInstaller::BundleStatus)),
                         emoticonSetInstaller, SLOT(showResult()));
        QObject::connect(emoticonSetInstaller, SIGNAL(showedResult()), this, SIGNAL(finished()));
        QObject::connect(emoticonSetInstaller, SIGNAL(showedResult()),
                         emoticonSetInstaller, SLOT(deleteLater()));
        QObject::connect(emoticonSetInstaller, SIGNAL(ignoredRequest()), this, SIGNAL(finished()));
        QObject::connect(emoticonSetInstaller, SIGNAL(ignoredRequest()),
                         emoticonSetInstaller, SLOT(deleteLater()));

        return;// BundleInstaller::BundleValid;
    }
    delete emoticonSetInstaller;

    KNotification *notification = new KNotification(QLatin1String("packagenotrecognized"),
                                                    NULL,
                                                    KNotification::Persistent);
    notification->setText( i18n("Package type not recognized or not supported") );
    QObject::connect(notification, SIGNAL(action1Activated()), notification, SLOT(close()));
    QObject::connect(notification, SIGNAL(ignored()), notification, SLOT(close()));
    notification->setActions( QStringList() << i18n("OK") );
    notification->setComponentName(ktelepathyComponentName());
    notification->sendEvent();

    Q_EMIT finished();
    return;// BundleInstaller::BundleUnknownError;
}
Exemple #22
0
void function(Ts... Vs) {    \
    ignored(std::cout<<Vs...);
    ///Alias<char[]> { '\0', (void(std::cout << Vs), '\0')... };
}
nsresult
WrapperPromiseCallback::Call(JSContext* aCx,
                             JS::Handle<JS::Value> aValue)
{
  JS::ExposeObjectToActiveJS(mGlobal);
  JS::ExposeValueToActiveJS(aValue);

  JSAutoCompartment ac(aCx, mGlobal);
  JS::Rooted<JS::Value> value(aCx, aValue);
  if (!JS_WrapValue(aCx, &value)) {
    NS_WARNING("Failed to wrap value into the right compartment.");
    return NS_ERROR_FAILURE;
  }

  ErrorResult rv;

  // PromiseReactionTask step 6
  JS::Rooted<JS::Value> retValue(aCx);
  JSCompartment* compartment;
  if (mNextPromise) {
    compartment = mNextPromise->Compartment();
  } else {
    MOZ_ASSERT(mNextPromiseObj);
    compartment = js::GetObjectCompartment(mNextPromiseObj);
  }
  mCallback->Call(value, &retValue, rv, "promise callback",
                  CallbackObject::eRethrowExceptions,
                  compartment);

  rv.WouldReportJSException();

  // PromiseReactionTask step 7
  if (rv.Failed()) {
    JS::Rooted<JS::Value> value(aCx);
    { // Scope for JSAutoCompartment
      // Convert the ErrorResult to a JS exception object that we can reject
      // ourselves with.  This will be exactly the exception that would get
      // thrown from a binding method whose ErrorResult ended up with whatever
      // is on "rv" right now.  Do this in the promise reflector compartment.
      Maybe<JSAutoCompartment> ac;
      if (mNextPromise) {
        ac.emplace(aCx, mNextPromise->GlobalJSObject());
      } else {
        ac.emplace(aCx, mNextPromiseObj);
      }
      DebugOnly<bool> conversionResult = ToJSValue(aCx, rv, &value);
      MOZ_ASSERT(conversionResult);
    }

    if (mNextPromise) {
      mNextPromise->RejectInternal(aCx, value);
    } else {
      JS::Rooted<JS::Value> ignored(aCx);
      ErrorResult rejectRv;
      mRejectFunc->Call(value, &ignored, rejectRv);
      // This reported any JS exceptions; we just have a pointless exception on
      // there now.
      rejectRv.SuppressException();
    }
    return NS_OK;
  }

  // If the return value is the same as the promise itself, throw TypeError.
  if (retValue.isObject()) {
    JS::Rooted<JSObject*> valueObj(aCx, &retValue.toObject());
    valueObj = js::CheckedUnwrap(valueObj);
    JS::Rooted<JSObject*> nextPromiseObj(aCx);
    if (mNextPromise) {
      nextPromiseObj = mNextPromise->GetWrapper();
    } else {
      MOZ_ASSERT(mNextPromiseObj);
      nextPromiseObj = mNextPromiseObj;
    }
    // XXXbz shouldn't this check be over in ResolveInternal anyway?
    if (valueObj == nextPromiseObj) {
      const char* fileName = nullptr;
      uint32_t lineNumber = 0;

      // Try to get some information about the callback to report a sane error,
      // but don't try too hard (only deals with scripted functions).
      JS::Rooted<JSObject*> unwrapped(aCx,
        js::CheckedUnwrap(mCallback->Callback()));

      if (unwrapped) {
        JSAutoCompartment ac(aCx, unwrapped);
        if (JS_ObjectIsFunction(aCx, unwrapped)) {
          JS::Rooted<JS::Value> asValue(aCx, JS::ObjectValue(*unwrapped));
          JS::Rooted<JSFunction*> func(aCx, JS_ValueToFunction(aCx, asValue));

          MOZ_ASSERT(func);
          JSScript* script = JS_GetFunctionScript(aCx, func);
          if (script) {
            fileName = JS_GetScriptFilename(script);
            lineNumber = JS_GetScriptBaseLineNumber(aCx, script);
          }
        }
      }

      // We're back in aValue's compartment here.
      JS::Rooted<JSString*> fn(aCx, JS_NewStringCopyZ(aCx, fileName));
      if (!fn) {
        // Out of memory. Promise will stay unresolved.
        JS_ClearPendingException(aCx);
        return NS_ERROR_OUT_OF_MEMORY;
      }

      JS::Rooted<JSString*> message(aCx,
        JS_NewStringCopyZ(aCx,
          "then() cannot return same Promise that it resolves."));
      if (!message) {
        // Out of memory. Promise will stay unresolved.
        JS_ClearPendingException(aCx);
        return NS_ERROR_OUT_OF_MEMORY;
      }

      JS::Rooted<JS::Value> typeError(aCx);
      if (!JS::CreateError(aCx, JSEXN_TYPEERR, nullptr, fn, lineNumber, 0,
                           nullptr, message, &typeError)) {
        // Out of memory. Promise will stay unresolved.
        JS_ClearPendingException(aCx);
        return NS_ERROR_OUT_OF_MEMORY;
      }

      if (mNextPromise) {
        mNextPromise->RejectInternal(aCx, typeError);
      } else {
        JS::Rooted<JS::Value> ignored(aCx);
        ErrorResult rejectRv;
        mRejectFunc->Call(typeError, &ignored, rejectRv);
        // This reported any JS exceptions; we just have a pointless exception
        // on there now.
        rejectRv.SuppressException();
      }
      return NS_OK;
    }
  }

  // Otherwise, run resolver's resolve with value.
  if (!JS_WrapValue(aCx, &retValue)) {
    NS_WARNING("Failed to wrap value into the right compartment.");
    return NS_ERROR_FAILURE;
  }

  if (mNextPromise) {
    mNextPromise->ResolveInternal(aCx, retValue);
  } else {
    JS::Rooted<JS::Value> ignored(aCx);
    ErrorResult resolveRv;
    mResolveFunc->Call(retValue, &ignored, resolveRv);
    // This reported any JS exceptions; we just have a pointless exception
    // on there now.
    resolveRv.SuppressException();
  }
    
  return NS_OK;
}