/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * This source file is part of SableVM. * * * * See the file "LICENSE" for the copyright information and for * * the terms and conditions for copying, distribution and * * modification of this source file. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* ---------------------------------------------------------------------- Java_java_lang_VMSystem_identityHashCode ---------------------------------------------------------------------- */ /* * Class: java_lang_VMSystem * Method: identityHashCode * Signature: (Ljava/lang/Object;)I */ JNIEXPORT jint JNICALL Java_java_lang_VMSystem_identityHashCode (JNIEnv *_env, jclass _class, jobject obj) { _svmt_JNIEnv *env = _svmf_cast_svmt_JNIEnv (_env); _svmt_JavaVM *vm = env->vm; jint hashcode = 0; _svmf_resuming_java (env); _svmm_identity_hashcode (env, obj, hashcode); _svmf_stopping_java (env); return hashcode; } /* ---------------------------------------------------------------------- Java_java_lang_VMSystem_arraycopy ---------------------------------------------------------------------- */ /* * Class: java_lang_VMSystem * Method: arraycopy * Signature: (Ljava/lang/Object;ILjava/lang/Object;II)V */ JNIEXPORT void JNICALL Java_java_lang_VMSystem_arraycopy (JNIEnv *_env, jclass class, jobject src, jint src_position, jobject dst, jint dst_position, jint length) { _svmt_JNIEnv *env = _svmf_cast_svmt_JNIEnv (_env); _svmt_JavaVM *vm = env->vm; _svmf_resuming_java (env); if (dst == NULL) { _svmf_error_NullPointerException (env); goto end; } if (src == NULL) { _svmf_error_NullPointerException (env); goto end; } if (!((*src)->vtable->type->is_array)) { _svmf_error_ArrayStoreException (env); goto end; } if (!((*dst)->vtable->type->is_array)) { _svmf_error_ArrayStoreException (env); goto end; } { _svmt_array_instance *src_instance = *_svmf_cast_jarray (src); _svmt_array_instance *dst_instance = *_svmf_cast_jarray (dst); _svmt_array_info *src_type = _svmf_cast_array (src_instance->vtable->type); _svmt_array_info *dst_type = _svmf_cast_array (dst_instance->vtable->type); assert (src_instance->size >= 0 && dst_instance->size >= 0); if (src_type->dimensions == 1 && dst_type->dimensions == 1 && src_type->base_type != dst_type->base_type) { _svmf_error_ArrayStoreException (env); goto end; } if (src_type->dimensions == 1 && src_type->base_type != SVM_TYPE_REFERENCE && dst_type->dimensions > 1) { _svmf_error_ArrayStoreException (env); goto end; } if (src_type->dimensions > 1 && dst_type->dimensions == 1 && dst_type->base_type != SVM_TYPE_REFERENCE) { _svmf_error_ArrayStoreException (env); goto end; } if (src_position < 0 || dst_position < 0 || length < 0 || (_svmt_u32) src_position + (_svmt_u32) length > (_svmt_u32) src_instance->size || (_svmt_u32) dst_position + (_svmt_u32) length > (_svmt_u32) dst_instance->size) { _svmf_error_ArrayIndexOutOfBoundsException (env); goto end; } /* The easy cases first... */ if (length == 0) { /* we're done */ goto end; } if (!_svmf_is_assignable_from (env, _svmf_cast_type_array (src_type), _svmf_cast_type_array (dst_type))) { /* incompatible array types */ jint i; assert (src_instance != dst_instance); assert (src_type->dimensions > 1 || src_type->base_type == SVM_TYPE_REFERENCE); assert (dst_type->dimensions > 1 || dst_type->base_type == SVM_TYPE_REFERENCE); for (i = 0; i < length; i++) { _svmt_object_instance *value = _svmf_get_reference_array_element (src_instance, src_position + i); if (_svmf_set_reference_array_element_no_exception (env, dst_instance, dst_position + i, value) != JNI_OK) { _svmf_error_ArrayStoreException (env); goto end; } } goto end; } /* src_type is assignable to dst_type. Note: Remember that src_type and dst_type are actual "runtime" types, not declared types. This means that any value that was successfully inserted into src is type compatible with dst, as dst has a "wider" element type. */ if (src_type->dimensions > 1 || src_type->base_type == SVM_TYPE_REFERENCE) { /* compatible reference array types */ _svmt_object_instance **src_elements; _svmt_object_instance **dst_elements; #if defined (_SABLEVM_BIDIRECTIONAL_OBJECT_LAYOUT) src_elements = (_svmt_object_instance **) src_instance; dst_elements = (_svmt_object_instance **) dst_instance; /* we must be careful; increasing array element indices are stored in decreasing memory locations. */ memmove (&dst_elements[-(dst_position + length)], &src_elements[-(src_position + length)], length * sizeof (void *)); #else src_elements = (_svmt_object_instance **) (((char *) src_instance) + _svmf_aligned_size_t (sizeof (_svmt_array_instance))); dst_elements = (_svmt_object_instance **) (((char *) dst_instance) + _svmf_aligned_size_t (sizeof (_svmt_array_instance))); memmove (&dst_elements[dst_position], &src_elements[src_position], length * sizeof (void *)); #endif goto end; } assert (src_type->dimensions == 1 && src_type->base_type != SVM_TYPE_REFERENCE); switch (src_type->base_type) { case SVM_TYPE_BOOLEAN: { jint i; for (i = 0; i < length; i++) { jboolean value = _svmf_get_boolean_array_element (src_instance, src_position + i); _svmf_set_boolean_array_element (dst_instance, dst_position + i, value); } goto end; } break; case SVM_TYPE_BYTE: { jbyte *src_elements = (jbyte *) (((char *) src_instance) + _svmf_aligned_size_t (sizeof (_svmt_array_instance))); jbyte *dst_elements = (jbyte *) (((char *) dst_instance) + _svmf_aligned_size_t (sizeof (_svmt_array_instance))); memmove (&dst_elements[dst_position], &src_elements[src_position], length * sizeof (jbyte)); goto end; } break; case SVM_TYPE_SHORT: { jshort *src_elements = (jshort *) (((char *) src_instance) + _svmf_aligned_size_t (sizeof (_svmt_array_instance))); jshort *dst_elements = (jshort *) (((char *) dst_instance) + _svmf_aligned_size_t (sizeof (_svmt_array_instance))); memmove (&dst_elements[dst_position], &src_elements[src_position], length * sizeof (jshort)); goto end; } break; case SVM_TYPE_CHAR: { jchar *src_elements = (jchar *) (((char *) src_instance) + _svmf_aligned_size_t (sizeof (_svmt_array_instance))); jchar *dst_elements = (jchar *) (((char *) dst_instance) + _svmf_aligned_size_t (sizeof (_svmt_array_instance))); memmove (&dst_elements[dst_position], &src_elements[src_position], length * sizeof (jchar)); goto end; } break; case SVM_TYPE_INT: { jint *src_elements = (jint *) (((char *) src_instance) + _svmf_aligned_size_t (sizeof (_svmt_array_instance))); jint *dst_elements = (jint *) (((char *) dst_instance) + _svmf_aligned_size_t (sizeof (_svmt_array_instance))); memmove (&dst_elements[dst_position], &src_elements[src_position], length * sizeof (jint)); goto end; } break; case SVM_TYPE_LONG: { jlong *src_elements = (jlong *) (((char *) src_instance) + _svmf_aligned_size_t (sizeof (_svmt_array_instance))); jlong *dst_elements = (jlong *) (((char *) dst_instance) + _svmf_aligned_size_t (sizeof (_svmt_array_instance))); memmove (&dst_elements[dst_position], &src_elements[src_position], length * sizeof (jlong)); goto end; } break; case SVM_TYPE_FLOAT: { jfloat *src_elements = (jfloat *) (((char *) src_instance) + _svmf_aligned_size_t (sizeof (_svmt_array_instance))); jfloat *dst_elements = (jfloat *) (((char *) dst_instance) + _svmf_aligned_size_t (sizeof (_svmt_array_instance))); memmove (&dst_elements[dst_position], &src_elements[src_position], length * sizeof (jfloat)); goto end; } break; case SVM_TYPE_DOUBLE: { jdouble *src_elements = (jdouble *) (((char *) src_instance) + _svmf_aligned_size_t (sizeof (_svmt_array_instance))); jdouble *dst_elements = (jdouble *) (((char *) dst_instance) + _svmf_aligned_size_t (sizeof (_svmt_array_instance))); memmove (&dst_elements[dst_position], &src_elements[src_position], length * sizeof (jdouble)); goto end; } break; default: { _svmm_fatal_error ("impossible control flow"); } break; } assert (src_instance->size >= 0 && dst_instance->size >= 0); } end: _svmf_stopping_java (env); } /* ---------------------------------------------------------------------- Java_java_lang_VMSystem_map ---------------------------------------------------------------------- */ /* * Class: java_lang_VMSystem * Method: mapLibraryName * Signature: (Ljava/lang/String;)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_java_lang_VMSystem_mapLibraryName (JNIEnv *_env, jclass _class, jstring libname) { _svmt_JNIEnv *env = _svmf_cast_svmt_JNIEnv (_env); jstring string = NULL; _svmf_resuming_java (env); { /* * Note: This functionality is not VM specify. * Could be rewritten in JNI and be added to Classpath native lib. */ char *short_name; char *name; size_t len; if (_svmm_galloc_utf_chars (env, libname, short_name) != JNI_OK) { goto end; } /* Assuming standard: "lib" + libname + ".so" */ len = 3 + strlen (short_name) + 4; if (_svmm_gmalloc_cchars (env, len, name) != JNI_OK) { _svmm_gfree_utf_chars (short_name); goto end; } strcpy (name, "lib"); strcat (name, short_name); strcat (name, ".so"); assert (strlen (name) == (len - 1)); string = _svmf_get_jni_frame_native_local (env); /* as we do nothing else after, we can safely ignore the return value (any exception being also set in the environment) */ _svmf_get_string (env, name, string); _svmm_gfree_utf_chars (short_name); _svmm_gmfree_cchars (name); } end: _svmf_stopping_java (env); return string; }