예제 #1
0
  virtual bool
  MainThreadRun() override
  {
    AssertIsOnMainThread();

    // Initialise an AutoJSAPI with the target window.
    AutoJSAPI jsapi;
    if (NS_WARN_IF(!jsapi.Init(mBackingStore->GetParentObject()))) {
      mRv.Throw(NS_ERROR_UNEXPECTED);
      return true;
    }
    JSContext* cx = jsapi.cx();

    JS::Rooted<JS::Value> value(cx);
    if (!mObjBuffer.read(cx, &value)) {
      JS_ClearPendingException(cx);
      mRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
      return true;
    }

    nsRefPtr<Promise> promise = mBackingStore->Add(cx,
                                                   value,
                                                   mId,
                                                   mRevisionId,
                                                   mRv);
    promise->AppendNativeHandler(mPromiseWorkerProxy);
    return true;
  }
// static
nsresult
AsyncConnectionHelper::ConvertCloneBufferToJSVal(
                                           JSContext* aCx,
                                           JSAutoStructuredCloneBuffer& aBuffer,
                                           jsval* aResult)
{
  NS_ASSERTION(aCx, "Null context!");
  NS_ASSERTION(aResult, "Null pointer!");

  JSAutoRequest ar(aCx);

  if (aBuffer.data()) {
    JSBool ok = aBuffer.read(aResult, aCx);

    aBuffer.clear(aCx);

    if (!ok) {
      NS_ERROR("Failed to decode!");
      return NS_ERROR_DOM_DATA_CLONE_ERR;
    }
  }
  else {
    *aResult = JSVAL_VOID;
  }

  return NS_OK;
}
예제 #3
0
/*
 * General-purpose structured-cloning utility for cases where the structured
 * clone buffer is only used in stack-scope (that is to say, the buffer does
 * not escape from this function). The stack-scoping allows us to pass
 * references to various JSObjects directly in certain situations without
 * worrying about lifetime issues.
 *
 * This function assumes that |cx| is already entered the compartment we want
 * to clone to, and that |val| may not be same-compartment with cx. When the
 * function returns, |val| is set to the result of the clone.
 */
bool
StackScopedClone(JSContext *cx, StackScopedCloneOptions &options,
                 MutableHandleValue val)
{
    JSAutoStructuredCloneBuffer buffer;
    StackScopedCloneData data(cx, &options);
    {
        // For parsing val we have to enter its compartment.
        // (unless it's a primitive)
        Maybe<JSAutoCompartment> ac;
        if (val.isObject()) {
            ac.construct(cx, &val.toObject());
        } else if (val.isString() && !JS_WrapValue(cx, val)) {
            return false;
        }

        if (!buffer.write(cx, val, &gStackScopedCloneCallbacks, &data))
            return false;
    }

    // Now recreate the clones in the target compartment.
    return buffer.read(cx, val, &gStackScopedCloneCallbacks, &data);
}
예제 #4
0
NS_IMETHODIMP
PostMessageRunnable::Run()
{
    MOZ_ASSERT(mPort);

    // Ensure that the buffer is freed even if we fail to post the message
    JSAutoStructuredCloneBuffer buffer;
    buffer.adopt(mMessage, mMessageLen);
    mMessage = nullptr;
    mMessageLen = 0;

    // Get the JSContext for the target window
    nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(mPort->GetOwner());
    NS_ENSURE_STATE(sgo);
    nsCOMPtr<nsIScriptContext> scriptContext = sgo->GetContext();
    AutoPushJSContext cx(scriptContext ? scriptContext->GetNativeContext()
                         : nsContentUtils::GetSafeJSContext());

    MOZ_ASSERT(cx);

    // Deserialize the structured clone data
    JS::Rooted<JS::Value> messageData(cx);
    {
        StructuredCloneInfo scInfo;
        scInfo.mEvent = this;
        scInfo.mPort = mPort;

        if (!buffer.read(cx, messageData.address(), &kPostMessageCallbacks,
                         &scInfo)) {
            return NS_ERROR_DOM_DATA_CLONE_ERR;
        }
    }

    // Create the event
    nsIDocument* doc = mPort->GetOwner()->GetExtantDoc();
    if (!doc) {
        return NS_OK;
    }

    ErrorResult error;
    nsRefPtr<nsDOMEvent> event =
        doc->CreateEvent(NS_LITERAL_STRING("MessageEvent"), error);
    if (error.Failed()) {
        return NS_OK;
    }

    nsCOMPtr<nsIDOMMessageEvent> message = do_QueryInterface(event);
    nsresult rv = message->InitMessageEvent(NS_LITERAL_STRING("message"),
                                            false /* non-bubbling */,
                                            true /* cancelable */,
                                            messageData,
                                            EmptyString(),
                                            EmptyString(),
                                            mPort->GetOwner());
    if (NS_FAILED(rv)) {
        return NS_OK;
    }

    message->SetTrusted(true);

    bool status;
    mPort->DispatchEvent(event, &status);
    return status ? NS_OK : NS_ERROR_FAILURE;
}