/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Helper functions to access data fields in Objects.
 */
#ifndef _DALVIK_OO_OBJECTINLINES
#define _DALVIK_OO_OBJECTINLINES

/*
 * Store a single value in the array, and if the value isn't null,
 * note in the write barrier.
 */
INLINE void dvmSetObjectArrayElement(const ArrayObject* obj, int index,
                                     Object* val) {
    ((Object **)(obj)->contents)[index] = val;
    if (val != NULL) {
        dvmWriteBarrierArray(obj, index, index + 1);
    }
}


/*
 * Field access functions.  Pass in the word offset from Field->byteOffset.
 *
 * We guarantee that long/double field data is 64-bit aligned, so it's safe
 * to access them with ldrd/strd on ARM.
 *
 * The VM treats all fields as 32 or 64 bits, so the field set functions
 * write 32 bits even if the underlying type is smaller.
 *
 * Setting Object types to non-null values includes a call to the
 * write barrier.
 */
#define BYTE_OFFSET(_ptr, _offset)  ((void*) (((u1*)(_ptr)) + (_offset)))

INLINE JValue* dvmFieldPtr(const Object* obj, int offset) {
    return ((JValue*)BYTE_OFFSET(obj, offset));
}

INLINE bool dvmGetFieldBoolean(const Object* obj, int offset) {
    return ((JValue*)BYTE_OFFSET(obj, offset))->z;
}
INLINE s1 dvmGetFieldByte(const Object* obj, int offset) {
    return ((JValue*)BYTE_OFFSET(obj, offset))->b;
}
INLINE s2 dvmGetFieldShort(const Object* obj, int offset) {
    return ((JValue*)BYTE_OFFSET(obj, offset))->s;
}
INLINE u2 dvmGetFieldChar(const Object* obj, int offset) {
    return ((JValue*)BYTE_OFFSET(obj, offset))->c;
}
INLINE s4 dvmGetFieldInt(const Object* obj, int offset) {
    return ((JValue*)BYTE_OFFSET(obj, offset))->i;
}
INLINE s8 dvmGetFieldLong(const Object* obj, int offset) {
    return ((JValue*)BYTE_OFFSET(obj, offset))->j;
}
INLINE float dvmGetFieldFloat(const Object* obj, int offset) {
    return ((JValue*)BYTE_OFFSET(obj, offset))->f;
}
INLINE double dvmGetFieldDouble(const Object* obj, int offset) {
    return ((JValue*)BYTE_OFFSET(obj, offset))->d;
}
INLINE Object* dvmGetFieldObject(const Object* obj, int offset) {
    return ((JValue*)BYTE_OFFSET(obj, offset))->l;
}
INLINE bool dvmGetFieldBooleanVolatile(const Object* obj, int offset) {
    s4* ptr = &((JValue*)BYTE_OFFSET(obj, offset))->i;
    return (bool)android_atomic_acquire_load(ptr);
}
INLINE s1 dvmGetFieldByteVolatile(const Object* obj, int offset) {
    s4* ptr = &((JValue*)BYTE_OFFSET(obj, offset))->i;
    return (s1)android_atomic_acquire_load(ptr);
}
INLINE s2 dvmGetFieldShortVolatile(const Object* obj, int offset) {
    s4* ptr = &((JValue*)BYTE_OFFSET(obj, offset))->i;
    return (s2)android_atomic_acquire_load(ptr);
}
INLINE u2 dvmGetFieldCharVolatile(const Object* obj, int offset) {
    s4* ptr = &((JValue*)BYTE_OFFSET(obj, offset))->i;
    return (u2)android_atomic_acquire_load(ptr);
}
INLINE s4 dvmGetFieldIntVolatile(const Object* obj, int offset) {
    s4* ptr = &((JValue*)BYTE_OFFSET(obj, offset))->i;
    return android_atomic_acquire_load(ptr);
}
INLINE float dvmGetFieldFloatVolatile(const Object* obj, int offset) {
    union { s4 ival; float fval; } alias;
    s4* ptr = &((JValue*)BYTE_OFFSET(obj, offset))->i;
    alias.ival = android_atomic_acquire_load(ptr);
    return alias.fval;
}
INLINE s8 dvmGetFieldLongVolatile(const Object* obj, int offset) {
    const s8* addr = BYTE_OFFSET(obj, offset);
    s8 val = dvmQuasiAtomicRead64(addr);
    ANDROID_MEMBAR_FULL();
    return val;
}
INLINE double dvmGetFieldDoubleVolatile(const Object* obj, int offset) {
    union { s8 lval; double dval; } alias;
    const s8* addr = BYTE_OFFSET(obj, offset);
    alias.lval = dvmQuasiAtomicRead64(addr);
    ANDROID_MEMBAR_FULL();
    return alias.dval;
}
INLINE Object* dvmGetFieldObjectVolatile(const Object* obj, int offset) {
    void** ptr = &((JValue*)BYTE_OFFSET(obj, offset))->l;
    return (Object*)android_atomic_acquire_load((int32_t*)ptr);
}

INLINE void dvmSetFieldBoolean(Object* obj, int offset, bool val) {
    ((JValue*)BYTE_OFFSET(obj, offset))->i = val;
}
INLINE void dvmSetFieldByte(Object* obj, int offset, s1 val) {
    ((JValue*)BYTE_OFFSET(obj, offset))->i = val;
}
INLINE void dvmSetFieldShort(Object* obj, int offset, s2 val) {
    ((JValue*)BYTE_OFFSET(obj, offset))->i = val;
}
INLINE void dvmSetFieldChar(Object* obj, int offset, u2 val) {
    ((JValue*)BYTE_OFFSET(obj, offset))->i = val;
}
INLINE void dvmSetFieldInt(Object* obj, int offset, s4 val) {
    ((JValue*)BYTE_OFFSET(obj, offset))->i = val;
}
INLINE void dvmSetFieldFloat(Object* obj, int offset, float val) {
    ((JValue*)BYTE_OFFSET(obj, offset))->f = val;
}
INLINE void dvmSetFieldLong(Object* obj, int offset, s8 val) {
    ((JValue*)BYTE_OFFSET(obj, offset))->j = val;
}
INLINE void dvmSetFieldDouble(Object* obj, int offset, double val) {
    ((JValue*)BYTE_OFFSET(obj, offset))->d = val;
}
INLINE void dvmSetFieldObject(Object* obj, int offset, Object* val) {
    JValue* lhs = BYTE_OFFSET(obj, offset);
    lhs->l = val;
    if (val != NULL) {
        dvmWriteBarrierField(obj, &lhs->l);
    }
}
INLINE void dvmSetFieldIntVolatile(Object* obj, int offset, s4 val) {
    s4* ptr = &((JValue*)BYTE_OFFSET(obj, offset))->i;
    android_atomic_release_store(val, ptr);
}
INLINE void dvmSetFieldBooleanVolatile(Object* obj, int offset, bool val) {
    dvmSetFieldIntVolatile(obj, offset, val);
}
INLINE void dvmSetFieldByteVolatile(Object* obj, int offset, s1 val) {
    dvmSetFieldIntVolatile(obj, offset, val);
}
INLINE void dvmSetFieldShortVolatile(Object* obj, int offset, s2 val) {
    dvmSetFieldIntVolatile(obj, offset, val);
}
INLINE void dvmSetFieldCharVolatile(Object* obj, int offset, u2 val) {
    dvmSetFieldIntVolatile(obj, offset, val);
}
INLINE void dvmSetFieldFloatVolatile(Object* obj, int offset, float val) {
    union { s4 ival; float fval; } alias;
    alias.fval = val;
    dvmSetFieldIntVolatile(obj, offset, alias.ival);
}
INLINE void dvmSetFieldLongVolatile(Object* obj, int offset, s8 val) {
    s8* addr = BYTE_OFFSET(obj, offset);
    ANDROID_MEMBAR_FULL();
    dvmQuasiAtomicSwap64(val, addr);
}
INLINE void dvmSetFieldDoubleVolatile(Object* obj, int offset, double val) {
    union { s8 lval; double dval; } alias;
    alias.dval = val;
    dvmSetFieldLongVolatile(obj, offset, alias.lval);
}
INLINE void dvmSetFieldObjectVolatile(Object* obj, int offset, Object* val) {
    void** ptr = &((JValue*)BYTE_OFFSET(obj, offset))->l;
    android_atomic_release_store((int32_t)val, (int32_t*)ptr);
    if (val != NULL) {
        dvmWriteBarrierField(obj, ptr);
    }
}

/*
 * Static field access functions.
 */
INLINE JValue* dvmStaticFieldPtr(const StaticField* sfield) {
    return (JValue*)&sfield->value;
}

INLINE bool dvmGetStaticFieldBoolean(const StaticField* sfield) {
    return sfield->value.z;
}
INLINE s1 dvmGetStaticFieldByte(const StaticField* sfield) {
    return sfield->value.b;
}
INLINE s2 dvmGetStaticFieldShort(const StaticField* sfield) {
    return sfield->value.s;
}
INLINE u2 dvmGetStaticFieldChar(const StaticField* sfield) {
    return sfield->value.c;
}
INLINE s4 dvmGetStaticFieldInt(const StaticField* sfield) {
    return sfield->value.i;
}
INLINE float dvmGetStaticFieldFloat(const StaticField* sfield) {
    return sfield->value.f;
}
INLINE s8 dvmGetStaticFieldLong(const StaticField* sfield) {
    return sfield->value.j;
}
INLINE double dvmGetStaticFieldDouble(const StaticField* sfield) {
    return sfield->value.d;
}
INLINE Object* dvmGetStaticFieldObject(const StaticField* sfield) {
    return sfield->value.l;
}
INLINE bool dvmGetStaticFieldBooleanVolatile(const StaticField* sfield) {
    const s4* ptr = &(sfield->value.i);
    return (bool)android_atomic_acquire_load((s4*)ptr);
}
INLINE s1 dvmGetStaticFieldByteVolatile(const StaticField* sfield) {
    const s4* ptr = &(sfield->value.i);
    return (s1)android_atomic_acquire_load((s4*)ptr);
}
INLINE s2 dvmGetStaticFieldShortVolatile(const StaticField* sfield) {
    const s4* ptr = &(sfield->value.i);
    return (s2)android_atomic_acquire_load((s4*)ptr);
}
INLINE u2 dvmGetStaticFieldCharVolatile(const StaticField* sfield) {
    const s4* ptr = &(sfield->value.i);
    return (u2)android_atomic_acquire_load((s4*)ptr);
}
INLINE s4 dvmGetStaticFieldIntVolatile(const StaticField* sfield) {
    const s4* ptr = &(sfield->value.i);
    return android_atomic_acquire_load((s4*)ptr);
}
INLINE float dvmGetStaticFieldFloatVolatile(const StaticField* sfield) {
    union { s4 ival; float fval; } alias;
    const s4* ptr = &(sfield->value.i);
    alias.ival = android_atomic_acquire_load((s4*)ptr);
    return alias.fval;
}
INLINE s8 dvmGetStaticFieldLongVolatile(const StaticField* sfield) {
    const s8* addr = &sfield->value.j;
    s8 val = dvmQuasiAtomicRead64(addr);
    ANDROID_MEMBAR_FULL();
    return val;
}
INLINE double dvmGetStaticFieldDoubleVolatile(const StaticField* sfield) {
    union { s8 lval; double dval; } alias;
    const s8* addr = &sfield->value.j;
    alias.lval = dvmQuasiAtomicRead64(addr);
    ANDROID_MEMBAR_FULL();
    return alias.dval;
}
INLINE Object* dvmGetStaticFieldObjectVolatile(const StaticField* sfield) {
    void* const* ptr = &(sfield->value.l);
    return (Object*)android_atomic_acquire_load((int32_t*)ptr);
}

INLINE void dvmSetStaticFieldBoolean(StaticField* sfield, bool val) {
    sfield->value.i = val;
}
INLINE void dvmSetStaticFieldByte(StaticField* sfield, s1 val) {
    sfield->value.i = val;
}
INLINE void dvmSetStaticFieldShort(StaticField* sfield, s2 val) {
    sfield->value.i = val;
}
INLINE void dvmSetStaticFieldChar(StaticField* sfield, u2 val) {
    sfield->value.i = val;
}
INLINE void dvmSetStaticFieldInt(StaticField* sfield, s4 val) {
    sfield->value.i = val;
}
INLINE void dvmSetStaticFieldFloat(StaticField* sfield, float val) {
    sfield->value.f = val;
}
INLINE void dvmSetStaticFieldLong(StaticField* sfield, s8 val) {
    sfield->value.j = val;
}
INLINE void dvmSetStaticFieldDouble(StaticField* sfield, double val) {
    sfield->value.d = val;
}
INLINE void dvmSetStaticFieldObject(StaticField* sfield, Object* val) {
    sfield->value.l = val;
    if (val != NULL) {
        dvmWriteBarrierField((Object *)sfield->field.clazz, &sfield->value.l);
    }
}
INLINE void dvmSetStaticFieldIntVolatile(StaticField* sfield, s4 val) {
    s4* ptr = &sfield->value.i;
    android_atomic_release_store(val, ptr);
}
INLINE void dvmSetStaticFieldBooleanVolatile(StaticField* sfield, bool val) {
    dvmSetStaticFieldIntVolatile(sfield, val);
}
INLINE void dvmSetStaticFieldByteVolatile(StaticField* sfield, s1 val) {
    dvmSetStaticFieldIntVolatile(sfield, val);
}
INLINE void dvmSetStaticFieldShortVolatile(StaticField* sfield, s2 val) {
    dvmSetStaticFieldIntVolatile(sfield, val);
}
INLINE void dvmSetStaticFieldCharVolatile(StaticField* sfield, u2 val) {
    dvmSetStaticFieldIntVolatile(sfield, val);
}
INLINE void dvmSetStaticFieldFloatVolatile(StaticField* sfield, float val) {
    union { s4 ival; float fval; } alias;
    alias.fval = val;
    dvmSetStaticFieldIntVolatile(sfield, alias.ival);
}
INLINE void dvmSetStaticFieldLongVolatile(StaticField* sfield, s8 val) {
    s8* addr = &sfield->value.j;
    ANDROID_MEMBAR_FULL();
    dvmQuasiAtomicSwap64(val, addr);
}
INLINE void dvmSetStaticFieldDoubleVolatile(StaticField* sfield, double val) {
    union { s8 lval; double dval; } alias;
    alias.dval = val;
    dvmSetStaticFieldLongVolatile(sfield, alias.lval);
}
INLINE void dvmSetStaticFieldObjectVolatile(StaticField* sfield, Object* val) {
    void** ptr = &(sfield->value.l);
    android_atomic_release_store((int32_t)val, (int32_t*)ptr);
    if (val != NULL) {
        dvmWriteBarrierField((Object *)sfield->field.clazz, &sfield->value.l);
    }
}

#endif /*_DALVIK_OO_OBJECTINLINES*/
