/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 * vim: set ts=8 sts=4 et sw=4 tw=99:
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/*
 * This file implements the structured clone algorithm of
 * http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#safe-passing-of-structured-data
 *
 * The implementation differs slightly in that it uses an explicit stack, and
 * the "memory" maps source objects to sequential integer indexes rather than
 * directly pointing to destination objects. As a result, the order in which
 * things are added to the memory must exactly match the order in which they
 * are placed into 'allObjs', an analogous array of back-referenceable
 * destination objects constructed while reading.
 *
 * For the most part, this is easy: simply add objects to the memory when first
 * encountering them. But reading in a typed array requires an ArrayBuffer for
 * construction, so objects cannot just be added to 'allObjs' in the order they
 * are created. If they were, ArrayBuffers would come before typed arrays when
 * in fact the typed array was added to 'memory' first.
 *
 * So during writing, we add objects to the memory when first encountering
 * them. When reading a typed array, a placeholder is pushed onto allObjs until
 * the ArrayBuffer has been read, then it is updated with the actual typed
 * array object.
 */

#include "js/StructuredClone.h"

#include "mozilla/EndianUtils.h"
#include "mozilla/FloatingPoint.h"

#include <algorithm>

#include "jsapi.h"
#include "jscntxt.h"
#include "jsdate.h"
#include "jswrapper.h"

#include "builtin/MapObject.h"
#include "js/Date.h"
#include "js/GCHashTable.h"
#include "vm/SavedFrame.h"
#include "vm/SharedArrayObject.h"
#include "vm/TypedArrayObject.h"
#include "vm/WrapperObject.h"

#include "jscntxtinlines.h"
#include "jsobjinlines.h"

using namespace js;

using mozilla::BitwiseCast;
using mozilla::IsNaN;
using mozilla::LittleEndian;
using mozilla::NativeEndian;
using mozilla::NumbersAreIdentical;
using JS::CanonicalizeNaN;

// When you make updates here, make sure you consider whether you need to bump the
// value of JS_STRUCTURED_CLONE_VERSION in js/public/StructuredClone.h.  You will
// likely need to increment the version if anything at all changes in the serialization
// format.
//
// Note that SCTAG_END_OF_KEYS is written into the serialized form and should have
// a stable ID, it need not be at the end of the list and should not be used for
// sizing data structures.

enum StructuredDataType : uint32_t {
    /* Structured data types provided by the engine */
    SCTAG_FLOAT_MAX = 0xFFF00000,
    SCTAG_NULL = 0xFFFF0000,
    SCTAG_UNDEFINED,
    SCTAG_BOOLEAN,
    SCTAG_INT32,
    SCTAG_STRING,
    SCTAG_DATE_OBJECT,
    SCTAG_REGEXP_OBJECT,
    SCTAG_ARRAY_OBJECT,
    SCTAG_OBJECT_OBJECT,
    SCTAG_ARRAY_BUFFER_OBJECT,
    SCTAG_BOOLEAN_OBJECT,
    SCTAG_STRING_OBJECT,
    SCTAG_NUMBER_OBJECT,
    SCTAG_BACK_REFERENCE_OBJECT,
    SCTAG_DO_NOT_USE_1, // Required for backwards compatibility
    SCTAG_DO_NOT_USE_2, // Required for backwards compatibility
    SCTAG_TYPED_ARRAY_OBJECT,
    SCTAG_MAP_OBJECT,
    SCTAG_SET_OBJECT,
    SCTAG_END_OF_KEYS,
    SCTAG_SHARED_TYPED_ARRAY_OBJECT,
    SCTAG_DATA_VIEW_OBJECT,
    SCTAG_SAVED_FRAME_OBJECT,

    SCTAG_JSPRINCIPALS,
    SCTAG_NULL_JSPRINCIPALS,
    SCTAG_RECONSTRUCTED_SAVED_FRAME_PRINCIPALS_IS_SYSTEM,
    SCTAG_RECONSTRUCTED_SAVED_FRAME_PRINCIPALS_IS_NOT_SYSTEM,

    SCTAG_TYPED_ARRAY_V1_MIN = 0xFFFF0100,
    SCTAG_TYPED_ARRAY_V1_INT8 = SCTAG_TYPED_ARRAY_V1_MIN + Scalar::Int8,
    SCTAG_TYPED_ARRAY_V1_UINT8 = SCTAG_TYPED_ARRAY_V1_MIN + Scalar::Uint8,
    SCTAG_TYPED_ARRAY_V1_INT16 = SCTAG_TYPED_ARRAY_V1_MIN + Scalar::Int16,
    SCTAG_TYPED_ARRAY_V1_UINT16 = SCTAG_TYPED_ARRAY_V1_MIN + Scalar::Uint16,
    SCTAG_TYPED_ARRAY_V1_INT32 = SCTAG_TYPED_ARRAY_V1_MIN + Scalar::Int32,
    SCTAG_TYPED_ARRAY_V1_UINT32 = SCTAG_TYPED_ARRAY_V1_MIN + Scalar::Uint32,
    SCTAG_TYPED_ARRAY_V1_FLOAT32 = SCTAG_TYPED_ARRAY_V1_MIN + Scalar::Float32,
    SCTAG_TYPED_ARRAY_V1_FLOAT64 = SCTAG_TYPED_ARRAY_V1_MIN + Scalar::Float64,
    SCTAG_TYPED_ARRAY_V1_UINT8_CLAMPED = SCTAG_TYPED_ARRAY_V1_MIN + Scalar::Uint8Clamped,
    SCTAG_TYPED_ARRAY_V1_MAX = SCTAG_TYPED_ARRAY_V1_MIN + Scalar::MaxTypedArrayViewType - 1,

    /*
     * Define a separate range of numbers for Transferable-only tags, since
     * they are not used for persistent clone buffers and therefore do not
     * require bumping JS_STRUCTURED_CLONE_VERSION.
     */
    SCTAG_TRANSFER_MAP_HEADER = 0xFFFF0200,
    SCTAG_TRANSFER_MAP_PENDING_ENTRY,
    SCTAG_TRANSFER_MAP_ARRAY_BUFFER,
    SCTAG_TRANSFER_MAP_SHARED_BUFFER,
    SCTAG_TRANSFER_MAP_END_OF_BUILTIN_TYPES,

    SCTAG_END_OF_BUILTIN_TYPES
};

/*
 * Format of transfer map:
 *   <SCTAG_TRANSFER_MAP_HEADER, TransferableMapHeader(UNREAD|TRANSFERRED)>
 *   numTransferables (64 bits)
 *   array of:
 *     <SCTAG_TRANSFER_MAP_*, TransferableOwnership>
 *     pointer (64 bits)
 *     extraData (64 bits), eg byte length for ArrayBuffers
 */

// Data associated with an SCTAG_TRANSFER_MAP_HEADER that tells whether the
// contents have been read out yet or not.
enum TransferableMapHeader {
    SCTAG_TM_UNREAD = 0,
    SCTAG_TM_TRANSFERRED
};

static inline uint64_t
PairToUInt64(uint32_t tag, uint32_t data)
{
    return uint64_t(data) | (uint64_t(tag) << 32);
}

namespace js {

struct SCOutput {
  public:
    explicit SCOutput(JSContext* cx);

    JSContext* context() const { return cx; }

    bool write(uint64_t u);
    bool writePair(uint32_t tag, uint32_t data);
    bool writeDouble(double d);
    bool writeBytes(const void* p, size_t nbytes);
    bool writeChars(const Latin1Char* p, size_t nchars);
    bool writeChars(const char16_t* p, size_t nchars);
    bool writePtr(const void*);

    template <class T>
    bool writeArray(const T* p, size_t nbytes);

    bool extractBuffer(uint64_t** datap, size_t* sizep);

    uint64_t count() const { return buf.length(); }
    uint64_t* rawBuffer() { return buf.begin(); }

  private:
    JSContext* cx;
    Vector<uint64_t> buf;
};

class SCInput {
  public:
    SCInput(JSContext* cx, uint64_t* data, size_t nbytes);

    JSContext* context() const { return cx; }

    static void getPtr(const uint64_t* buffer, void** ptr);
    static void getPair(const uint64_t* buffer, uint32_t* tagp, uint32_t* datap);

    bool read(uint64_t* p);
    bool readNativeEndian(uint64_t* p);
    bool readPair(uint32_t* tagp, uint32_t* datap);
    bool readDouble(double* p);
    bool readBytes(void* p, size_t nbytes);
    bool readChars(Latin1Char* p, size_t nchars);
    bool readChars(char16_t* p, size_t nchars);
    bool readPtr(void**);

    bool get(uint64_t* p);
    bool getPair(uint32_t* tagp, uint32_t* datap);

    uint64_t* tell() const { return point; }
    uint64_t* end() const { return bufEnd; }

    template <class T>
    bool readArray(T* p, size_t nelems);

    bool reportTruncated() {
         JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
                              JSMSG_SC_BAD_SERIALIZED_DATA, "truncated");
         return false;
     }

  private:
    void staticAssertions() {
        JS_STATIC_ASSERT(sizeof(char16_t) == 2);
        JS_STATIC_ASSERT(sizeof(uint32_t) == 4);
    }

    JSContext* cx;
    uint64_t* point;
    uint64_t* bufEnd;
};

} /* namespace js */

struct JSStructuredCloneReader {
  public:
    explicit JSStructuredCloneReader(SCInput& in, const JSStructuredCloneCallbacks* cb,
                                     void* cbClosure)
        : in(in), objs(in.context()), allObjs(in.context()),
          callbacks(cb), closure(cbClosure) { }

    SCInput& input() { return in; }
    bool read(MutableHandleValue vp);

  private:
    JSContext* context() { return in.context(); }

    bool readTransferMap();

    template <typename CharT>
    JSString* readStringImpl(uint32_t nchars);
    JSString* readString(uint32_t data);

    bool checkDouble(double d);
    bool readTypedArray(uint32_t arrayType, uint32_t nelems, MutableHandleValue vp,
                        bool v1Read = false);
    bool readDataView(uint32_t byteLength, MutableHandleValue vp);
    bool readArrayBuffer(uint32_t nbytes, MutableHandleValue vp);
    bool readV1ArrayBuffer(uint32_t arrayType, uint32_t nelems, MutableHandleValue vp);
    JSObject* readSavedFrame(uint32_t principalsTag);
    bool startRead(MutableHandleValue vp);

    SCInput& in;

    // Stack of objects with properties remaining to be read.
    AutoValueVector objs;

    // Stack of all objects read during this deserialization
    AutoValueVector allObjs;

    // The user defined callbacks that will be used for cloning.
    const JSStructuredCloneCallbacks* callbacks;

    // Any value passed to JS_ReadStructuredClone.
    void* closure;

    friend bool JS_ReadTypedArray(JSStructuredCloneReader* r, MutableHandleValue vp);
};

struct JSStructuredCloneWriter {
  public:
    explicit JSStructuredCloneWriter(JSContext* cx,
                                     const JSStructuredCloneCallbacks* cb,
                                     void* cbClosure,
                                     Value tVal)
        : out(cx), objs(out.context()),
          counts(out.context()), entries(out.context()),
          memory(out.context(), CloneMemory(out.context())), callbacks(cb),
          closure(cbClosure), transferable(out.context(), tVal), transferableObjects(out.context())
    {}

    ~JSStructuredCloneWriter();

    bool init() { return memory.init() && parseTransferable() && writeTransferMap(); }

    bool write(HandleValue v);

    SCOutput& output() { return out; }

    bool extractBuffer(uint64_t** datap, size_t* sizep) {
        return out.extractBuffer(datap, sizep);
    }

  private:
    JSStructuredCloneWriter() = delete;
    JSStructuredCloneWriter(const JSStructuredCloneWriter&) = delete;

    JSContext* context() { return out.context(); }

    bool writeTransferMap();

    bool writeString(uint32_t tag, JSString* str);
    bool writeArrayBuffer(HandleObject obj);
    bool writeTypedArray(HandleObject obj);
    bool writeDataView(HandleObject obj);
    bool writeSharedArrayBuffer(HandleObject obj);
    bool startObject(HandleObject obj, bool* backref);
    bool startWrite(HandleValue v);
    bool traverseObject(HandleObject obj);
    bool traverseMap(HandleObject obj);
    bool traverseSet(HandleObject obj);
    bool traverseSavedFrame(HandleObject obj);

    bool parseTransferable();
    bool reportErrorTransferable(uint32_t errorId);
    bool transferOwnership();

    inline void checkStack();

    SCOutput out;

    // Vector of objects with properties remaining to be written.
    //
    // NB: These can span multiple compartments, so the compartment must be
    // entered before any manipulation is performed.
    AutoValueVector objs;

    // counts[i] is the number of entries of objs[i] remaining to be written.
    // counts.length() == objs.length() and sum(counts) == entries.length().
    Vector<size_t> counts;

    // For JSObject: Property IDs as value
    // For Map: Key followed by value
    // For Set: Key
    // For SavedFrame: parent SavedFrame
    AutoValueVector entries;

    // The "memory" list described in the HTML5 internal structured cloning algorithm.
    // memory is a superset of objs; items are never removed from Memory
    // until a serialization operation is finished
    using CloneMemory = GCHashMap<JSObject*, uint32_t, MovableCellHasher<JSObject*>>;
    Rooted<CloneMemory> memory;

    // The user defined callbacks that will be used for cloning.
    const JSStructuredCloneCallbacks* callbacks;

    // Any value passed to JS_WriteStructuredClone.
    void* closure;

    // List of transferable objects
    RootedValue transferable;
    AutoObjectVector transferableObjects;

    friend bool JS_WriteString(JSStructuredCloneWriter* w, HandleString str);
    friend bool JS_WriteTypedArray(JSStructuredCloneWriter* w, HandleValue v);
};

JS_FRIEND_API(uint64_t)
js::GetSCOffset(JSStructuredCloneWriter* writer)
{
    MOZ_ASSERT(writer);
    return writer->output().count() * sizeof(uint64_t);
}

JS_STATIC_ASSERT(SCTAG_END_OF_BUILTIN_TYPES <= JS_SCTAG_USER_MIN);
JS_STATIC_ASSERT(JS_SCTAG_USER_MIN <= JS_SCTAG_USER_MAX);
JS_STATIC_ASSERT(Scalar::Int8 == 0);

static void
ReportErrorTransferable(JSContext* cx,
                        const JSStructuredCloneCallbacks* callbacks,
                        uint32_t errorId)
{
    if (callbacks && callbacks->reportError)
        callbacks->reportError(cx, errorId);
    else if (errorId == JS_SCERR_DUP_TRANSFERABLE)
        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_SC_DUP_TRANSFERABLE);
    else
        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_SC_NOT_TRANSFERABLE);
}

bool
WriteStructuredClone(JSContext* cx, HandleValue v, uint64_t** bufp, size_t* nbytesp,
                     const JSStructuredCloneCallbacks* cb, void* cbClosure,
                     Value transferable)
{
    JSStructuredCloneWriter w(cx, cb, cbClosure, transferable);
    return w.init() && w.write(v) && w.extractBuffer(bufp, nbytesp);
}

bool
ReadStructuredClone(JSContext* cx, uint64_t* data, size_t nbytes, MutableHandleValue vp,
                    const JSStructuredCloneCallbacks* cb, void* cbClosure)
{
    SCInput in(cx, data, nbytes);
    JSStructuredCloneReader r(in, cb, cbClosure);
    return r.read(vp);
}

// If the given buffer contains Transferables, free them. Note that custom
// Transferables will use the JSStructuredCloneCallbacks::freeTransfer() to
// delete their transferables.
static void
DiscardTransferables(uint64_t* buffer, size_t nbytes,
                     const JSStructuredCloneCallbacks* cb, void* cbClosure)
{
    MOZ_ASSERT(nbytes % sizeof(uint64_t) == 0);
    uint64_t* end = buffer + nbytes / sizeof(uint64_t);
    uint64_t* point = buffer;
    if (point == end)
        return; // Empty buffer

    uint32_t tag, data;
    SCInput::getPair(point++, &tag, &data);
    if (tag != SCTAG_TRANSFER_MAP_HEADER)
        return;

    if (TransferableMapHeader(data) == SCTAG_TM_TRANSFERRED)
        return;

    // freeTransfer should not GC
    JS::AutoSuppressGCAnalysis nogc;

    if (point == end)
        return;

    uint64_t numTransferables = LittleEndian::readUint64(point++);
    while (numTransferables--) {
        if (point == end)
            return;

        uint32_t ownership;
        SCInput::getPair(point++, &tag, &ownership);
        MOZ_ASSERT(tag >= SCTAG_TRANSFER_MAP_PENDING_ENTRY);
        if (point == end)
            return;

        void* content;
        SCInput::getPtr(point++, &content);
        if (point == end)
            return;

        uint64_t extraData = LittleEndian::readUint64(point++);

        if (ownership < JS::SCTAG_TMO_FIRST_OWNED)
            continue;

        if (ownership == JS::SCTAG_TMO_ALLOC_DATA) {
            js_free(content);
        } else if (ownership == JS::SCTAG_TMO_MAPPED_DATA) {
            JS_ReleaseMappedArrayBufferContents(content, extraData);
        } else if (ownership == JS::SCTAG_TMO_SHARED_BUFFER) {
            SharedArrayRawBuffer* raw = static_cast<SharedArrayRawBuffer*>(content);
            if (raw)
                raw->dropReference();
        } else if (cb && cb->freeTransfer) {
            cb->freeTransfer(tag, JS::TransferableOwnership(ownership), content, extraData, cbClosure);
        } else {
            MOZ_ASSERT(false, "unknown ownership");
        }
    }
}

static bool
StructuredCloneHasTransferObjects(const uint64_t* data, size_t nbytes)
{
    if (!data)
        return false;

    uint64_t u = LittleEndian::readUint64(data);
    uint32_t tag = uint32_t(u >> 32);
    return (tag == SCTAG_TRANSFER_MAP_HEADER);
}

namespace js {

SCInput::SCInput(JSContext* cx, uint64_t* data, size_t nbytes)
    : cx(cx), point(data), bufEnd(data + nbytes / 8)
{
    // On 32-bit, we sometimes construct an SCInput from an SCOutput buffer,
    // which is not guaranteed to be 8-byte aligned
    MOZ_ASSERT((uintptr_t(data) & (sizeof(int) - 1)) == 0);
    MOZ_ASSERT((nbytes & 7) == 0);
}

bool
SCInput::read(uint64_t* p)
{
    if (point == bufEnd) {
        *p = 0;  /* initialize to shut GCC up */
        return reportTruncated();
    }
    *p = LittleEndian::readUint64(point++);
    return true;
}

bool
SCInput::readNativeEndian(uint64_t* p)
{
    if (point == bufEnd) {
        *p = 0;  /* initialize to shut GCC up */
        return reportTruncated();
    }
    *p = *(point++);
    return true;
}

bool
SCInput::readPair(uint32_t* tagp, uint32_t* datap)
{
    uint64_t u;
    bool ok = read(&u);
    if (ok) {
        *tagp = uint32_t(u >> 32);
        *datap = uint32_t(u);
    }
    return ok;
}

bool
SCInput::get(uint64_t* p)
{
    if (point == bufEnd)
        return reportTruncated();
    *p = LittleEndian::readUint64(point);
    return true;
}

bool
SCInput::getPair(uint32_t* tagp, uint32_t* datap)
{
    uint64_t u = 0;
    if (!get(&u))
        return false;

    *tagp = uint32_t(u >> 32);
    *datap = uint32_t(u);
    return true;
}

void
SCInput::getPair(const uint64_t* p, uint32_t* tagp, uint32_t* datap)
{
    uint64_t u = LittleEndian::readUint64(p);
    *tagp = uint32_t(u >> 32);
    *datap = uint32_t(u);
}

bool
SCInput::readDouble(double* p)
{
    union {
        uint64_t u;
        double d;
    } pun;
    if (!read(&pun.u))
        return false;
    *p = CanonicalizeNaN(pun.d);
    return true;
}

template <typename T>
static void
copyAndSwapFromLittleEndian(T* dest, const void* src, size_t nelems)
{
    if (nelems > 0)
        NativeEndian::copyAndSwapFromLittleEndian(dest, src, nelems);
}

template <>
void
copyAndSwapFromLittleEndian(uint8_t* dest, const void* src, size_t nelems)
{
    memcpy(dest, src, nelems);
}

template <class T>
bool
SCInput::readArray(T* p, size_t nelems)
{
    JS_STATIC_ASSERT(sizeof(uint64_t) % sizeof(T) == 0);

    /*
     * Fail if nelems is so huge as to make JS_HOWMANY overflow or if nwords is
     * larger than the remaining data.
     */
    size_t nwords = JS_HOWMANY(nelems, sizeof(uint64_t) / sizeof(T));
    if (nelems + sizeof(uint64_t) / sizeof(T) - 1 < nelems || nwords > size_t(bufEnd - point))
        return reportTruncated();

    copyAndSwapFromLittleEndian(p, point, nelems);
    point += nwords;
    return true;
}

bool
SCInput::readBytes(void* p, size_t nbytes)
{
    return readArray((uint8_t*) p, nbytes);
}

bool
SCInput::readChars(Latin1Char* p, size_t nchars)
{
    static_assert(sizeof(Latin1Char) == sizeof(uint8_t), "Latin1Char must fit in 1 byte");
    return readBytes(p, nchars);
}

bool
SCInput::readChars(char16_t* p, size_t nchars)
{
    MOZ_ASSERT(sizeof(char16_t) == sizeof(uint16_t));
    return readArray((uint16_t*) p, nchars);
}

void
SCInput::getPtr(const uint64_t* p, void** ptr)
{
    // No endianness conversion is used for pointers, since they are not sent
    // across address spaces anyway.
    *ptr = reinterpret_cast<void*>(*p);
}

bool
SCInput::readPtr(void** p)
{
    uint64_t u;
    if (!readNativeEndian(&u))
        return false;
    *p = reinterpret_cast<void*>(NativeEndian::swapFromLittleEndian(u));
    return true;
}

SCOutput::SCOutput(JSContext* cx) : cx(cx), buf(cx) {}

bool
SCOutput::write(uint64_t u)
{
    return buf.append(NativeEndian::swapToLittleEndian(u));
}

bool
SCOutput::writePair(uint32_t tag, uint32_t data)
{
    /*
     * As it happens, the tag word appears after the data word in the output.
     * This is because exponents occupy the last 2 bytes of doubles on the
     * little-endian platforms we care most about.
     *
     * For example, TrueValue() is written using writePair(SCTAG_BOOLEAN, 1).
     * PairToUInt64 produces the number 0xFFFF000200000001.
     * That is written out as the bytes 01 00 00 00 02 00 FF FF.
     */
    return write(PairToUInt64(tag, data));
}

static inline double
ReinterpretPairAsDouble(uint32_t tag, uint32_t data)
{
    return BitwiseCast<double>(PairToUInt64(tag, data));
}

bool
SCOutput::writeDouble(double d)
{
    return write(BitwiseCast<uint64_t>(CanonicalizeNaN(d)));
}

template <typename T>
static void
copyAndSwapToLittleEndian(void* dest, const T* src, size_t nelems)
{
    if (nelems > 0)
        NativeEndian::copyAndSwapToLittleEndian(dest, src, nelems);
}

template <>
void
copyAndSwapToLittleEndian(void* dest, const uint8_t* src, size_t nelems)
{
    memcpy(dest, src, nelems);
}

template <class T>
bool
SCOutput::writeArray(const T* p, size_t nelems)
{
    MOZ_ASSERT(8 % sizeof(T) == 0);
    MOZ_ASSERT(sizeof(uint64_t) % sizeof(T) == 0);

    if (nelems == 0)
        return true;

    if (nelems + sizeof(uint64_t) / sizeof(T) - 1 < nelems) {
        ReportAllocationOverflow(context());
        return false;
    }
    size_t nwords = JS_HOWMANY(nelems, sizeof(uint64_t) / sizeof(T));
    size_t start = buf.length();
    if (!buf.growByUninitialized(nwords))
        return false;

    buf.back() = 0;  /* zero-pad to an 8-byte boundary */

    T* q = (T*) &buf[start];
    copyAndSwapToLittleEndian(q, p, nelems);
    return true;
}

bool
SCOutput::writeBytes(const void* p, size_t nbytes)
{
    return writeArray((const uint8_t*) p, nbytes);
}

bool
SCOutput::writeChars(const char16_t* p, size_t nchars)
{
    static_assert(sizeof(char16_t) == sizeof(uint16_t),
                  "required so that treating char16_t[] memory as uint16_t[] "
                  "memory is permissible");
    return writeArray((const uint16_t*) p, nchars);
}

bool
SCOutput::writeChars(const Latin1Char* p, size_t nchars)
{
    static_assert(sizeof(Latin1Char) == sizeof(uint8_t), "Latin1Char must fit in 1 byte");
    return writeBytes(p, nchars);
}

bool
SCOutput::writePtr(const void* p)
{
    return write(reinterpret_cast<uint64_t>(p));
}

bool
SCOutput::extractBuffer(uint64_t** datap, size_t* sizep)
{
    *sizep = buf.length() * sizeof(uint64_t);
    return (*datap = buf.extractRawBuffer()) != nullptr;
}

} /* namespace js */

JS_STATIC_ASSERT(JSString::MAX_LENGTH < UINT32_MAX);

JSStructuredCloneWriter::~JSStructuredCloneWriter()
{
    // Free any transferable data left lying around in the buffer
    uint64_t* data;
    size_t size;
    {
        AutoEnterOOMUnsafeRegion oomUnsafe;
        if (!extractBuffer(&data, &size))
            oomUnsafe.crash("Unable to extract clone buffer");
        DiscardTransferables(data, size, callbacks, closure);
        js_free(data);
    }
}

bool
JSStructuredCloneWriter::parseTransferable()
{
    MOZ_ASSERT(transferableObjects.empty(), "parseTransferable called with stale data");

    if (transferable.isNull() || transferable.isUndefined())
        return true;

    if (!transferable.isObject())
        return reportErrorTransferable(JS_SCERR_TRANSFERABLE);

    JSContext* cx = context();
    RootedObject array(cx, &transferable.toObject());
    bool isArray;
    if (!JS_IsArrayObject(cx, array, &isArray))
        return false;
    if (!isArray)
        return reportErrorTransferable(JS_SCERR_TRANSFERABLE);

    uint32_t length;
    if (!JS_GetArrayLength(cx, array, &length)) {
        return false;
    }

    RootedValue v(context());

    for (uint32_t i = 0; i < length; ++i) {
        if (!JS_GetElement(cx, array, i, &v))
            return false;

        if (!v.isObject())
            return reportErrorTransferable(JS_SCERR_TRANSFERABLE);
        RootedObject tObj(context(), &v.toObject());

        // No duplicates allowed
        if (std::find(transferableObjects.begin(), transferableObjects.end(), tObj) != transferableObjects.end()) {
            return reportErrorTransferable(JS_SCERR_DUP_TRANSFERABLE);
        }

        if (!transferableObjects.append(tObj))
            return false;
    }

    return true;
}

bool
JSStructuredCloneWriter::reportErrorTransferable(uint32_t errorId)
{
    ReportErrorTransferable(context(), callbacks, errorId);
    return false;
}

bool
JSStructuredCloneWriter::writeString(uint32_t tag, JSString* str)
{
    JSLinearString* linear = str->ensureLinear(context());
    if (!linear)
        return false;

    static_assert(JSString::MAX_LENGTH <= INT32_MAX, "String length must fit in 31 bits");

    uint32_t length = linear->length();
    uint32_t lengthAndEncoding = length | (uint32_t(linear->hasLatin1Chars()) << 31);
    if (!out.writePair(tag, lengthAndEncoding))
        return false;

    JS::AutoCheckCannotGC nogc;
    return linear->hasLatin1Chars()
           ? out.writeChars(linear->latin1Chars(nogc), length)
           : out.writeChars(linear->twoByteChars(nogc), length);
}

inline void
JSStructuredCloneWriter::checkStack()
{
#ifdef DEBUG
    /* To avoid making serialization O(n^2), limit stack-checking at 10. */
    const size_t MAX = 10;

    size_t limit = Min(counts.length(), MAX);
    MOZ_ASSERT(objs.length() == counts.length());
    size_t total = 0;
    for (size_t i = 0; i < limit; i++) {
        MOZ_ASSERT(total + counts[i] >= total);
        total += counts[i];
    }
    if (counts.length() <= MAX)
        MOZ_ASSERT(total == entries.length());
    else
        MOZ_ASSERT(total <= entries.length());

    size_t j = objs.length();
    for (size_t i = 0; i < limit; i++)
        MOZ_ASSERT(memory.has(&objs[--j].toObject()));
#endif
}

/*
 * Write out a typed array. Note that post-v1 structured clone buffers do not
 * perform endianness conversion on stored data, so multibyte typed arrays
 * cannot be deserialized into a different endianness machine. Endianness
 * conversion would prevent sharing ArrayBuffers: if you have Int8Array and
 * Int16Array views of the same ArrayBuffer, should the data bytes be
 * byte-swapped when writing or not? The Int8Array requires them to not be
 * swapped; the Int16Array requires that they are.
 */
bool
JSStructuredCloneWriter::writeTypedArray(HandleObject obj)
{
    Rooted<TypedArrayObject*> tarr(context(), &CheckedUnwrap(obj)->as<TypedArrayObject>());
    JSAutoCompartment ac(context(), tarr);

    if (!TypedArrayObject::ensureHasBuffer(context(), tarr))
        return false;

    if (!out.writePair(SCTAG_TYPED_ARRAY_OBJECT, tarr->length()))
        return false;
    uint64_t type = tarr->type();
    if (!out.write(type))
        return false;

    // Write out the ArrayBuffer tag and contents
    RootedValue val(context(), TypedArrayObject::bufferValue(tarr));
    if (!startWrite(val))
        return false;

    return out.write(tarr->byteOffset());
}

bool
JSStructuredCloneWriter::writeDataView(HandleObject obj)
{
    Rooted<DataViewObject*> view(context(), &CheckedUnwrap(obj)->as<DataViewObject>());
    JSAutoCompartment ac(context(), view);

    if (!out.writePair(SCTAG_DATA_VIEW_OBJECT, view->byteLength()))
        return false;

    // Write out the ArrayBuffer tag and contents
    RootedValue val(context(), DataViewObject::bufferValue(view));
    if (!startWrite(val))
        return false;

    return out.write(view->byteOffset());
}

bool
JSStructuredCloneWriter::writeArrayBuffer(HandleObject obj)
{
    ArrayBufferObject& buffer = CheckedUnwrap(obj)->as<ArrayBufferObject>();
    JSAutoCompartment ac(context(), &buffer);

    return out.writePair(SCTAG_ARRAY_BUFFER_OBJECT, buffer.byteLength()) &&
           out.writeBytes(buffer.dataPointer(), buffer.byteLength());
}

bool
JSStructuredCloneWriter::writeSharedArrayBuffer(HandleObject obj)
{
    JS_ReportErrorNumber(context(), GetErrorMessage, nullptr, JSMSG_SC_SHMEM_MUST_TRANSFER);
    return false;
}

bool
JSStructuredCloneWriter::startObject(HandleObject obj, bool* backref)
{
    /* Handle cycles in the object graph. */
    CloneMemory::AddPtr p = memory.lookupForAdd(obj);
    if ((*backref = p.found()))
        return out.writePair(SCTAG_BACK_REFERENCE_OBJECT, p->value());
    if (!memory.add(p, obj, memory.count()))
        return false;

    if (memory.count() == UINT32_MAX) {
        JS_ReportErrorNumber(context(), GetErrorMessage, nullptr,
                             JSMSG_NEED_DIET, "object graph to serialize");
        return false;
    }

    return true;
}

bool
JSStructuredCloneWriter::traverseObject(HandleObject obj)
{
    /*
     * Get enumerable property ids and put them in reverse order so that they
     * will come off the stack in forward order.
     */
    AutoIdVector properties(context());
    if (!GetPropertyKeys(context(), obj, JSITER_OWNONLY, &properties))
        return false;

    for (size_t i = properties.length(); i > 0; --i) {
        MOZ_ASSERT(JSID_IS_STRING(properties[i - 1]) || JSID_IS_INT(properties[i - 1]));
        RootedValue val(context(), IdToValue(properties[i - 1]));
        if (!entries.append(val))
            return false;
    }

    /* Push obj and count to the stack. */
    if (!objs.append(ObjectValue(*obj)) || !counts.append(properties.length()))
        return false;

    checkStack();

    /* Write the header for obj. */
    ESClassValue cls;
    if (!GetBuiltinClass(context(), obj, &cls))
        return false;
    return out.writePair(cls == ESClass_Array ? SCTAG_ARRAY_OBJECT : SCTAG_OBJECT_OBJECT, 0);
}

bool
JSStructuredCloneWriter::traverseMap(HandleObject obj)
{
    AutoValueVector newEntries(context());
    {
        // If there is no wrapper, the compartment munging is a no-op.
        RootedObject unwrapped(context(), CheckedUnwrap(obj));
        MOZ_ASSERT(unwrapped);
        JSAutoCompartment ac(context(), unwrapped);
        if (!MapObject::getKeysAndValuesInterleaved(context(), unwrapped, &newEntries))
            return false;
    }
    if (!context()->compartment()->wrap(context(), newEntries))
        return false;

    for (size_t i = newEntries.length(); i > 0; --i) {
        if (!entries.append(newEntries[i - 1]))
            return false;
    }

    /* Push obj and count to the stack. */
    if (!objs.append(ObjectValue(*obj)) || !counts.append(newEntries.length()))
        return false;

    checkStack();

    /* Write the header for obj. */
    return out.writePair(SCTAG_MAP_OBJECT, 0);
}

bool
JSStructuredCloneWriter::traverseSet(HandleObject obj)
{
    AutoValueVector keys(context());
    {
        // If there is no wrapper, the compartment munging is a no-op.
        RootedObject unwrapped(context(), CheckedUnwrap(obj));
        MOZ_ASSERT(unwrapped);
        JSAutoCompartment ac(context(), unwrapped);
        if (!SetObject::keys(context(), unwrapped, &keys))
            return false;
    }
    if (!context()->compartment()->wrap(context(), keys))
        return false;

    for (size_t i = keys.length(); i > 0; --i) {
        if (!entries.append(keys[i - 1]))
            return false;
    }

    /* Push obj and count to the stack. */
    if (!objs.append(ObjectValue(*obj)) || !counts.append(keys.length()))
        return false;

    checkStack();

    /* Write the header for obj. */
    return out.writePair(SCTAG_SET_OBJECT, 0);
}

// Objects are written as a "preorder" traversal of the object graph: object
// "headers" (the class tag and any data needed for initial construction) are
// visited first, then the children are recursed through (where children are
// properties, Set or Map entries, etc.). So for example
//
//     m = new Map();
//     m.set(key1 = {}, value1 = {})
//
// would be stored as
//
//     <Map tag>
//     <key1 class tag>
//     <value1 class tag>
//     <end-of-children marker for key1>
//     <end-of-children marker for value1>
//     <end-of-children marker for Map>
//
// Notice how the end-of-children marker for key1 is sandwiched between the
// value1 beginning and end.
bool
JSStructuredCloneWriter::traverseSavedFrame(HandleObject obj)
{
    RootedObject unwrapped(context(), js::CheckedUnwrap(obj));
    MOZ_ASSERT(unwrapped && unwrapped->is<SavedFrame>());

    RootedSavedFrame savedFrame(context(), &unwrapped->as<SavedFrame>());

    RootedObject parent(context(), savedFrame->getParent());
    if (!context()->compartment()->wrap(context(), &parent))
        return false;

    if (!objs.append(ObjectValue(*obj)) ||
        !entries.append(parent ? ObjectValue(*parent) : NullValue()) ||
        !counts.append(1))
    {
        return false;
    }

    checkStack();

    // Write the SavedFrame tag and the SavedFrame's principals.

    if (savedFrame->getPrincipals() == &ReconstructedSavedFramePrincipals::IsSystem) {
        if (!out.writePair(SCTAG_SAVED_FRAME_OBJECT,
                           SCTAG_RECONSTRUCTED_SAVED_FRAME_PRINCIPALS_IS_SYSTEM))
        {
            return false;
        };
    } else if (savedFrame->getPrincipals() == &ReconstructedSavedFramePrincipals::IsNotSystem) {
        if (!out.writePair(SCTAG_SAVED_FRAME_OBJECT,
                           SCTAG_RECONSTRUCTED_SAVED_FRAME_PRINCIPALS_IS_NOT_SYSTEM))
        {
            return false;
        }
    } else {
        if (auto principals = savedFrame->getPrincipals()) {
            if (!out.writePair(SCTAG_SAVED_FRAME_OBJECT, SCTAG_JSPRINCIPALS) ||
                !principals->write(context(), this))
            {
                return false;
            }
        } else {
            if (!out.writePair(SCTAG_SAVED_FRAME_OBJECT, SCTAG_NULL_JSPRINCIPALS))
                return false;
        }
    }

    // Write the SavedFrame's reserved slots, except for the parent, which is
    // queued on objs for further traversal.

    RootedValue val(context());

    val = StringValue(savedFrame->getSource());
    if (!startWrite(val))
        return false;

    val = NumberValue(savedFrame->getLine());
    if (!startWrite(val))
        return false;

    val = NumberValue(savedFrame->getColumn());
    if (!startWrite(val))
        return false;

    auto name = savedFrame->getFunctionDisplayName();
    val = name ? StringValue(name) : NullValue();
    if (!startWrite(val))
        return false;

    auto cause = savedFrame->getAsyncCause();
    val = cause ? StringValue(cause) : NullValue();
    if (!startWrite(val))
        return false;

    return true;
}

bool
JSStructuredCloneWriter::startWrite(HandleValue v)
{
    assertSameCompartment(context(), v);

    if (v.isString()) {
        return writeString(SCTAG_STRING, v.toString());
    } else if (v.isInt32()) {
        return out.writePair(SCTAG_INT32, v.toInt32());
    } else if (v.isDouble()) {
        return out.writeDouble(v.toDouble());
    } else if (v.isBoolean()) {
        return out.writePair(SCTAG_BOOLEAN, v.toBoolean());
    } else if (v.isNull()) {
        return out.writePair(SCTAG_NULL, 0);
    } else if (v.isUndefined()) {
        return out.writePair(SCTAG_UNDEFINED, 0);
    } else if (v.isObject()) {
        RootedObject obj(context(), &v.toObject());

        bool backref;
        if (!startObject(obj, &backref))
            return false;
        if (backref)
            return true;

        ESClassValue cls;
        if (!GetBuiltinClass(context(), obj, &cls))
            return false;

        if (cls == ESClass_RegExp) {
            RegExpGuard re(context());
            if (!RegExpToShared(context(), obj, &re))
                return false;
            return out.writePair(SCTAG_REGEXP_OBJECT, re->getFlags()) &&
                   writeString(SCTAG_STRING, re->getSource());
        } else if (cls == ESClass_Date) {
            RootedValue unboxed(context());
            if (!Unbox(context(), obj, &unboxed))
                return false;
            return out.writePair(SCTAG_DATE_OBJECT, 0) && out.writeDouble(unboxed.toNumber());
        } else if (JS_IsTypedArrayObject(obj)) {
            return writeTypedArray(obj);
        } else if (JS_IsDataViewObject(obj)) {
            return writeDataView(obj);
        } else if (JS_IsArrayBufferObject(obj) && JS_ArrayBufferHasData(obj)) {
            return writeArrayBuffer(obj);
        } else if (JS_IsSharedArrayBufferObject(obj)) {
            return writeSharedArrayBuffer(obj);
        } else if (cls == ESClass_Object) {
            return traverseObject(obj);
        } else if (cls == ESClass_Array) {
            return traverseObject(obj);
        } else if (cls == ESClass_Boolean) {
            RootedValue unboxed(context());
            if (!Unbox(context(), obj, &unboxed))
                return false;
            return out.writePair(SCTAG_BOOLEAN_OBJECT, unboxed.toBoolean());
        } else if (cls == ESClass_Number) {
            RootedValue unboxed(context());
            if (!Unbox(context(), obj, &unboxed))
                return false;
            return out.writePair(SCTAG_NUMBER_OBJECT, 0) && out.writeDouble(unboxed.toNumber());
        } else if (cls == ESClass_String) {
            RootedValue unboxed(context());
            if (!Unbox(context(), obj, &unboxed))
                return false;
            return writeString(SCTAG_STRING_OBJECT, unboxed.toString());
        } else if (cls == ESClass_Map) {
            return traverseMap(obj);
        } else if (cls == ESClass_Set) {
            return traverseSet(obj);
        } else if (SavedFrame::isSavedFrameOrWrapperAndNotProto(*obj)) {
            return traverseSavedFrame(obj);
        }

        if (callbacks && callbacks->write)
            return callbacks->write(context(), this, obj, closure);
        /* else fall through */
    }

    JS_ReportErrorNumber(context(), GetErrorMessage, nullptr, JSMSG_SC_UNSUPPORTED_TYPE);
    return false;
}

bool
JSStructuredCloneWriter::writeTransferMap()
{
    if (transferableObjects.empty())
        return true;

    if (!out.writePair(SCTAG_TRANSFER_MAP_HEADER, (uint32_t)SCTAG_TM_UNREAD))
        return false;

    if (!out.write(transferableObjects.length()))
        return false;

    for (JS::AutoObjectVector::Range tr = transferableObjects.all(); !tr.empty(); tr.popFront()) {
        JSObject* obj = tr.front();

        if (!memory.put(obj, memory.count()))
            return false;

        // Emit a placeholder pointer. We will steal the data and neuter the
        // transferable later, in the case of ArrayBufferObject.
        if (!out.writePair(SCTAG_TRANSFER_MAP_PENDING_ENTRY, JS::SCTAG_TMO_UNFILLED))
            return false;
        if (!out.writePtr(nullptr)) // Pointer to ArrayBuffer contents or to SharedArrayRawBuffer.
            return false;
        if (!out.write(0)) // extraData
            return false;
    }

    return true;
}

bool
JSStructuredCloneWriter::transferOwnership()
{
    if (transferableObjects.empty())
        return true;

    // Walk along the transferables and the transfer map at the same time,
    // grabbing out pointers from the transferables and stuffing them into the
    // transfer map.
    uint64_t* point = out.rawBuffer();
    MOZ_ASSERT(uint32_t(LittleEndian::readUint64(point) >> 32) == SCTAG_TRANSFER_MAP_HEADER);
    point++;
    MOZ_ASSERT(LittleEndian::readUint64(point) == transferableObjects.length());
    point++;

    for (JS::AutoObjectVector::Range tr = transferableObjects.all(); !tr.empty(); tr.popFront()) {
        RootedObject obj(context(), tr.front());

        uint32_t tag;
        JS::TransferableOwnership ownership;
        void* content;
        uint64_t extraData;

#if DEBUG
        SCInput::getPair(point, &tag, (uint32_t*) &ownership);
        MOZ_ASSERT(tag == SCTAG_TRANSFER_MAP_PENDING_ENTRY);
        MOZ_ASSERT(ownership == JS::SCTAG_TMO_UNFILLED);
#endif

        ESClassValue cls;
        if (!GetBuiltinClass(context(), obj, &cls))
            return false;

        if (cls == ESClass_ArrayBuffer) {
            // The current setup of the array buffer inheritance hierarchy doesn't
            // lend itself well to generic manipulation via proxies.
            Rooted<ArrayBufferObject*> arrayBuffer(context(), &CheckedUnwrap(obj)->as<ArrayBufferObject>());
            size_t nbytes = arrayBuffer->byteLength();

            // Structured cloning currently only has optimizations for mapped
            // and malloc'd buffers, not asm.js-ified buffers.
            bool hasStealableContents = arrayBuffer->hasStealableContents() &&
                                        (arrayBuffer->isMapped() || arrayBuffer->hasMallocedContents());

            ArrayBufferObject::BufferContents bufContents =
                ArrayBufferObject::stealContents(context(), arrayBuffer, hasStealableContents);
            if (!bufContents)
                return false; // Destructor will clean up the already-transferred data.

            content = bufContents.data();
            tag = SCTAG_TRANSFER_MAP_ARRAY_BUFFER;
            if (bufContents.kind() == ArrayBufferObject::MAPPED)
                ownership = JS::SCTAG_TMO_MAPPED_DATA;
            else
                ownership = JS::SCTAG_TMO_ALLOC_DATA;
            extraData = nbytes;
        } else if (cls == ESClass_SharedArrayBuffer) {
            Rooted<SharedArrayBufferObject*> sharedArrayBuffer(context(), &CheckedUnwrap(obj)->as<SharedArrayBufferObject>());
            SharedArrayRawBuffer* rawbuf = sharedArrayBuffer->rawBufferObject();

            // Avoids a race condition where the parent thread frees the buffer
            // before the child has accepted the transferable.
            rawbuf->addReference();

            tag = SCTAG_TRANSFER_MAP_SHARED_BUFFER;
            ownership = JS::SCTAG_TMO_SHARED_BUFFER;
            content = rawbuf;
            extraData = 0;
        } else {
            if (!callbacks || !callbacks->writeTransfer)
                return reportErrorTransferable(JS_SCERR_TRANSFERABLE);
            if (!callbacks->writeTransfer(context(), obj, closure, &tag, &ownership, &content, &extraData))
                return false;
            MOZ_ASSERT(tag > SCTAG_TRANSFER_MAP_PENDING_ENTRY);
        }

        LittleEndian::writeUint64(point++, PairToUInt64(tag, ownership));
        LittleEndian::writeUint64(point++, reinterpret_cast<uint64_t>(content));
        LittleEndian::writeUint64(point++, extraData);
    }

    MOZ_ASSERT(point <= out.rawBuffer() + out.count());
    MOZ_ASSERT_IF(point < out.rawBuffer() + out.count(),
                  uint32_t(LittleEndian::readUint64(point) >> 32) < SCTAG_TRANSFER_MAP_HEADER);

    return true;
}

bool
JSStructuredCloneWriter::write(HandleValue v)
{
    if (!startWrite(v))
        return false;

    while (!counts.empty()) {
        RootedObject obj(context(), &objs.back().toObject());
        AutoCompartment ac(context(), obj);
        if (counts.back()) {
            counts.back()--;
            RootedValue key(context(), entries.back());
            entries.popBack();
            checkStack();

            ESClassValue cls;
            if (!GetBuiltinClass(context(), obj, &cls))
                return false;

            if (cls == ESClass_Map) {
                counts.back()--;
                RootedValue val(context(), entries.back());
                entries.popBack();
                checkStack();

                if (!startWrite(key) || !startWrite(val))
                    return false;
            } else if (cls == ESClass_Set || SavedFrame::isSavedFrameOrWrapperAndNotProto(*obj)) {
                if (!startWrite(key))
                    return false;
            } else {
                RootedId id(context());
                if (!ValueToId<CanGC>(context(), key, &id))
                  return false;
                MOZ_ASSERT(JSID_IS_STRING(id) || JSID_IS_INT(id));

                /*
                 * If obj still has an own property named id, write it out.
                 * The cost of re-checking could be avoided by using
                 * NativeIterators.
                 */
                bool found;
                if (!HasOwnProperty(context(), obj, id, &found))
                    return false;

                if (found) {
                    RootedValue val(context());
                    if (!startWrite(key) ||
                        !GetProperty(context(), obj, obj, id, &val) ||
                        !startWrite(val))
                    {
                        return false;
                    }
                }
            }
        } else {
            out.writePair(SCTAG_END_OF_KEYS, 0);
            objs.popBack();
            counts.popBack();
        }
    }

    memory.clear();
    return transferOwnership();
}

bool
JSStructuredCloneReader::checkDouble(double d)
{
    jsval_layout l;
    l.asDouble = d;
    if (!JSVAL_IS_DOUBLE_IMPL(l)) {
        JS_ReportErrorNumber(context(), GetErrorMessage, nullptr,
                             JSMSG_SC_BAD_SERIALIZED_DATA, "unrecognized NaN");
        return false;
    }
    return true;
}

namespace {

template <typename CharT>
class Chars {
    JSContext* cx;
    CharT* p;
  public:
    explicit Chars(JSContext* cx) : cx(cx), p(nullptr) {}
    ~Chars() { js_free(p); }

    bool allocate(size_t len) {
        MOZ_ASSERT(!p);
        // We're going to null-terminate!
        p = cx->pod_malloc<CharT>(len + 1);
        if (p) {
            p[len] = CharT(0);
            return true;
        }
        return false;
    }
    CharT* get() { return p; }
    void forget() { p = nullptr; }
};

} /* anonymous namespace */

template <typename CharT>
JSString*
JSStructuredCloneReader::readStringImpl(uint32_t nchars)
{
    if (nchars > JSString::MAX_LENGTH) {
        JS_ReportErrorNumber(context(), GetErrorMessage, nullptr,
                             JSMSG_SC_BAD_SERIALIZED_DATA, "string length");
        return nullptr;
    }
    Chars<CharT> chars(context());
    if (!chars.allocate(nchars) || !in.readChars(chars.get(), nchars))
        return nullptr;
    JSString* str = NewString<CanGC>(context(), chars.get(), nchars);
    if (str)
        chars.forget();
    return str;
}

JSString*
JSStructuredCloneReader::readString(uint32_t data)
{
    uint32_t nchars = data & JS_BITMASK(31);
    bool latin1 = data & (1 << 31);
    return latin1 ? readStringImpl<Latin1Char>(nchars) : readStringImpl<char16_t>(nchars);
}

static uint32_t
TagToV1ArrayType(uint32_t tag)
{
    MOZ_ASSERT(tag >= SCTAG_TYPED_ARRAY_V1_MIN && tag <= SCTAG_TYPED_ARRAY_V1_MAX);
    return tag - SCTAG_TYPED_ARRAY_V1_MIN;
}

bool
JSStructuredCloneReader::readTypedArray(uint32_t arrayType, uint32_t nelems, MutableHandleValue vp,
                                        bool v1Read)
{
    if (arrayType > Scalar::Uint8Clamped) {
        JS_ReportErrorNumber(context(), GetErrorMessage, nullptr,
                             JSMSG_SC_BAD_SERIALIZED_DATA, "unhandled typed array element type");
        return false;
    }

    // Push a placeholder onto the allObjs list to stand in for the typed array
    uint32_t placeholderIndex = allObjs.length();
    Value dummy = UndefinedValue();
    if (!allObjs.append(dummy))
        return false;

    // Read the ArrayBuffer object and its contents (but no properties)
    RootedValue v(context());
    uint32_t byteOffset;
    if (v1Read) {
        if (!readV1ArrayBuffer(arrayType, nelems, &v))
            return false;
        byteOffset = 0;
    } else {
        if (!startRead(&v))
            return false;
        uint64_t n;
        if (!in.read(&n))
            return false;
        byteOffset = n;
    }
    RootedObject buffer(context(), &v.toObject());
    RootedObject obj(context(), nullptr);

    switch (arrayType) {
      case Scalar::Int8:
        obj = JS_NewInt8ArrayWithBuffer(context(), buffer, byteOffset, nelems);
        break;
      case Scalar::Uint8:
        obj = JS_NewUint8ArrayWithBuffer(context(), buffer, byteOffset, nelems);
        break;
      case Scalar::Int16:
        obj = JS_NewInt16ArrayWithBuffer(context(), buffer, byteOffset, nelems);
        break;
      case Scalar::Uint16:
        obj = JS_NewUint16ArrayWithBuffer(context(), buffer, byteOffset, nelems);
        break;
      case Scalar::Int32:
        obj = JS_NewInt32ArrayWithBuffer(context(), buffer, byteOffset, nelems);
        break;
      case Scalar::Uint32:
        obj = JS_NewUint32ArrayWithBuffer(context(), buffer, byteOffset, nelems);
        break;
      case Scalar::Float32:
        obj = JS_NewFloat32ArrayWithBuffer(context(), buffer, byteOffset, nelems);
        break;
      case Scalar::Float64:
        obj = JS_NewFloat64ArrayWithBuffer(context(), buffer, byteOffset, nelems);
        break;
      case Scalar::Uint8Clamped:
        obj = JS_NewUint8ClampedArrayWithBuffer(context(), buffer, byteOffset, nelems);
        break;
      default:
        MOZ_CRASH("Can't happen: arrayType range checked above");
    }

    if (!obj)
        return false;
    vp.setObject(*obj);

    allObjs[placeholderIndex].set(vp);

    return true;
}

bool
JSStructuredCloneReader::readDataView(uint32_t byteLength, MutableHandleValue vp)
{
    // Push a placeholder onto the allObjs list to stand in for the DataView.
    uint32_t placeholderIndex = allObjs.length();
    Value dummy = UndefinedValue();
    if (!allObjs.append(dummy))
        return false;

    // Read the ArrayBuffer object and its contents (but no properties).
    RootedValue v(context());
    if (!startRead(&v))
        return false;

    // Read byteOffset.
    uint64_t n;
    if (!in.read(&n))
        return false;
    uint32_t byteOffset = n;

    RootedObject buffer(context(), &v.toObject());
    RootedObject obj(context(), JS_NewDataView(context(), buffer, byteOffset, byteLength));
    if (!obj)
        return false;
    vp.setObject(*obj);

    allObjs[placeholderIndex].set(vp);

    return true;
}

bool
JSStructuredCloneReader::readArrayBuffer(uint32_t nbytes, MutableHandleValue vp)
{
    JSObject* obj = ArrayBufferObject::create(context(), nbytes);
    if (!obj)
        return false;
    vp.setObject(*obj);
    ArrayBufferObject& buffer = obj->as<ArrayBufferObject>();
    MOZ_ASSERT(buffer.byteLength() == nbytes);
    return in.readArray(buffer.dataPointer(), nbytes);
}

/*
 * Read in the data for a structured clone version 1 ArrayBuffer, performing
 * endianness-conversion while reading.
 */
bool
JSStructuredCloneReader::readV1ArrayBuffer(uint32_t arrayType, uint32_t nelems,
                                           MutableHandleValue vp)
{
    MOZ_ASSERT(arrayType <= Scalar::Uint8Clamped);

    uint32_t nbytes = nelems << TypedArrayShift(static_cast<Scalar::Type>(arrayType));
    JSObject* obj = ArrayBufferObject::create(context(), nbytes);
    if (!obj)
        return false;
    vp.setObject(*obj);
    ArrayBufferObject& buffer = obj->as<ArrayBufferObject>();
    MOZ_ASSERT(buffer.byteLength() == nbytes);

    switch (arrayType) {
      case Scalar::Int8:
      case Scalar::Uint8:
      case Scalar::Uint8Clamped:
        return in.readArray((uint8_t*) buffer.dataPointer(), nelems);
      case Scalar::Int16:
      case Scalar::Uint16:
        return in.readArray((uint16_t*) buffer.dataPointer(), nelems);
      case Scalar::Int32:
      case Scalar::Uint32:
      case Scalar::Float32:
        return in.readArray((uint32_t*) buffer.dataPointer(), nelems);
      case Scalar::Float64:
        return in.readArray((uint64_t*) buffer.dataPointer(), nelems);
      default:
        MOZ_CRASH("Can't happen: arrayType range checked by caller");
    }
}

static bool
PrimitiveToObject(JSContext* cx, MutableHandleValue vp)
{
    JSObject* obj = js::PrimitiveToObject(cx, vp);
    if (!obj)
        return false;

    vp.setObject(*obj);
    return true;
}

bool
JSStructuredCloneReader::startRead(MutableHandleValue vp)
{
    uint32_t tag, data;

    if (!in.readPair(&tag, &data))
        return false;

    switch (tag) {
      case SCTAG_NULL:
        vp.setNull();
        break;

      case SCTAG_UNDEFINED:
        vp.setUndefined();
        break;

      case SCTAG_INT32:
        vp.setInt32(data);
        break;

      case SCTAG_BOOLEAN:
      case SCTAG_BOOLEAN_OBJECT:
        vp.setBoolean(!!data);
        if (tag == SCTAG_BOOLEAN_OBJECT && !PrimitiveToObject(context(), vp))
            return false;
        break;

      case SCTAG_STRING:
      case SCTAG_STRING_OBJECT: {
        JSString* str = readString(data);
        if (!str)
            return false;
        vp.setString(str);
        if (tag == SCTAG_STRING_OBJECT && !PrimitiveToObject(context(), vp))
            return false;
        break;
      }

      case SCTAG_NUMBER_OBJECT: {
        double d;
        if (!in.readDouble(&d) || !checkDouble(d))
            return false;
        vp.setDouble(d);
        if (!PrimitiveToObject(context(), vp))
            return false;
        break;
      }

      case SCTAG_DATE_OBJECT: {
        double d;
        if (!in.readDouble(&d) || !checkDouble(d))
            return false;
        JS::ClippedTime t = JS::TimeClip(d);
        if (!NumbersAreIdentical(d, t.toDouble())) {
            JS_ReportErrorNumber(context(), GetErrorMessage, nullptr,
                                 JSMSG_SC_BAD_SERIALIZED_DATA, "date");
            return false;
        }
        JSObject* obj = NewDateObjectMsec(context(), t);
        if (!obj)
            return false;
        vp.setObject(*obj);
        break;
      }

      case SCTAG_REGEXP_OBJECT: {
        RegExpFlag flags = RegExpFlag(data);
        uint32_t tag2, stringData;
        if (!in.readPair(&tag2, &stringData))
            return false;
        if (tag2 != SCTAG_STRING) {
            JS_ReportErrorNumber(context(), GetErrorMessage, nullptr,
                                 JSMSG_SC_BAD_SERIALIZED_DATA, "regexp");
            return false;
        }
        JSString* str = readString(stringData);
        if (!str)
            return false;

        RootedAtom atom(context(), AtomizeString(context(), str));
        if (!atom)
            return false;

        RegExpObject* reobj = RegExpObject::createNoStatics(context(), atom, flags, nullptr,
                                                            context()->tempLifoAlloc());
        if (!reobj)
            return false;
        vp.setObject(*reobj);
        break;
      }

      case SCTAG_ARRAY_OBJECT:
      case SCTAG_OBJECT_OBJECT: {
        JSObject* obj = (tag == SCTAG_ARRAY_OBJECT)
                        ? (JSObject*) NewDenseEmptyArray(context())
                        : (JSObject*) NewBuiltinClassInstance<PlainObject>(context());
        if (!obj || !objs.append(ObjectValue(*obj)))
            return false;
        vp.setObject(*obj);
        break;
      }

      case SCTAG_BACK_REFERENCE_OBJECT: {
        if (data >= allObjs.length()) {
            JS_ReportErrorNumber(context(), GetErrorMessage, nullptr,
                                 JSMSG_SC_BAD_SERIALIZED_DATA,
                                 "invalid back reference in input");
            return false;
        }
        vp.set(allObjs[data]);
        return true;
      }

      case SCTAG_TRANSFER_MAP_HEADER:
      case SCTAG_TRANSFER_MAP_PENDING_ENTRY:
        // We should be past all the transfer map tags.
        JS_ReportErrorNumber(context(), GetErrorMessage, NULL,
                             JSMSG_SC_BAD_SERIALIZED_DATA,
                             "invalid input");
        return false;

      case SCTAG_ARRAY_BUFFER_OBJECT:
        if (!readArrayBuffer(data, vp))
            return false;
        break;

      case SCTAG_TYPED_ARRAY_OBJECT: {
        // readTypedArray adds the array to allObjs.
        uint64_t arrayType;
        if (!in.read(&arrayType))
            return false;
        return readTypedArray(arrayType, data, vp);
      }

      case SCTAG_DATA_VIEW_OBJECT: {
        // readDataView adds the array to allObjs.
        return readDataView(data, vp);
      }

      case SCTAG_MAP_OBJECT: {
        JSObject* obj = MapObject::create(context());
        if (!obj || !objs.append(ObjectValue(*obj)))
            return false;
        vp.setObject(*obj);
        break;
      }

      case SCTAG_SET_OBJECT: {
        JSObject* obj = SetObject::create(context());
        if (!obj || !objs.append(ObjectValue(*obj)))
            return false;
        vp.setObject(*obj);
        break;
      }

      case SCTAG_SAVED_FRAME_OBJECT: {
        auto obj = readSavedFrame(data);
        if (!obj || !objs.append(ObjectValue(*obj)))
            return false;
        vp.setObject(*obj);
        break;
      }

      default: {
        if (tag <= SCTAG_FLOAT_MAX) {
            double d = ReinterpretPairAsDouble(tag, data);
            if (!checkDouble(d))
                return false;
            vp.setNumber(d);
            break;
        }

        if (SCTAG_TYPED_ARRAY_V1_MIN <= tag && tag <= SCTAG_TYPED_ARRAY_V1_MAX) {
            // A v1-format typed array
            // readTypedArray adds the array to allObjs
            return readTypedArray(TagToV1ArrayType(tag), data, vp, true);
        }

        if (!callbacks || !callbacks->read) {
            JS_ReportErrorNumber(context(), GetErrorMessage, nullptr,
                                 JSMSG_SC_BAD_SERIALIZED_DATA, "unsupported type");
            return false;
        }
        JSObject* obj = callbacks->read(context(), this, tag, data, closure);
        if (!obj)
            return false;
        vp.setObject(*obj);
      }
    }

    if (vp.isObject() && !allObjs.append(vp))
        return false;

    return true;
}

bool
JSStructuredCloneReader::readTransferMap()
{
    JSContext* cx = context();
    uint64_t* headerPos = in.tell();

    uint32_t tag, data;
    if (!in.getPair(&tag, &data))
        return in.reportTruncated();

    if (tag != SCTAG_TRANSFER_MAP_HEADER || TransferableMapHeader(data) == SCTAG_TM_TRANSFERRED)
        return true;

    uint64_t numTransferables;
    MOZ_ALWAYS_TRUE(in.readPair(&tag, &data));
    if (!in.read(&numTransferables))
        return false;

    for (uint64_t i = 0; i < numTransferables; i++) {
        uint64_t* pos = in.tell();

        if (!in.readPair(&tag, &data))
            return false;

        MOZ_ASSERT(tag != SCTAG_TRANSFER_MAP_PENDING_ENTRY);
        RootedObject obj(cx);

        void* content;
        if (!in.readPtr(&content))
            return false;

        uint64_t extraData;
        if (!in.read(&extraData))
            return false;

        if (tag == SCTAG_TRANSFER_MAP_ARRAY_BUFFER) {
            size_t nbytes = extraData;
            MOZ_ASSERT(data == JS::SCTAG_TMO_ALLOC_DATA ||
                       data == JS::SCTAG_TMO_MAPPED_DATA);
            if (data == JS::SCTAG_TMO_ALLOC_DATA)
                obj = JS_NewArrayBufferWithContents(cx, nbytes, content);
            else if (data == JS::SCTAG_TMO_MAPPED_DATA)
                obj = JS_NewMappedArrayBufferWithContents(cx, nbytes, content);
        } else if (tag == SCTAG_TRANSFER_MAP_SHARED_BUFFER) {
            MOZ_ASSERT(data == JS::SCTAG_TMO_SHARED_BUFFER);
            obj = SharedArrayBufferObject::New(context(), (SharedArrayRawBuffer*)content);
        } else {
            if (!callbacks || !callbacks->readTransfer) {
                ReportErrorTransferable(cx, callbacks, JS_SCERR_TRANSFERABLE);
                return false;
            }
            if (!callbacks->readTransfer(cx, this, tag, content, extraData, closure, &obj))
                return false;
            MOZ_ASSERT(obj);
            MOZ_ASSERT(!cx->isExceptionPending());
        }

        // On failure, the buffer will still own the data (since its ownership
        // will not get set to SCTAG_TMO_UNOWNED), so the data will be freed by
        // DiscardTransferables.
        if (!obj)
            return false;

        // Mark the SCTAG_TRANSFER_MAP_* entry as no longer owned by the input
        // buffer.
        *pos = PairToUInt64(tag, JS::SCTAG_TMO_UNOWNED);
        MOZ_ASSERT(headerPos < pos && pos < in.end());

        if (!allObjs.append(ObjectValue(*obj)))
            return false;
    }

    // Mark the whole transfer map as consumed.
    MOZ_ASSERT(headerPos <= in.tell());
#ifdef DEBUG
    SCInput::getPair(headerPos, &tag, &data);
    MOZ_ASSERT(tag == SCTAG_TRANSFER_MAP_HEADER);
    MOZ_ASSERT(TransferableMapHeader(data) != SCTAG_TM_TRANSFERRED);
#endif
    *headerPos = PairToUInt64(SCTAG_TRANSFER_MAP_HEADER, SCTAG_TM_TRANSFERRED);

    return true;
}

JSObject*
JSStructuredCloneReader::readSavedFrame(uint32_t principalsTag)
{
    RootedSavedFrame savedFrame(context(), SavedFrame::create(context()));
    if (!savedFrame)
        return nullptr;

    JSPrincipals* principals;
    if (principalsTag == SCTAG_JSPRINCIPALS) {
        if (!context()->runtime()->readPrincipals) {
            JS_ReportErrorNumber(context(), GetErrorMessage, nullptr,
                                 JSMSG_SC_UNSUPPORTED_TYPE);
            return nullptr;
        }

        if (!context()->runtime()->readPrincipals(context(), this, &principals))
            return nullptr;
    } else if (principalsTag == SCTAG_RECONSTRUCTED_SAVED_FRAME_PRINCIPALS_IS_SYSTEM) {
        principals = &ReconstructedSavedFramePrincipals::IsSystem;
        principals->refcount++;
    } else if (principalsTag == SCTAG_RECONSTRUCTED_SAVED_FRAME_PRINCIPALS_IS_NOT_SYSTEM) {
        principals = &ReconstructedSavedFramePrincipals::IsNotSystem;
        principals->refcount++;
    } else if (principalsTag == SCTAG_NULL_JSPRINCIPALS) {
        principals = nullptr;
    } else {
        JS_ReportErrorNumber(context(), GetErrorMessage, nullptr,
                             JSMSG_SC_BAD_SERIALIZED_DATA, "bad SavedFrame principals");
        return nullptr;
    }
    savedFrame->initPrincipalsAlreadyHeld(principals);

    RootedValue source(context());
    if (!startRead(&source) || !source.isString())
        return nullptr;
    auto atomSource = AtomizeString(context(), source.toString());
    if (!atomSource)
        return nullptr;
    savedFrame->initSource(atomSource);

    RootedValue lineVal(context());
    uint32_t line;
    if (!startRead(&lineVal) || !lineVal.isNumber() || !ToUint32(context(), lineVal, &line))
        return nullptr;
    savedFrame->initLine(line);

    RootedValue columnVal(context());
    uint32_t column;
    if (!startRead(&columnVal) || !columnVal.isNumber() || !ToUint32(context(), columnVal, &column))
        return nullptr;
    savedFrame->initColumn(column);

    RootedValue name(context());
    if (!startRead(&name) || !(name.isString() || name.isNull()))
        return nullptr;
    JSAtom* atomName = nullptr;
    if (name.isString()) {
        atomName = AtomizeString(context(), name.toString());
        if (!atomName)
            return nullptr;
    }
    savedFrame->initFunctionDisplayName(atomName);

    RootedValue cause(context());
    if (!startRead(&cause) || !(cause.isString() || cause.isNull()))
        return nullptr;
    JSAtom* atomCause = nullptr;
    if (cause.isString()) {
        atomCause = AtomizeString(context(), cause.toString());
        if (!atomCause)
            return nullptr;
    }
    savedFrame->initAsyncCause(atomCause);

    return savedFrame;
}

// Perform the whole recursive reading procedure.
bool
JSStructuredCloneReader::read(MutableHandleValue vp)
{
    if (!readTransferMap())
        return false;

    // Start out by reading in the main object and pushing it onto the 'objs'
    // stack. The data related to this object and its descendants extends from
    // here to the SCTAG_END_OF_KEYS at the end of the stream.
    if (!startRead(vp))
        return false;

    // Stop when the stack shows that all objects have been read.
    while (objs.length() != 0) {
        // What happens depends on the top obj on the objs stack.
        RootedObject obj(context(), &objs.back().toObject());

        uint32_t tag, data;
        if (!in.getPair(&tag, &data))
            return false;

        if (tag == SCTAG_END_OF_KEYS) {
            // Pop the current obj off the stack, since we are done with it and
            // its children.
            MOZ_ALWAYS_TRUE(in.readPair(&tag, &data));
            objs.popBack();
            continue;
        }

        // The input stream contains a sequence of "child" values, whose
        // interpretation depends on the type of obj. These values can be
        // anything, and startRead() will push onto 'objs' for any non-leaf
        // value (i.e., anything that may contain children).
        //
        // startRead() will allocate the (empty) object, but note that when
        // startRead() returns, 'key' is not yet initialized with any of its
        // properties. Those will be filled in by returning to the head of this
        // loop, processing the first child obj, and continuing until all
        // children have been fully created.
        //
        // Note that this means the ordering in the stream is a little funky
        // for things like Map. See the comment above startWrite() for an
        // example.
        RootedValue key(context());
        if (!startRead(&key))
            return false;

        if (key.isNull() &&
            !(obj->is<MapObject>() || obj->is<SetObject>() || obj->is<SavedFrame>()))
        {
            // Backwards compatibility: Null formerly indicated the end of
            // object properties.
            objs.popBack();
            continue;
        }

        // Set object: the values between obj header (from startRead()) and
        // SCTAG_END_OF_KEYS are all interpreted as values to add to the set.
        if (obj->is<SetObject>()) {
            if (!SetObject::add(context(), obj, key))
                return false;
            continue;
        }

        // SavedFrame object: there is one following value, the parent
        // SavedFrame, which is either null or another SavedFrame object.
        if (obj->is<SavedFrame>()) {
            SavedFrame* parentFrame;
            if (key.isNull())
                parentFrame = nullptr;
            else if (key.isObject() && key.toObject().is<SavedFrame>())
                parentFrame = &key.toObject().as<SavedFrame>();
            else
                return false;

            obj->as<SavedFrame>().initParent(parentFrame);
            continue;
        }

        // Everything else uses a series of key,value,key,value,... Value
        // objects.
        RootedValue val(context());
        if (!startRead(&val))
            return false;

        if (obj->is<MapObject>()) {
            // For a Map, store those <key,value> pairs in the contained map
            // data structure.
            if (!MapObject::set(context(), obj, key, val))
                return false;
        } else {
            // For any other Object, interpret them as plain properties.
            RootedId id(context());
            if (!ValueToId<CanGC>(context(), key, &id))
                return false;

            if (!DefineProperty(context(), obj, id, val))
                return false;
         }
    }

    allObjs.clear();

    return true;
}

using namespace js;

JS_PUBLIC_API(bool)
JS_ReadStructuredClone(JSContext* cx, uint64_t* buf, size_t nbytes,
                       uint32_t version, MutableHandleValue vp,
                       const JSStructuredCloneCallbacks* optionalCallbacks,
                       void* closure)
{
    AssertHeapIsIdle(cx);
    CHECK_REQUEST(cx);

    if (version > JS_STRUCTURED_CLONE_VERSION) {
        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_SC_BAD_CLONE_VERSION);
        return false;
    }
    const JSStructuredCloneCallbacks* callbacks = optionalCallbacks;
    return ReadStructuredClone(cx, buf, nbytes, vp, callbacks, closure);
}

JS_PUBLIC_API(bool)
JS_WriteStructuredClone(JSContext* cx, HandleValue value, uint64_t** bufp, size_t* nbytesp,
                        const JSStructuredCloneCallbacks* optionalCallbacks,
                        void* closure, HandleValue transferable)
{
    AssertHeapIsIdle(cx);
    CHECK_REQUEST(cx);
    assertSameCompartment(cx, value);

    const JSStructuredCloneCallbacks* callbacks = optionalCallbacks;
    return WriteStructuredClone(cx, value, bufp, nbytesp, callbacks, closure, transferable);
}

JS_PUBLIC_API(bool)
JS_ClearStructuredClone(uint64_t* data, size_t nbytes,
                        const JSStructuredCloneCallbacks* optionalCallbacks,
                        void* closure, bool freeData)
{
    DiscardTransferables(data, nbytes, optionalCallbacks, closure);
    if (freeData) {
      js_free(data);
    }
    return true;
}

JS_PUBLIC_API(bool)
JS_StructuredCloneHasTransferables(const uint64_t* data, size_t nbytes,
                                   bool* hasTransferable)
{
    *hasTransferable = StructuredCloneHasTransferObjects(data, nbytes);
    return true;
}

JS_PUBLIC_API(bool)
JS_StructuredClone(JSContext* cx, HandleValue value, MutableHandleValue vp,
                   const JSStructuredCloneCallbacks* optionalCallbacks,
                   void* closure)
{
    AssertHeapIsIdle(cx);
    CHECK_REQUEST(cx);

    // Strings are associated with zones, not compartments,
    // so we copy the string by wrapping it.
    if (value.isString()) {
      RootedString strValue(cx, value.toString());
      if (!cx->compartment()->wrap(cx, &strValue)) {
        return false;
      }
      vp.setString(strValue);
      return true;
    }

    const JSStructuredCloneCallbacks* callbacks = optionalCallbacks;

    JSAutoStructuredCloneBuffer buf;
    {
        // If we use Maybe<AutoCompartment> here, G++ can't tell that the
        // destructor is only called when Maybe::construct was called, and
        // we get warnings about using uninitialized variables.
        if (value.isObject()) {
            AutoCompartment ac(cx, &value.toObject());
            if (!buf.write(cx, value, callbacks, closure))
                return false;
        } else {
            if (!buf.write(cx, value, callbacks, closure))
                return false;
        }
    }

    return buf.read(cx, vp, callbacks, closure);
}

JSAutoStructuredCloneBuffer::JSAutoStructuredCloneBuffer(JSAutoStructuredCloneBuffer&& other)
{
    ownTransferables_ = other.ownTransferables_;
    other.steal(&data_, &nbytes_, &version_, &callbacks_, &closure_);
}

JSAutoStructuredCloneBuffer&
JSAutoStructuredCloneBuffer::operator=(JSAutoStructuredCloneBuffer&& other)
{
    MOZ_ASSERT(&other != this);
    clear();
    ownTransferables_ = other.ownTransferables_;
    other.steal(&data_, &nbytes_, &version_, &callbacks_, &closure_);
    return *this;
}

void
JSAutoStructuredCloneBuffer::clear(const JSStructuredCloneCallbacks* optionalCallbacks,
                                   void* optionalClosure)
{
    if (!data_)
        return;

    const JSStructuredCloneCallbacks* callbacks =
        optionalCallbacks ?  optionalCallbacks : callbacks_;
    void* closure = optionalClosure ?  optionalClosure : closure_;

    if (ownTransferables_ == OwnsTransferablesIfAny)
        DiscardTransferables(data_, nbytes_, callbacks, closure);
    ownTransferables_ = NoTransferables;
    js_free(data_);
    data_ = nullptr;
    nbytes_ = 0;
    version_ = 0;
}

bool
JSAutoStructuredCloneBuffer::copy(const uint64_t* srcData, size_t nbytes, uint32_t version,
                                  const JSStructuredCloneCallbacks* callbacks,
                                  void* closure)
{
    // transferable objects cannot be copied
    if (StructuredCloneHasTransferObjects(data_, nbytes_))
        return false;

    uint64_t* newData = static_cast<uint64_t*>(js_malloc(nbytes));
    if (!newData)
        return false;

    js_memcpy(newData, srcData, nbytes);

    clear();
    data_ = newData;
    nbytes_ = nbytes;
    version_ = version;
    callbacks_ = callbacks;
    closure_ = closure;
    ownTransferables_ = NoTransferables;
    return true;
}

void
JSAutoStructuredCloneBuffer::adopt(uint64_t* data, size_t nbytes, uint32_t version,
                                   const JSStructuredCloneCallbacks* callbacks,
                                   void* closure)
{
    clear();
    data_ = data;
    nbytes_ = nbytes;
    version_ = version;
    callbacks_ = callbacks;
    closure_ = closure;
    ownTransferables_ = OwnsTransferablesIfAny;
}

void
JSAutoStructuredCloneBuffer::steal(uint64_t** datap, size_t* nbytesp, uint32_t* versionp,
                                   const JSStructuredCloneCallbacks** callbacks,
                                   void** closure)
{
    *datap = data_;
    *nbytesp = nbytes_;
    if (versionp)
        *versionp = version_;
    if (callbacks)
        *callbacks = callbacks_;
    if (closure)
        *closure = closure_;

    data_ = nullptr;
    nbytes_ = 0;
    version_ = 0;
    callbacks_ = 0;
    closure_ = 0;
    ownTransferables_ = NoTransferables;
}

bool
JSAutoStructuredCloneBuffer::read(JSContext* cx, MutableHandleValue vp,
                                  const JSStructuredCloneCallbacks* optionalCallbacks,
                                  void* closure)
{
    MOZ_ASSERT(cx);
    MOZ_ASSERT(data_);
    return !!JS_ReadStructuredClone(cx, data_, nbytes_, version_, vp,
                                    optionalCallbacks, closure);
}

bool
JSAutoStructuredCloneBuffer::write(JSContext* cx, HandleValue value,
                                   const JSStructuredCloneCallbacks* optionalCallbacks,
                                   void* closure)
{
    HandleValue transferable = UndefinedHandleValue;
    return write(cx, value, transferable, optionalCallbacks, closure);
}

bool
JSAutoStructuredCloneBuffer::write(JSContext* cx, HandleValue value,
                                   HandleValue transferable,
                                   const JSStructuredCloneCallbacks* optionalCallbacks,
                                   void* closure)
{
    clear();
    bool ok = JS_WriteStructuredClone(cx, value, &data_, &nbytes_,
                                      optionalCallbacks, closure,
                                      transferable);

    if (ok) {
        ownTransferables_ = OwnsTransferablesIfAny;
    } else {
        data_ = nullptr;
        nbytes_ = 0;
        version_ = JS_STRUCTURED_CLONE_VERSION;
        ownTransferables_ = NoTransferables;
    }
    return ok;
}

JS_PUBLIC_API(bool)
JS_ReadUint32Pair(JSStructuredCloneReader* r, uint32_t* p1, uint32_t* p2)
{
    return r->input().readPair((uint32_t*) p1, (uint32_t*) p2);
}

JS_PUBLIC_API(bool)
JS_ReadBytes(JSStructuredCloneReader* r, void* p, size_t len)
{
    return r->input().readBytes(p, len);
}

JS_PUBLIC_API(bool)
JS_ReadTypedArray(JSStructuredCloneReader* r, MutableHandleValue vp)
{
    uint32_t tag, nelems;
    if (!r->input().readPair(&tag, &nelems))
        return false;
    if (tag >= SCTAG_TYPED_ARRAY_V1_MIN && tag <= SCTAG_TYPED_ARRAY_V1_MAX) {
        return r->readTypedArray(TagToV1ArrayType(tag), nelems, vp, true);
    } else if (tag == SCTAG_TYPED_ARRAY_OBJECT) {
        uint64_t arrayType;
        if (!r->input().read(&arrayType))
            return false;
        return r->readTypedArray(arrayType, nelems, vp);
    } else {
        JS_ReportErrorNumber(r->context(), GetErrorMessage, nullptr,
                             JSMSG_SC_BAD_SERIALIZED_DATA, "expected type array");
        return false;
    }
}

JS_PUBLIC_API(bool)
JS_WriteUint32Pair(JSStructuredCloneWriter* w, uint32_t tag, uint32_t data)
{
    return w->output().writePair(tag, data);
}

JS_PUBLIC_API(bool)
JS_WriteBytes(JSStructuredCloneWriter* w, const void* p, size_t len)
{
    return w->output().writeBytes(p, len);
}

JS_PUBLIC_API(bool)
JS_WriteString(JSStructuredCloneWriter* w, HandleString str)
{
    return w->writeString(SCTAG_STRING, str);
}

JS_PUBLIC_API(bool)
JS_WriteTypedArray(JSStructuredCloneWriter* w, HandleValue v)
{
    MOZ_ASSERT(v.isObject());
    assertSameCompartment(w->context(), v);
    RootedObject obj(w->context(), &v.toObject());
    return w->writeTypedArray(obj);
}
