bool
StructuredCloneHelper::WriteTransferCallback(JSContext* aCx,
                                             JS::Handle<JSObject*> aObj,
                                             uint32_t* aTag,
                                             JS::TransferableOwnership* aOwnership,
                                             void** aContent,
                                             uint64_t* aExtraData)
{
  if (!mSupportsTransferring) {
    return false;
  }

  {
    MessagePortBase* port = nullptr;
    nsresult rv = UNWRAP_OBJECT(MessagePort, aObj, port);
    if (NS_SUCCEEDED(rv)) {
      // We use aExtraData to store the index of this new port identifier.
      *aExtraData = mPortIdentifiers.Length();
      MessagePortIdentifier* identifier = mPortIdentifiers.AppendElement();

      if (!port->CloneAndDisentangle(*identifier)) {
        return false;
      }

      *aTag = SCTAG_DOM_MAP_MESSAGEPORT;
      *aOwnership = JS::SCTAG_TMO_CUSTOM;
      *aContent = nullptr;

      return true;
    }
  }

  return false;
}
Example #2
0
bool
WriteTransfer(JSContext* aCx, JS::Handle<JSObject*> aObj, void* aClosure,
              uint32_t* aTag, JS::TransferableOwnership* aOwnership,
              void** aContent, uint64_t* aExtraData)
{
  MOZ_ASSERT(aClosure);

  auto* closure = static_cast<StructuredCloneClosureInternal*>(aClosure);

  MessagePortBase* port = nullptr;
  nsresult rv = UNWRAP_OBJECT(MessagePort, aObj, port);
  if (NS_FAILED(rv)) {
    return false;
  }

  if (closure->mTransferredPorts.Contains(port)) {
    // No duplicates.
    return false;
  }

  MessagePortIdentifier identifier;
  if (!port->CloneAndDisentangle(identifier)) {
    return false;
  }

  closure->mClosure.mMessagePortIdentifiers.AppendElement(identifier);
  closure->mTransferredPorts.AppendElement(port);

  *aTag = SCTAG_DOM_MAP_MESSAGEPORT;
  *aOwnership = JS::SCTAG_TMO_CUSTOM;
  *aContent = nullptr;
  *aExtraData = closure->mClosure.mMessagePortIdentifiers.Length() - 1;

  return true;
}
Example #3
0
static bool
PostMessageTransferStructuredClone(JSContext* aCx,
                                   JS::Handle<JSObject*> aObj,
                                   void* aClosure,
                                   uint32_t* aTag,
                                   JS::TransferableOwnership* aOwnership,
                                   void** aContent,
                                   uint64_t *aExtraData)
{
  StructuredCloneInfo* scInfo = static_cast<StructuredCloneInfo*>(aClosure);
  NS_ASSERTION(scInfo, "Must have scInfo!");

  MessagePortBase *port = nullptr;
  nsresult rv = UNWRAP_OBJECT(MessagePort, aObj, port);
  if (NS_SUCCEEDED(rv)) {
    nsRefPtr<MessagePortBase> newPort;
    if (scInfo->mPorts.Get(port, getter_AddRefs(newPort))) {
      // No duplicate.
      return false;
    }

    newPort = port->Clone();
    scInfo->mPorts.Put(port, newPort);

    *aTag = SCTAG_DOM_MAP_MESSAGEPORT;
    *aOwnership = JS::SCTAG_TMO_CUSTOM;
    *aContent = newPort;
    *aExtraData = 0;

    return true;
  }

  return false;
}