/* -*- 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/. */

#include "vm/Xdr.h"

#include <string.h>

#include "jsprf.h"
#include "jsapi.h"
#include "jscntxt.h"
#include "jsscript.h"

#include "vm/Debugger.h"

#include "jsscriptinlines.h"

using namespace js;

void
XDRBuffer::freeBuffer()
{
    js_free(base);
#ifdef DEBUG
    memset(this, 0xe2, sizeof *this);
#endif
}

bool
XDRBuffer::grow(size_t n)
{
    JS_ASSERT(n > size_t(limit - cursor));

    const size_t MEM_BLOCK = 8192;
    size_t offset = cursor - base;
    size_t newCapacity = JS_ROUNDUP(offset + n, MEM_BLOCK);
    if (isUint32Overflow(newCapacity)) {
        JS_ReportErrorNumber(cx(), js_GetErrorMessage, NULL, JSMSG_TOO_BIG_TO_ENCODE);
        return false;
    }

    void *data = js_realloc(base, newCapacity);
    if (!data) {
        js_ReportOutOfMemory(cx());
        return false;
    }
    base = static_cast<uint8_t *>(data);
    cursor = base + offset;
    limit = base + newCapacity;
    return true;
}

template<XDRMode mode>
bool
XDRState<mode>::codeChars(jschar *chars, size_t nchars)
{
    size_t nbytes = nchars * sizeof(jschar);
    if (mode == XDR_ENCODE) {
        uint8_t *ptr = buf.write(nbytes);
        if (!ptr)
            return false;
        mozilla::NativeEndian::copyAndSwapToLittleEndian(ptr, chars, nchars);
    } else {
        const uint8_t *ptr = buf.read(nbytes);
        mozilla::NativeEndian::copyAndSwapFromLittleEndian(chars, ptr, nchars);
    }
    return true;
}

template<XDRMode mode>
static bool
VersionCheck(XDRState<mode> *xdr)
{
    uint32_t bytecodeVer;
    if (mode == XDR_ENCODE)
        bytecodeVer = XDR_BYTECODE_VERSION;

    if (!xdr->codeUint32(&bytecodeVer))
        return false;

    if (mode == XDR_DECODE && bytecodeVer != XDR_BYTECODE_VERSION) {
        /* We do not provide binary compatibility with older scripts. */
        JS_ReportErrorNumber(xdr->cx(), js_GetErrorMessage, NULL, JSMSG_BAD_SCRIPT_MAGIC);
        return false;
    }

    return true;
}

template<XDRMode mode>
bool
XDRState<mode>::codeFunction(MutableHandleObject objp)
{
    if (mode == XDR_DECODE)
        objp.set(NULL);

    if (!VersionCheck(this))
        return false;

    return XDRInterpretedFunction(this, NullPtr(), NullPtr(), objp);
}

template<XDRMode mode>
bool
XDRState<mode>::codeScript(MutableHandleScript scriptp)
{
    RootedScript script(cx());
    if (mode == XDR_DECODE) {
        script = NULL;
        scriptp.set(NULL);
    } else {
        script = scriptp.get();
    }

    if (!VersionCheck(this))
        return false;

    if (!XDRScript(this, NullPtr(), NullPtr(), NullPtr(), &script))
        return false;

    if (mode == XDR_DECODE) {
        JS_ASSERT(!script->compileAndGo);
        CallNewScriptHook(cx(), script, NullPtr());
        Debugger::onNewScript(cx(), script, NULL);
        scriptp.set(script);
    }

    return true;
}

template<XDRMode mode>
void
XDRState<mode>::initScriptPrincipals(JSScript *script)
{
    JS_ASSERT(mode == XDR_DECODE);

    /* The origin principals must be normalized at this point. */
    JS_ASSERT_IF(principals, originPrincipals);
    JS_ASSERT(!script->originPrincipals);
    if (principals)
        JS_ASSERT(script->principals() == principals);

    if (originPrincipals) {
        script->originPrincipals = originPrincipals;
        JS_HoldPrincipals(originPrincipals);
    }
}

XDRDecoder::XDRDecoder(JSContext *cx, const void *data, uint32_t length,
                       JSPrincipals *principals, JSPrincipals *originPrincipals)
  : XDRState<XDR_DECODE>(cx)
{
    buf.setData(data, length);
    this->principals = principals;
    this->originPrincipals = JSScript::normalizeOriginPrincipals(principals, originPrincipals);
}

template class js::XDRState<XDR_ENCODE>;
template class js::XDRState<XDR_DECODE>;
