Merged with tip.
[cacao.git] / src / vm / builtin.c
index 812e0467b9cb5cbce1968fa04b6901ea70d8dc42..377bad8830fd3370390200d55b26348f91e13fd7 100644 (file)
@@ -1,7 +1,7 @@
 /* src/vm/builtin.c - functions for unsupported operations
 
    Copyright (C) 1996-2005, 2006, 2007, 2008
-   CACAOVM - Verein zu Foerderung der freien virtuellen Machine CACAO
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
@@ -54,7 +54,7 @@
 #include "native/llni.h"
 
 #include "threads/lock-common.h"
-#include "threads/threads-common.h"
+#include "threads/thread.h"
 
 #include "toolbox/logging.h"
 #include "toolbox/util.h"
@@ -65,7 +65,7 @@
 #include "vm/exceptions.h"
 #include "vm/global.h"
 #include "vm/initialize.h"
-#include "vm/primitive.h"
+#include "vm/primitive.hpp"
 #include "vm/stringlocal.h"
 
 #include "vm/jit/asmpart.h"
@@ -266,6 +266,8 @@ static void builtintable_sort_automatic(void)
 
 bool builtin_init(void)
 {
+       TRACESUBSYSTEMINITIALIZATION("builtin_init");
+
        /* initialize the builtin tables */
 
        if (!builtintable_init())
@@ -414,16 +416,16 @@ bool builtintable_replace_function(void *iptr_)
 
 *******************************************************************************/
 
-s4 builtin_instanceof(java_handle_t *o, classinfo *class)
+bool builtin_instanceof(java_handle_t *o, classinfo *c)
 {
-       classinfo *c;
+       classinfo *oc;
 
        if (o == NULL)
                return 0;
 
-       LLNI_class_get(o, c);
+       LLNI_class_get(o, oc);
 
-       return class_isanysubclass(c, class);
+       return class_isanysubclass(oc, c);
 }
 
 
@@ -437,16 +439,16 @@ s4 builtin_instanceof(java_handle_t *o, classinfo *class)
 
 *******************************************************************************/
 
-s4 builtin_checkcast(java_handle_t *o, classinfo *class)
+bool builtin_checkcast(java_handle_t *o, classinfo *c)
 {
-       classinfo *c;
+       classinfo *oc;
 
        if (o == NULL)
                return 1;
 
-       LLNI_class_get(o, c);
+       LLNI_class_get(o, oc);
 
-       if (class_isanysubclass(c, class))
+       if (class_isanysubclass(oc, c))
                return 1;
 
        return 0;
@@ -463,8 +465,7 @@ s4 builtin_checkcast(java_handle_t *o, classinfo *class)
                        
 *******************************************************************************/
 
-static s4 builtin_descriptorscompatible(arraydescriptor *desc,
-                                                                               arraydescriptor *target)
+static bool builtin_descriptorscompatible(arraydescriptor *desc, arraydescriptor *target)
 {
        if (desc == target)
                return 1;
@@ -478,6 +479,8 @@ static s4 builtin_descriptorscompatible(arraydescriptor *desc,
        /* {both arrays are arrays of references} */
 
        if (desc->dimension == target->dimension) {
+               if (!desc->elementvftbl)
+                       return 0;
                /* an array which contains elements of interface types is
            allowed to be casted to Object (JOWENN)*/
 
@@ -485,8 +488,8 @@ static s4 builtin_descriptorscompatible(arraydescriptor *desc,
                        (target->elementvftbl->baseval == 1))
                        return 1;
 
-               return class_isanysubclass(desc->elementvftbl->class,
-                                                                  target->elementvftbl->class);
+               return class_isanysubclass(desc->elementvftbl->clazz,
+                                                                  target->elementvftbl->clazz);
        }
 
        if (desc->dimension < target->dimension)
@@ -495,7 +498,7 @@ static s4 builtin_descriptorscompatible(arraydescriptor *desc,
        /* {desc has higher dimension than target} */
 
        return class_isanysubclass(pseudo_class_Arraystub,
-                                                          target->elementvftbl->class);
+                                                          target->elementvftbl->clazz);
 }
 
 
@@ -514,7 +517,7 @@ static s4 builtin_descriptorscompatible(arraydescriptor *desc,
 
 *******************************************************************************/
 
-s4 builtin_fast_arraycheckcast(java_object_t *o, classinfo *targetclass)
+bool builtin_fast_arraycheckcast(java_object_t *o, classinfo *targetclass)
 {
        arraydescriptor *desc;
 
@@ -536,7 +539,7 @@ s4 builtin_fast_arraycheckcast(java_object_t *o, classinfo *targetclass)
 
 *******************************************************************************/
 
-s4 builtin_fast_arrayinstanceof(java_object_t *o, classinfo *targetclass)
+bool builtin_fast_arrayinstanceof(java_object_t *o, classinfo *targetclass)
 {
        if (o == NULL)
                return 0;
@@ -551,9 +554,9 @@ s4 builtin_fast_arrayinstanceof(java_object_t *o, classinfo *targetclass)
 
 *******************************************************************************/
 
-s4 builtin_arrayinstanceof(java_handle_t *h, classinfo *targetclass)
+bool builtin_arrayinstanceof(java_handle_t *h, classinfo *targetclass)
 {
-       s4 result;
+       bool result;
 
        LLNI_CRITICAL_START;
 
@@ -633,9 +636,9 @@ java_object_t *builtin_retrieve_exception(void)
 
 *******************************************************************************/
 
-s4 builtin_canstore(java_handle_objectarray_t *oa, java_handle_t *o)
+bool builtin_canstore(java_handle_objectarray_t *oa, java_handle_t *o)
 {
-       int result;
+       bool result;
 
        LLNI_CRITICAL_START;
 
@@ -664,7 +667,7 @@ s4 builtin_canstore(java_handle_objectarray_t *oa, java_handle_t *o)
 
 *******************************************************************************/
 
-s4 builtin_fast_canstore(java_objectarray_t *oa, java_object_t *o)
+bool builtin_fast_canstore(java_objectarray_t *oa, java_object_t *o)
 {
        arraydescriptor *desc;
        arraydescriptor *valuedesc;
@@ -672,7 +675,7 @@ s4 builtin_fast_canstore(java_objectarray_t *oa, java_object_t *o)
        vftbl_t         *valuevftbl;
        int32_t          baseval;
        uint32_t         diffval;
-       int              result;
+       bool             result;
 
        if (o == NULL)
                return 1;
@@ -734,14 +737,14 @@ s4 builtin_fast_canstore(java_objectarray_t *oa, java_object_t *o)
 
 
 /* This is an optimized version where a is guaranteed to be one-dimensional */
-s4 builtin_fast_canstore_onedim(java_objectarray_t *a, java_object_t *o)
+bool builtin_fast_canstore_onedim(java_objectarray_t *a, java_object_t *o)
 {
        arraydescriptor *desc;
        vftbl_t         *elementvftbl;
        vftbl_t         *valuevftbl;
        int32_t          baseval;
        uint32_t         diffval;
-       int              result;
+       bool             result;
        
        if (o == NULL)
                return 1;
@@ -785,12 +788,12 @@ s4 builtin_fast_canstore_onedim(java_objectarray_t *a, java_object_t *o)
 
 /* This is an optimized version where a is guaranteed to be a
  * one-dimensional array of a class type */
-s4 builtin_fast_canstore_onedim_class(java_objectarray_t *a, java_object_t *o)
+bool builtin_fast_canstore_onedim_class(java_objectarray_t *a, java_object_t *o)
 {
        vftbl_t  *elementvftbl;
        vftbl_t  *valuevftbl;
        uint32_t  diffval;
-       int       result;
+       bool      result;
        
        if (o == NULL)
                return 1;
@@ -901,6 +904,90 @@ java_handle_t *builtin_new(classinfo *c)
        return o;
 }
 
+#if defined(ENABLE_ESCAPE_REASON)
+java_handle_t *builtin_escape_reason_new(classinfo *c) {
+       print_escape_reasons();
+       return builtin_java_new(c);
+}
+#endif
+
+#if defined(ENABLE_TLH)
+java_handle_t *builtin_tlh_new(classinfo *c)
+{
+       java_handle_t *o;
+#if defined(ENABLE_RT_TIMING)
+       struct timespec time_start, time_end;
+#endif
+#if defined(ENABLE_CYCLES_STATS)
+       u8 cycles_start, cycles_end;
+#endif
+
+       RT_TIMING_GET_TIME(time_start);
+       CYCLES_STATS_GET(cycles_start);
+
+       /* is the class loaded */
+
+       assert(c->state & CLASS_LOADED);
+
+       /* check if we can instantiate this class */
+
+       if (c->flags & ACC_ABSTRACT) {
+               exceptions_throw_instantiationerror(c);
+               return NULL;
+       }
+
+       /* is the class linked */
+
+       if (!(c->state & CLASS_LINKED))
+               if (!link_class(c))
+                       return NULL;
+
+       if (!(c->state & CLASS_INITIALIZED)) {
+#if !defined(NDEBUG)
+               if (initverbose)
+                       log_message_class("Initialize class (from builtin_new): ", c);
+#endif
+
+               if (!initialize_class(c))
+                       return NULL;
+       }
+
+       /*
+       o = tlh_alloc(&(THREADOBJECT->tlh), c->instancesize);
+       */
+       o = NULL;
+
+       if (o == NULL) {
+               o = heap_alloc(c->instancesize, c->flags & ACC_CLASS_HAS_POINTERS,
+                                          c->finalizer, true);
+       }
+
+       if (!o)
+               return NULL;
+
+#if !defined(ENABLE_GC_CACAO) && defined(ENABLE_HANDLES)
+       /* XXX this is only a dirty hack to make Boehm work with handles */
+
+       o = LLNI_WRAP((java_object_t *) o);
+#endif
+
+       LLNI_vftbl_direct(o) = c->vftbl;
+
+#if defined(ENABLE_THREADS)
+       lock_init_object_lock(LLNI_DIRECT(o));
+#endif
+
+       CYCLES_STATS_GET(cycles_end);
+       RT_TIMING_GET_TIME(time_end);
+
+/*
+       CYCLES_STATS_COUNT(builtin_new,cycles_end - cycles_start);
+       RT_TIMING_TIME_DIFF(time_start, time_end, RT_TIMING_NEW_OBJECT);
+*/
+
+       return o;
+#endif
+}
 
 /* builtin_java_new ************************************************************
 
@@ -990,7 +1077,7 @@ java_object_t *builtin_fast_new(classinfo *c)
 
 *******************************************************************************/
 
-java_handle_t *builtin_newarray(s4 size, classinfo *arrayclass)
+java_handle_t *builtin_newarray(int32_t size, classinfo *arrayclass)
 {
        arraydescriptor *desc;
        s4               dataoffset;
@@ -1053,7 +1140,7 @@ java_handle_t *builtin_newarray(s4 size, classinfo *arrayclass)
 
 *******************************************************************************/
 
-java_handle_t *builtin_java_newarray(s4 size, java_handle_t *arrayclazz)
+java_handle_t *builtin_java_newarray(int32_t size, java_handle_t *arrayclazz)
 {
        return builtin_newarray(size, LLNI_classinfo_unwrap(arrayclazz));
 }
@@ -1071,7 +1158,7 @@ java_handle_t *builtin_java_newarray(s4 size, java_handle_t *arrayclazz)
 
 *******************************************************************************/
 
-java_handle_objectarray_t *builtin_anewarray(s4 size, classinfo *componentclass)
+java_handle_objectarray_t *builtin_anewarray(int32_t size, classinfo *componentclass)
 {
        classinfo *arrayclass;
        
@@ -1106,7 +1193,7 @@ java_handle_objectarray_t *builtin_anewarray(s4 size, classinfo *componentclass)
 *******************************************************************************/
 
 #define BUILTIN_NEWARRAY_TYPE(type, arraytype)                             \
-java_handle_##type##array_t *builtin_newarray_##type(s4 size)              \
+java_handle_##type##array_t *builtin_newarray_##type(int32_t size)              \
 {                                                                          \
        return (java_handle_##type##array_t *)                                 \
                builtin_newarray(size, primitivetype_table[arraytype].arrayclass); \
@@ -1161,7 +1248,7 @@ static java_handle_t *builtin_multianewarray_intern(int n,
 
        /* get the class of the components to create */
 
-       componentclass = arrayclass->vftbl->arraydesc->componentvftbl->class;
+       componentclass = arrayclass->vftbl->arraydesc->componentvftbl->clazz;
 
        /* The verifier guarantees that the dimension count is in the range. */
 
@@ -2120,15 +2207,24 @@ void builtin_arraycopy(java_handle_t *src, s4 srcStart,
                return;
        }
 
-       /* we try to throw exception with the same message as SUN does */
+       // Check if offsets and length are positive.
+       if ((srcStart < 0) || (destStart < 0) || (len < 0)) {
+               exceptions_throw_arrayindexoutofboundsexception();
+               return;
+       }
 
-       if ((len < 0) || (srcStart < 0) || (destStart < 0) ||
-               (srcStart  + len < 0) || (srcStart  + len > LLNI_array_size(src)) ||
-               (destStart + len < 0) || (destStart + len > LLNI_array_size(dest))) {
+       // Check if ranges are valid.
+       if ((((uint32_t) srcStart  + (uint32_t) len) > (uint32_t) LLNI_array_size(src)) ||
+               (((uint32_t) destStart + (uint32_t) len) > (uint32_t) LLNI_array_size(dest))) {
                exceptions_throw_arrayindexoutofboundsexception();
                return;
        }
 
+       // Special case.
+       if (len == 0) {
+               return;
+       }
+
        if (sdesc->componentvftbl == ddesc->componentvftbl) {
                /* We copy primitive values or references of exactly the same type */