/*
 * Copyright 2024 Gabriel Ivăncescu for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */


#include <limits.h>
#include <math.h>
#include <stdarg.h>
#include <stdlib.h>

#include "ntstatus.h"
#include "windef.h"
#include "winbase.h"
#include "ntsecapi.h"

#include "jscript.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(jscript);

typedef struct {
    jsdisp_t dispex;
    DWORD size;
    DECLSPEC_ALIGN(sizeof(double)) BYTE buf[];
} ArrayBufferInstance;

typedef struct {
    jsdisp_t dispex;

    ArrayBufferInstance *buffer;
    DWORD offset;
    DWORD size;
} DataViewInstance;

typedef struct {
    jsdisp_t dispex;

    ArrayBufferInstance *buffer;
    DWORD offset;
    DWORD length;
} TypedArrayInstance;

static inline ArrayBufferInstance *arraybuf_from_jsdisp(jsdisp_t *jsdisp)
{
    return CONTAINING_RECORD(jsdisp, ArrayBufferInstance, dispex);
}

static inline DataViewInstance *dataview_from_jsdisp(jsdisp_t *jsdisp)
{
    return CONTAINING_RECORD(jsdisp, DataViewInstance, dispex);
}

static inline TypedArrayInstance *typedarr_from_jsdisp(jsdisp_t *jsdisp)
{
    return CONTAINING_RECORD(jsdisp, TypedArrayInstance, dispex);
}

static inline ArrayBufferInstance *arraybuf_this(jsval_t vthis)
{
    jsdisp_t *jsdisp = is_object_instance(vthis) ? to_jsdisp(get_object(vthis)) : NULL;
    return (jsdisp && is_class(jsdisp, JSCLASS_ARRAYBUFFER)) ? arraybuf_from_jsdisp(jsdisp) : NULL;
}

static HRESULT create_arraybuf(script_ctx_t*,DWORD,ArrayBufferInstance**);

static HRESULT ArrayBuffer_get_byteLength(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r)
{
    TRACE("%p\n", jsthis);

    *r = jsval_number(arraybuf_from_jsdisp(jsthis)->size);
    return S_OK;
}

static HRESULT ArrayBuffer_slice(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
        jsval_t *r)
{
    ArrayBufferInstance *arraybuf, *ret;
    DWORD begin = 0, end, size;
    HRESULT hres;
    double n;

    TRACE("\n");

    if(!(arraybuf = arraybuf_this(vthis)))
        return JS_E_ARRAYBUFFER_EXPECTED;
    end = arraybuf->size;
    if(!r)
        return S_OK;

    if(argc) {
        hres = to_integer(ctx, argv[0], &n);
        if(FAILED(hres))
            return hres;
        if(n < 0.0)
            n += arraybuf->size;
        if(n >= 0.0 && n < arraybuf->size) {
            begin = n;
            if(argc > 1 && !is_undefined(argv[1])) {
                hres = to_integer(ctx, argv[1], &n);
                if(FAILED(hres))
                    return hres;
                if(n < 0.0)
                    n += arraybuf->size;
                if(n >= 0.0) {
                    end = n < arraybuf->size ? n : arraybuf->size;
                    end = end < begin ? begin : end;
                }else
                    end = begin;
            }
        }else
            end = 0;
    }

    size = end - begin;
    hres = create_arraybuf(ctx, size, &ret);
    if(FAILED(hres))
        return hres;
    memcpy(ret->buf, arraybuf->buf + begin, size);

    *r = jsval_obj(&ret->dispex);
    return S_OK;
}

static const builtin_prop_t ArrayBuffer_props[] = {
    {L"byteLength",            NULL, 0,                    ArrayBuffer_get_byteLength},
    {L"slice",                 ArrayBuffer_slice,          PROPF_METHOD|2},
};

static const builtin_info_t ArrayBuffer_info = {
    .class     = JSCLASS_ARRAYBUFFER,
    .props_cnt = ARRAY_SIZE(ArrayBuffer_props),
    .props     = ArrayBuffer_props,
};

static const builtin_prop_t ArrayBufferInst_props[] = {
    {L"byteLength",            NULL, 0,                    ArrayBuffer_get_byteLength},
};

static const builtin_info_t ArrayBufferInst_info = {
    .class     = JSCLASS_ARRAYBUFFER,
    .props_cnt = ARRAY_SIZE(ArrayBufferInst_props),
    .props     = ArrayBufferInst_props,
};

static HRESULT create_arraybuf(script_ctx_t *ctx, DWORD size, ArrayBufferInstance **ret)
{
    ArrayBufferInstance *arraybuf;
    HRESULT hres;

    if(!(arraybuf = calloc(1, FIELD_OFFSET(ArrayBufferInstance, buf[size]))))
        return E_OUTOFMEMORY;

    hres = init_dispex_from_constr(&arraybuf->dispex, ctx, &ArrayBufferInst_info, ctx->arraybuf_constr);
    if(FAILED(hres)) {
        free(arraybuf);
        return hres;
    }
    arraybuf->size = size;

    *ret = arraybuf;
    return S_OK;
}

HRESULT create_arraybuffer(script_ctx_t *ctx, DWORD size, IWineJSDispatch **ret, void **data)
{
    ArrayBufferInstance *buf;
    HRESULT hres;

    hres = create_arraybuf(ctx, size, &buf);
    if(FAILED(hres))
        return hres;

    *ret = &buf->dispex.IWineJSDispatch_iface;
    *data = buf->buf;
    return S_OK;
}

static HRESULT ArrayBufferConstr_isView(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
        jsval_t *r)
{
    BOOL ret = FALSE;
    jsdisp_t *obj;

    TRACE("\n");

    if(!r)
        return S_OK;

    if(argc && is_object_instance(argv[0]) && (obj = to_jsdisp(get_object(argv[0]))) &&
       (obj->builtin_info->class == JSCLASS_DATAVIEW ||
        (obj->builtin_info->class >= FIRST_TYPEDARRAY_JSCLASS && obj->builtin_info->class <= LAST_TYPEDARRAY_JSCLASS)))
        ret = TRUE;

    *r = jsval_bool(ret);
    return S_OK;
}

static HRESULT ArrayBufferConstr_value(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
        jsval_t *r)
{
    ArrayBufferInstance *arraybuf;
    DWORD size = 0;
    HRESULT hres;

    TRACE("\n");

    switch(flags) {
    case DISPATCH_METHOD:
    case DISPATCH_CONSTRUCT: {
        if(argc) {
            double n;
            hres = to_integer(ctx, argv[0], &n);
            if(FAILED(hres))
                return hres;
            if(n < 0.0)
                return JS_E_INVALID_LENGTH;
            if(n > (UINT_MAX - FIELD_OFFSET(ArrayBufferInstance, buf[0])))
                return E_OUTOFMEMORY;
            size = n;
        }

        if(r) {
            hres = create_arraybuf(ctx, size, &arraybuf);
            if(FAILED(hres))
                return hres;
            *r = jsval_obj(&arraybuf->dispex);
        }
        break;
    }
    default:
        FIXME("unimplemented flags: %x\n", flags);
        return E_NOTIMPL;
    }

    return S_OK;
}

static const builtin_prop_t ArrayBufferConstr_props[] = {
    {L"isView",                ArrayBufferConstr_isView,   PROPF_METHOD|1},
};

static const builtin_info_t ArrayBufferConstr_info = {
    .class     = JSCLASS_FUNCTION,
    .call      = Function_value,
    .props_cnt = ARRAY_SIZE(ArrayBufferConstr_props),
    .props     = ArrayBufferConstr_props,
};

static inline DataViewInstance *dataview_this(jsval_t vthis)
{
    jsdisp_t *jsdisp = is_object_instance(vthis) ? to_jsdisp(get_object(vthis)) : NULL;
    return (jsdisp && is_class(jsdisp, JSCLASS_DATAVIEW)) ? dataview_from_jsdisp(jsdisp) : NULL;
}

static HRESULT DataView_get_buffer(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
        jsval_t *r)
{
    DataViewInstance *view;

    TRACE("\n");

    if(!(view = dataview_this(vthis)))
        return JS_E_NOT_DATAVIEW;
    if(r) *r = jsval_obj(jsdisp_addref(&view->buffer->dispex));
    return S_OK;
}

static HRESULT DataView_get_byteLength(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
        jsval_t *r)
{
    DataViewInstance *view;

    TRACE("\n");

    if(!(view = dataview_this(vthis)))
        return JS_E_NOT_DATAVIEW;
    if(r) *r = jsval_number(view->size);
    return S_OK;
}

static HRESULT DataView_get_byteOffset(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
        jsval_t *r)
{
    DataViewInstance *view;

    TRACE("\n");

    if(!(view = dataview_this(vthis)))
        return JS_E_NOT_DATAVIEW;
    if(r) *r = jsval_number(view->offset);
    return S_OK;
}

static inline void copy_type_data(void *dst, const void *src, unsigned type_size, BOOL little_endian)
{
    const BYTE *in = src;
    BYTE *out = dst;
    unsigned i;

    if(little_endian)
        memcpy(out, in, type_size);
    else
        for(i = 0; i < type_size; i++)
            out[i] = in[type_size - i - 1];
}

static HRESULT get_data(script_ctx_t *ctx, jsval_t vthis, unsigned argc, jsval_t *argv, unsigned type_size, void *ret)
{
    BOOL little_endian = FALSE;
    DataViewInstance *view;
    HRESULT hres;
    DWORD offset;
    BYTE *data;
    double n;

    if(!(view = dataview_this(vthis)))
        return JS_E_NOT_DATAVIEW;
    if(!argc || is_undefined(argv[0]))
        return JS_E_DATAVIEW_NO_ARGUMENT;

    hres = to_integer(ctx, argv[0], &n);
    if(FAILED(hres))
        return hres;

    if(n < 0.0 || n + type_size > view->size)
        return JS_E_DATAVIEW_INVALID_ACCESS;

    offset = n;
    data = &view->buffer->buf[view->offset + offset];

    if(type_size == 1) {
        *(BYTE*)ret = data[0];
        return S_OK;
    }

    if(argc > 1) {
        hres = to_boolean(argv[1], &little_endian);
        if(FAILED(hres))
            return hres;
    }

    copy_type_data(ret, data, type_size, little_endian);
    return S_OK;
}

static HRESULT set_data(script_ctx_t *ctx, jsval_t vthis, unsigned argc, jsval_t *argv, unsigned type_size, const void *val)
{
    BOOL little_endian = FALSE;
    DataViewInstance *view;
    HRESULT hres;
    DWORD offset;
    BYTE *data;
    double n;

    if(!(view = dataview_this(vthis)))
        return JS_E_NOT_DATAVIEW;
    if(is_undefined(argv[0]) || is_undefined(argv[1]))
        return JS_E_DATAVIEW_NO_ARGUMENT;

    hres = to_integer(ctx, argv[0], &n);
    if(FAILED(hres))
        return hres;

    if(n < 0.0 || n + type_size > view->size)
        return JS_E_DATAVIEW_INVALID_ACCESS;

    offset = n;
    data = &view->buffer->buf[view->offset + offset];

    if(type_size == 1) {
        data[0] = *(const BYTE*)val;
        return S_OK;
    }

    if(argc > 2) {
        hres = to_boolean(argv[2], &little_endian);
        if(FAILED(hres))
            return hres;
    }

    copy_type_data(data, val, type_size, little_endian);
    return S_OK;
}

static HRESULT DataView_getFloat32(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
{
    HRESULT hres;
    float v;

    TRACE("\n");

    hres = get_data(ctx, vthis, argc, argv, sizeof(v), &v);
    if(FAILED(hres))
        return hres;
    if(r) *r = jsval_number(v);
    return S_OK;
}

static HRESULT DataView_getFloat64(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
{
    HRESULT hres;
    double v;

    TRACE("\n");

    hres = get_data(ctx, vthis, argc, argv, sizeof(v), &v);
    if(FAILED(hres))
        return hres;
    if(r) *r = jsval_number(v);
    return S_OK;
}

static HRESULT DataView_getInt8(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
{
    HRESULT hres;
    INT8 v;

    TRACE("\n");

    hres = get_data(ctx, vthis, argc, argv, sizeof(v), &v);
    if(FAILED(hres))
        return hres;
    if(r) *r = jsval_number(v);
    return S_OK;
}

static HRESULT DataView_getInt16(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
{
    HRESULT hres;
    INT16 v;

    TRACE("\n");

    hres = get_data(ctx, vthis, argc, argv, sizeof(v), &v);
    if(FAILED(hres))
        return hres;
    if(r) *r = jsval_number(v);
    return S_OK;
}

static HRESULT DataView_getInt32(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
{
    HRESULT hres;
    INT32 v;

    TRACE("\n");

    hres = get_data(ctx, vthis, argc, argv, sizeof(v), &v);
    if(FAILED(hres))
        return hres;
    if(r) *r = jsval_number(v);
    return S_OK;
}

static HRESULT DataView_getUint8(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
{
    HRESULT hres;
    UINT8 v;

    TRACE("\n");

    hres = get_data(ctx, vthis, argc, argv, sizeof(v), &v);
    if(FAILED(hres))
        return hres;
    if(r) *r = jsval_number(v);
    return S_OK;
}

static HRESULT DataView_getUint16(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
{
    HRESULT hres;
    UINT16 v;

    TRACE("\n");

    hres = get_data(ctx, vthis, argc, argv, sizeof(v), &v);
    if(FAILED(hres))
        return hres;
    if(r) *r = jsval_number(v);
    return S_OK;
}

static HRESULT DataView_getUint32(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
{
    HRESULT hres;
    UINT32 v;

    TRACE("\n");

    hres = get_data(ctx, vthis, argc, argv, sizeof(v), &v);
    if(FAILED(hres))
        return hres;
    if(r) *r = jsval_number(v);
    return S_OK;
}

static HRESULT DataView_setFloat32(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
{
    HRESULT hres;
    double n;
    float v;

    TRACE("\n");

    if(argc < 2)
        return JS_E_DATAVIEW_NO_ARGUMENT;
    hres = to_number(ctx, argv[1], &n);
    if(FAILED(hres))
        return hres;
    v = n;  /* FIXME: don't assume rounding mode is round-to-nearest ties-to-even */

    hres = set_data(ctx, vthis, argc, argv, sizeof(v), &v);
    if(FAILED(hres))
        return hres;
    if(r) *r = jsval_undefined();
    return S_OK;
}

static HRESULT DataView_setFloat64(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
{
    HRESULT hres;
    double v;

    TRACE("\n");

    if(argc < 2)
        return JS_E_DATAVIEW_NO_ARGUMENT;
    hres = to_number(ctx, argv[1], &v);
    if(FAILED(hres))
        return hres;

    hres = set_data(ctx, vthis, argc, argv, sizeof(v), &v);
    if(FAILED(hres))
        return hres;
    if(r) *r = jsval_undefined();
    return S_OK;
}

static HRESULT DataView_setInt8(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
{
    HRESULT hres;
    INT32 n;
    INT8 v;

    TRACE("\n");

    if(argc < 2)
        return JS_E_DATAVIEW_NO_ARGUMENT;
    hres = to_int32(ctx, argv[1], &n);
    if(FAILED(hres))
        return hres;
    v = n;

    hres = set_data(ctx, vthis, argc, argv, sizeof(v), &v);
    if(FAILED(hres))
        return hres;
    if(r) *r = jsval_undefined();
    return S_OK;
}

static HRESULT DataView_setInt16(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
{
    HRESULT hres;
    INT32 n;
    INT16 v;

    TRACE("\n");

    if(argc < 2)
        return JS_E_DATAVIEW_NO_ARGUMENT;
    hres = to_int32(ctx, argv[1], &n);
    if(FAILED(hres))
        return hres;
    v = n;

    hres = set_data(ctx, vthis, argc, argv, sizeof(v), &v);
    if(FAILED(hres))
        return hres;
    if(r) *r = jsval_undefined();
    return S_OK;
}

static HRESULT DataView_setInt32(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
{
    HRESULT hres;
    INT32 v;

    TRACE("\n");

    if(argc < 2)
        return JS_E_DATAVIEW_NO_ARGUMENT;
    hres = to_int32(ctx, argv[1], &v);
    if(FAILED(hres))
        return hres;

    hres = set_data(ctx, vthis, argc, argv, sizeof(v), &v);
    if(FAILED(hres))
        return hres;
    if(r) *r = jsval_undefined();
    return S_OK;
}

static const builtin_prop_t DataView_props[] = {
    {L"getFloat32",            DataView_getFloat32,        PROPF_METHOD|1},
    {L"getFloat64",            DataView_getFloat64,        PROPF_METHOD|1},
    {L"getInt16",              DataView_getInt16,          PROPF_METHOD|1},
    {L"getInt32",              DataView_getInt32,          PROPF_METHOD|1},
    {L"getInt8",               DataView_getInt8,           PROPF_METHOD|1},
    {L"getUint16",             DataView_getUint16,         PROPF_METHOD|1},
    {L"getUint32",             DataView_getUint32,         PROPF_METHOD|1},
    {L"getUint8",              DataView_getUint8,          PROPF_METHOD|1},
    {L"setFloat32",            DataView_setFloat32,        PROPF_METHOD|1},
    {L"setFloat64",            DataView_setFloat64,        PROPF_METHOD|1},
    {L"setInt16",              DataView_setInt16,          PROPF_METHOD|1},
    {L"setInt32",              DataView_setInt32,          PROPF_METHOD|1},
    {L"setInt8",               DataView_setInt8,           PROPF_METHOD|1},
    {L"setUint16",             DataView_setInt16,          PROPF_METHOD|1},
    {L"setUint32",             DataView_setInt32,          PROPF_METHOD|1},
    {L"setUint8",              DataView_setInt8,           PROPF_METHOD|1},
};

static void DataView_destructor(jsdisp_t *dispex)
{
    DataViewInstance *view = dataview_from_jsdisp(dispex);
    if(view->buffer)
        jsdisp_release(&view->buffer->dispex);
}

static HRESULT DataView_gc_traverse(struct gc_ctx *gc_ctx, enum gc_traverse_op op, jsdisp_t *dispex)
{
    DataViewInstance *view = dataview_from_jsdisp(dispex);
    return gc_process_linked_obj(gc_ctx, op, dispex, &view->buffer->dispex, (void**)&view->buffer);
}

static const builtin_info_t DataView_info = {
    .class       = JSCLASS_DATAVIEW,
    .props_cnt   = ARRAY_SIZE(DataView_props),
    .props       = DataView_props,
    .destructor  = DataView_destructor,
    .gc_traverse = DataView_gc_traverse
};

static const builtin_info_t DataViewInst_info = {
    .class       = JSCLASS_DATAVIEW,
    .destructor  = DataView_destructor,
    .gc_traverse = DataView_gc_traverse
};

static HRESULT DataViewConstr_value(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
        jsval_t *r)
{
    ArrayBufferInstance *arraybuf;
    DataViewInstance *view;
    DWORD offset = 0, size;
    HRESULT hres;

    TRACE("\n");

    switch(flags) {
    case DISPATCH_METHOD:
    case DISPATCH_CONSTRUCT: {
        if(!argc || !(arraybuf = arraybuf_this(argv[0])))
            return JS_E_DATAVIEW_NO_ARGUMENT;
        size = arraybuf->size;

        if(argc > 1) {
            double offs, len, maxsize = size;
            hres = to_integer(ctx, argv[1], &offs);
            if(FAILED(hres))
                return hres;
            if(offs < 0.0 || offs > maxsize)
                return JS_E_DATAVIEW_INVALID_OFFSET;
            offset = offs;

            if(argc > 2 && !is_undefined(argv[2])) {
                hres = to_integer(ctx, argv[2], &len);
                if(FAILED(hres))
                    return hres;
                if(len < 0.0 || offs+len > maxsize)
                    return JS_E_DATAVIEW_INVALID_OFFSET;
                size = len;
            }else
                size -= offset;
        }

        if(!r)
            return S_OK;

        if(!(view = calloc(1, sizeof(DataViewInstance))))
            return E_OUTOFMEMORY;

        hres = init_dispex_from_constr(&view->dispex, ctx, &DataViewInst_info, ctx->dataview_constr);
        if(FAILED(hres)) {
            free(view);
            return hres;
        }

        jsdisp_addref(&arraybuf->dispex);
        view->buffer = arraybuf;
        view->offset = offset;
        view->size = size;

        *r = jsval_obj(&view->dispex);
        break;
    }
    default:
        FIXME("unimplemented flags: %x\n", flags);
        return E_NOTIMPL;
    }

    return S_OK;
}

static const builtin_info_t DataViewConstr_info = {
    .class = JSCLASS_FUNCTION,
    .call  = Function_value,
};

/* NOTE: Keep in sync with the JSCLASS ordering of typed arrays */
#define ALL_TYPED_ARRAYS \
    X(Int8Array)         \
    X(Int16Array)        \
    X(Int32Array)        \
    X(Uint8Array)        \
    X(Uint8ClampedArray) \
    X(Uint16Array)       \
    X(Uint32Array)       \
    X(Float32Array)      \
    X(Float64Array)

enum {
#define X(name) name ##_desc_idx,
ALL_TYPED_ARRAYS
#undef X
};

struct typed_array_desc {
    unsigned size;
    double (*get)(const void*);
    void (*set)(void*,double);
};

static double get_s8(const void *p) { return *(const INT8 *)p; }
static double get_u8(const void *p) { return *(const UINT8 *)p; }
static void set_u8(void *p, double v) { *(UINT8 *)p = double_to_int32(v); }
static double get_s16(const void *p) { return *(const INT16 *)p; }
static double get_u16(const void *p) { return *(const UINT16 *)p; }
static void set_u16(void *p, double v) { *(UINT16 *)p = double_to_int32(v); }
static double get_s32(const void *p) { return *(const INT32 *)p; }
static double get_u32(const void *p) { return *(const UINT32 *)p; }
static void set_u32(void *p, double v) { *(UINT32 *)p = double_to_int32(v); }
static double get_f32(const void *p) { return *(const float *)p; }
static void set_f32(void *p, double v) { *(float *)p = v; }
static double get_f64(const void *p) { return *(const double *)p; }
static void set_f64(void *p, double v) { *(double *)p = v; }

static void set_clamped_u8(void *p, double v)
{
    *(UINT8 *)p = v >= 255.0 ? 255 : v > 0 ? lround(v) : 0;
}

static const struct typed_array_desc typed_array_descs[NUM_TYPEDARRAY_TYPES] = {
    [Int8Array_desc_idx]         = { 1, get_s8,  set_u8         },
    [Int16Array_desc_idx]        = { 2, get_s16, set_u16        },
    [Int32Array_desc_idx]        = { 4, get_s32, set_u32        },
    [Uint8Array_desc_idx]        = { 1, get_u8,  set_u8         },
    [Uint8ClampedArray_desc_idx] = { 1, get_u8,  set_clamped_u8 },
    [Uint16Array_desc_idx]       = { 2, get_u16, set_u16        },
    [Uint32Array_desc_idx]       = { 4, get_u32, set_u32        },
    [Float32Array_desc_idx]      = { 4, get_f32, set_f32        },
    [Float64Array_desc_idx]      = { 8, get_f64, set_f64        }
};

static inline TypedArrayInstance *typedarr_this(jsval_t vthis, jsclass_t class)
{
    jsdisp_t *jsdisp = is_object_instance(vthis) ? to_jsdisp(get_object(vthis)) : NULL;
    return (jsdisp && is_class(jsdisp, class)) ? typedarr_from_jsdisp(jsdisp) : NULL;
}

static HRESULT create_typedarr(const builtin_info_t*,script_ctx_t*,ArrayBufferInstance*,DWORD,DWORD,jsdisp_t**);

static HRESULT TypedArray_get_buffer(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r)
{
    TRACE("%p\n", jsthis);

    *r = jsval_obj(jsdisp_addref(&typedarr_from_jsdisp(jsthis)->buffer->dispex));
    return S_OK;
}

static HRESULT TypedArray_get_byteLength(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r)
{
    TRACE("%p\n", jsthis);

    *r = jsval_number(typedarr_from_jsdisp(jsthis)->length * typed_array_descs[jsthis->builtin_info->class - FIRST_TYPEDARRAY_JSCLASS].size);
    return S_OK;
}

static HRESULT TypedArray_get_byteOffset(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r)
{
    TRACE("%p\n", jsthis);

    *r = jsval_number(typedarr_from_jsdisp(jsthis)->offset);
    return S_OK;
}

static HRESULT TypedArray_get_length(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r)
{
    TRACE("%p\n", jsthis);

    *r = jsval_number(typedarr_from_jsdisp(jsthis)->length);
    return S_OK;
}

static HRESULT fill_typedarr_data_from_object(const struct typed_array_desc *desc, script_ctx_t *ctx, BYTE *data, jsdisp_t *obj, DWORD length)
{
    HRESULT hres;
    jsval_t val;
    UINT32 i;

    for(i = 0; i < length; i++) {
        double n;

        hres = jsdisp_get_idx(obj, i, &val);
        if(FAILED(hres)) {
            if(hres != DISP_E_UNKNOWNNAME)
                return hres;
            val = jsval_undefined();
        }

        hres = to_number(ctx, val, &n);
        jsval_release(val);
        if(FAILED(hres))
            return hres;
        desc->set(&data[i * desc->size], n);
    }

    return S_OK;
}

static HRESULT TypedArray_set(const builtin_info_t *info, script_ctx_t *ctx, jsval_t vthis, WORD flags,
        unsigned argc, jsval_t *argv, jsval_t *r)
{
    const struct typed_array_desc *desc = &typed_array_descs[info->class - FIRST_TYPEDARRAY_JSCLASS];
    TypedArrayInstance *typedarr;
    DWORD begin = 0, size;
    BYTE *dest, *data;
    IDispatch *disp;
    jsdisp_t *obj;
    HRESULT hres;
    jsval_t val;
    UINT32 len;
    double n;

    if(!(typedarr = typedarr_this(vthis, info->class)))
        return JS_E_NOT_TYPEDARRAY;
    if(!argc)
        return JS_E_TYPEDARRAY_INVALID_SOURCE;

    hres = to_object(ctx, argv[0], &disp);
    if(FAILED(hres))
        return JS_E_TYPEDARRAY_INVALID_SOURCE;

    if(!(obj = to_jsdisp(disp))) {
        FIXME("Non-JS array object\n");
        hres = JS_E_TYPEDARRAY_INVALID_SOURCE;
        goto done;
    }

    hres = jsdisp_propget_name(obj, L"length", &val);
    if(FAILED(hres))
        goto done;

    hres = to_uint32(ctx, val, &len);
    jsval_release(val);
    if(FAILED(hres))
        goto done;

    if(argc > 1) {
        hres = to_integer(ctx, argv[1], &n);
        if(FAILED(hres))
            goto done;
        if(n < 0.0 || n > typedarr->length) {
            hres = JS_E_TYPEDARRAY_INVALID_OFFSLEN;
            goto done;
        }
        begin = n;
    }

    if(len > typedarr->length - begin) {
        hres = JS_E_TYPEDARRAY_INVALID_OFFSLEN;
        goto done;
    }
    size = len * desc->size;
    dest = data = &typedarr->buffer->buf[typedarr->offset + begin * desc->size];

    /* If they overlap, make a temporary copy */
    if(obj->builtin_info->class >= FIRST_TYPEDARRAY_JSCLASS && obj->builtin_info->class <= LAST_TYPEDARRAY_JSCLASS) {
        TypedArrayInstance *src_arr = typedarr_from_jsdisp(obj);
        const BYTE *src = src_arr->buffer->buf + src_arr->offset;

        if(dest < src + len * typed_array_descs[obj->builtin_info->class - FIRST_TYPEDARRAY_JSCLASS].size &&
           dest + size > src) {
            if(!(data = malloc(size))) {
                hres = E_OUTOFMEMORY;
                goto done;
            }
        }
    }

    hres = fill_typedarr_data_from_object(desc, ctx, data, obj, len);
    if(SUCCEEDED(hres) && dest != data) {
        memcpy(dest, data, size);
        free(data);
    }

done:
    IDispatch_Release(disp);
    return hres;
}

static HRESULT TypedArray_subarray(const builtin_info_t *info, script_ctx_t *ctx, jsval_t vthis, WORD flags,
        unsigned argc, jsval_t *argv, jsval_t *r)
{
    TypedArrayInstance *typedarr;
    DWORD begin = 0, end;
    jsdisp_t *obj;
    HRESULT hres;
    double n;

    if(!(typedarr = typedarr_this(vthis, info->class)))
        return JS_E_NOT_TYPEDARRAY;
    if(!argc)
        return JS_E_TYPEDARRAY_INVALID_SUBARRAY;
    if(!r)
        return S_OK;

    hres = to_integer(ctx, argv[0], &n);
    if(FAILED(hres))
        return hres;
    end = typedarr->length;
    if(n < 0.0)
        n += typedarr->length;
    if(n >= 0.0)
        begin = n < typedarr->length ? n : typedarr->length;

    if(argc > 1 && !is_undefined(argv[1])) {
        hres = to_integer(ctx, argv[1], &n);
        if(FAILED(hres))
            return hres;
        if(n < 0.0)
            n += typedarr->length;
        if(n >= 0.0) {
            end = n < typedarr->length ? n : typedarr->length;
            end = end < begin ? begin : end;
        }else
            end = begin;
    }

    hres = create_typedarr(info, ctx, typedarr->buffer,
                           typedarr->offset + begin * typed_array_descs[info->class - FIRST_TYPEDARRAY_JSCLASS].size,
                           end - begin, &obj);
    if(FAILED(hres))
        return hres;

    *r = jsval_obj(obj);
    return S_OK;
}

static void TypedArray_destructor(jsdisp_t *dispex)
{
    TypedArrayInstance *typedarr = typedarr_from_jsdisp(dispex);
    if(typedarr->buffer)
        jsdisp_release(&typedarr->buffer->dispex);
}

static HRESULT TypedArray_lookup_prop(jsdisp_t *dispex, const WCHAR *name, unsigned flags, struct property_info *desc)
{
    TypedArrayInstance *typedarr = typedarr_from_jsdisp(dispex);

    /* Typed Arrays override every positive index */
    return jsdisp_index_lookup(&typedarr->dispex, name, INT_MAX, desc);
}

static inline HRESULT TypedArray_prop_get(const builtin_info_t *info, jsdisp_t *dispex, unsigned idx, jsval_t *r)
{
    const struct typed_array_desc *desc = &typed_array_descs[info->class - FIRST_TYPEDARRAY_JSCLASS];
    TypedArrayInstance *typedarr = typedarr_from_jsdisp(dispex);

    if(idx >= typedarr->length)
        *r = jsval_undefined();
    else
        *r = jsval_number(desc->get(&typedarr->buffer->buf[typedarr->offset + idx * desc->size]));
    return S_OK;
}

static inline HRESULT TypedArray_prop_put(const builtin_info_t *info, jsdisp_t *dispex, unsigned idx, jsval_t val)
{
    const struct typed_array_desc *desc = &typed_array_descs[info->class - FIRST_TYPEDARRAY_JSCLASS];
    TypedArrayInstance *typedarr = typedarr_from_jsdisp(dispex);
    HRESULT hres;
    double n;

    if(idx >= typedarr->length)
        return S_OK;

    hres = to_number(typedarr->dispex.ctx, val, &n);
    if(SUCCEEDED(hres))
        desc->set(&typedarr->buffer->buf[typedarr->offset + idx * desc->size], n);
    return hres;
}

static HRESULT TypedArray_fill_props(jsdisp_t *dispex)
{
    TypedArrayInstance *typedarr = typedarr_from_jsdisp(dispex);

    return jsdisp_fill_indices(&typedarr->dispex, typedarr->length);
}

static HRESULT TypedArray_gc_traverse(struct gc_ctx *gc_ctx, enum gc_traverse_op op, jsdisp_t *dispex)
{
    TypedArrayInstance *typedarr = typedarr_from_jsdisp(dispex);
    return gc_process_linked_obj(gc_ctx, op, dispex, &typedarr->buffer->dispex, (void**)&typedarr->buffer);
}

static const builtin_prop_t TypedArrayInst_props[] = {
    {L"buffer",                NULL, 0,                    TypedArray_get_buffer},
    {L"byteLength",            NULL, 0,                    TypedArray_get_byteLength},
    {L"byteOffset",            NULL, 0,                    TypedArray_get_byteOffset},
    {L"length",                NULL, 0,                    TypedArray_get_length},
};

static HRESULT create_typedarr(const builtin_info_t *info, script_ctx_t *ctx, ArrayBufferInstance *buffer,
        DWORD offset, DWORD length, jsdisp_t **ret)
{
    TypedArrayInstance *typedarr;
    HRESULT hres;

    if(!(typedarr = calloc(1, sizeof(TypedArrayInstance))))
        return E_OUTOFMEMORY;

    hres = init_dispex_from_constr(&typedarr->dispex, ctx, info, ctx->typedarr_constr[info->class - FIRST_TYPEDARRAY_JSCLASS]);
    if(FAILED(hres)) {
        free(typedarr);
        return hres;
    }

    jsdisp_addref(&buffer->dispex);
    typedarr->buffer = buffer;
    typedarr->offset = offset;
    typedarr->length = length;

    *ret = &typedarr->dispex;
    return S_OK;
}

static HRESULT TypedArrayConstr_value(const builtin_info_t *info, script_ctx_t *ctx, jsval_t vthis, WORD flags,
        unsigned argc, jsval_t *argv, jsval_t *r)
{
    const struct typed_array_desc *desc = &typed_array_descs[info->class - FIRST_TYPEDARRAY_JSCLASS];
    const unsigned elem_size = desc->size;
    ArrayBufferInstance *buffer = NULL;
    DWORD offset = 0, length = 0;
    jsdisp_t *typedarr;
    HRESULT hres;
    double n;

    switch(flags) {
    case DISPATCH_METHOD:
    case DISPATCH_CONSTRUCT: {
        if(argc) {
            if(is_object_instance(argv[0])) {
                jsdisp_t *obj = to_jsdisp(get_object(argv[0]));

                if(!obj)
                    return JS_E_TYPEDARRAY_BAD_CTOR_ARG;

                if(obj->builtin_info->class == JSCLASS_ARRAYBUFFER) {
                    buffer = arraybuf_from_jsdisp(obj);
                    if(argc > 1) {
                        hres = to_integer(ctx, argv[1], &n);
                        if(FAILED(hres))
                            return hres;
                        if(n < 0.0 || n > buffer->size)
                            return JS_E_TYPEDARRAY_INVALID_OFFSLEN;
                        offset = n;
                        if(offset % elem_size)
                            return JS_E_TYPEDARRAY_INVALID_OFFSLEN;
                    }
                    if(argc > 2 && !is_undefined(argv[2])) {
                        hres = to_integer(ctx, argv[2], &n);
                        if(FAILED(hres))
                            return hres;
                        if(n < 0.0 || n > UINT_MAX)
                            return JS_E_TYPEDARRAY_INVALID_OFFSLEN;
                        length = n;
                        if(offset + length * elem_size > buffer->size)
                            return JS_E_TYPEDARRAY_INVALID_OFFSLEN;
                    }else {
                        length = buffer->size - offset;
                        if(length % elem_size)
                            return JS_E_TYPEDARRAY_INVALID_OFFSLEN;
                        length /= elem_size;
                    }
                    jsdisp_addref(&buffer->dispex);
                }else {
                    jsval_t val;
                    UINT32 len;
                    DWORD size;

                    hres = jsdisp_propget_name(obj, L"length", &val);
                    if(FAILED(hres))
                        return hres;
                    if(is_undefined(val))
                        return JS_E_TYPEDARRAY_BAD_CTOR_ARG;

                    hres = to_uint32(ctx, val, &len);
                    jsval_release(val);
                    if(FAILED(hres))
                        return hres;

                    length = len;
                    size = length * elem_size;
                    if(size < length || size > (UINT_MAX - FIELD_OFFSET(ArrayBufferInstance, buf[0])))
                        return E_OUTOFMEMORY;

                    hres = create_arraybuf(ctx, size, &buffer);
                    if(FAILED(hres))
                        return hres;

                    hres = fill_typedarr_data_from_object(desc, ctx, buffer->buf, obj, length);
                    if(FAILED(hres)) {
                        jsdisp_release(&buffer->dispex);
                        return hres;
                    }
                }
            }else if(is_number(argv[0])) {
                hres = to_integer(ctx, argv[0], &n);
                if(FAILED(hres))
                    return hres;
                if(n < 0.0)
                    return JS_E_TYPEDARRAY_INVALID_OFFSLEN;
                if(n * elem_size > (UINT_MAX - FIELD_OFFSET(ArrayBufferInstance, buf[0])))
                    return E_OUTOFMEMORY;
                length = n;
            }else
                return JS_E_TYPEDARRAY_BAD_CTOR_ARG;
        }

        if(!r)
            return S_OK;

        if(!buffer) {
            hres = create_arraybuf(ctx, length * elem_size, &buffer);
            if(FAILED(hres))
                return hres;
        }

        hres = create_typedarr(info, ctx, buffer, offset, length, &typedarr);
        jsdisp_release(&buffer->dispex);
        if(FAILED(hres))
            return hres;

        *r = jsval_obj(typedarr);
        break;
    }
    default:
        FIXME("unimplemented flags: %x\n", flags);
        return E_NOTIMPL;
    }

    return S_OK;
}

#define X(name)                                                                         \
static const builtin_info_t name##_info;                                                \
                                                                                        \
static HRESULT name##_set(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) \
{                                                                                       \
    TRACE("\n");                                                                        \
    return TypedArray_set(&name##_info, ctx, vthis, flags, argc, argv, r);              \
}                                                                                       \
                                                                                        \
static HRESULT name##_subarray(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) \
{                                                                                       \
    TRACE("\n");                                                                        \
    return TypedArray_subarray(&name##_info, ctx, vthis, flags, argc, argv, r);         \
}                                                                                       \
                                                                                        \
static HRESULT name##_prop_get(jsdisp_t *dispex, unsigned idx, jsval_t *r)              \
{                                                                                       \
    TRACE("%p[%u]\n", dispex, idx);                                                     \
    return TypedArray_prop_get(&name##_info, dispex, idx, r);                           \
}                                                                                       \
                                                                                        \
static HRESULT name##_prop_put(jsdisp_t *dispex, unsigned idx, jsval_t val)             \
{                                                                                       \
    TRACE("%p[%u] = %s\n", dispex, idx, debugstr_jsval(val));                           \
    return TypedArray_prop_put(&name##_info, dispex, idx, val);                         \
}                                                                                       \
                                                                                        \
static const builtin_prop_t name##_props[] = {                                          \
    {L"buffer",                NULL, 0,                    TypedArray_get_buffer},      \
    {L"byteLength",            NULL, 0,                    TypedArray_get_byteLength},  \
    {L"byteOffset",            NULL, 0,                    TypedArray_get_byteOffset},  \
    {L"length",                NULL, 0,                    TypedArray_get_length},      \
    {L"set",                   name##_set,                 PROPF_METHOD|2},             \
    {L"subarray",              name##_subarray,            PROPF_METHOD|2},             \
};                                                                                      \
                                                                                        \
static const builtin_info_t name##_info =                                               \
{                                                                                       \
    .class          = FIRST_TYPEDARRAY_JSCLASS + name ##_desc_idx,                      \
    .props_cnt      = ARRAY_SIZE(name##_props),                                         \
    .props          = name##_props,                                                     \
    .destructor     = TypedArray_destructor,                                            \
    .lookup_prop    = TypedArray_lookup_prop,                                           \
    .prop_get       = name##_prop_get,                                                  \
    .prop_put       = name##_prop_put,                                                  \
    .fill_props     = TypedArray_fill_props,                                            \
    .gc_traverse    = TypedArray_gc_traverse,                                           \
};                                                                                      \
                                                                                        \
static const builtin_info_t name##Inst_info =                                           \
{                                                                                       \
    .class          = FIRST_TYPEDARRAY_JSCLASS + name##_desc_idx,                       \
    .props_cnt      = ARRAY_SIZE(TypedArrayInst_props),                                 \
    .props          = TypedArrayInst_props,                                             \
    .destructor     = TypedArray_destructor,                                            \
    .lookup_prop    = TypedArray_lookup_prop,                                           \
    .prop_get       = name##_prop_get,                                                  \
    .prop_put       = name##_prop_put,                                                  \
    .fill_props     = TypedArray_fill_props,                                            \
    .gc_traverse    = TypedArray_gc_traverse,                                           \
};                                                                                      \
static HRESULT name ## Constr_value(script_ctx_t *ctx, jsval_t jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) \
{                                                                                       \
    TRACE("\n");                                                                        \
    return TypedArrayConstr_value(&name##Inst_info, ctx, jsthis, flags, argc, argv, r); \
}
ALL_TYPED_ARRAYS
#undef X

static const builtin_info_t TypedArrayConstr_info = {
    .class = JSCLASS_FUNCTION,
    .call  = Function_value,
};

static HRESULT init_typed_array_constructor(script_ctx_t *ctx, builtin_invoke_t func, const WCHAR *name, const builtin_info_t *info)
{
    const unsigned type_idx = info->class - FIRST_TYPEDARRAY_JSCLASS;
    TypedArrayInstance *prototype;
    HRESULT hres;

    if(!(prototype = calloc(1, sizeof(*prototype))))
        return E_OUTOFMEMORY;

    hres = create_arraybuf(ctx, 0, &prototype->buffer);
    if(FAILED(hres)) {
        free(prototype);
        return hres;
    }

    hres = init_dispex(&prototype->dispex, ctx, info, ctx->object_prototype);
    if(FAILED(hres)) {
        jsdisp_release(&prototype->buffer->dispex);
        free(prototype);
        return hres;
    }

    hres = create_builtin_constructor(ctx, func, name, &TypedArrayConstr_info, PROPF_CONSTR|1, &prototype->dispex, &ctx->typedarr_constr[type_idx]);
    jsdisp_release(&prototype->dispex);
    if(FAILED(hres))
        return hres;

    hres = jsdisp_define_data_property(ctx->typedarr_constr[type_idx], L"BYTES_PER_ELEMENT", 0,
                                       jsval_number(typed_array_descs[type_idx].size));
    if(FAILED(hres))
        return hres;

    return jsdisp_define_data_property(ctx->global, name, PROPF_CONFIGURABLE | PROPF_WRITABLE,
                                       jsval_obj(ctx->typedarr_constr[type_idx]));
}

HRESULT init_arraybuf_constructors(script_ctx_t *ctx)
{
    static const struct {
        const WCHAR *name;
        builtin_invoke_t constr_func;
        const builtin_info_t *prototype_info;
    } typed_arrays[] = {
        { L"Int8Array",     Int8ArrayConstr_value,     &Int8Array_info },
        { L"Int16Array",    Int16ArrayConstr_value,    &Int16Array_info },
        { L"Int32Array",    Int32ArrayConstr_value,    &Int32Array_info },
        { L"Uint8Array",    Uint8ArrayConstr_value,    &Uint8Array_info },
        { L"Uint16Array",   Uint16ArrayConstr_value,   &Uint16Array_info },
        { L"Uint32Array",   Uint32ArrayConstr_value,   &Uint32Array_info },
        { L"Float32Array",  Float32ArrayConstr_value,  &Float32Array_info },
        { L"Float64Array",  Float64ArrayConstr_value,  &Float64Array_info },
    };
    static const struct {
        const WCHAR *name;
        builtin_invoke_t get;
    } DataView_getters[] = {
        { L"buffer",        DataView_get_buffer },
        { L"byteLength",    DataView_get_byteLength },
        { L"byteOffset",    DataView_get_byteOffset },
    };
    ArrayBufferInstance *arraybuf;
    DataViewInstance *view;
    property_desc_t desc;
    HRESULT hres;
    unsigned i;

    if(ctx->version < SCRIPTLANGUAGEVERSION_ES5_1)
        return S_OK;

    if(!(arraybuf = calloc(1, FIELD_OFFSET(ArrayBufferInstance, buf[0]))))
        return E_OUTOFMEMORY;

    hres = init_dispex(&arraybuf->dispex, ctx, &ArrayBuffer_info, ctx->object_prototype);
    if(FAILED(hres)) {
        free(arraybuf);
        return hres;
    }

    hres = create_builtin_constructor(ctx, ArrayBufferConstr_value, L"ArrayBuffer", &ArrayBufferConstr_info,
                                      PROPF_CONSTR|1, &arraybuf->dispex, &ctx->arraybuf_constr);
    jsdisp_release(&arraybuf->dispex);
    if(FAILED(hres))
        return hres;

    hres = jsdisp_define_data_property(ctx->global, L"ArrayBuffer", PROPF_CONFIGURABLE | PROPF_WRITABLE,
                                       jsval_obj(ctx->arraybuf_constr));
    if(FAILED(hres))
        return hres;

    if(!(view = calloc(1, sizeof(DataViewInstance))))
        return E_OUTOFMEMORY;

    hres = create_arraybuf(ctx, 0, &view->buffer);
    if(FAILED(hres)) {
        free(view);
        return hres;
    }

    hres = init_dispex(&view->dispex, ctx, &DataView_info, ctx->object_prototype);
    if(FAILED(hres)) {
        jsdisp_release(&view->buffer->dispex);
        free(view);
        return hres;
    }

    desc.flags = PROPF_CONFIGURABLE;
    desc.mask  = PROPF_CONFIGURABLE | PROPF_ENUMERABLE;
    desc.explicit_getter = desc.explicit_setter = TRUE;
    desc.explicit_value = FALSE;
    desc.setter = NULL;

    /* FIXME: If we find we need builtin accessors in other places, we should consider a more generic solution */
    for(i = 0; i < ARRAY_SIZE(DataView_getters); i++) {
        hres = create_builtin_function(ctx, DataView_getters[i].get, NULL, NULL, PROPF_METHOD, NULL, &desc.getter);
        if(SUCCEEDED(hres)) {
            hres = jsdisp_define_property(&view->dispex, DataView_getters[i].name, &desc);
            jsdisp_release(desc.getter);
        }
        if(FAILED(hres)) {
            jsdisp_release(&view->dispex);
            return hres;
        }
    }

    hres = create_builtin_constructor(ctx, DataViewConstr_value, L"DataView", &DataViewConstr_info,
                                      PROPF_CONSTR|1, &view->dispex, &ctx->dataview_constr);
    jsdisp_release(&view->dispex);
    if(FAILED(hres))
        return hres;

    hres = jsdisp_define_data_property(ctx->global, L"DataView", PROPF_CONFIGURABLE | PROPF_WRITABLE,
                                       jsval_obj(ctx->dataview_constr));
    if(FAILED(hres))
        return hres;

    for(i = 0; i < ARRAY_SIZE(typed_arrays); i++) {
        hres = init_typed_array_constructor(ctx, typed_arrays[i].constr_func, typed_arrays[i].name, typed_arrays[i].prototype_info);
        if(FAILED(hres))
            return hres;
    }

    if(ctx->version >= SCRIPTLANGUAGEVERSION_ES6) {
        hres = init_typed_array_constructor(ctx, Uint8ClampedArrayConstr_value, L"Uint8ClampedArray", &Uint8ClampedArray_info);
        if(FAILED(hres))
            return hres;
    }

    return hres;
}

HRESULT typed_array_get_random_values(jsdisp_t *obj)
{
    TypedArrayInstance *typedarr;
    DWORD size;

    if(!obj || obj->builtin_info->class < FIRST_TYPEDARRAY_JSCLASS || obj->builtin_info->class > LAST_TYPEDARRAY_JSCLASS)
        return E_INVALIDARG;

    if(obj->builtin_info->class == JSCLASS_FLOAT32ARRAY || obj->builtin_info->class == JSCLASS_FLOAT64ARRAY) {
        /* FIXME: Return TypeMismatchError */
        return E_FAIL;
    }

    typedarr = typedarr_from_jsdisp(obj);
    size = typedarr->length * typed_array_descs[obj->builtin_info->class - FIRST_TYPEDARRAY_JSCLASS].size;
    if(size > 65536) {
        /* FIXME: Return QuotaExceededError */
        return E_FAIL;
    }

    if(!RtlGenRandom(&typedarr->buffer->buf[typedarr->offset], size))
        return HRESULT_FROM_WIN32(GetLastError());

    return S_OK;
}
