1 // prims.cc - Code for core of runtime environment.
3 /* Copyright (C) 1998, 1999, 2000 Free Software Foundation
5 This file is part of libgcj.
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
13 #ifdef USE_WIN32_SIGNALLING
15 #endif /* USE_WIN32_SIGNALLING */
18 #undef __INSIDE_CYGWIN__
20 #endif /* USE_WINSOCK */
34 #include <java-signal.h>
35 #include <java-threads.h>
37 #ifndef DISABLE_GETENV_PROPERTIES
39 #include <java-props.h>
40 #define PROCESS_GCJ_PROPERTIES process_gcj_properties()
42 #define PROCESS_GCJ_PROPERTIES
43 #endif // DISABLE_GETENV_PROPERTIES
45 #include <java/lang/Class.h>
46 #include <java/lang/Runtime.h>
47 #include <java/lang/String.h>
48 #include <java/lang/Thread.h>
49 #include <java/lang/ThreadGroup.h>
50 #include <gnu/gcj/runtime/FirstThread.h>
51 #include <java/lang/ArrayIndexOutOfBoundsException.h>
52 #include <java/lang/ArithmeticException.h>
53 #include <java/lang/ClassFormatError.h>
54 #include <java/lang/NegativeArraySizeException.h>
55 #include <java/lang/NullPointerException.h>
56 #include <java/lang/OutOfMemoryError.h>
57 #include <java/lang/System.h>
58 #include <java/lang/reflect/Modifier.h>
59 #include <java/io/PrintStream.h>
65 #define ObjectClass _CL_Q34java4lang6Object
66 extern java::lang::Class ObjectClass
;
68 // We allocate a single OutOfMemoryError exception which we keep
69 // around for use if we run out of memory.
70 static java::lang::OutOfMemoryError
*no_memory
;
72 // Largest representable size_t.
73 #define SIZE_T_MAX ((size_t) (~ (size_t) 0))
75 // Properties set at compile time.
76 const char **_Jv_Compiler_Properties
;
78 #ifndef DISABLE_GETENV_PROPERTIES
79 // Property key/value pairs.
80 property_pair
*_Jv_Environment_Properties
;
83 // The name of this executable.
84 static char * _Jv_execName
;
89 static java::lang::NullPointerException
*nullp
;
90 SIGNAL_HANDLER (catch_segv
)
93 nullp
->fillInStackTrace ();
98 static java::lang::ArithmeticException
*arithexception
;
101 SIGNAL_HANDLER (catch_fpe
)
103 #ifdef HANDLE_DIVIDE_OVERFLOW
104 HANDLE_DIVIDE_OVERFLOW
;
108 arithexception
->fillInStackTrace ();
109 _Jv_Throw (arithexception
);
116 _Jv_equalUtf8Consts (Utf8Const
* a
, Utf8Const
*b
)
119 register _Jv_ushort
*aptr
, *bptr
;
122 if (a
->hash
!= b
->hash
)
125 if (b
->length
!= len
)
127 aptr
= (_Jv_ushort
*)a
->data
;
128 bptr
= (_Jv_ushort
*)b
->data
;
129 len
= (len
+ 1) >> 1;
131 if (*aptr
++ != *bptr
++)
136 /* True iff A is equal to STR.
137 HASH is STR->hashCode().
141 _Jv_equal (Utf8Const
* a
, jstring str
, jint hash
)
143 if (a
->hash
!= (_Jv_ushort
) hash
)
145 jint len
= str
->length();
147 jchar
*sptr
= _Jv_GetStringChars (str
);
148 register unsigned char* ptr
= (unsigned char*) a
->data
;
149 register unsigned char* limit
= ptr
+ a
->length
;
152 int ch
= UTF8_GET (ptr
, limit
);
161 /* Like _Jv_equal, but stop after N characters. */
163 _Jv_equaln (Utf8Const
*a
, jstring str
, jint n
)
165 jint len
= str
->length();
167 jchar
*sptr
= _Jv_GetStringChars (str
);
168 register unsigned char* ptr
= (unsigned char*) a
->data
;
169 register unsigned char* limit
= ptr
+ a
->length
;
170 for (; n
-- > 0; i
++, sptr
++)
172 int ch
= UTF8_GET (ptr
, limit
);
181 /* Count the number of Unicode chars encoded in a given Ut8 string. */
183 _Jv_strLengthUtf8(char* str
, int len
)
185 register unsigned char* ptr
;
186 register unsigned char* limit
;
189 ptr
= (unsigned char*) str
;
192 for (; ptr
< limit
; str_length
++) {
193 if (UTF8_GET (ptr
, limit
) < 0) {
200 /* Calculate a hash value for a string encoded in Utf8 format.
201 * This returns the same hash value as specified or java.lang.String.hashCode.
204 hashUtf8String (char* str
, int len
)
206 register unsigned char* ptr
= (unsigned char*) str
;
207 register unsigned char* limit
= ptr
+ len
;
212 int ch
= UTF8_GET (ptr
, limit
);
213 /* Updated specification from
214 http://www.javasoft.com/docs/books/jls/clarify.html. */
215 hash
= (31 * hash
) + ch
;
221 _Jv_makeUtf8Const (char* s
, int len
)
225 Utf8Const
* m
= (Utf8Const
*) _Jv_AllocBytes (sizeof(Utf8Const
) + len
+ 1);
228 memcpy (m
->data
, s
, len
);
231 m
->hash
= hashUtf8String (s
, len
) & 0xFFFF;
236 _Jv_makeUtf8Const (jstring string
)
238 jint hash
= string
->hashCode ();
239 jint len
= _Jv_GetStringUTFLength (string
);
241 Utf8Const
* m
= (Utf8Const
*)
242 _Jv_AllocBytesChecked (sizeof(Utf8Const
) + len
+ 1);
247 _Jv_GetStringUTFRegion (string
, 0, string
->length (), m
->data
);
257 _Jv_Abort (const char *function
, const char *file
, int line
,
261 _Jv_Abort (const char *, const char *, int, const char *message
)
266 "libgcj failure: %s\n in function %s, file %s, line %d\n",
267 message
, function
, file
, line
);
269 java::io::PrintStream
*err
= java::lang::System::err
;
270 err
->print(JvNewStringLatin1 ("libgcj failure: "));
271 err
->println(JvNewStringLatin1 (message
));
278 fail_on_finalization (jobject
)
280 JvFail ("object was finalized");
284 _Jv_GCWatch (jobject obj
)
286 _Jv_RegisterFinalizer (obj
, fail_on_finalization
);
290 _Jv_ThrowBadArrayIndex(jint bad_index
)
292 JvThrow (new java::lang::ArrayIndexOutOfBoundsException
293 (java::lang::String::valueOf(bad_index
)));
296 // Allocate some unscanned memory and throw an exception if no memory.
298 _Jv_AllocBytesChecked (jsize size
)
300 void *r
= _Jv_AllocBytes (size
);
302 _Jv_Throw (no_memory
);
306 // Allocate a new object of class C. SIZE is the size of the object
307 // to allocate. You might think this is redundant, but it isn't; some
308 // classes, such as String, aren't of fixed size.
310 _Jv_AllocObject (jclass c
, jint size
)
314 jobject obj
= (jobject
) _Jv_AllocObj (size
);
317 *((_Jv_VTable
**) obj
) = c
->vtable
;
319 // If this class has inherited finalize from Object, then don't
320 // bother registering a finalizer. We know that finalize() is the
321 // very first method after the dummy entry. If this turns out to be
322 // unreliable, a more robust implementation can be written. Such an
323 // implementation would look for Object.finalize in Object's method
324 // table at startup, and then use that information to find the
325 // appropriate index in the method vector.
326 if (c
->vtable
->method
[1] != ObjectClass
.vtable
->method
[1])
327 _Jv_RegisterFinalizer (obj
, _Jv_FinalizeObject
);
332 // Allocate a new array of Java objects. Each object is of type
333 // `elementClass'. `init' is used to initialize each slot in the
336 _Jv_NewObjectArray (jsize count
, jclass elementClass
, jobject init
)
339 JvThrow (new java::lang::NegativeArraySizeException
);
341 JvAssert (! elementClass
->isPrimitive ());
343 jobjectArray obj
= NULL
;
344 size_t size
= (size_t) _Jv_GetArrayElementFromElementType (obj
,
347 // Check for overflow.
348 if ((size_t) count
> (SIZE_T_MAX
- size
) / sizeof (jobject
))
351 size
+= count
* sizeof (jobject
);
353 // FIXME: second argument should be "current loader" //
354 jclass clas
= _Jv_FindArrayClass (elementClass
, 0);
356 obj
= (jobjectArray
) _Jv_AllocArray (size
);
360 jobject
* ptr
= elements(obj
);
361 // We know the allocator returns zeroed memory. So don't bother
368 // Set the vtbl last to avoid problems if the GC happens during the
369 // window in this function between the allocation and this
371 *((_Jv_VTable
**) obj
) = clas
->vtable
;
375 // Allocate a new array of primitives. ELTYPE is the type of the
376 // element, COUNT is the size of the array.
378 _Jv_NewPrimArray (jclass eltype
, jint count
)
380 int elsize
= eltype
->size();
382 JvThrow (new java::lang::NegativeArraySizeException ());
384 JvAssert (eltype
->isPrimitive ());
385 jobject dummy
= NULL
;
386 size_t size
= (size_t) _Jv_GetArrayElementFromElementType (dummy
, eltype
);
388 // Check for overflow.
389 if ((size_t) count
> (SIZE_T_MAX
- size
) / elsize
)
392 __JArray
*arr
= (__JArray
*) _Jv_AllocObj (size
+ elsize
* count
);
396 // Note that we assume we are given zeroed memory by the allocator.
398 jclass klass
= _Jv_FindArrayClass (eltype
, 0);
399 // Set the vtbl last to avoid problems if the GC happens during the
400 // window in this function between the allocation and this
402 *((_Jv_VTable
**) arr
) = klass
->vtable
;
407 _Jv_NewArray (jint type
, jint size
)
411 case 4: return JvNewBooleanArray (size
);
412 case 5: return JvNewCharArray (size
);
413 case 6: return JvNewFloatArray (size
);
414 case 7: return JvNewDoubleArray (size
);
415 case 8: return JvNewByteArray (size
);
416 case 9: return JvNewShortArray (size
);
417 case 10: return JvNewIntArray (size
);
418 case 11: return JvNewLongArray (size
);
420 JvFail ("newarray - bad type code");
421 return NULL
; // Placate compiler.
425 _Jv_NewMultiArray (jclass type
, jint dimensions
, jint
*sizes
)
427 JvAssert (type
->isArray());
428 jclass element_type
= type
->getComponentType();
430 if (element_type
->isPrimitive())
431 result
= _Jv_NewPrimArray (element_type
, sizes
[0]);
433 result
= _Jv_NewObjectArray (sizes
[0], element_type
, NULL
);
437 JvAssert (! element_type
->isPrimitive());
438 JvAssert (element_type
->isArray());
439 jobject
*contents
= elements ((jobjectArray
) result
);
440 for (int i
= 0; i
< sizes
[0]; ++i
)
441 contents
[i
] = _Jv_NewMultiArray (element_type
, dimensions
- 1,
449 _Jv_NewMultiArray (jclass array_type
, jint dimensions
, ...)
452 jint sizes
[dimensions
];
453 va_start (args
, dimensions
);
454 for (int i
= 0; i
< dimensions
; ++i
)
456 jint size
= va_arg (args
, jint
);
461 return _Jv_NewMultiArray (array_type
, dimensions
, sizes
);
466 class _Jv_PrimClass
: public java::lang::Class
469 // FIXME: calling convention is weird. If we use the natural types
470 // then the compiler will complain because they aren't Java types.
471 _Jv_PrimClass (jobject cname
, jbyte sig
, jint len
)
473 using namespace java::lang::reflect
;
475 // We must initialize every field of the class. We do this in
476 // the same order they are declared in Class.h.
478 name
= _Jv_makeUtf8Const ((char *) cname
, -1);
479 accflags
= Modifier::PUBLIC
| Modifier::FINAL
;
482 constants
.tags
= NULL
;
483 constants
.data
= NULL
;
486 vtable_method_count
= 0;
490 static_field_count
= 0;
491 vtable
= JV_PRIMITIVE_VTABLE
;
495 state
= JV_STATE_NOTHING
;
500 #define DECLARE_PRIM_TYPE(NAME, SIG, LEN) \
501 _Jv_PrimClass _Jv_##NAME##Class((jobject) #NAME, (jbyte) SIG, (jint) LEN)
503 DECLARE_PRIM_TYPE(byte
, 'B', 1);
504 DECLARE_PRIM_TYPE(short, 'S', 2);
505 DECLARE_PRIM_TYPE(int, 'I', 4);
506 DECLARE_PRIM_TYPE(long, 'J', 8);
507 DECLARE_PRIM_TYPE(boolean
, 'Z', 1);
508 DECLARE_PRIM_TYPE(char, 'C', 2);
509 DECLARE_PRIM_TYPE(float, 'F', 4);
510 DECLARE_PRIM_TYPE(double, 'D', 8);
511 DECLARE_PRIM_TYPE(void, 'V', 0);
514 _Jv_FindClassFromSignature (char *sig
, java::lang::ClassLoader
*loader
)
519 return JvPrimClass (byte
);
521 return JvPrimClass (short);
523 return JvPrimClass (int);
525 return JvPrimClass (long);
527 return JvPrimClass (boolean
);
529 return JvPrimClass (char);
531 return JvPrimClass (float);
533 return JvPrimClass (double);
535 return JvPrimClass (void);
539 for (i
= 1; sig
[i
] && sig
[i
] != ';'; ++i
)
541 _Jv_Utf8Const
*name
= _Jv_makeUtf8Const (&sig
[1], i
- 1);
542 return _Jv_FindClass (name
, loader
);
546 return _Jv_FindArrayClass (_Jv_FindClassFromSignature (&sig
[1], loader
),
549 JvFail ("couldn't understand class signature");
550 return NULL
; // Placate compiler.
556 JvConvertArgv (int argc
, const char **argv
)
560 jobjectArray ar
= JvNewObjectArray(argc
, &StringClass
, NULL
);
561 jobject
* ptr
= elements(ar
);
562 for (int i
= 0; i
< argc
; i
++)
564 const char *arg
= argv
[i
];
565 // FIXME - should probably use JvNewStringUTF.
566 *ptr
++ = JvNewStringLatin1(arg
, strlen(arg
));
568 return (JArray
<jstring
>*) ar
;
571 // FIXME: These variables are static so that they will be
572 // automatically scanned by the Boehm collector. This is needed
573 // because with qthreads the collector won't scan the initial stack --
574 // it will only scan the qthreads stacks.
576 // Command line arguments.
577 static jobject arg_vec
;
579 // The primary threadgroup.
580 static java::lang::ThreadGroup
*main_group
;
582 // The primary thread.
583 static java::lang::Thread
*main_thread
;
586 _Jv_ThisExecutable (void)
592 _Jv_ThisExecutable (const char *name
)
596 _Jv_execName
= new char[strlen (name
) + 1];
597 strcpy (_Jv_execName
, name
);
601 #ifdef USE_WIN32_SIGNALLING
603 extern "C" int* win32_get_restart_frame (void *);
606 win32_exception_handler (LPEXCEPTION_POINTERS e
)
609 if (e
->ExceptionRecord
->ExceptionCode
== EXCEPTION_ACCESS_VIOLATION
)
610 setjmp_buf
= win32_get_restart_frame (nullp
);
611 else if (e
->ExceptionRecord
->ExceptionCode
== EXCEPTION_INT_DIVIDE_BY_ZERO
)
612 setjmp_buf
= win32_get_restart_frame (arithexception
);
614 return EXCEPTION_CONTINUE_SEARCH
;
616 e
->ContextRecord
->Ebp
= setjmp_buf
[0];
617 // FIXME: Why does i386-signal.h increment the PC here, do we need to do it?
618 e
->ContextRecord
->Eip
= setjmp_buf
[1];
619 // FIXME: Is this the stack pointer? Do we need it?
620 e
->ContextRecord
->Esp
= setjmp_buf
[2];
622 return EXCEPTION_CONTINUE_EXECUTION
;
634 arithexception
= new java::lang::ArithmeticException
635 (JvNewStringLatin1 ("/ by zero"));
638 no_memory
= new java::lang::OutOfMemoryError
;
641 LTDL_SET_PRELOADED_SYMBOLS ();
645 // Initialise winsock for networking
647 if (WSAStartup (MAKEWORD (1, 1), &data
))
648 MessageBox (NULL
, "Error initialising winsock library.", "Error", MB_OK
| MB_ICONEXCLAMATION
);
649 #endif /* USE_WINSOCK */
651 #ifdef USE_WIN32_SIGNALLING
652 // Install exception handler
653 SetUnhandledExceptionFilter (win32_exception_handler
);
655 // We only want this on POSIX systems.
656 struct sigaction act
;
657 act
.sa_handler
= SIG_IGN
;
658 sigemptyset (&act
.sa_mask
);
660 sigaction (SIGPIPE
, &act
, NULL
);
661 #endif /* USE_WIN32_SIGNALLING */
666 #ifndef DISABLE_GETENV_PROPERTIES
669 next_property_key (char *s
, size_t *length
)
675 // Skip over whitespace
679 // If we've reached the end, return NULL. Also return NULL if for
680 // some reason we've come across a malformed property string.
686 // Determine the length of the property key.
704 next_property_value (char *s
, size_t *length
)
720 // If we've reached the end, return NULL.
724 // Determine the length of the property value.
743 process_gcj_properties ()
745 char *props
= getenv("GCJ_PROPERTIES");
748 size_t property_count
= 0;
753 // Whip through props quickly in order to count the number of
755 while (p
&& (p
= next_property_key (p
, &length
)))
757 // Skip to the end of the key
760 p
= next_property_value (p
, &length
);
767 // Allocate an array of property value/key pairs.
768 _Jv_Environment_Properties
=
769 (property_pair
*) malloc (sizeof(property_pair
)
770 * (property_count
+ 1));
772 // Go through the properties again, initializing _Jv_Properties
776 while (p
&& (p
= next_property_key (p
, &length
)))
778 _Jv_Environment_Properties
[property_count
].key
= p
;
779 _Jv_Environment_Properties
[property_count
].key_length
= length
;
781 // Skip to the end of the key
784 p
= next_property_value (p
, &length
);
786 _Jv_Environment_Properties
[property_count
].value
= p
;
787 _Jv_Environment_Properties
[property_count
].value_length
= length
;
794 memset ((void *) &_Jv_Environment_Properties
[property_count
],
795 0, sizeof (property_pair
));
799 // Null terminate the strings.
800 while (_Jv_Environment_Properties
[i
].key
)
802 _Jv_Environment_Properties
[i
].key
[_Jv_Environment_Properties
[i
].key_length
] = 0;
803 _Jv_Environment_Properties
[i
++].value
[_Jv_Environment_Properties
[i
].value_length
] = 0;
807 #endif // DISABLE_GETENV_PROPERTIES
810 JvRunMain (jclass klass
, int argc
, const char **argv
)
812 PROCESS_GCJ_PROPERTIES
;
815 #ifdef HAVE_PROC_SELF_EXE
817 sprintf (exec_name
, "/proc/%d/exe", getpid ());
818 _Jv_ThisExecutable (exec_name
);
820 _Jv_ThisExecutable (argv
[0]);
823 arg_vec
= JvConvertArgv (argc
- 1, argv
+ 1);
824 main_group
= new java::lang::ThreadGroup (23);
825 main_thread
= new gnu::gcj::runtime::FirstThread (main_group
,
828 main_thread
->start();
831 java::lang::Runtime::getRuntime ()->exit (0);
835 _Jv_RunMain (const char *class_name
, int argc
, const char **argv
)
837 PROCESS_GCJ_PROPERTIES
;
841 #ifdef HAVE_PROC_SELF_EXE
843 sprintf (exec_name
, "/proc/%d/exe", getpid ());
844 _Jv_ThisExecutable (exec_name
);
847 arg_vec
= JvConvertArgv (argc
- 1, argv
+ 1);
848 main_group
= new java::lang::ThreadGroup (23);
849 main_thread
= new gnu::gcj::runtime::FirstThread (main_group
,
850 JvNewStringLatin1 (class_name
),
852 main_thread
->start();
855 java::lang::Runtime::getRuntime ()->exit (0);
860 // Parse a string and return a heap size.
862 parse_heap_size (const char *spec
)
865 unsigned long val
= strtoul (spec
, &end
, 10);
866 if (*end
== 'k' || *end
== 'K')
868 else if (*end
== 'm' || *end
== 'M')
873 // Set the initial heap size. This might be ignored by the GC layer.
874 // This must be called before _Jv_RunMain.
876 _Jv_SetInitialHeapSize (const char *arg
)
878 size_t size
= parse_heap_size (arg
);
879 _Jv_GCSetInitialHeapSize (size
);
882 // Set the maximum heap size. This might be ignored by the GC layer.
883 // This must be called before _Jv_RunMain.
885 _Jv_SetMaximumHeapSize (const char *arg
)
887 size_t size
= parse_heap_size (arg
);
888 _Jv_GCSetMaximumHeapSize (size
);
894 _Jv_Malloc (jsize size
)
898 void *ptr
= malloc ((size_t) size
);
905 _Jv_Realloc (void *ptr
, jsize size
)
909 ptr
= realloc (ptr
, (size_t) size
);
916 _Jv_MallocUnchecked (jsize size
)
920 return malloc ((size_t) size
);
931 // In theory, these routines can be #ifdef'd away on machines which
932 // support divide overflow signals. However, we never know if some
933 // code might have been compiled with "-fuse-divide-subroutine", so we
934 // always include them in libgcj.
937 _Jv_divI (jint dividend
, jint divisor
)
940 _Jv_Throw (arithexception
);
942 if (dividend
== (jint
) 0x80000000L
&& divisor
== -1)
945 return dividend
/ divisor
;
949 _Jv_remI (jint dividend
, jint divisor
)
952 _Jv_Throw (arithexception
);
954 if (dividend
== (jint
) 0x80000000L
&& divisor
== -1)
957 return dividend
% divisor
;
961 _Jv_divJ (jlong dividend
, jlong divisor
)
964 _Jv_Throw (arithexception
);
966 if (dividend
== (jlong
) 0x8000000000000000LL
&& divisor
== -1)
969 return dividend
/ divisor
;
973 _Jv_remJ (jlong dividend
, jlong divisor
)
976 _Jv_Throw (arithexception
);
978 if (dividend
== (jlong
) 0x8000000000000000LL
&& divisor
== -1)
981 return dividend
% divisor
;