/*
 * Copyright 2012 Jacek Caban 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
 */

#ifndef JSVAL_H
#define JSVAL_H

#include "jsstr.h"

/*
 * jsval_t structure is used to represent JavaScript dynamically-typed values.
 * It's a (type,value) pair, usually represented as a structure of enum (type)
 * and union (value of given type). For both memory and speed performance, we
 * use tricks allowing storing both values as a struct with size equal to
 * size of double (that is 64-bit) on 32-bit systems. For that, we use the fact
 * that NaN value representation has 52 (almost) free bits.
 */

#ifdef __i386__
#define JSVAL_DOUBLE_LAYOUT_PTR32
#endif

#ifdef JSVAL_DOUBLE_LAYOUT_PTR32
/* NaN exponent and our 0x80000 marker */
#define JSV_VAL(x) (0x7ff80000|x)
#else
#define JSV_VAL(x) x
#endif

typedef enum {
    JSV_UNDEFINED = JSV_VAL(1),
    JSV_NULL      = JSV_VAL(2),
    JSV_OBJECT    = JSV_VAL(3),
    JSV_STRING    = JSV_VAL(4),
    JSV_NUMBER    = JSV_VAL(5),
    JSV_BOOL      = JSV_VAL(6),
    JSV_VARIANT   = JSV_VAL(7)
} jsval_type_t;

struct _jsval_t {
#ifdef JSVAL_DOUBLE_LAYOUT_PTR32
    union {
        double n;
        struct {
            union {
                IDispatch *obj;
                jsstr_t *str;
                BOOL b;
                VARIANT *v;
                UINT_PTR as_uintptr;
            } u;
            jsval_type_t tag;
        } s;
    } u;
#else
    jsval_type_t type;
    union {
        IDispatch *obj;
        jsstr_t *str;
        double n;
        BOOL b;
        VARIANT *v;
    } u;
#endif
};

#ifdef JSVAL_DOUBLE_LAYOUT_PTR32

C_ASSERT(sizeof(jsval_t) == sizeof(double));

#define __JSVAL_TYPE(x) ((x).u.s.tag)
#define __JSVAL_BOOL(x) ((x).u.s.u.b)
#define __JSVAL_STR(x)  ((x).u.s.u.str)
#define __JSVAL_OBJ(x)  ((x).u.s.u.obj)
#define __JSVAL_VAR(x)  ((x).u.s.u.v)

#else

#define __JSVAL_TYPE(x) ((x).type)
#define __JSVAL_BOOL(x) ((x).u.b)
#define __JSVAL_STR(x)  ((x).u.str)
#define __JSVAL_OBJ(x)  ((x).u.obj)
#define __JSVAL_VAR(x)  ((x).u.v)

#endif

static inline jsval_t jsval_bool(BOOL b)
{
    jsval_t ret;
    __JSVAL_TYPE(ret) = JSV_BOOL;
    __JSVAL_BOOL(ret) = b;
    return ret;
}

static inline jsval_t jsval_string(jsstr_t *str)
{
    jsval_t ret;
    __JSVAL_TYPE(ret) = JSV_STRING;
    __JSVAL_STR(ret) = str;
    return ret;
}

static inline jsval_t jsval_disp(IDispatch *obj)
{
    jsval_t ret;
    __JSVAL_TYPE(ret) = JSV_OBJECT;
    __JSVAL_OBJ(ret) = obj;
    return ret;
}

static inline jsval_t jsval_obj(jsdisp_t *obj)
{
    return jsval_disp(to_disp(obj));
}

static inline jsval_t jsval_null(void)
{
    jsval_t ret;
    __JSVAL_TYPE(ret) = JSV_NULL;
    return ret;
}

static inline jsval_t jsval_undefined(void)
{
    jsval_t ret;
    __JSVAL_TYPE(ret) = JSV_UNDEFINED;
    return ret;
}

static inline jsval_t jsval_number(double n)
{
    jsval_t ret;
#ifdef JSVAL_DOUBLE_LAYOUT_PTR32
    ret.u.n = n;
    /* normalize NaN value */
    if((ret.u.s.tag & 0x7ff00000) == 0x7ff00000) {
        /* isinf */
        if(ret.u.s.tag & 0xfffff) {
            ret.u.s.tag = 0x7ff00000;
            ret.u.s.u.as_uintptr = ~0;
        }else if(ret.u.s.u.as_uintptr) {
            ret.u.s.tag = 0x7ff00000;
        }
    }
#else
    ret.type = JSV_NUMBER;
    ret.u.n = n;
#endif
    return ret;
}

static inline BOOL is_object_instance(jsval_t v)
{
    return __JSVAL_TYPE(v) == JSV_OBJECT;
}

static inline BOOL is_undefined(jsval_t v)
{
    return __JSVAL_TYPE(v) == JSV_UNDEFINED;
}

static inline BOOL is_null(jsval_t v)
{
    return __JSVAL_TYPE(v) == JSV_NULL;
}

static inline BOOL is_null_instance(jsval_t v)
{
    return is_null(v) || (is_object_instance(v) && !__JSVAL_OBJ(v));
}

static inline BOOL is_string(jsval_t v)
{
    return __JSVAL_TYPE(v) == JSV_STRING;
}

static inline BOOL is_number(jsval_t v)
{
#ifdef JSVAL_DOUBLE_LAYOUT_PTR32
    return (v.u.s.tag & 0x7ff80000) != 0x7ff80000;
#else
    return v.type == JSV_NUMBER;
#endif
}

static inline BOOL is_variant(jsval_t v)
{
    return __JSVAL_TYPE(v) == JSV_VARIANT;
}

static inline BOOL is_bool(jsval_t v)
{
    return __JSVAL_TYPE(v) == JSV_BOOL;
}

static inline jsval_type_t jsval_type(jsval_t v)
{
#ifdef JSVAL_DOUBLE_LAYOUT_PTR32
    return is_number(v) ? JSV_NUMBER : v.u.s.tag;
#else
    return v.type;
#endif
}

static inline IDispatch *get_object(jsval_t v)
{
    return __JSVAL_OBJ(v);
}

static inline double get_number(jsval_t v)
{
    return v.u.n;
}

static inline jsstr_t *get_string(jsval_t v)
{
    return __JSVAL_STR(v);
}

static inline VARIANT *get_variant(jsval_t v)
{
    return __JSVAL_VAR(v);
}

static inline BOOL get_bool(jsval_t v)
{
    return __JSVAL_BOOL(v);
}

HRESULT variant_to_jsval(VARIANT*,jsval_t*) DECLSPEC_HIDDEN;
HRESULT jsval_to_variant(jsval_t,VARIANT*) DECLSPEC_HIDDEN;
void jsval_release(jsval_t) DECLSPEC_HIDDEN;
HRESULT jsval_copy(jsval_t,jsval_t*) DECLSPEC_HIDDEN;

#endif
