| // natSystem.cc - Native code implementing System class. |
| |
| /* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2006 Free Software Foundation |
| |
| This file is part of libgcj. |
| |
| This software is copyrighted work licensed under the terms of the |
| Libgcj License. Please consult the file "LIBGCJ_LICENSE" for |
| details. */ |
| |
| #include <config.h> |
| #include <platform.h> |
| |
| #include <stdio.h> |
| #include <string.h> |
| #include <stdlib.h> |
| |
| #include <gcj/cni.h> |
| #include <jvm.h> |
| #include <java/lang/System.h> |
| #include <java/lang/Class.h> |
| #include <java/lang/ArrayStoreException.h> |
| #include <java/lang/ArrayIndexOutOfBoundsException.h> |
| #include <java/lang/NullPointerException.h> |
| #include <java/io/PrintStream.h> |
| #include <java/io/InputStream.h> |
| |
| |
| |
| void |
| java::lang::System::setErr0 (java::io::PrintStream *newErr) |
| { |
| err = newErr; |
| } |
| |
| void |
| java::lang::System::setIn0 (java::io::InputStream *newIn) |
| { |
| in = newIn; |
| } |
| |
| void |
| java::lang::System::setOut0 (java::io::PrintStream *newOut) |
| { |
| out = newOut; |
| } |
| |
| void |
| java::lang::System::arraycopy (jobject src, jint src_offset, |
| jobject dst, jint dst_offset, |
| jint count) |
| { |
| if (! src || ! dst) |
| throw new NullPointerException; |
| |
| jclass src_c = src->getClass(); |
| jclass dst_c = dst->getClass(); |
| jclass src_comp = src_c->getComponentType(); |
| jclass dst_comp = dst_c->getComponentType(); |
| |
| if (! src_c->isArray() || ! dst_c->isArray() |
| || src_comp->isPrimitive() != dst_comp->isPrimitive() |
| || (src_comp->isPrimitive() && src_comp != dst_comp)) |
| throw new ArrayStoreException; |
| |
| __JArray *src_a = (__JArray *) src; |
| __JArray *dst_a = (__JArray *) dst; |
| if (src_offset < 0 || dst_offset < 0 || count < 0 |
| || (unsigned jint) src_offset > (unsigned jint) src_a->length |
| || (unsigned jint) (src_offset + count) > (unsigned jint) src_a->length |
| || (unsigned jint) dst_offset > (unsigned jint) dst_a->length |
| || (unsigned jint) (dst_offset + count) > (unsigned jint) dst_a->length) |
| throw new ArrayIndexOutOfBoundsException; |
| |
| // Do-nothing cases. |
| if ((src == dst && src_offset == dst_offset) |
| || ! count) |
| return; |
| |
| // If both are primitive, we can optimize trivially. If DST |
| // components are always assignable from SRC components, then we |
| // will never need to raise an error, and thus can do the |
| // optimization. If source and destinations are the same, then we |
| // know that the assignability premise always holds. |
| const bool prim = src_comp->isPrimitive(); |
| if (prim || dst_comp->isAssignableFrom(src_comp) || src == dst) |
| { |
| const size_t size = (prim ? src_comp->size() |
| : sizeof elements((jobjectArray)src)[0]); |
| |
| char *src_elts = _Jv_GetArrayElementFromElementType (src, src_comp); |
| src_elts += size * src_offset; |
| |
| char *dst_elts = _Jv_GetArrayElementFromElementType (dst, dst_comp); |
| dst_elts += size * dst_offset; |
| |
| #if HAVE_MEMMOVE |
| // We don't bother trying memcpy. It can't be worth the cost of |
| // the check. |
| // Don't cast to (void*), as memmove may expect (char*) |
| memmove (dst_elts, src_elts, count * size); |
| #else |
| bcopy (src_elts, dst_elts, count * size); |
| #endif |
| } |
| else |
| { |
| jobject *src_elts = elements ((jobjectArray) src_a) + src_offset; |
| jobject *dst_elts = elements ((jobjectArray) dst_a) + dst_offset; |
| |
| for (int i = 0; i < count; ++i) |
| { |
| if (*src_elts |
| && ! dst_comp->isAssignableFrom((*src_elts)->getClass())) |
| throw new ArrayStoreException; |
| *dst_elts++ = *src_elts++; |
| } |
| } |
| } |
| |
| jlong |
| java::lang::System::currentTimeMillis (void) |
| { |
| return _Jv_platform_gettimeofday (); |
| } |
| |
| jlong |
| java::lang::System::nanoTime () |
| { |
| return _Jv_platform_nanotime (); |
| } |
| |
| jint |
| java::lang::System::identityHashCode (jobject obj) |
| { |
| return _Jv_HashCode (obj); |
| } |
| |
| jstring |
| java::lang::System::getenv0 (jstring name) |
| { |
| jint len = _Jv_GetStringUTFLength (name); |
| char buf[len + 1]; |
| jsize total = JvGetStringUTFRegion (name, 0, name->length(), buf); |
| buf[total] = '\0'; |
| const char *value = ::getenv (buf); |
| if (value == NULL) |
| return NULL; |
| return JvNewStringUTF (value); |
| } |