text:
#define LOG_DOMAIN "vm.core"
#include "cxxlog.h"

#include "open/vm_properties.h"
#include "open/vm_type_access.h"
#include "open/vm_field_access.h"
#include "open/vm_method_access.h"
#include "open/vm_class_loading.h"
#include "open/vm_class_manipulation.h"
#include "open/vm_class_info.h"
#include "open/vm_ee.h"

#include "classloader.h"
#include "class_interface.h"
#include "Package.h"
#include "vtable.h"

#include "vm_arrays.h"
#include "compile.h"
#include "port_mutex.h"
#include "cci.h"
#include "nogc.h"
#include "exceptions.h"

BOOLEAN class_is_final(Class_Handle cl) {
    assert(cl);
    return cl->is_final();
}

BOOLEAN class_is_abstract(Class_Handle cl) {
    assert(cl);
    return cl->is_abstract();
}

BOOLEAN class_is_interface(Class_Handle cl) {
    assert(cl);
    return cl->is_interface();
}

BOOLEAN class_is_array(Class_Handle cl) {
    assert(cl);
    return cl->is_array();
} //class_is_array

static unsigned countLeadingChars(const char* str, char c) {
    U_32 n=0;
    while (str[n]==c) {
        n++;
    }
    return n;
}

unsigned class_cp_get_num_array_dimensions(Class_Handle cl, unsigned short cpIndex) {
    ConstantPool& cp  = cl->get_constant_pool();
    unsigned char tag = cp.get_tag(cpIndex);
    char c = '[';
    switch (tag) {
        case CONSTANT_Class: {
            uint16 nameIdx = cp.get_class_name_index(cpIndex);
            const char* str = cp.get_utf8_string(nameIdx)->bytes;
            return countLeadingChars(str, c);
        }
        case CONSTANT_Fieldref: {
            const char* str = class_cp_get_entry_descriptor(cl, cpIndex);
            return countLeadingChars(str, c);
        }
        default:
            assert(0);
    }
    return 0;
}

const char* class_get_package_name(Class_Handle cl) {
    assert(cl);
    return cl->get_package()->get_name()->bytes;
}

BOOLEAN method_is_abstract(Method_Handle m) {
    assert(m);
    return m->is_abstract();
} // method_is_abstract

BOOLEAN field_is_static(Field_Handle f)
{
    assert(f);
    return f->is_static();
}

BOOLEAN field_is_final(Field_Handle f)
{
    assert(f);
    return f->is_final();
}

BOOLEAN field_is_volatile(Field_Handle f)
{
    assert(f);
    return f->is_volatile();
}

BOOLEAN field_is_private(Field_Handle f)
{
    assert(f);
    return f->is_private();
}

BOOLEAN field_is_public(Field_Handle f)
{
    assert(f);
    return f->is_public();
}

unsigned field_get_offset(Field_Handle f)
{
    assert(f);
    assert(!f->is_static());
    return f->get_offset();
} //field_get_offset

void* field_get_address(Field_Handle f)
{
    assert(f);
    assert(f->is_static());
    return f->get_address();
} // field_get_address

const char* field_get_name(Field_Handle f)
{
    assert(f);
    return f->get_name()->bytes;
}

const char* field_get_descriptor(Field_Handle f)
{
    assert(f);
    return f->get_descriptor()->bytes;
}

Java_Type field_get_type(Field_Handle f)
{
    assert(f);
    return f->get_java_type();
} // field_get_type

unsigned field_get_flags(Field_Handle f)
{
    assert(f);
    return f->get_access_flags();
}

Class_Handle field_get_class(Field_Handle f)
{
    assert(f);
    return f->get_class();
} //field_get_class

void field_get_track_access_flag(Field_Handle f, char** address,
                                 char* mask)
{
    return f->get_track_access_flag(address, mask);
}

void field_get_track_modification_flag(Field_Handle f, char** address,
                                 char* mask)
{
    return f->get_track_modification_flag(address, mask);
}

BOOLEAN method_is_static(Method_Handle m)
{
    assert(m);
    return m->is_static();
} // method_is_static

BOOLEAN method_is_final(Method_Handle m)
{
    assert(m);
    return m->is_final();
} // method_is_final

BOOLEAN method_is_synchronized(Method_Handle m)
{
    assert(m);
    return m->is_synchronized();
} // method_is_synchronized

BOOLEAN method_is_private(Method_Handle m)
{
    assert(m);
    return m->is_private();
} // method_is_private

BOOLEAN method_is_strict(Method_Handle m)
{
    assert(m);
    return m->is_strict();
} // method_is_strict

BOOLEAN method_is_native(Method_Handle m)
{
    assert(m);
    return m->is_native();
} // method_is_native

U_8* method_allocate_info_block(Method_Handle m, JIT_Handle j, size_t size)
{
    assert(m);
    return (U_8*)(m->allocate_jit_info_block(size, (JIT *)j));
} //method_allocate_info_block

U_8* method_allocate_jit_data_block(Method_Handle m, JIT_Handle j, size_t size, size_t alignment)
{
    assert(m);
    return (U_8*)(m->allocate_JIT_data_block(size, (JIT *)j, alignment));
} //method_allocate_jit_data_block

U_8* method_get_info_block_jit(Method_Handle m, JIT_Handle j)
{
    assert(m);
    CodeChunkInfo *jit_info = m->get_chunk_info_no_create_mt((JIT *)j, CodeChunkInfo::main_code_chunk_id);
    if (jit_info == NULL) {
        return NULL;
    }
    return (U_8*)jit_info->_jit_info_block;
} //method_get_info_block_jit

unsigned method_get_info_block_size_jit(Method_Handle m, JIT_Handle j)
{
    assert(m);
    CodeChunkInfo *jit_info = ((Method *)m)->get_chunk_info_no_create_mt((JIT *)j, CodeChunkInfo::main_code_chunk_id);
    return jit_info == 0 ? 0 : (unsigned) jit_info->_jit_info_block_size;
} //method_get_info_block_size_jit

U_8* method_allocate_data_block(Method_Handle m, JIT_Handle j, size_t size, size_t alignment)
{
    assert(m);
    return (U_8*)(m->allocate_rw_data_block(size, alignment, (JIT*)j));
} //method_allocate_data_block

U_8*
method_allocate_code_block(Method_Handle m,
                           JIT_Handle j,
                           size_t size,
                           size_t alignment,
                           CodeBlockHeat heat,
                           int id,
                           Code_Allocation_Action action)
{
    assert(m);

    JIT *jit = (JIT *)j;
    assert(jit);

    U_32 drlHeat;
    if (heat == CodeBlockHeatMin)
        drlHeat = CODE_BLOCK_HEAT_COLD;
    else if (heat == CodeBlockHeatMax)
        drlHeat = CODE_BLOCK_HEAT_MAX/2;
    else {
        assert (heat == CodeBlockHeatDefault);
        drlHeat = CODE_BLOCK_HEAT_DEFAULT;
    }

    // the following method is safe to call from multiple threads
    U_8* code_block = (U_8*)m->allocate_code_block_mt(size, alignment, jit, drlHeat, id, action);

    return code_block;
} // method_allocate_code_block

U_8* method_get_code_block_jit(Method_Handle m, JIT_Handle j)
{
    assert(m);
    return method_get_code_block_addr_jit_new(m, j, 0);
} //method_get_code_block_addr_jit

unsigned method_get_code_block_size_jit(Method_Handle m, JIT_Handle j)
{
    assert(m);
    return method_get_code_block_size_jit_new(m, j, 0);
} //method_get_code_block_size_jit

U_8* method_get_code_block_addr_jit_new(Method_Handle method,
                                         JIT_Handle j,
                                         int id)
{
    assert(method);
    CodeChunkInfo* jit_info = method->get_chunk_info_no_create_mt((JIT *)j, id);
    assert(jit_info);
    return (U_8*)jit_info->get_code_block_addr();
} //method_get_code_block_addr_jit_new

unsigned method_get_code_block_size_jit_new(Method_Handle method,
                                            JIT_Handle j,
                                            int id)
{
    assert(method);
    CodeChunkInfo *jit_info = ((Method *)method)->get_chunk_info_no_create_mt((JIT *)j, id);
    return jit_info == 0 ? 0 :(unsigned) jit_info->get_code_block_size();
} //method_get_code_block_size_jit_new

const U_8* method_get_bytecode(Method_Handle m)
{
    assert(m);
    return m->get_byte_code_addr();
}

U_32
method_get_bytecode_length(Method_Handle m)
{
    assert(m);
    return m->get_byte_code_size();
}

U_32 method_get_max_locals(Method_Handle m)
{
    assert(m);
    return m->get_max_locals();
}

uint16 method_get_max_stack(Method_Handle m)
{
    assert(m);
    return m->get_max_stack();
}

size_t  method_get_vtable_offset(Method_Handle m)
{
    assert(m);
    return m->get_offset();
}

void *method_get_indirect_address(Method_Handle m)
{
    assert(m);
    return m->get_indirect_address();
} //method_get_indirect_address

const char *
method_get_name(Method_Handle m)
{
    assert(m);
    return m->get_name()->bytes;
}

const char* method_get_descriptor(Method_Handle m)
{
    assert(m);
    return m->get_descriptor()->bytes;
}

Class_Handle method_get_class(Method_Handle m)
{
    assert(m);
    return m->get_class();
}

void method_lock(Method_Handle m)
{
    assert(m);
    return m->lock();
}

void method_unlock(Method_Handle m)
{
    assert(m);
    return m->unlock();
}

Java_Type method_get_return_type(Method_Handle m)
{
    assert(m);
    return m->get_return_java_type();
}

BOOLEAN method_is_overridden(Method_Handle m)
{
    assert(m);
    return m->is_overridden();
} // method_is_overridden

const char* class_get_name(Class_Handle cl)
{
    assert(cl);
    return cl->get_name()->bytes;
} //class_get_name

unsigned short class_get_version(Class_Handle klass)
{
    assert(klass);
    return klass->get_version();
} // class_get_version

unsigned class_get_flags(Class_Handle cl)
{
    assert(cl);
    return cl->get_access_flags();
} //class_get_flags

U_32 class_get_depth(Class_Handle cl)
{
    assert(cl);
    return cl->get_depth();
} //class_get_depth

BOOLEAN class_is_support_fast_instanceof(Class_Handle cl)
{
    assert(cl);
    return cl->get_fast_instanceof_flag();
} //class_get_depth

Class_Handle vtable_get_class(VTable_Handle vh) {
    return vh->clss;
} // vtable_get_class

BOOLEAN class_is_initialized(Class_Handle ch)
{
    assert(ch);
    return ch->is_initialized();
} //class_is_initialized

Class_Handle class_get_super_class(Class_Handle cl)
{
    assert(cl);
    return cl->get_super_class();
} // class_get_super_class

Class_Handle class_get_extended_class(Class_Handle klass, const char* super_name)
{
    assert(klass);
    assert(super_name);

    Global_Env* env = VM_Global_State::loader_env;
    String* pooled_name = env->string_pool.lookup(super_name);

    for(Class* clss = klass; clss; clss = clss->get_super_class()) {
        if(clss->get_name() == pooled_name) {
            // found class with given name
            return clss;
        }
    }
    return NULL;
} // class_get_extended_class

unsigned class_number_implements(Class_Handle ch)
{
    assert(ch);
    return ch->get_number_of_superinterfaces();
}

Class_Handle class_get_implements(Class_Handle ch, unsigned idx)
{
    assert(ch);
    return ch->get_superinterface(idx);
}

Class_Handle class_get_declaring_class(Class_Handle ch)
{
    return ch->resolve_declaring_class(VM_Global_State::loader_env);
}

unsigned class_number_inner_classes(Class_Handle ch)
{
    assert(ch);
    return ch->get_number_of_inner_classes();
}

Boolean class_is_inner_class_public(Class_Handle ch, unsigned idx)
{
    assert(ch);
    return (ch->get_inner_class_access_flags(idx) & ACC_PUBLIC) != 0;
}

Class_Handle class_get_inner_class(Class_Handle ch, unsigned idx)
{
    assert(ch);
    uint16 cp_index = ch->get_inner_class_index(idx);
    return ch->_resolve_class(VM_Global_State::loader_env, cp_index);
}

BOOLEAN class_is_instanceof(Class_Handle s, Class_Handle t)
{
    assert(s);
    assert(t);
    return class_is_subtype(s, t);
} // class_is_instanceof

unsigned class_get_array_element_size(Class_Handle ch)
{
    assert(ch);
    return ch->get_array_element_size();
}

Class_Handle class_get_array_element_class(Class_Handle cl)
{
    assert(cl);
    return cl->get_array_element_class();
} //class_get_array_element_class

BOOLEAN class_is_throwable(Class_Handle ch)
{
    assert(ch);
    Global_Env *env = VM_Global_State::loader_env;
    Class *exc_base_clss = env->java_lang_Throwable_Class;
    while(ch != NULL) {
        if(ch == exc_base_clss) {
            return TRUE;
        }
        //sundr printf("class name before super: %s %p\n", ch->name->bytes, ch);
        ch = class_get_super_class(ch);
    }
    return FALSE;
} // class_is_throwable

Class_Handle class_get_class_of_primitive_type(VM_Data_Type typ)
{
    Global_Env *env = VM_Global_State::loader_env;
    Class *clss = NULL;
    switch(typ) {
    case VM_DATA_TYPE_INT8:
        clss = env->Byte_Class;
        break;
    case VM_DATA_TYPE_INT16:
        clss = env->Short_Class;
        break;
    case VM_DATA_TYPE_INT32:
        clss = env->Int_Class;
        break;
    case VM_DATA_TYPE_INT64:
        clss = env->Long_Class;
        break;
    case VM_DATA_TYPE_F8:
        clss = env->Double_Class;
        break;
    case VM_DATA_TYPE_F4:
        clss = env->Float_Class;
        break;
    case VM_DATA_TYPE_BOOLEAN:
        clss = env->Boolean_Class;
        break;
    case VM_DATA_TYPE_CHAR:
        clss = env->Char_Class;
        break;
    case VM_DATA_TYPE_VOID:
        clss = env->Void_Class;
        break;
    case VM_DATA_TYPE_INTPTR:
    case VM_DATA_TYPE_UINTPTR:
    case VM_DATA_TYPE_UINT8:
    case VM_DATA_TYPE_UINT16:
    case VM_DATA_TYPE_UINT32:
    case VM_DATA_TYPE_UINT64:
        clss = NULL;    // to allow star jit initialization
        break;
    default:
        LDIE(69, "Unknown vm data type");          // We need a better way to indicate an internal error
    }
    return clss;
} // class_get_class_of_primitive_type

VTable_Handle class_get_vtable(Class_Handle cl)
{
    assert(cl);
    return cl->get_vtable();
} //class_get_vtable

const char* class_get_source_file_name(Class_Handle cl)
{
    assert(cl);
    if(!cl->has_source_information())
        return NULL;
    return cl->get_source_file_name();
} // class_get_source_file_name

const char* class_cp_get_const_string(Class_Handle cl, U_16 index)
{
    assert(cl);
    return cl->get_constant_pool().get_string_chars(index);
} //class_get_const_string

// Returns the address where the interned version of the string is stored: this will be the address
// of a slot containing a Java_java_lang_String* or a U_32 compressed reference. Also interns the
// string so that the JIT can load a reference to the interned string without checking if it is null.
const void *class_get_const_string_intern_addr(Class_Handle cl, unsigned short index)
{
    assert(cl);
    Global_Env* env = VM_Global_State::loader_env;
    String* str = cl->get_constant_pool().get_string(index);
    assert(str);

    assert((void *)(&(str->intern.raw_ref)) == (void *)(&(str->intern.compressed_ref)));
    return &(str->intern.raw_ref);

} //class_get_const_string_intern_addr

const char* class_cp_get_entry_descriptor(Class_Handle src_class, unsigned short index)
{
    ConstantPool& cp = src_class->get_constant_pool();
    if(!(cp.is_fieldref(index)
        || cp.is_methodref(index)
        || cp.is_interfacemethodref(index)))
    {
        return NULL;
    }

    index = cp.get_ref_name_and_type_index(index);
    index = cp.get_name_and_type_descriptor_index(index);
    return cp.get_utf8_chars(index);
} // class_cp_get_entry_descriptor

VM_Data_Type class_cp_get_field_type(Class_Handle src_class, U_16 cp_index)
{
    assert(src_class->get_constant_pool().is_fieldref(cp_index));

    char class_id = (class_cp_get_entry_descriptor(src_class, cp_index))[0];
    switch(class_id)
    {
    case VM_DATA_TYPE_BOOLEAN:
    case VM_DATA_TYPE_CHAR:
    case VM_DATA_TYPE_INT8:
    case VM_DATA_TYPE_INT16:
    case VM_DATA_TYPE_INT32:
    case VM_DATA_TYPE_INT64:
    case VM_DATA_TYPE_F4:
    case VM_DATA_TYPE_F8:
        return (VM_Data_Type)class_id;
    case VM_DATA_TYPE_ARRAY:
    case VM_DATA_TYPE_CLASS:
        return VM_DATA_TYPE_CLASS;
    default:
        LDIE(69, "Unknown vm data type");
    }
    return VM_DATA_TYPE_INVALID;
} // class_cp_get_field_type

VM_Data_Type class_cp_get_const_type(Class_Handle cl, U_16 index)
{
    assert(cl);
    Java_Type jt = JAVA_TYPE_INVALID;
    ConstantPool& cp = cl->get_constant_pool();
    switch(cp.get_tag(index)) {
    case CONSTANT_String:
        jt = JAVA_TYPE_STRING;
        break;
    case CONSTANT_Integer:
        jt = JAVA_TYPE_INT;
        break;
    case CONSTANT_Float:
        jt = JAVA_TYPE_FLOAT;
        break;
    case CONSTANT_Long:
        jt = JAVA_TYPE_LONG;
        break;
    case CONSTANT_Double:
        jt = JAVA_TYPE_DOUBLE;
        break;
    case CONSTANT_Class:
        jt = JAVA_TYPE_CLASS;
        break;
    case CONSTANT_UnusedEntry:
        if(cp.get_tag(index - 1) == CONSTANT_Double) {
            jt = JAVA_TYPE_DOUBLE;
            break;
        } else if(cp.get_tag(index - 1) == CONSTANT_Long) {
            jt = JAVA_TYPE_LONG;
            break;
        }
    default:
        LDIE(5, "non-constant type is requested from constant pool : {0}" << cp.get_tag(index));
    }

    return (VM_Data_Type)jt;
} //class_cp_get_const_type

const void *class_cp_get_const_addr(Class_Handle cl, U_16 index)
{
    assert(cl);
    return cl->get_constant_pool().get_address_of_constant(index);
} //class_cp_get_const_addr

void* method_get_native_func_addr(Method_Handle method) {
    return (void*)classloader_find_native(method);
}

Arg_List_Iterator method_get_argument_list(Method_Handle m)
{
    assert(m);
    return (Arg_List_Iterator)((Method *)m)->get_argument_list();
}

Class_Handle resolve_class_from_constant_pool(Class_Handle c_handle, unsigned index)
{
    assert(c_handle);
    return c_handle->_resolve_class(VM_Global_State::loader_env, index);
}

Field_Handle class_resolve_nonstatic_field(Class_Handle clss, unsigned short cp_index)
{
    assert(clss);
    Field* f = clss->_resolve_field(VM_Global_State::loader_env, cp_index);
    return (!f || f->is_static()) ? NULL : f;
} // class_resolve_nonstatic_field

Class_Loader_Handle
class_get_class_loader(Class_Handle ch)
{
    assert(ch);
    return ch->get_class_loader();
} //class_get_class_loader

Class_Handle
vm_load_class_with_bootstrap(const char *name)
{
    Global_Env *env = VM_Global_State::loader_env;
    String *n = env->string_pool.lookup(name);
    return env->bootstrap_class_loader->LoadClass(env, n);
}

Class_Handle
vm_lookup_class_with_bootstrap(const char* name)
{
    Global_Env *env = VM_Global_State::loader_env;
    String *n = env->string_pool.lookup(name);
    Class *clss = env->bootstrap_class_loader->LookupClass(n);
    return (Class_Handle)clss;
}

Class_Handle
class_load_class_by_descriptor(const char *descr,
                               Class_Handle ch)
{
    assert(ch);
    Global_Env *env = VM_Global_State::loader_env;
    String *n;
    switch(descr[0]) {
    case '[':
        n = env->string_pool.lookup(descr);
        break;
    case 'L':
        {
            int len = (int) strlen(descr);
            n = env->string_pool.lookup(descr + 1, len - 2);
        }
        break;
    case 'B':
        return env->Byte_Class;
    case 'C':
        return env->Char_Class;
    case 'D':
        return env->Double_Class;
    case 'F':
        return env->Float_Class;
    case 'I':
        return env->Int_Class;
    case 'J':
        return env->Long_Class;
    case 'S':
        return env->Short_Class;
    case 'Z':
        return env->Boolean_Class;
    default:
        n = 0;
    }
    assert(n);
    return ch->get_class_loader()->LoadClass(env, n);;
} //class_load_class_by_descriptor

//
// The following do not cause constant pools to be resolve, if they are not
// resolved already
//
const char* class_cp_get_entry_name(Class_Handle cl, U_16 index)
{
    assert(cl);
    ConstantPool& const_pool = cl->get_constant_pool();
    if (!(const_pool.is_fieldref(index)
        || const_pool.is_methodref(index)
        || const_pool.is_interfacemethodref(index)))
    {
        LDIE(70, "Wrong index");
        return 0;
    }
    index = const_pool.get_ref_name_and_type_index(index);
    index = const_pool.get_name_and_type_name_index(index);
    return const_pool.get_utf8_chars(index);
} // class_cp_get_entry_name

const char* class_cp_get_entry_class_name(Class_Handle cl, unsigned short index)
{
    assert(cl);
    ConstantPool& const_pool = cl->get_constant_pool();
    if (!(const_pool.is_fieldref(index)
        || const_pool.is_methodref(index)
        || const_pool.is_interfacemethodref(index)))
    {
        LDIE(70, "Wrong index");
        return 0;
    }
    index = const_pool.get_ref_class_index(index);
    return class_cp_get_class_name(cl,index);
} // class_cp_get_entry_class_name

const char* class_cp_get_class_name(Class_Handle cl, unsigned short index)
{
    assert(cl);
    ConstantPool& const_pool = cl->get_constant_pool();
    if (!const_pool.is_class(index)) {
        LDIE(70, "Wrong index");
        return 0;
    }
    return const_pool.get_utf8_chars(const_pool.get_class_name_index(index));
} // class_cp_get_class_name

Class_Handle method_get_throws(Method_Handle mh, unsigned idx)
{
    assert(hythread_is_suspend_enabled());
    assert(mh);
    Method* m = (Method*)mh;
    String* exn_name = m->get_exception_name(idx);
    if (!exn_name) return NULL;
    ClassLoader* class_loader = m->get_class()->get_class_loader();
    Class *c =
        class_loader->LoadVerifyAndPrepareClass(VM_Global_State::loader_env, exn_name);
    // if loading failed - exception should be raised
    assert((!c && exn_raised()) || (c && !exn_raised()));
    return c;
}

uint16 method_get_exc_handler_number(Method_Handle m)
{
    assert(m);
    return m->num_bc_exception_handlers();
} // method_get_exc_handler_number

void method_get_exc_handler_info(Method_Handle m,
                                 uint16 handler_id,
                                 uint16* begin_offset,
                                 uint16* end_offset,
                                 uint16* handler_offset,
                                 uint16* handler_cpindex)
{
    assert(m);
    Handler* h = m->get_bc_exception_handler_info(handler_id);
    *begin_offset    = h->get_start_pc();
    *end_offset      = h->get_end_pc();
    *handler_offset  = h->get_handler_pc();
    *handler_cpindex = h->get_catch_type_index();
}

void method_set_num_target_handlers(Method_Handle m,
                                    JIT_Handle j,
                                    unsigned num_handlers)
{
    assert(m);
    ((Method *)m)->set_num_target_exception_handlers((JIT *)j, num_handlers);
} //method_set_num_target_handlers

void method_set_target_handler_info(Method_Handle m,
                                    JIT_Handle    j,
                                    unsigned      eh_number,
                                    void         *start_ip,
                                    void         *end_ip,
                                    void         *handler_ip,
                                    Class_Handle  catch_cl,
                                    Boolean       exc_obj_is_dead)
{
    assert(m);
    ((Method *)m)->set_target_exception_handler_info((JIT *)j,
                                                     eh_number,
                                                     start_ip,
                                                     end_ip,
                                                     handler_ip,
                                                     (Class *)catch_cl,
                                                     (exc_obj_is_dead == TRUE));
} //method_set_target_handler_info

Method_Side_Effects method_get_side_effects(Method_Handle m)
{
    assert(m);
    return ((Method *)m)->get_side_effects();
} //method_get_side_effects

void method_set_side_effects(Method_Handle m, Method_Side_Effects mse)
{
    assert(m);
    ((Method *)m)->set_side_effects(mse);
} //method_set_side_effects

Method_Handle class_lookup_method_recursively(Class_Handle clss,
                                              const char *name,
                                              const char *descr)
{
    assert(clss);
    return (Method_Handle) class_lookup_method_recursive((Class *)clss, name, descr);
} //class_lookup_method_recursively

size_t object_get_vtable_offset()
{
    return 0;
} //object_get_vtable_offset

Class_Handle vm_get_system_object_class()
{
    Global_Env *env = VM_Global_State::loader_env;
    return env->JavaLangObject_Class;
} // vm_get_system_object_class

Class_Handle vm_get_system_class_class()
{
    Global_Env *env = VM_Global_State::loader_env;
    return env->JavaLangClass_Class;
} // vm_get_system_class_class

Class_Handle vm_get_system_string_class()
{
    Global_Env *env = VM_Global_State::loader_env;
    return env->JavaLangString_Class;
} // vm_get_system_string_class

BOOLEAN field_is_literal(Field_Handle fh)
{
    assert(fh);
    Field *f = (Field *)fh;
    return f->get_const_value_index() != 0;
} //field_is_literal

int vector_first_element_offset_unboxed(Class_Handle element_type)
{
    assert(element_type);
    Class *clss = (Class *)element_type;
    int offset = 0;
    if(clss->is_primitive()) {
        Global_Env *env = VM_Global_State::loader_env;
        if(clss == env->Double_Class) {
            offset = VM_VECTOR_FIRST_ELEM_OFFSET_8;
        } else if(clss == env->Long_Class) {
            offset = VM_VECTOR_FIRST_ELEM_OFFSET_8;
        } else {
            offset = VM_VECTOR_FIRST_ELEM_OFFSET_1_2_4;
        }
    } else {
        offset = VM_VECTOR_FIRST_ELEM_OFFSET_REF;
    }
    assert(offset);
    return offset;
} //vector_first_element_offset_unboxed

int vector_first_element_offset(VM_Data_Type element_type)
{
    switch(element_type) {
    case VM_DATA_TYPE_CLASS:
        return VM_VECTOR_FIRST_ELEM_OFFSET_REF;
    default:
        {
            Class_Handle elem_class = class_get_class_of_primitive_type(element_type);
            return vector_first_element_offset_unboxed(elem_class);
        }
    }
} //vector_first_element_offset

int vector_first_element_offset_class_handle(Class_Handle element_type)
{
    return vector_first_element_offset_unboxed(element_type);
    //return VM_VECTOR_FIRST_ELEM_OFFSET_REF;
}

Boolean method_is_java(Method_Handle mh)
{
    assert(mh);
    return TRUE;
} //method_is_java

BOOLEAN class_is_enum(Class_Handle ch)
{
    assert(ch);
    return ch->is_enum() ? TRUE : FALSE;
} // class_is_enum

static Class *class_get_array_of_primitive_type(VM_Data_Type typ)
{
    Global_Env *env = VM_Global_State::loader_env;
    Class *clss = NULL;
    switch(typ) {
    case VM_DATA_TYPE_INT8:
        clss = env->ArrayOfByte_Class;
        break;
    case VM_DATA_TYPE_INT16:
        clss = env->ArrayOfShort_Class;
        break;
    case VM_DATA_TYPE_INT32:
        clss = env->ArrayOfInt_Class;
        break;
    case VM_DATA_TYPE_INT64:
        clss = env->ArrayOfLong_Class;
        break;
    case VM_DATA_TYPE_F8:
        clss = env->ArrayOfDouble_Class;
        break;
    case VM_DATA_TYPE_F4:
        clss = env->ArrayOfFloat_Class;
        break;
    case VM_DATA_TYPE_BOOLEAN:
        clss = env->ArrayOfBoolean_Class;
        break;
    case VM_DATA_TYPE_CHAR:
        clss = env->ArrayOfChar_Class;
        break;
    case VM_DATA_TYPE_UINT8:
    case VM_DATA_TYPE_UINT16:
    case VM_DATA_TYPE_UINT32:
    case VM_DATA_TYPE_UINT64:
    case VM_DATA_TYPE_INTPTR:
    case VM_DATA_TYPE_UINTPTR:
    default:
        DIE(("Unexpected vm data type"));          // We need a better way to indicate an internal error
        break;
    }
    return clss;
} // class_get_array_of_primitive_type

BOOLEAN class_is_primitive(Class_Handle ch)
{
    assert(ch);
    return ch->is_primitive();
} // class_is_primitive

VM_Data_Type class_get_primitive_type_of_class(Class_Handle ch)
{
    assert(ch);
    Global_Env *env = VM_Global_State::loader_env;
    if (ch == env->Boolean_Class)
        return VM_DATA_TYPE_BOOLEAN;
    if (ch == env->Char_Class)
        return VM_DATA_TYPE_CHAR;
    if (ch == env->Byte_Class)
        return VM_DATA_TYPE_INT8;
    if (ch == env->Short_Class)
        return VM_DATA_TYPE_INT16;
    if (ch == env->Int_Class)
        return VM_DATA_TYPE_INT32;
    if (ch == env->Long_Class)
        return VM_DATA_TYPE_INT64;
    if (ch == env->Float_Class)
        return VM_DATA_TYPE_F4;
    if (ch == env->Double_Class)
        return VM_DATA_TYPE_F8;

    return VM_DATA_TYPE_CLASS;
} // class_get_primitive_type_of_class

// Returns the number of arguments defined for the method.
// This number includes the this pointer (if present).
unsigned char method_args_get_number(Method_Signature_Handle mh)
{
    assert(mh);
    assert(!mh->sig);
    return mh->method->get_num_args();
} // method_args_get_number

// 20020303 At the moment we resolve the return type eagerly, but
// arguments are resolved lazily.  We should rewrite return type resolution
// to be lazy too.
void Method_Signature::initialize_from_java_method(Method *meth)
{
    assert(meth);
    num_args = meth->get_num_args();

    ClassLoader* cl = meth->get_class()->get_class_loader();
    const char* d = meth->get_descriptor()->bytes;
    assert(d[0]=='(');
    d++;
    arg_type_descs = (TypeDesc**)STD_MALLOC(sizeof(TypeDesc*)*num_args);
    assert(arg_type_descs);
    unsigned cur = 0;
    if (!meth->is_static()) {
        arg_type_descs[cur] = type_desc_create_from_java_class(meth->get_class());
        assert(arg_type_descs[cur]);
        cur++;
    }
    while (d[0]!=')') {
        assert(cur<num_args);
        arg_type_descs[cur] = type_desc_create_from_java_descriptor(d, cl);
        assert(arg_type_descs[cur]);
        cur++;
        // Advance d to next argument
        while (d[0]=='[') d++;
        d++;
        if (d[-1]=='L') {
            while(d[0]!=';') d++;
            d++;
        }
    }
    assert(cur==num_args);
    d++;
    return_type_desc = type_desc_create_from_java_descriptor(d, cl);
    assert(return_type_desc);
} //Method_Signature::initialize_from_java_method

void Method_Signature::reset()
{
    return_type_desc = 0;
    if (arg_type_descs)
        STD_FREE(arg_type_descs);

    num_args         = 0;
    arg_type_descs   = 0;
    method           = 0;
    sig              = 0;
} //Method_Signature::reset

void Method_Signature::initialize_from_method(Method *meth)
{
    assert(meth);
    reset();
    method      = meth;
    initialize_from_java_method(meth);
} //Method_Signature::initialize_from_method

Method_Signature_Handle method_get_signature(Method_Handle mh)
{
    assert(mh);
    Method *m = (Method *)mh;
    Method_Signature *ms = m->get_method_sig();
    if(!ms) {
        ms = new Method_Signature();

        if (ms == NULL) {
            exn_raise_object(VM_Global_State::loader_env->java_lang_OutOfMemoryError);
            return NULL;
        }

        assert(ms);
        ms->initialize_from_method(m);
        m->set_method_sig(ms);
    }
    return ms;
} // method_get_signature

U_16 class_number_fields(Class_Handle ch)
{
    assert(ch);
    return ch->get_number_of_fields();
}

unsigned class_num_instance_fields(Class_Handle ch)
{
    assert(ch);
    return ch->get_number_of_fields() - ch->get_number_of_static_fields();
} //class_num_instance_fields

unsigned class_num_instance_fields_recursive(Class_Handle ch)
{
    assert(ch);
    unsigned num_inst_fields = 0;
    while(ch) {
        num_inst_fields += class_num_instance_fields(ch);
        ch = class_get_super_class(ch);
    }
    return num_inst_fields;
} // class_num_instance_fields_recursive

Field_Handle class_get_field(Class_Handle ch, U_16 idx)
{
    assert(ch);
    if(idx >= ch->get_number_of_fields()) return NULL;
    return ch->get_field(idx);
} // class_get_field

Method_Handle class_get_method_by_name(Class_Handle ch, const char* name)
{
    assert(ch);
    for(int idx = 0; idx < ch->get_number_of_methods(); idx++) {
        Method_Handle meth = ch->get_method(idx);
        if(strcmp(meth->get_name()->bytes, name) == 0) {
            return meth;
        }
    }
    return NULL;
} // class_get_method_by_name

Field_Handle class_get_field_by_name(Class_Handle ch, const char* name)
{
    assert(ch);
    for(int idx = 0; idx < ch->get_number_of_fields(); idx++) {
        Field_Handle fld = ch->get_field(idx);
        if(strcmp(fld->get_name()->bytes, name) == 0) {
            return fld;
        }
    }
    return NULL;
} // class_get_field_by_name

Field_Handle class_get_instance_field(Class_Handle ch, unsigned idx)
{
    assert(ch);
    return ch->get_field(ch->get_number_of_static_fields() + idx);
} // class_get_instance_field

Field_Handle class_get_instance_field_recursive(Class_Handle ch, unsigned idx)
{
    assert(ch);
    unsigned num_fields_recursive = class_num_instance_fields_recursive(ch);
    assert(idx < num_fields_recursive);
    while(ch) {
        unsigned num_fields = class_num_instance_fields(ch);
        unsigned num_inherited_fields = num_fields_recursive - num_fields;
        if(idx >= num_inherited_fields) {
            Field_Handle fh = class_get_instance_field(ch, idx - num_inherited_fields);
            return fh;
        }
        num_fields_recursive = num_inherited_fields;
        ch = class_get_super_class(ch);
    }
    return 0;
} // class_get_instance_field_recursive

unsigned class_get_number_methods(Class_Handle ch)
{
    assert(ch);
    return ch->get_number_of_methods();
} // class_get_number_methods

// -gc magic needs this to do the recursive load.
Class_Handle field_get_class_of_field_type(Field_Handle fh)
{
    assert(hythread_is_suspend_enabled());
    assert(fh);
    Class_Handle ch = class_load_class_by_descriptor(field_get_descriptor(fh),
                                          field_get_class(fh));
    if(!ch->verify(VM_Global_State::loader_env))
        return NULL;
    if(!ch->prepare(VM_Global_State::loader_env))
        return NULL;
    return ch;
} // field_get_class_of_field_type

BOOLEAN field_is_reference(Field_Handle fh)
{
    assert((Field *)fh);
    Java_Type typ = fh->get_java_type();
    return (typ == JAVA_TYPE_CLASS || typ == JAVA_TYPE_ARRAY);
} //field_is_reference

BOOLEAN field_is_magic(Field_Handle fh)
{
    assert((Field *)fh);

    return fh->is_magic_type();
} //field_is_magic

Boolean field_is_enumerable_reference(Field_Handle fh)
{
    assert((Field *)fh);
    return ((field_is_reference(fh) && !field_is_magic(fh)));
} //field_is_enumerable_reference

BOOLEAN field_is_injected(Field_Handle f)
{
    assert(f);
    return f->is_injected();
} //field_is_injected

/////////////////////////////////////////////////////////////////////
// New GC interface demo

// This is just for the purposes of the demo.  The GC is free to define
// whatever it wants in this structure, as long as it doesn't exceed the
// size limit.  What should the size limit be?

struct GC_VTable {
    Class_Handle ch;  // for debugging
    U_32 num_ref_fields;
    U_32 *ref_fields_offsets;
    unsigned is_array : 1;
    unsigned is_primitive : 1;
};

#define VERBOSE_GC_CLASS_PREPARED 0

/////////////////////////////////////////////////////////////////////
//  New signature stuff

Type_Info_Handle method_args_get_type_info(Method_Signature_Handle msh,
                                           unsigned idx)
{
    assert(msh);
    Method_Signature *ms = (Method_Signature *)msh;
    if(idx >= ms->num_args) {
        LDIE(70, "Wrong index");
        return 0;
    }
    assert(ms->arg_type_descs);
    return ms->arg_type_descs[idx];
} //method_args_get_type_info

Type_Info_Handle method_ret_type_get_type_info(Method_Signature_Handle msh)
{
    assert(msh);
    Method_Signature *ms = (Method_Signature *)msh;
    return ms->return_type_desc;
} //method_ret_type_get_type_info

Type_Info_Handle field_get_type_info(Field_Handle fh)
{
    assert(fh);
    Field *field = (Field *)fh;
    TypeDesc* td = field->get_field_type_desc();
    assert(td);
    return td;
} // field_get_type_info

/////////////////////////////////////////////////////
// New GC stuff

BOOLEAN class_is_non_ref_array(Class_Handle ch)
{
    assert(ch);
    // Use the if statement to normalize the value of TRUE
    if((ch->get_vtable()->class_properties & CL_PROP_NON_REF_ARRAY_MASK) != 0)
    {
        assert(ch->is_array());
        return TRUE;
    } else {
        return FALSE;
    }
} // class_is_non_ref_array

BOOLEAN class_is_finalizable(Class_Handle ch)
{
    assert(ch);
    assert(ch->has_finalizer() ==
        ((ch->get_vtable()->class_properties & CL_PROP_FINALIZABLE_MASK) != 0));
    return ch->has_finalizer() ? TRUE : FALSE;
} // class_is_finalizable

WeakReferenceType class_is_reference(Class_Handle clss)
{
    assert(clss);
    if(class_get_extended_class(clss, "java/lang/ref/WeakReference") != NULL)
        return WEAK_REFERENCE;
    else if(class_get_extended_class(clss, "java/lang/ref/SoftReference") != NULL)
        return SOFT_REFERENCE;
    else if(class_get_extended_class(clss, "java/lang/ref/PhantomReference") != NULL)
        return PHANTOM_REFERENCE;
    else
        return NOT_REFERENCE;
}

unsigned class_get_referent_offset(Class_Handle ch)
{
    Field_Handle referent =
        class_lookup_field_recursive(ch, "referent", "Ljava/lang/Object;");
    if (!referent) {
        LDIE(6, "Class {0} has no 'Object referent' field" << class_get_name(ch));
    }
    return referent->get_offset();
}

void* class_alloc_via_classloader(Class_Handle ch, I_32 size)
{
    assert(ch);
    assert(size >= 0);
    Class *clss = (Class *)ch;
    assert (clss->get_class_loader());
    return clss->get_class_loader()->Alloc(size);
} //class_alloc_via_classloader

unsigned class_get_alignment(Class_Handle ch)
{
    assert(ch);
    return (unsigned)(ch->get_vtable()->class_properties
        & CL_PROP_ALIGNMENT_MASK);
} //class_get_alignment

//
// Returns the size of an element in the array class.
//
unsigned class_element_size(Class_Handle ch)
{
    assert(ch);
    return ch->get_array_element_size();
} //class_element_size

size_t class_get_object_size(Class_Handle ch)
{
    assert(ch);
    return ch->get_allocated_size();
} //class_get_object_size

static struct {
    const char* c;
    const char* m;
    const char* d;
} no_inlining_table[] = {
    { "java/lang/ClassLoader", "getCallerClassLoader", "()Ljava/lang/ClassLoader;" },
    { "java/lang/Class", "forName", "(Ljava/lang/String;)Ljava/lang/Class;" },
};

static unsigned no_inlining_table_count = sizeof(no_inlining_table)/sizeof(no_inlining_table[0]);

BOOLEAN method_is_no_inlining(Method_Handle mh)
{
    assert(mh);
    const char* c = class_get_name(method_get_class(mh));
    const char* m = method_get_name(mh);
    const char* d = method_get_descriptor(mh);
    for(unsigned i=0; i<no_inlining_table_count; i++)
        if (strcmp(c, no_inlining_table[i].c)==0 &&
            strcmp(m, no_inlining_table[i].m)==0 &&
            strcmp(d, no_inlining_table[i].d)==0)
            return TRUE;
    return FALSE;
} // method_is_no_inlining

// Class ch is a subclass of method_get_class(mh).  The function returns a method handle
// for an accessible method overriding mh in ch or in its closest superclass that overrides mh.
// Class ch must be a class not an interface.
Method_Handle method_get_overriding_method(Class_Handle ch, Method_Handle mh)
{
    assert(ch);
    assert(mh);
    Method *method = (Method *)mh;
    assert(!ch->is_interface());   // ch cannot be an interface

    const String *name = method->get_name();
    const String *desc = method->get_descriptor();
    Method *m = NULL;
    for(; ch;  ch = ch->get_super_class()) {
        m = ch->lookup_method(name, desc);
        if (m != NULL) {
            // IllegalAccessError will be thrown if implementation of
            // interface method is not public
            if (method->get_class()->is_interface() && !m->is_public()) {
                return NULL;
            }
            // The method m can only override mh/method
            // if m's class can access mh/method (JLS 6.6.5).
            if(m->get_class()->can_access_member(method)) {
                break;
            }
        }
    }
    return m;
} // method_get_overriding_method

I_32 vector_get_length(Vector_Handle vector)
{
    assert(vector);
    // XXX- need some assert that "vector" is really an array type
    return get_vector_length(vector);
} //vector_get_length

Managed_Object_Handle *vector_get_element_address_ref(Vector_Handle vector, I_32 idx)
{
    assert(vector);
    Managed_Object_Handle *elem = (Managed_Object_Handle *)get_vector_element_address_ref(vector, idx);
    return elem;
} //vector_get_element_address_ref

unsigned vm_vector_size(Class_Handle vector_class, int length)
{
    assert(vector_class);
    return vector_class->calculate_array_size(length);
} // vm_vector_size

static osmutex_t vm_gc_lock;

void vm_gc_lock_init()
{
    IDATA UNUSED status = port_mutex_create(&vm_gc_lock, APR_THREAD_MUTEX_NESTED);
    assert(status == TM_ERROR_NONE);
} // vm_gc_lock_init

void vm_gc_lock_enum()
{
    hythread_t self = tm_self_tls;
    int disable_count = self->disable_count;
    self->disable_count = 0;

    while (true) {
        IDATA UNUSED status = port_mutex_lock(&vm_gc_lock);
        assert(status == TM_ERROR_NONE);

        self->disable_count = disable_count;
        if (disable_count && self->suspend_count) {
            status = port_mutex_unlock(&vm_gc_lock);
            assert(status == TM_ERROR_NONE);

            self->disable_count = 0;
            hythread_safe_point_other(self);
        } else {
            break;
        }
    }
} // vm_gc_lock_enum

void vm_gc_unlock_enum()
{
    IDATA UNUSED status = port_mutex_unlock(&vm_gc_lock);
    assert(status == TM_ERROR_NONE);
} // vm_gc_unlock_enum

void *vm_get_gc_thread_local()
{
    return (void *) &p_TLS_vmthread->_gc_private_information;
}

size_t vm_number_of_gc_bytes_in_vtable()
{
    return GC_BYTES_IN_VTABLE;
}

size_t vm_number_of_gc_bytes_in_thread_local()
{
    return GC_BYTES_IN_THREAD_LOCAL;
}

BOOLEAN vm_is_heap_compressed()
{
    return REFS_IS_COMPRESSED_MODE;
} //vm_is_heap_compressed

void *vm_get_heap_base_address()
{
    return (void*)VM_Global_State::loader_env->heap_base;
} //vm_get_heap_base_address

void *vm_get_heap_ceiling_address()
{
    return (void *)VM_Global_State::loader_env->heap_end;
} //vm_get_heap_ceiling_address

BOOLEAN vm_is_vtable_compressed()
{
    return ManagedObject::are_vtable_pointers_compressed();
} //vm_is_vtable_compressed

Class_Handle allocation_handle_get_class(Allocation_Handle ah)
{
    assert(ah);
    VTable *vt;

    if (vm_is_vtable_compressed())
    {
        vt = (VTable *) ((UDATA)ah + (UDATA)vm_get_vtable_base_address());
    }
    else
    {
        vt = (VTable *) ah;
    }
    return (Class_Handle) vt->clss;
}

Allocation_Handle class_get_allocation_handle(Class_Handle ch)
{
    assert(ch);
    return ch->get_allocation_handle();
}

////////////////////////////////////////////////////////////////////////////////////
// Direct call-related functions that allow a JIT to be notified whenever a VM data
// structure changes that would require code patching or recompilation.
////////////////////////////////////////////////////////////////////////////////////

// Called by a JIT in order to be notified whenever the given method is recompiled or
// initially compiled. The callback_data pointer will be passed back to the JIT during the callback.
// The callback method is JIT_recompiled_method_callback.
void vm_register_jit_recompiled_method_callback(JIT_Handle jit, Method_Handle method,
                                                Method_Handle caller,
                                                 void *callback_data)
{
    assert(method);
    assert(caller);
    JIT *jit_to_be_notified = (JIT *)jit;
    Method *m = (Method *)method;
    m->register_jit_recompiled_method_callback(jit_to_be_notified, caller, callback_data);
} //vm_register_jit_recompiled_method_callback

void vm_patch_code_block(U_8* code_block, U_8* new_code, size_t size)
{
    assert(code_block != NULL);
    assert(new_code != NULL);

    // 20030203 We ensure that no thread is executing code that is simultaneously being patched.
    // We do this in part by stopping the other threads. This ensures that no thread will try to
    // execute code while it is being patched. Also, we take advantage of restrictions on the
    // patches done by JIT on IPF: it replaces the branch offset in a single bundle containing
    // a branch long. Note that this function does not synchronize the I- or D-caches.

    // Run through list of active threads and suspend the other ones.
    hythread_suspend_all(NULL, NULL);
    patch_code_with_threads_suspended(code_block, new_code, size);

    hythread_resume_all(NULL);

} //vm_patch_code_block

// Called by JIT during compilation to have the VM synchronously request a JIT (maybe another one)
// to compile another method.
JIT_Result vm_compile_method(JIT_Handle jit, Method_Handle method)
{
    return compile_do_compilation_jit((Method*) method, (JIT*) jit);
} // vm_compile_method

void vm_properties_set_value(const char* key, const char* value, PropertyTable table_number)
{
    assert(key);
    switch(table_number) {
    case JAVA_PROPERTIES:
        VM_Global_State::loader_env->JavaProperties()->set(key, value);
        break;
    case VM_PROPERTIES:
        VM_Global_State::loader_env->VmProperties()->set(key, value);
        break;
    default:
        LDIE(71, "Unknown property table: {0}" << table_number);
    }
}

char* vm_properties_get_value(const char* key, PropertyTable table_number)
{
    assert(key);
    char* value;
    switch(table_number) {
    case JAVA_PROPERTIES:
        value = VM_Global_State::loader_env->JavaProperties()->get(key);
        break;
    case VM_PROPERTIES:
        value = VM_Global_State::loader_env->VmProperties()->get(key);
        break;
    default:
        value = NULL;
        LDIE(71, "Unknown property table: {0}" << table_number);
    }
    return value;
}

void vm_properties_destroy_value(char* value)
{
    if (value)
    {
        //FIXME which properties?
        VM_Global_State::loader_env->JavaProperties()->destroy(value);
    }
}

BOOLEAN vm_property_is_set(const char* key, PropertyTable table_number)
{
    bool value = false;
    assert(key);
    switch(table_number) {
    case JAVA_PROPERTIES:
        value = VM_Global_State::loader_env->JavaProperties()->is_set(key);
        break;
    case VM_PROPERTIES:
        value = VM_Global_State::loader_env->VmProperties()->is_set(key);
        break;
    default:
        LDIE(71, "Unknown property table: {0}" << table_number);
    }
    return value ? TRUE : FALSE;
}

char** vm_properties_get_keys(PropertyTable table_number)
{
    char** value;
    switch(table_number) {
    case JAVA_PROPERTIES:
        value = VM_Global_State::loader_env->JavaProperties()->get_keys();
        break;
    case VM_PROPERTIES:
        value = VM_Global_State::loader_env->VmProperties()->get_keys();
        break;
    default:
        value = NULL;
        LDIE(71, "Unknown property table: {0}" << table_number);
    }
    return value;
}

char** vm_properties_get_keys_starting_with(const char* prefix, PropertyTable table_number)
{
    assert(prefix);
    char** value;
    switch(table_number) {
    case JAVA_PROPERTIES:
        value = VM_Global_State::loader_env->JavaProperties()->get_keys_staring_with(prefix);
        break;
    case VM_PROPERTIES:
        value = VM_Global_State::loader_env->VmProperties()->get_keys_staring_with(prefix);
        break;
    default:
        value = NULL;
        LDIE(71, "Unknown property table: {0}" << table_number);
    }
    return value;
}

void vm_properties_destroy_keys(char** keys)
{
    if (keys)
    {
        //FIXME which properties?
        VM_Global_State::loader_env->JavaProperties()->destroy(keys);
    }
}

int vm_property_get_integer(const char *property_name, int default_value, PropertyTable table_number)
{
    assert(property_name);
    char *value = vm_properties_get_value(property_name, table_number);
    int return_value = default_value;
    if (NULL != value)
    {
        return_value = atoi(value);
        vm_properties_destroy_value(value);
    }
    return return_value;
}

BOOLEAN vm_property_get_boolean(const char *property_name, BOOLEAN default_value, PropertyTable table_number)
{
    assert(property_name);
    char *value = vm_properties_get_value(property_name, table_number);
    if (NULL == value)
    {
        return default_value;
    }
    Boolean return_value = default_value;
    if (0 == strcmp("no", value)
        || 0 == strcmp("off", value)
        || 0 == strcmp("false", value)
        || 0 == strcmp("0", value))
    {
        return_value = FALSE;
    }
    else if (0 == strcmp("yes", value)
             || 0 == strcmp("on", value)
             || 0 == strcmp("true", value)
             || 0 == strcmp("1", value))
    {
        return_value = TRUE;
    }
    vm_properties_destroy_value(value);
    return return_value;
}

size_t vm_property_get_size(const char *property_name, size_t default_value, PropertyTable table_number)
{
  char* size_string;
  size_t size;
  int sizeModifier;
  size_t unit = 1;

  size_string = vm_properties_get_value(property_name, table_number);

  if (size_string == NULL) {
    return default_value;
  }

  size = atol(size_string);
  sizeModifier = tolower(size_string[strlen(size_string) - 1]);
  vm_properties_destroy_value(size_string);

  switch (sizeModifier) {
  case 'k': unit = 1024; break;
  case 'm': unit = 1024 * 1024; break;
  case 'g': unit = 1024 * 1024 * 1024;break;
  }

  size_t res = size * unit;
  if (res / unit != size) {
    /* overflow happened */
    return 0;
  }
  return res;
}

static Annotation* lookup_annotation(AnnotationTable* table, Class* owner, Class* antn_type) {
    for (int i = table->length - 1; i >= 0; --i) {
        Annotation* antn = table->table[i];
        Type_Info_Handle tih = (Type_Info_Handle) type_desc_create_from_java_descriptor(antn->type->bytes, owner->get_class_loader());
        if (tih) {
            //FIXME optimize: first check if class name matches
            Class* type = type_info_get_class(tih);
            if (antn_type == type) {
                return antn;
            }
        }
    }
    TRACE("No such annotation " << antn_type->get_name()->bytes);
    return NULL;
}

BOOLEAN method_has_annotation(Method_Handle target, Class_Handle antn_type) {
    assert(target);
    assert(antn_type);
    if (target->get_declared_annotations()) {
        Annotation* antn = lookup_annotation(target->get_declared_annotations(), target->get_class(), antn_type);
        return antn!=NULL;
    }
    return false;
}

char * get_method_entry_flag_address()
{
    return VM_Global_State::loader_env->TI->get_method_entry_flag_address();
}

char * get_method_exit_flag_address()
{
    return VM_Global_State::loader_env->TI->get_method_exit_flag_address();
}


text:
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
module Reflex.Dom.Builder.InputDisabled where

import Control.Lens
import Control.Monad.Fix
import Control.Monad.Ref
import Control.Monad.Trans
import Control.Monad.Trans.Control
import qualified Data.Map as Map
import Foreign.JavaScript.TH
import Reflex
import Reflex.Deletable.Class
import Reflex.Dom.Builder.Class
import Reflex.Host.Class

-- | A DomBuilder transformer that disables all 'inputElement's,
-- 'textAreaElement's, and 'selectElement's by adding the "disabled" HTML
-- attribute.  Note that 'element's that happen to have "input", "textarea", or
-- "select" as their tag will NOT be disabled.
newtype InputDisabledT m a = InputDisabledT { runInputDisabledT :: m a } deriving (Functor, Applicative, Monad, MonadAtomicRef, MonadFix, MonadIO)

deriving instance MonadSample t m => MonadSample t (InputDisabledT m)
deriving instance MonadHold t m => MonadHold t (InputDisabledT m)

instance MonadTrans InputDisabledT where
  lift = InputDisabledT

instance MonadTransControl InputDisabledT where
  type StT InputDisabledT a = a
  liftWith f = InputDisabledT $ f runInputDisabledT
  restoreT = InputDisabledT

instance MonadRef m => MonadRef (InputDisabledT m) where
  type Ref (InputDisabledT m) = Ref m
  newRef = lift . newRef
  readRef = lift . readRef
  writeRef ref = lift . writeRef ref

instance PerformEvent t m => PerformEvent t (InputDisabledT m) where
  type Performable (InputDisabledT m) = Performable m
  performEvent_ = lift . performEvent_
  performEvent = lift . performEvent

disableElementConfig :: Reflex t => ElementConfig er t m -> ElementConfig er t m
disableElementConfig cfg = cfg
  { _elementConfig_initialAttributes = Map.insert "disabled" "disabled" $ _elementConfig_initialAttributes cfg
  , _elementConfig_modifyAttributes = Map.delete "disabled" <$> _elementConfig_modifyAttributes cfg
  }

instance Deletable t m => Deletable t (InputDisabledT m) where
  deletable d = liftThrough $ deletable d

instance PostBuild t m => PostBuild t (InputDisabledT m) where
  getPostBuild = lift getPostBuild

deriving instance TriggerEvent t m => TriggerEvent t (InputDisabledT m)

instance MonadReflexCreateTrigger t m => MonadReflexCreateTrigger t (InputDisabledT m) where
  newEventWithTrigger = lift . newEventWithTrigger
  newFanEventWithTrigger f = lift $ newFanEventWithTrigger f

instance DomBuilder t m => DomBuilder t (InputDisabledT m) where
  type DomBuilderSpace (InputDisabledT m) = DomBuilderSpace m
  placeholder cfg = lift $ placeholder $ cfg
    & placeholderConfig_insertAbove %~ fmap runInputDisabledT
  inputElement cfg = lift $ inputElement $ cfg
    { _inputElementConfig_elementConfig = liftElementConfig $ disableElementConfig $ _inputElementConfig_elementConfig cfg
    }
  textAreaElement cfg = lift $ textAreaElement $ cfg
    { _textAreaElementConfig_elementConfig = liftElementConfig $ disableElementConfig $ _textAreaElementConfig_elementConfig cfg
    }
  selectElement cfg child = do
    let cfg' = cfg
          { _selectElementConfig_elementConfig = liftElementConfig $ disableElementConfig $ _selectElementConfig_elementConfig cfg
          }
    lift $ selectElement cfg' $ runInputDisabledT child

instance HasWebView m => HasWebView (InputDisabledT m) where
  type WebViewPhantom (InputDisabledT m) = WebViewPhantom m
  askWebView = lift askWebView

instance HasJS js m => HasJS js (InputDisabledT m) where
  type JSM (InputDisabledT m) = JSM m
  liftJS = lift . liftJS

redpajama_set_name: RedPajamaGithub


text:
import {NgModule,Directive,ElementRef,AfterViewInit,OnDestroy,HostBinding,HostListener,Input} from '@angular/core';
import {DomHandler} from '../dom/domhandler';
import {CommonModule} from '@angular/common';

@Directive({
    selector: '[pButton]',
    host: {
        '[class.ui-state-hover]': 'hover&&!isDisabled()',
        '[class.ui-state-focus]': 'focus',
        '[class.ui-state-active]': 'active',
        '[class.ui-state-disabled]': 'isDisabled()'
    },
    providers: [DomHandler]
})
export class Button implements AfterViewInit, OnDestroy {

    @Input() icon: string;

    @Input() iconPos: string = 'left';

    @Input() cornerStyleClass: string = 'ui-corner-all';

    public _label: string;

    public hover: boolean;

    public focus: boolean;

    public active: boolean;

    public initialized: boolean;

    constructor(public el: ElementRef, public domHandler: DomHandler) {}

    ngAfterViewInit() {
        this.domHandler.addMultipleClasses(this.el.nativeElement, this.getStyleClass());
        if(this.icon) {
            let iconElement = document.createElement("span");
            let iconPosClass = (this.iconPos == 'right') ? 'ui-button-icon-right': 'ui-button-icon-left';
            iconElement.className = iconPosClass  + ' ui-c fa fa-fw ' + this.icon;
            this.el.nativeElement.appendChild(iconElement);
        }

        let labelElement = document.createElement("span");
        labelElement.className = 'ui-button-text ui-c';
        labelElement.appendChild(document.createTextNode(this.label||'ui-button'));
        this.el.nativeElement.appendChild(labelElement);
        this.initialized = true;
    }

    @HostListener('mouseenter', ['$event'])
    onMouseenter(e: Event) {
        this.hover = true;
    }

    @HostListener('mouseleave', ['$event'])
    onMouseleave(e: Event) {
        this.hover = false;
        this.active = false;
    }

    @HostListener('mousedown', ['$event'])
    onMouseDown(e: Event) {
        this.active = true;
    }

    @HostListener('mouseup', ['$event'])
    onMouseUp(e: Event) {
        this.active = false;
    }

    @HostListener('focus', ['$event'])
    onFocus(e: Event) {
        this.focus = true;
    }

    @HostListener('blur', ['$event'])
    onBlur(e: Event) {
        this.focus = false;
    }

    isDisabled() {
        return this.el.nativeElement.disabled;
    }

    getStyleClass(): string {
        let styleClass = 'ui-button ui-widget ui-state-default ' + this.cornerStyleClass;
        if(this.icon) {
            if(this.label != null && this.label != undefined) {
                if(this.iconPos == 'left')
                    styleClass = styleClass + ' ui-button-text-icon-left';
                else
                    styleClass = styleClass + ' ui-button-text-icon-right';
            }
            else {
                styleClass = styleClass + ' ui-button-icon-only';
            }
        }
        else {
            styleClass = styleClass + ' ui-button-text-only';
        }

        return styleClass;
    }

    @Input() get label(): string {
        return this._label;
    }

    set label(val: string) {
        this._label = val;

        if(this.initialized) {
            this.domHandler.findSingle(this.el.nativeElement, '.ui-button-text').textContent = this._label;
        }
    }

    ngOnDestroy() {
        while(this.el.nativeElement.hasChildNodes()) {
            this.el.nativeElement.removeChild(this.el.nativeElement.lastChild);
        }

        this.initialized = false;
    }
}

@NgModule({
    imports: [CommonModule],
    exports: [Button],
    declarations: [Button]
})
export class ButtonModule { }


text:
package com.klatunetworks.webhooks.core.store;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.klatunetworks.webhooks.core.Webhook;
import com.klatunetworks.webhooks.core.WebhookResult;

/**
 * A WebhookStore which retries Webhook calls (store in memory) based on the configured backoff function.
 *
 * @author Dan Simpson
 *
 */
public class WebhookMemoryStore implements WebhookStore, Runnable {

	private static final Logger log = LoggerFactory.getLogger(WebhookMemoryStore.class);

	private static class WebhookRetryDetails {

		public boolean enqueued;
		public long firstAttemptAt;
		public long nextAttemptAt;
		public int numAttempts = 0;

		public WebhookRetryDetails() {
			this.firstAttemptAt = nextAttemptAt = System.currentTimeMillis();
			this.enqueued = false;
		}

		public long numSeconds() {
			return TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis() - firstAttemptAt);
		}

		public void enqueued() {
			this.enqueued = true;
			this.numAttempts++;
		}

		public void reschedule(long nextAttemptAt) {
			this.enqueued = false;
			this.nextAttemptAt = nextAttemptAt;
		}

		public boolean isExhausted() {
			return nextAttemptAt <= 0;
		}
	}

	private final Map<Webhook, WebhookRetryDetails> webhooks = new ConcurrentHashMap<Webhook, WebhookRetryDetails>();
	private final LinkedBlockingQueue<Webhook> outbox = new LinkedBlockingQueue<Webhook>();

	private final Function<Integer, Long> backoffFn;

	public WebhookMemoryStore(Function<Integer, Long> backoffFn) {
		this.backoffFn = backoffFn;
	}

	@Override
	public LinkedBlockingQueue<Webhook> getQueue() {
		return outbox;
	}

	@Override
	public void add(Webhook webhook) {
		if (webhooks.put(webhook, new WebhookRetryDetails()) != null) {
			log.warn("Map overwrite detected, calling code is likely misusing the store.");
		}
	}

	@Override
	public synchronized void update(WebhookResult result) {
		if (result.isSuccessful()) {
			WebhookRetryDetails retry = webhooks.remove(result.getWebhook());
			if (retry != null && retry.numAttempts > 1) {
				log.info("Retry succeeded after {} attempts and {} seconds", retry.numAttempts, retry.numSeconds());
			}
		} else {
			WebhookRetryDetails retry = webhooks.get(result.getWebhook());
			if (retry == null) {
				return;
			}

			retry.reschedule(backoffFn.apply(retry.numAttempts + 1));
			if (retry.isExhausted()) {
				log.warn("Retry failed after {} attempts and {} seconds. Purging.", retry.numAttempts, retry.numSeconds());
				webhooks.remove(result.getWebhook());
			}
		}
	}

	@Override
	/**
	 * Flush the ready-to-retry Webhooks to the queue for the service to consume
	 */
	public void run() {
		long threshold = System.currentTimeMillis();
		webhooks.forEach((webhook, retry) -> {
			if (retry.nextAttemptAt < threshold && !retry.enqueued) {
				retry.enqueued();
				outbox.add(webhook);
			}
		});
	}

	public int getDelayedWebhooks() {
		return webhooks.size();
	}
}


text:
package edu.sharif.behin.androidstreamer.local;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * Created by Behin on 1/30/2017.
 */

public class BufferLoopBackStream {
    private final Queue<byte[]> buffer=new ConcurrentLinkedQueue<>();

    public OutputStream getOutputStream(){
        return new OutputStream() {
            @Override
            public void write(int i) throws IOException {
                throw new RuntimeException("Write int");
            }

            @Override
            public void write(byte [] bytes) throws IOException {
                synchronized (buffer) {
                    buffer.add(bytes);
                    buffer.notify();
                }
            }
        };
    }

    public InputStream getInputStream(){
        return new InputStream() {
            @Override
            public int read() throws IOException {
                throw new RuntimeException("Read Int");
            }
            public int read(byte[] bytes) throws IOException {
                synchronized (buffer) {
                    if(buffer.size()==0) {
                        try {
                            buffer.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    byte[] item = buffer.poll();
                    System.arraycopy(item,0,bytes,0,bytes.length);
                    return bytes.length;
                }

            }
        };
    }
}


text:
package io.sarl.tests.api.tools;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import com.google.common.base.Strings;
import org.apache.log4j.Level;
import org.apache.log4j.LogManager;
import org.eclipse.xtext.util.DiffUtil;
import org.eclipse.xtext.xbase.lib.Pure;

/** Set of utility classes that provide additional assertion functions.
 *
 * @param <S> - the type of the service.
 * @author $Author: sgalland$
 * @version $FullVersion$
 * @mavengroupid $GroupId$
 * @mavenartifactid $ArtifactId$
 * @since 0.11
 */
public final class TestUtils {

	/** Precision of the floating point number epsilon-tests.
	 */
	public static final int DEFAULT_DECIMAL_COUNT = 6;

	private TestUtils() {
		//
	}

	/** Merge two arrays.
	 *
	 * @param operand1 the first array.
	 * @param operand2 the second array.
	 * @return the merge.
	 */
	@Pure
	public static String[] merge(String[] operand1, String[] operand2) {
		if (operand1 == null) {
			if (operand2 == null) {
				return new String[0];
			}
			return operand2;
		}
		if (operand2 == null) {
			return operand1;
		}
		String[] tab = new String[operand1.length + operand2.length];
		System.arraycopy(
				operand1, 0,
				tab, 0,
				operand1.length);
		System.arraycopy(
				operand2, 0,
				tab, operand1.length,
				operand2.length);
		return tab;
	}

	/** Helper for setting a field, even if it is not visible.
	 *
	 * @param instance the object.
	 * @param fieldType the type of the field.
	 * @param fieldName the name of the field.
	 * @param fieldValue the field value.
	 */
	public static <T> void setField(Object instance, Class<T> fieldType,
			String fieldName, T fieldValue) {
		Field field = null;
		Class<?> type = instance.getClass();
		while (type != null) {
			try {
				field = type.getDeclaredField(fieldName);
				assertEquals(fieldType, field.getType());
				boolean acc = field.isAccessible();
				try {
					field.setAccessible(true);
					field.set(instance, fieldValue);
					return;
				} finally {
					field.setAccessible(acc);
				}
			} catch (Throwable exception) {
				type = type.getSuperclass();
			}
		}
		throw new NoSuchFieldError(fieldName);
	}

	/** Replies if the runtime environment is Eclipse.
	 *
	 * @return true if the runtime environment is Eclipse.
	 */
	@Pure
	public static boolean isEclipseRuntimeEnvironment() {
		final String cmd = System.getProperty("sun.java.command", "");
		// Assuming that the Maven launcher is providing an absolute path to the launcher.
		return cmd != null
				&& (cmd.startsWith("org.eclipse.equinox.launcher.Main")
						|| cmd.startsWith("org.eclipse.jdt.internal.junit."));
	}

	/** Change the log level at the global level.
	 *
	 * @param level the new level.
	 */
	public static void setGlobalLogLevel(Level level) {
		LogManager.getRootLogger().setLevel(level);
	}

	/** Replies the stack trace of the caller of this function.
	 *
	 * @return the stack trace.
	 */
	@Pure
	public static StackTraceElement[] getStackTrace() {
		try {
			throw new Exception();
		} catch (Throwable e) {
			List<StackTraceElement> types = new ArrayList<>();
			StackTraceElement[] elements = e.getStackTrace();
			for (int i = 1; i < elements.length; ++i) {
				types.add(elements[i]);
			}
			StackTraceElement[] array = new StackTraceElement[types.size()];
			types.toArray(array);
			return array;
		}
	}

	/** Replies the OS-dependent line separator.
	 *
	 * @return the line separator from the {@code "line.separator"} property, or {@code "\n"}.
	 * @since 0.5
	 */
	@Pure
	public static String getLineSeparator() {
		final String nl = System.getProperty("line.separator");
		if (Strings.isNullOrEmpty(nl)) {
			throw new Error("NO LINE SEPARATOR DEFINED");
			//return "\n";
		}
		return nl;
	}

	/** Helper for writing a multi-line string in unit tests, which supports the
	 * OS-dependent line separator.
	 *
	 * @param lines the lines in the string.
	 * @return the complete multi-line string.
	 */
	@Pure
	public static String multilineString(Object... lines) {
		final StringBuilder buffer = new StringBuilder();
		final String nl = getLineSeparator();
		boolean first = true;
		for (final Object obj : lines) {
			if (first) {
				first = false;
			} else {
				buffer.append(nl);
			}
			if (obj != null) {
				if (obj instanceof CharSequence) {
					buffer.append((CharSequence) obj);
				} else {
					buffer.append(obj.toString());
				}
			}
		}
		return buffer.toString();
	}

	/** Replies if two values are equals at epsilon.
	 *
	 * @param v1 the first value.
	 * @param v2 the second value.
	 * @param isNaNEqual indicates if the NaN value is equals to itself.
	 * @return true or false
	 */
	@Pure
	public static boolean isEpsilonEquals(double v1, double v2, boolean isNaNEqual) {
		if (v1 == v2) {
			return true;
		}
		final boolean nanA = Double.isNaN(v1);
		final boolean nanB = Double.isNaN(v2);
		if (nanA || nanB) {
			if (isNaNEqual) {
				return nanA == nanB;
			}
			return false;
		}
		if (!Double.isInfinite(v1) && !Double.isInfinite(v1)
				&& !Double.isNaN(v1) && !Double.isNaN(v2)) {
			return isEpsilonEquals(new BigDecimal(v1), new BigDecimal(v2), DEFAULT_DECIMAL_COUNT / 2);
		}
		return false;
	}

	/** Replies if two values are equals at epsilon.
	 *
	 * @param v1 the first value.
	 * @param v2 the second value.
	 * @param precision is the number of decimal digits to test.
	 * @return true or false
	 */
	@Pure
	public static boolean isEpsilonEquals(BigDecimal v1, BigDecimal v2, int precision) {
		final BigDecimal ma = v1.movePointRight(precision);
		final BigDecimal mb = v2.movePointRight(precision);
		BigDecimal aa = ma.setScale(0, BigDecimal.ROUND_HALF_UP);
		BigDecimal bb = mb.setScale(0, BigDecimal.ROUND_HALF_UP);
		if (aa.compareTo(bb) == 0) {
			return true;
		}
		aa = ma.setScale(0, BigDecimal.ROUND_DOWN);
		bb = mb.setScale(0, BigDecimal.ROUND_DOWN);
		return aa.compareTo(bb) == 0;
	}

	/**
	 * Replies result at the given index of the run of the agent.
	 *
	 * @param source - the source of the data.
	 * @param type - the type of the result.
	 * @param index - the index of the result.
	 * @return the value; or {@code null} if no result.
	 */
	@Pure
	public static <T> T elementAt(List<?> source, Class<T> type, int index) {
		final Object element = source.get(index);
		if (element == null || type.isInstance(element)) {
			return type.cast(element);
		}
		return null;
	}

	/** Replies the simple name of the given type name
	 *
	 * @param typeName the fully qualified name of a type.
	 */
	@Pure
	public static String simpleTypeName(String typeName) {
		final int index1 = typeName.lastIndexOf("$");
		final int index2 = typeName.lastIndexOf(".");
		final int index = Math.max(index1, index2);
		if (index >= 0) {
			return typeName.substring(index + 1);
		}
		return typeName;
	}

	/** Replies a string describing the differences between two strings.
	 *
	 * @param a the first string.
	 * @param b the second string
	 * @return the description of the difference.
	 * @since 0.12
	 */
	@Pure
	public static String differences(String a, String b) {
		final String diff = DiffUtil.diff(a,  b);
		return diff;
	}

}


text:
import * as express from "express"

declare module "express" {
  interface Request {
    user?: any
  }
}


text:
package org.apache.druid.timeline.partition;

import com.fasterxml.jackson.annotation.JacksonInject;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.hash.HashFunction;
import com.google.common.hash.Hashing;
import org.apache.druid.data.input.InputRow;
import org.apache.druid.data.input.Rows;

import javax.annotation.Nullable;
import java.util.List;

public class HashBasedNumberedShardSpec extends NumberedShardSpec
{
  private static final HashFunction HASH_FUNCTION = Hashing.murmur3_32();
  private static final List<String> DEFAULT_PARTITION_DIMENSIONS = ImmutableList.of();

  private final ObjectMapper jsonMapper;
  @JsonIgnore
  private final List<String> partitionDimensions;

  @JsonCreator
  public HashBasedNumberedShardSpec(
      @JsonProperty("partitionNum") int partitionNum,    // partitionId
      @JsonProperty("partitions") int partitions,        // # of partitions
      @JsonProperty("partitionDimensions") @Nullable List<String> partitionDimensions,
      @JacksonInject ObjectMapper jsonMapper
  )
  {
    super(partitionNum, partitions);
    this.jsonMapper = jsonMapper;
    this.partitionDimensions = partitionDimensions == null ? DEFAULT_PARTITION_DIMENSIONS : partitionDimensions;
  }

  @JsonProperty("partitionDimensions")
  public List<String> getPartitionDimensions()
  {
    return partitionDimensions;
  }

  @Override
  public boolean isCompatible(Class<? extends ShardSpec> other)
  {
    return other == HashBasedNumberedShardSpec.class;
  }

  @Override
  public boolean isInChunk(long timestamp, InputRow inputRow)
  {
    return (((long) hash(timestamp, inputRow)) - getPartitionNum()) % getPartitions() == 0;
  }

  protected int hash(long timestamp, InputRow inputRow)
  {
    final List<Object> groupKey = getGroupKey(timestamp, inputRow);
    try {
      return hash(jsonMapper, groupKey);
    }
    catch (JsonProcessingException e) {
      throw new RuntimeException(e);
    }
  }

  @VisibleForTesting
  List<Object> getGroupKey(final long timestamp, final InputRow inputRow)
  {
    if (partitionDimensions.isEmpty()) {
      return Rows.toGroupKey(timestamp, inputRow);
    } else {
      return Lists.transform(partitionDimensions, inputRow::getDimension);
    }
  }

  @VisibleForTesting
  public static int hash(ObjectMapper jsonMapper, List<Object> objects) throws JsonProcessingException
  {
    return HASH_FUNCTION.hashBytes(jsonMapper.writeValueAsBytes(objects)).asInt();
  }

  @Override
  public String toString()
  {
    return "HashBasedNumberedShardSpec{" +
           "partitionNum=" + getPartitionNum() +
           ", partitions=" + getPartitions() +
           ", partitionDimensions=" + getPartitionDimensions() +
           '}';
  }

  @Override
  public ShardSpecLookup getLookup(final List<ShardSpec> shardSpecs)
  {
    return (long timestamp, InputRow row) -> {
      int index = Math.abs(hash(timestamp, row) % getPartitions());
      return shardSpecs.get(index);
    };
  }
}


text:
import plist from "../src/index";
import { DemoFile } from "./utils/types";

const filePath = `${__dirname}/test-xml1.plist`;

type TestXml1 = DemoFile & { "Empty String": string };

describe("readFileSync can properly load and read a file", () => {
  const contents = plist.readFileSync<TestXml1>(filePath);
  it("has the proper values", () => {
    if (!contents["Name"]) {
      fail(`Failed to parse ${filePath}`);
    }
    expect(contents).toMatchInlineSnapshot(`
      Object {
        "Birth Year": 1942,
        "Empty String": "",
        "Name": "John Doe",
        "Travel Log": Array [
          "Tokyo, Honshu, Japan",
          "Philadelphia, PA",
          "Recife, Pernambuco, Brazil",
        ],
      }
    `);
  });
});

describe("readFile works asynchronously", () => {
  it("has the proper values", (done) => {
    plist.readFile<TestXml1>(filePath, (err, contents) => {
      if (!contents) {
        fail(`Failed to parse ${filePath}`);
      }
      expect(contents).toMatchInlineSnapshot(`
        Object {
          "Birth Year": 1942,
          "Empty String": "",
          "Name": "John Doe",
          "Travel Log": Array [
            "Tokyo, Honshu, Japan",
            "Philadelphia, PA",
            "Recife, Pernambuco, Brazil",
          ],
        }
      `);
      done();
    });
  });
});


text:
typedef  int  ELEMENT_TYPE;

#ifndef  Array_H
#define  Array_H

//Array - a class that provides the same type of fuctionality as
//built - in arrays, but it allows for specifying lower
//and upper bound index values and uses dynamic memory.
class Array
{
public:

	//Constructors
	Array(int lwr,
		  int uppr);

	Array(int uppr);

	Array(const Array &copy);

	//Destructor
	~Array();

	//Methods
	void set(int index, ELEMENT_TYPE input);
	ELEMENT_TYPE get(int index);
	int lowerBound() const;
	int upperBound() const;
	int numElements() const;
	int size() const;

private:

	//Private member variables
	int mUpper;
	int mLower;
	ELEMENT_TYPE *mData;

	//Helper method
	void boundsMemoryCheck() const;
};

#endif

#ifndef  SafeArray_H
#define  SafeArray_H

//SafeArray - same functionality as Array but adds the additional
//behavior of index bounds checking.
class SafeArray
{
public:

	//Constructors
	SafeArray(int lwr,
		int uppr);

	SafeArray(int uppr);

	SafeArray(const SafeArray &copy);

	//Methods
	int lowerBound() const;
	int upperBound() const;
	int numElements() const;
	int size() const;
	void set(int index, ELEMENT_TYPE value);
	ELEMENT_TYPE get(int index);

private:

	//member variable
	Array mArray;

	//Helper method
	void boundsCheck(int index) const;
};

#endif