1 // natSystem.cc - Native code implementing System class.
2 
3 /* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2006 Free Software Foundation
4 
5    This file is part of libgcj.
6 
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
9 details.  */
10 
11 #include <config.h>
12 #include <platform.h>
13 
14 #include <stdio.h>
15 #include <string.h>
16 #include <stdlib.h>
17 
18 #include <gcj/cni.h>
19 #include <jvm.h>
20 #include <java/lang/System.h>
21 #include <java/lang/Class.h>
22 #include <java/lang/ArrayStoreException.h>
23 #include <java/lang/ArrayIndexOutOfBoundsException.h>
24 #include <java/lang/NullPointerException.h>
25 #include <java/io/PrintStream.h>
26 #include <java/io/InputStream.h>
27 
28 
29 
30 void
setErr0(java::io::PrintStream * newErr)31 java::lang::System::setErr0 (java::io::PrintStream *newErr)
32 {
33   err = newErr;
34 }
35 
36 void
setIn0(java::io::InputStream * newIn)37 java::lang::System::setIn0 (java::io::InputStream *newIn)
38 {
39   in = newIn;
40 }
41 
42 void
setOut0(java::io::PrintStream * newOut)43 java::lang::System::setOut0 (java::io::PrintStream *newOut)
44 {
45   out = newOut;
46 }
47 
48 void
arraycopy(jobject src,jint src_offset,jobject dst,jint dst_offset,jint count)49 java::lang::System::arraycopy (jobject src, jint src_offset,
50 			       jobject dst, jint dst_offset,
51 			       jint count)
52 {
53   if (! src || ! dst)
54     throw new NullPointerException;
55 
56   jclass src_c = src->getClass();
57   jclass dst_c = dst->getClass();
58   jclass src_comp = src_c->getComponentType();
59   jclass dst_comp = dst_c->getComponentType();
60 
61   if (! src_c->isArray() || ! dst_c->isArray()
62       || src_comp->isPrimitive() != dst_comp->isPrimitive()
63       || (src_comp->isPrimitive() && src_comp != dst_comp))
64     throw new ArrayStoreException;
65 
66   __JArray *src_a = (__JArray *) src;
67   __JArray *dst_a = (__JArray *) dst;
68   if (src_offset < 0 || dst_offset < 0 || count < 0
69       || (unsigned jint) src_offset > (unsigned jint) src_a->length
70       || (unsigned jint) (src_offset + count) > (unsigned jint) src_a->length
71       || (unsigned jint) dst_offset > (unsigned jint) dst_a->length
72       || (unsigned jint) (dst_offset + count) > (unsigned jint) dst_a->length)
73     throw new ArrayIndexOutOfBoundsException;
74 
75   // Do-nothing cases.
76   if ((src == dst && src_offset == dst_offset)
77       || ! count)
78     return;
79 
80   // If both are primitive, we can optimize trivially.  If DST
81   // components are always assignable from SRC components, then we
82   // will never need to raise an error, and thus can do the
83   // optimization.  If source and destinations are the same, then we
84   // know that the assignability premise always holds.
85   const bool prim = src_comp->isPrimitive();
86   if (prim || dst_comp->isAssignableFrom(src_comp) || src == dst)
87     {
88       const size_t size = (prim ? src_comp->size()
89 			   : sizeof elements((jobjectArray)src)[0]);
90 
91       char *src_elts = _Jv_GetArrayElementFromElementType (src, src_comp);
92       src_elts += size * src_offset;
93 
94       char *dst_elts = _Jv_GetArrayElementFromElementType (dst, dst_comp);
95       dst_elts += size * dst_offset;
96 
97 #if HAVE_MEMMOVE
98       // We don't bother trying memcpy.  It can't be worth the cost of
99       // the check.
100       // Don't cast to (void*), as memmove may expect (char*)
101       memmove (dst_elts, src_elts, count * size);
102 #else
103       bcopy (src_elts, dst_elts, count * size);
104 #endif
105     }
106   else
107     {
108       jobject *src_elts = elements ((jobjectArray) src_a) + src_offset;
109       jobject *dst_elts = elements ((jobjectArray) dst_a) + dst_offset;
110 
111       for (int i = 0; i < count; ++i)
112 	{
113 	  if (*src_elts
114 	      && ! dst_comp->isAssignableFrom((*src_elts)->getClass()))
115 	    throw new ArrayStoreException;
116 	  *dst_elts++ = *src_elts++;
117 	}
118     }
119 }
120 
121 jlong
currentTimeMillis(void)122 java::lang::System::currentTimeMillis (void)
123 {
124   return _Jv_platform_gettimeofday ();
125 }
126 
127 jlong
nanoTime()128 java::lang::System::nanoTime ()
129 {
130   return _Jv_platform_nanotime ();
131 }
132 
133 jint
identityHashCode(jobject obj)134 java::lang::System::identityHashCode (jobject obj)
135 {
136   return _Jv_HashCode (obj);
137 }
138 
139 jstring
getenv0(jstring name)140 java::lang::System::getenv0 (jstring name)
141 {
142   jint len = _Jv_GetStringUTFLength (name);
143   char buf[len + 1];
144   jsize total = JvGetStringUTFRegion (name, 0, name->length(), buf);
145   buf[total] = '\0';
146   const char *value = ::getenv (buf);
147   if (value == NULL)
148     return NULL;
149   return JvNewStringUTF (value);
150 }
151