gcc/libjava/java/lang/reflect/natArray.cc
Bryce McKinlay 18744d9b72 New Stack Trace infrastructure.
2005-03-10  Bryce McKinlay  <mckinlay@redhat.com>

	New Stack Trace infrastructure.
	* Makefile.am (libgcj0_convenience_la_SOURCES): Add stacktrace.cc.
	(gnu/gcj/runtime/StackTrace.lo): Removed.
	(ordinary_java_source_files): Remove obsolete files.
	(nat_source_files): Remove obsolete files. Add natVMThrowable.cc.
	* configure.host (fallback_backtrace_h): Set backtrace header
	for mingw and cygwin targets.
	* configure.ac: Make symlink for fallback backtrace headers.
	* Makefile.in, configure: Rebuilt.
	* defineclass.cc (_Jv_ClassReader::read_one_code_attribute):
	Read 'LineNumberTable' attribute.
	(_Jv_ClassReader::read_one_class_attribute): Read 'SourceFile'
	attribute.
	(_Jv_ClassReader::handleCodeAttribute): Initialize method line
	table fields.
	* exception.cc: Remove unused include.
	* interpret.cc (DIRECT_THREADED, insn_slot): Moved to java-interp.h.
	(SAVE_PC): New macro. Save current PC in the interpreter frame.
	(NULLCHECK, NULLARRAYCHECK): Use SAVE_PC.
	(_Jv_InterpMethod::compile): Translate bytecode PC values in the line
	table to direct threaded instruction values.
	(_Jv_StartOfInterpreter, _Jv_EndOfInterpreter): Removed.
	(_Jv_InterpMethod::run): No longer member function. All
	callers updated. Remove _Unwind calls. Call SAVE_PC whenever a call
	is made or where an instruction could throw.
	(_Jv_InterpMethod::get_source_line): New. Look up source line numbers
	in line_table.
	* prims.cc (catch_segv): Construct exception after MAKE_THROW_FRAME.
	(catch_fpe): Likewise.
	* stacktrace.cc: New file. Stack trace code now here.
	* gnu/gcj/runtime/MethodRef.java:
	* gnu/gcj/runtime/NameFinder.java: Mostly reimplemented. Now simply
	calls addr2line to look up PC addresses in a given binary or shared
	library.
	* gnu/gcj/runtime/StackTrace.java, gnu/gcj/runtime/natNameFinder.cc,
	gnu/gcj/runtime/natStackTrace.cc: Removed.
	* gnu/java/lang/MainThread.java (call_main): Add comment warning that
	this function name is specially recognised by the stack trace code
	and shouldn't be changed.
	* include/java-interp.h (DIRECT_THREADED, insn_slot): Moved here.
	(struct  _Jv_LineTableEntry, line_table, line_table_len): New.
	(_Jv_InterpMethod::run): Update declaration.
	(_Jv_StackTrace_): New friend. NameFinder and StackTrace no longer
	friends.
	(_Jv_InterpFrame): Renamed from _Jv_MethodChain. Add PC field.
	* include/java-stack.h: New file. Declarations for stack tracing.
	* include/jvm.h (_Jv_Frame_info): Removed.
	* java/lang/Class.h: Update friend declarations.
	* java/lang/VMClassLoader.java (getSystemClassLoader): Simplify
	exception message.
	* java/lang/VMThrowable.java (fillInStackTrace): Now native.
	(getStackTrace): Now native.
	(data): New RawDataManaged field.
	* java/lang/natClass.cc: Update includes.
	(forName): Use _Jv_StackTrace::GetCallingClass for
	calling-classloader check.
	(getClassLoader): Likewise.
	* java/lang/natRuntime.cc: Update includes.
	(_load): Use _Jv_StackTrace::GetFirstNonSystemClassLoader.
	* java/lang/natVMSecurityManager.cc: Update includes.
	(getClassContext): Use _Jv_StackTrace::GetClassContext.
	* java/lang/natVMThrowable.cc: New file. Native methods for
	VMThrowable.
	* java/lang/reflect/natArray.cc: Update includes.
	(newInstance): Use _Jv_StackTrace::GetCallingClass to implement
	accessibility check.
	* java/lang/reflect/natConstructor.cc: Update includes.
	(newInstance): Use _Jv_StackTrace::GetCallingClass to implement
	accessibility check.
	* java/lang/reflect/natField.cc: Update includes.
	(getAddr): Use _Jv_StackTrace::GetCallingClass to implement
	accessibility check.
	* java/lang/reflect/natMethod.cc: Update includes.
	(invoke): Use _Jv_StackTrace::GetCallingClass to implement
	accessibility check.
	* java/util/natResourceBundle.cc: Update includes.
	(getCallingClassLoader): Use _Jv_StackTrace::GetCallingClass.
	* java/util/logging/natLogger.cc: Update includes. Use
	_Jv_StackTrace::GetCallerInfo to get call-site info.
	* sysdep/generic/backtrace.h: Fallback backtrace code. Stub
	implementation.
	* sysdep/i386/backtrace.h: New. Fallback backtrace code. i386
	implementation.

From-SVN: r96253
2005-03-10 19:02:21 +00:00

361 lines
12 KiB
C++

// natField.cc - Implementation of java.lang.reflect.Field native methods.
/* Copyright (C) 1999, 2000, 2001, 2003 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 <stdlib.h>
#include <jvm.h>
#include <gcj/cni.h>
#include <java-stack.h>
#include <java/lang/reflect/Array.h>
#include <java/lang/ArrayIndexOutOfBoundsException.h>
#include <java/lang/IllegalArgumentException.h>
#include <java/lang/Byte.h>
#include <java/lang/Short.h>
#include <java/lang/Integer.h>
#include <java/lang/Long.h>
#include <java/lang/Float.h>
#include <java/lang/Double.h>
#include <java/lang/Boolean.h>
#include <java/lang/Character.h>
jobject
java::lang::reflect::Array::newInstance (jclass componentType, jint length)
{
if (componentType->isPrimitive())
{
// We could check for this in _Jv_NewPrimArray, but that seems
// like needless overhead when the only real route to this
// problem is here.
if (componentType == JvPrimClass (void))
throw new java::lang::IllegalArgumentException ();
return _Jv_NewPrimArray (componentType, length);
}
else
// FIXME: class loader?
return JvNewObjectArray (length, componentType, NULL);
}
jobject
java::lang::reflect::Array::newInstance (jclass componentType,
jintArray dimensions)
{
jint ndims = dimensions->length;
if (ndims == 0)
throw new java::lang::IllegalArgumentException ();
jint* dims = elements (dimensions);
if (ndims == 1)
return newInstance (componentType, dims[0]);
Class *caller = _Jv_StackTrace::GetCallingClass (&Array::class$);
ClassLoader *caller_loader = NULL;
if (caller)
caller_loader = caller->getClassLoaderInternal();
jclass arrayType = componentType;
for (int i = 0; i < ndims; i++)
arrayType = _Jv_GetArrayClass (arrayType, caller_loader);
return _Jv_NewMultiArray (arrayType, ndims, dims);
}
jint
java::lang::reflect::Array::getLength (jobject array)
{
jclass arrayType = array->getClass();
if (! arrayType->isArray ())
throw new java::lang::IllegalArgumentException;
return ((__JArray*) array)->length;
}
jclass
java::lang::reflect::Array::getElementType (jobject array, jint index)
{
jclass arrayType = array->getClass();
if (! arrayType->isArray ())
throw new java::lang::IllegalArgumentException;
jint length = ((__JArray*) array)->length;
if ((_Jv_uint) index >= (_Jv_uint) length)
_Jv_ThrowBadArrayIndex(index);
return arrayType->getComponentType ();
}
jboolean
java::lang::reflect::Array::getBoolean (jobject array, jint index)
{
jclass elementType = getElementType (array, index);
if (elementType == JvPrimClass (boolean))
return elements ((jbooleanArray) array) [index];
throw new java::lang::IllegalArgumentException;
}
jchar
java::lang::reflect::Array::getChar (jobject array, jint index)
{
jclass elementType = getElementType (array, index);
if (elementType == JvPrimClass (char))
return elements ((jcharArray) array) [index];
throw new java::lang::IllegalArgumentException;
}
jbyte
java::lang::reflect::Array::getByte (jobject array, jint index)
{
jclass elementType = getElementType (array, index);
if (elementType == JvPrimClass (byte))
return elements ((jbyteArray) array) [index];
throw new java::lang::IllegalArgumentException;
}
jshort
java::lang::reflect::Array::getShort (jobject array, jint index)
{
jclass elementType = getElementType (array, index);
if (elementType == JvPrimClass (short))
return elements ((jshortArray) array) [index];
if (elementType == JvPrimClass (byte))
return elements ((jbyteArray) array) [index];
throw new java::lang::IllegalArgumentException;
}
jint
java::lang::reflect::Array::getInt (jobject array, jint index)
{
jclass elementType = getElementType (array, index);
if (elementType == JvPrimClass (int))
return elements ((jintArray) array) [index];
if (elementType == JvPrimClass (short))
return elements ((jshortArray) array) [index];
if (elementType == JvPrimClass (byte))
return elements ((jbyteArray) array) [index];
if (elementType == JvPrimClass (char))
return elements ((jcharArray) array) [index];
throw new java::lang::IllegalArgumentException;
}
jlong
java::lang::reflect::Array::getLong (jobject array, jint index)
{
jclass elementType = getElementType (array, index);
if (elementType == JvPrimClass (long))
return elements ((jlongArray) array) [index];
if (elementType == JvPrimClass (int))
return elements ((jintArray) array) [index];
if (elementType == JvPrimClass (short))
return elements ((jshortArray) array) [index];
if (elementType == JvPrimClass (byte))
return elements ((jbyteArray) array) [index];
if (elementType == JvPrimClass (char))
return elements ((jcharArray) array) [index];
throw new java::lang::IllegalArgumentException;
}
jfloat
java::lang::reflect::Array::getFloat (jobject array, jint index)
{
jclass elementType = getElementType (array, index);
if (elementType == JvPrimClass (float))
return elements ((jfloatArray) array) [index];
if (elementType == JvPrimClass (long))
return elements ((jlongArray) array) [index];
if (elementType == JvPrimClass (int))
return elements ((jintArray) array) [index];
if (elementType == JvPrimClass (short))
return elements ((jshortArray) array) [index];
if (elementType == JvPrimClass (byte))
return elements ((jbyteArray) array) [index];
if (elementType == JvPrimClass (char))
return elements ((jcharArray) array) [index];
throw new java::lang::IllegalArgumentException;
}
jdouble
java::lang::reflect::Array::getDouble (jobject array, jint index)
{
jclass elementType = getElementType (array, index);
if (elementType == JvPrimClass (double))
return elements ((jdoubleArray) array) [index];
if (elementType == JvPrimClass (float))
return elements ((jfloatArray) array) [index];
if (elementType == JvPrimClass (long))
return elements ((jlongArray) array) [index];
if (elementType == JvPrimClass (int))
return elements ((jintArray) array) [index];
if (elementType == JvPrimClass (short))
return elements ((jshortArray) array) [index];
if (elementType == JvPrimClass (byte))
return elements ((jbyteArray) array) [index];
if (elementType == JvPrimClass (char))
return elements ((jcharArray) array) [index];
throw new java::lang::IllegalArgumentException;
}
jobject
java::lang::reflect::Array::get (jobject array, jint index)
{
jclass elementType = getElementType (array, index);
if (! elementType->isPrimitive ())
return elements ((jobjectArray) array) [index];
if (elementType == JvPrimClass (double))
return new java::lang::Double (elements ((jdoubleArray) array) [index]);
if (elementType == JvPrimClass (float))
return new java::lang::Float (elements ((jfloatArray) array) [index]);
if (elementType == JvPrimClass (long))
return new java::lang::Long (elements ((jlongArray) array) [index]);
if (elementType == JvPrimClass (int))
return new java::lang::Integer (elements ((jintArray) array) [index]);
if (elementType == JvPrimClass (short))
return new java::lang::Short (elements ((jshortArray) array) [index]);
if (elementType == JvPrimClass (byte))
return new java::lang::Byte (elements ((jbyteArray) array) [index]);
if (elementType == JvPrimClass (char))
return new java::lang::Character (elements ((jcharArray) array) [index]);
if (elementType == JvPrimClass (boolean))
{
_Jv_InitClass (&java::lang::Boolean::class$);
if (elements ((jbooleanArray) array) [index])
return java::lang::Boolean::TRUE;
else
return java::lang::Boolean::FALSE;
}
throw new java::lang::IllegalArgumentException;
}
void
java::lang::reflect::Array::setChar (jobject array, jint index, jchar value)
{
jclass elementType = getElementType (array, index);
if (elementType == JvPrimClass (char))
elements ((jcharArray) array) [index] = value;
else if (elementType == JvPrimClass (int))
elements ((jintArray) array) [index] = value;
else if (elementType == JvPrimClass (long))
elements ((jlongArray) array) [index] = value;
else if (elementType == JvPrimClass (float))
elements ((jfloatArray) array) [index] = value;
else if (elementType == JvPrimClass (double))
elements ((jdoubleArray) array) [index] = value;
else
throw new java::lang::IllegalArgumentException;
}
void
java::lang::reflect::Array::setByte (jobject array, jint index, jbyte value)
{
jclass elementType = getElementType (array, index);
if (elementType == JvPrimClass (byte))
elements ((jbyteArray) array) [index] = value;
else if (elementType == JvPrimClass (short))
elements ((jshortArray) array) [index] = value;
else if (elementType == JvPrimClass (int))
elements ((jintArray) array) [index] = value;
else if (elementType == JvPrimClass (long))
elements ((jlongArray) array) [index] = value;
else if (elementType == JvPrimClass (float))
elements ((jfloatArray) array) [index] = value;
else if (elementType == JvPrimClass (double))
elements ((jdoubleArray) array) [index] = value;
else
throw new java::lang::IllegalArgumentException;
}
void
java::lang::reflect::Array::setShort (jobject array, jint index, jshort value)
{
jclass elementType = getElementType (array, index);
if (elementType == JvPrimClass (short))
elements ((jshortArray) array) [index] = value;
else if (elementType == JvPrimClass (int))
elements ((jintArray) array) [index] = value;
else if (elementType == JvPrimClass (long))
elements ((jlongArray) array) [index] = value;
else if (elementType == JvPrimClass (float))
elements ((jfloatArray) array) [index] = value;
else if (elementType == JvPrimClass (double))
elements ((jdoubleArray) array) [index] = value;
else
throw new java::lang::IllegalArgumentException;
}
void
java::lang::reflect::Array::setInt (jobject array, jint index, jint value)
{
jclass elementType = getElementType (array, index);
if (elementType == JvPrimClass (int))
elements ((jintArray) array) [index] = value;
else if (elementType == JvPrimClass (long))
elements ((jlongArray) array) [index] = value;
else if (elementType == JvPrimClass (float))
elements ((jfloatArray) array) [index] = value;
else if (elementType == JvPrimClass (double))
elements ((jdoubleArray) array) [index] = value;
else
throw new java::lang::IllegalArgumentException;
}
void
java::lang::reflect::Array::setLong (jobject array, jint index, jlong value)
{
jclass elementType = getElementType (array, index);
if (elementType == JvPrimClass (long))
elements ((jlongArray) array) [index] = value;
else if (elementType == JvPrimClass (float))
elements ((jfloatArray) array) [index] = value;
else if (elementType == JvPrimClass (double))
elements ((jdoubleArray) array) [index] = value;
else
throw new java::lang::IllegalArgumentException;
}
void
java::lang::reflect::Array::setFloat (jobject array, jint index, jfloat value)
{
jclass elementType = getElementType (array, index);
if (elementType == JvPrimClass (float))
elements ((jfloatArray) array) [index] = value;
else if (elementType == JvPrimClass (double))
elements ((jdoubleArray) array) [index] = value;
else
throw new java::lang::IllegalArgumentException;
}
void
java::lang::reflect::Array::setDouble (jobject array, jint index, jdouble value)
{
jclass elementType = getElementType (array, index);
if (elementType == JvPrimClass (double))
elements ((jdoubleArray) array) [index] = value;
else
throw new java::lang::IllegalArgumentException;
}
void
java::lang::reflect::Array::setBoolean (jobject array,
jint index, jboolean value)
{
jclass elementType = getElementType (array, index);
if (elementType == JvPrimClass (boolean))
elements ((jbooleanArray) array) [index] = value;
else
throw new java::lang::IllegalArgumentException;
}
void
java::lang::reflect::Array::set (jobject array, jint index,
jobject value, jclass elType)
{
// We don't have to call getElementType here, or check INDEX,
// because it was already done in the Java wrapper.
if (value != NULL && ! _Jv_IsInstanceOf (value, elType))
throw new java::lang::IllegalArgumentException;
elements ((jobjectArray) array) [index] = value;
}