You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ge...@apache.org on 2005/10/05 04:20:10 UTC

svn commit: r294974 [20/25] - in /incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm: ./ jchevm/ jchevm/doc/ jchevm/etc/ jchevm/include/ jchevm/java/ jchevm/java/org/ jchevm/java/org/dellroad/ jchevm/java/org/dellroad/jc/ jchevm/java/org/dellroad...

Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/native/java_lang_reflect_Field.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/native/java_lang_reflect_Field.c?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/native/java_lang_reflect_Field.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/native/java_lang_reflect_Field.c Tue Oct  4 19:19:16 2005
@@ -0,0 +1,652 @@
+
+/*
+ * Copyright 2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ * 
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ * $Id: java_lang_reflect_Field.c,v 1.13 2005/07/09 19:58:35 archiecobbs Exp $
+ */
+
+#include "libjc.h"
+#include "java_lang_reflect_Field.h"
+
+/* Internal functions */
+static _jc_field	*_jc_check_field(_jc_env *env, _jc_object *this);
+static jint		_jc_field_get(_jc_env *env, _jc_object *this,
+				_jc_object *obj, int dtype, _jc_value *value);
+static jint		_jc_field_set(_jc_env *env, _jc_object *this,
+				_jc_object *obj, int stype, _jc_value *value);
+static void		*_jc_field_validate(_jc_env *env, _jc_object *this,
+				_jc_field **fieldp, _jc_object *obj);
+
+/*
+ * public final native Object get(Object)
+ */
+_jc_object * _JC_JCNI_ATTR
+JCNI_java_lang_reflect_Field_get(_jc_env *env, _jc_object *this,
+	_jc_object *obj)
+{
+	_jc_value value;
+
+	/* Get field */
+	if (_jc_field_get(env, this, obj, _JC_TYPE_REFERENCE, &value) != JNI_OK)
+		_jc_throw_exception(env);
+
+	/* Return value */
+	return value.l;
+}
+
+/*
+ * public final native boolean getBoolean(Object)
+ */
+jboolean _JC_JCNI_ATTR
+JCNI_java_lang_reflect_Field_getBoolean(_jc_env *env, _jc_object *this,
+	_jc_object *obj)
+{
+	_jc_value value;
+
+	/* Get field */
+	if (_jc_field_get(env, this, obj, _JC_TYPE_BOOLEAN, &value) != JNI_OK)
+		_jc_throw_exception(env);
+
+	/* Return value */
+	return value.z;
+}
+
+/*
+ * public final native byte getByte(Object)
+ */
+jbyte _JC_JCNI_ATTR
+JCNI_java_lang_reflect_Field_getByte(_jc_env *env, _jc_object *this,
+	_jc_object *obj)
+{
+	_jc_value value;
+
+	/* Get field */
+	if (_jc_field_get(env, this, obj, _JC_TYPE_BYTE, &value) != JNI_OK)
+		_jc_throw_exception(env);
+
+	/* Return value */
+	return value.b;
+}
+
+/*
+ * public final native char getChar(Object)
+ */
+jchar _JC_JCNI_ATTR
+JCNI_java_lang_reflect_Field_getChar(_jc_env *env, _jc_object *this,
+	_jc_object *obj)
+{
+	_jc_value value;
+
+	/* Get field */
+	if (_jc_field_get(env, this, obj, _JC_TYPE_CHAR, &value) != JNI_OK)
+		_jc_throw_exception(env);
+
+	/* Return value */
+	return value.c;
+}
+
+/*
+ * public final native double getDouble(Object)
+ */
+jdouble _JC_JCNI_ATTR
+JCNI_java_lang_reflect_Field_getDouble(_jc_env *env, _jc_object *this,
+	_jc_object *obj)
+{
+	_jc_value value;
+
+	/* Get field */
+	if (_jc_field_get(env, this, obj, _JC_TYPE_DOUBLE, &value) != JNI_OK)
+		_jc_throw_exception(env);
+
+	/* Return value */
+	return value.d;
+}
+
+/*
+ * public final native float getFloat(Object)
+ */
+jfloat _JC_JCNI_ATTR
+JCNI_java_lang_reflect_Field_getFloat(_jc_env *env, _jc_object *this,
+	_jc_object *obj)
+{
+	_jc_value value;
+
+	/* Get field */
+	if (_jc_field_get(env, this, obj, _JC_TYPE_FLOAT, &value) != JNI_OK)
+		_jc_throw_exception(env);
+
+	/* Return value */
+	return value.f;
+}
+
+/*
+ * public final native int getInt(Object)
+ */
+jint _JC_JCNI_ATTR
+JCNI_java_lang_reflect_Field_getInt(_jc_env *env, _jc_object *this,
+	_jc_object *obj)
+{
+	_jc_value value;
+
+	/* Get field */
+	if (_jc_field_get(env, this, obj, _JC_TYPE_INT, &value) != JNI_OK)
+		_jc_throw_exception(env);
+
+	/* Return value */
+	return value.i;
+}
+
+/*
+ * public final native long getLong(Object)
+ */
+jlong _JC_JCNI_ATTR
+JCNI_java_lang_reflect_Field_getLong(_jc_env *env, _jc_object *this,
+	_jc_object *obj)
+{
+	_jc_value value;
+
+	/* Get field */
+	if (_jc_field_get(env, this, obj, _JC_TYPE_LONG, &value) != JNI_OK)
+		_jc_throw_exception(env);
+
+	/* Return value */
+	return value.j;
+}
+
+/*
+ * public final native int getModifiers()
+ */
+jint _JC_JCNI_ATTR
+JCNI_java_lang_reflect_Field_getModifiers(_jc_env *env, _jc_object *this)
+{
+	_jc_field *field;
+
+	/* Get field */
+	field = _jc_check_field(env, this);
+
+	/* Return flags */
+	return field->access_flags & _JC_ACC_MASK;
+}
+
+/*
+ * public final native short getShort(Object)
+ */
+jshort _JC_JCNI_ATTR
+JCNI_java_lang_reflect_Field_getShort(_jc_env *env, _jc_object *this,
+	_jc_object *obj)
+{
+	_jc_value value;
+
+	/* Get field */
+	if (_jc_field_get(env, this, obj, _JC_TYPE_SHORT, &value) != JNI_OK)
+		_jc_throw_exception(env);
+
+	/* Return value */
+	return value.s;
+}
+
+/*
+ * public final native Class getType()
+ */
+_jc_object * _JC_JCNI_ATTR
+JCNI_java_lang_reflect_Field_getType(_jc_env *env, _jc_object *this)
+{
+	_jc_field *field;
+
+	/* Get field */
+	field = _jc_check_field(env, this);
+
+	/* Return field's type's Class instance */
+	return field->type->instance;
+}
+
+/*
+ * public final native void set(Object, Object)
+ */
+void _JC_JCNI_ATTR
+JCNI_java_lang_reflect_Field_set(_jc_env *env, _jc_object *this,
+	_jc_object *obj, _jc_object *valobj)
+{
+	_jc_field *field;
+	_jc_value value;
+	int ftype;
+
+	/* Get field */
+	field = _jc_check_field(env, this);
+	ftype = (field->type->flags & _JC_TYPE_MASK);
+
+	/* Unwrap primitive values */
+	if (ftype == _JC_TYPE_REFERENCE)
+		value.l = valobj;
+	else if ((ftype = _jc_unwrap_primitive(env,
+	    valobj, &value)) == _JC_TYPE_INVALID)
+		_jc_throw_exception(env);
+
+	/* Set field */
+	if (_jc_field_set(env, this, obj, ftype, &value) != JNI_OK)
+		_jc_throw_exception(env);
+}
+
+/*
+ * public final native void setBoolean(Object, boolean)
+ */
+void _JC_JCNI_ATTR
+JCNI_java_lang_reflect_Field_setBoolean(_jc_env *env, _jc_object *this,
+	_jc_object *obj, jboolean to_set)
+{
+	_jc_value value;
+
+	/* Get value */
+	value.z = to_set;
+
+	/* Set field */
+	if (_jc_field_set(env, this, obj, _JC_TYPE_BOOLEAN, &value) != JNI_OK)
+		_jc_throw_exception(env);
+}
+
+/*
+ * public final native void setByte(Object, byte)
+ */
+void _JC_JCNI_ATTR
+JCNI_java_lang_reflect_Field_setByte(_jc_env *env, _jc_object *this,
+	_jc_object *obj, jbyte to_set)
+{
+	_jc_value value;
+
+	/* Get value */
+	value.b = to_set;
+
+	/* Set field */
+	if (_jc_field_set(env, this, obj, _JC_TYPE_BYTE, &value) != JNI_OK)
+		_jc_throw_exception(env);
+}
+
+/*
+ * public final native void setChar(Object, char)
+ */
+void _JC_JCNI_ATTR
+JCNI_java_lang_reflect_Field_setChar(_jc_env *env, _jc_object *this,
+	_jc_object *obj, jchar to_set)
+{
+	_jc_value value;
+
+	/* Get value */
+	value.c = to_set;
+
+	/* Set field */
+	if (_jc_field_set(env, this, obj, _JC_TYPE_CHAR, &value) != JNI_OK)
+		_jc_throw_exception(env);
+}
+
+/*
+ * public final native void setDouble(Object, double)
+ */
+void _JC_JCNI_ATTR
+JCNI_java_lang_reflect_Field_setDouble(_jc_env *env, _jc_object *this,
+	_jc_object *obj, jdouble to_set)
+{
+	_jc_value value;
+
+	/* Get value */
+	value.d = to_set;
+
+	/* Set field */
+	if (_jc_field_set(env, this, obj, _JC_TYPE_DOUBLE, &value) != JNI_OK)
+		_jc_throw_exception(env);
+}
+
+/*
+ * public final native void setFloat(Object, float)
+ */
+void _JC_JCNI_ATTR
+JCNI_java_lang_reflect_Field_setFloat(_jc_env *env, _jc_object *this,
+	_jc_object *obj, jfloat to_set)
+{
+	_jc_value value;
+
+	/* Get value */
+	value.f = to_set;
+
+	/* Set field */
+	if (_jc_field_set(env, this, obj, _JC_TYPE_FLOAT, &value) != JNI_OK)
+		_jc_throw_exception(env);
+}
+
+/*
+ * public final native void setInt(Object, int)
+ */
+void _JC_JCNI_ATTR
+JCNI_java_lang_reflect_Field_setInt(_jc_env *env, _jc_object *this,
+	_jc_object *obj, jint to_set)
+{
+	_jc_value value;
+
+	/* Get value */
+	value.i = to_set;
+
+	/* Set field */
+	if (_jc_field_set(env, this, obj, _JC_TYPE_INT, &value) != JNI_OK)
+		_jc_throw_exception(env);
+}
+
+/*
+ * public final native void setLong(Object, long)
+ */
+void _JC_JCNI_ATTR
+JCNI_java_lang_reflect_Field_setLong(_jc_env *env, _jc_object *this,
+	_jc_object *obj, jlong to_set)
+{
+	_jc_value value;
+
+	/* Get value */
+	value.j = to_set;
+
+	/* Set field */
+	if (_jc_field_set(env, this, obj, _JC_TYPE_LONG, &value) != JNI_OK)
+		_jc_throw_exception(env);
+}
+
+/*
+ * public final native void setShort(Object, short)
+ */
+void _JC_JCNI_ATTR
+JCNI_java_lang_reflect_Field_setShort(_jc_env *env, _jc_object *this,
+	_jc_object *obj, jshort to_set)
+{
+	_jc_value value;
+
+	/* Get value */
+	value.s = to_set;
+
+	/* Set field */
+	if (_jc_field_set(env, this, obj, _JC_TYPE_SHORT, &value) != JNI_OK)
+		_jc_throw_exception(env);
+}
+
+/*
+ * Find the _jc_field structure corresponding to a Field object.
+ */
+static _jc_field *
+_jc_check_field(_jc_env *env, _jc_object *this)
+{
+	/* Check for null */
+	if (this == NULL) {
+		_jc_post_exception(env, _JC_NullPointerException);
+		_jc_throw_exception(env);
+	}
+
+	/* Return field */
+	return _jc_get_field(env, this);
+}
+
+/*
+ * Get a field, doing so with the Java atomicity guarantees.
+ * Convert the field to destination type 'dtype', or post an
+ * IllegalArgumentException if it can't be so converted.
+ */
+static jint
+_jc_field_get(_jc_env *env, _jc_object *this, _jc_object *obj,
+	int dtype, _jc_value *value)
+{
+	_jc_jvm *const vm = env->vm;
+	_jc_field *field;
+	void *data;
+	int stype;
+
+	/* Validate access */
+	if ((data = _jc_field_validate(env, this, &field, obj)) == NULL)
+		return JNI_ERR;
+
+	/* Get the field's content */
+	stype = (field->type->flags & _JC_TYPE_MASK);
+	switch (stype) {
+	case _JC_TYPE_BOOLEAN:
+		value->z = *(jboolean *)data;
+		break;
+	case _JC_TYPE_BYTE:
+		value->b = *(jbyte *)data;
+		break;
+	case _JC_TYPE_CHAR:
+		value->c = *(jchar *)data;
+		break;
+	case _JC_TYPE_SHORT:
+		value->s = *(jshort *)data;
+		break;
+	case _JC_TYPE_INT:
+		value->i = *(jint *)data;
+		break;
+	case _JC_TYPE_LONG:
+		value->j = *(jlong *)data;
+		break;
+	case _JC_TYPE_FLOAT:
+		value->f = *(jfloat *)data;
+		break;
+	case _JC_TYPE_DOUBLE:
+		value->d = *(jdouble *)data;
+		break;
+	case _JC_TYPE_REFERENCE:
+		value->l = *(_jc_object **)data;
+		break;
+	default:
+		_jc_fatal_error(vm, "impossible");
+	}
+
+	/* Do any implicit primitive type conversion if necessary */
+	if (dtype != _JC_TYPE_REFERENCE && stype != _JC_TYPE_REFERENCE) {
+		if (_jc_convert_primitive(env, dtype, stype, value) != JNI_OK)
+			return JNI_ERR;
+	}
+
+	/* Handle the case where a primitive result is desired */
+	if (dtype != _JC_TYPE_REFERENCE) {
+		if (stype == _JC_TYPE_REFERENCE) {
+			_jc_post_exception_msg(env,
+			    _JC_IllegalArgumentException,
+			    "can't convert value of type `%s' to %s",
+			    field->type->name, _jc_prim_names[dtype]);
+			return JNI_ERR;
+		}
+		return JNI_OK;
+	}
+
+	/* Wrap primitive values in instance of wrapper class */
+	if (stype != _JC_TYPE_REFERENCE
+	    && (value->l = _jc_wrap_primitive(env, stype, value)) == NULL)
+		_jc_throw_exception(env);
+
+	/* Done */
+	return JNI_OK;
+}
+
+/*
+ * Set a field, doing so with the Java atomicity guarantees.
+ * Convert the field from the primitive type 'stype', or throw
+ * an IllegalArgumentException if it can't be so converted.
+ */
+static jint
+_jc_field_set(_jc_env *env, _jc_object *this, _jc_object *obj,
+	int stype, _jc_value *value)
+{
+	_jc_jvm *const vm = env->vm;
+	_jc_field *field;
+	void *data;
+	int status;
+	int dtype;
+
+	/* Validate access */
+	if ((data = _jc_field_validate(env, this, &field, obj)) == NULL)
+		return JNI_ERR;
+	dtype = (field->type->flags & _JC_TYPE_MASK);
+
+	/* Check that we're not trying to set a final field */
+	if (_JC_ACC_TEST(field, FINAL)) {
+		_jc_post_exception_msg(env, _JC_IllegalAccessException,
+		    "field `%s' is final", field->name);
+		return JNI_ERR;
+	}
+
+	/* Check for basic compatibility */
+	if ((stype == _JC_TYPE_REFERENCE) != (dtype == _JC_TYPE_REFERENCE)) {
+		_jc_post_exception_msg(env, _JC_IllegalArgumentException,
+		    "value of type `%s' is not compatible"
+		    " with field's type `%s'", stype == _JC_TYPE_REFERENCE ?
+		       (value->l == NULL ? "null" : value->l->type->name) :
+		      _jc_prim_names[stype], field->type->name);
+		return JNI_ERR;
+	}
+
+	/* Handle fields of reference type */
+	if (stype == _JC_TYPE_REFERENCE) {
+
+		/* Always OK to set field to null */
+		if (value->l == NULL) {
+			*(_jc_object **)data = NULL;
+			return JNI_OK;
+		}
+
+		/* Check type compatibility */
+		switch (_jc_instance_of(env, value->l, field->type)) {
+		case 1:
+			break;
+		case 0:
+			_jc_post_exception_msg(env,
+			    _JC_IllegalArgumentException,
+			    "value of type `%s' is not compatible with"
+			    " field's type `%s'", value->l->type->name,
+			    field->type->name);
+			/* FALLTHROUGH */
+		case -1:
+			return JNI_ERR;
+		default:
+			_JC_ASSERT(JNI_FALSE);
+		}
+
+		/* Types are compatible, make the assignment */
+		*(_jc_object **)data = value->l;
+		return JNI_OK;
+	}
+
+	/* Convert primitive value to the field's type */
+	if ((status = _jc_convert_primitive(env,
+	    dtype, stype, value)) != JNI_OK)
+		return status;
+
+	/* Set the field's content */
+	switch (dtype) {
+	case _JC_TYPE_BOOLEAN:
+		*(jboolean *)data = value->z;
+		break;
+	case _JC_TYPE_BYTE:
+		*(jbyte *)data = value->b;
+		break;
+	case _JC_TYPE_CHAR:
+		*(jchar *)data = value->c;
+		break;
+	case _JC_TYPE_SHORT:
+		*(jshort *)data = value->s;
+		break;
+	case _JC_TYPE_INT:
+		*(jint *)data = value->i;
+		break;
+	case _JC_TYPE_LONG:
+		*(jlong *)data = value->j;
+		break;
+	case _JC_TYPE_FLOAT:
+		*(jfloat *)data = value->f;
+		break;
+	case _JC_TYPE_DOUBLE:
+		*(jdouble *)data = value->d;
+		break;
+	default:
+		_jc_fatal_error(vm, "impossible");
+	}
+
+	/* Done */
+	return JNI_OK;
+}
+
+/*
+ * Validate the field access and return a pointer to the field itself.
+ */
+static void *
+_jc_field_validate(_jc_env *env, _jc_object *this,
+	_jc_field **fieldp, _jc_object *obj)
+{
+	_jc_jvm *const vm = env->vm;
+	_jc_type *calling_class;
+	_jc_field *field;
+	int is_static;
+	int ptype;
+
+	/* Get field info */
+	field = _jc_check_field(env, this);
+	*fieldp = field;
+	ptype = (field->type->flags & _JC_TYPE_MASK);
+	is_static = _JC_ACC_TEST(field, STATIC);
+
+	/* Check the validity of the instance object */
+	if (!is_static) {
+		if (obj == NULL) {
+			_jc_post_exception(env, _JC_NullPointerException);
+			return NULL;
+		}
+		switch (_jc_instance_of(env, obj, field->class)) {
+		case 1:
+			break;
+		case 0:
+			_jc_post_exception_msg(env,
+			    _JC_IllegalArgumentException,
+			    "field and target object don't match");
+			/* FALLTHROUGH */
+		case -1:
+			return NULL;
+		default:
+			_JC_ASSERT(JNI_FALSE);
+		}
+	}
+
+	/* Check accessibility */
+	if (_jc_invoke_virtual(env,
+	    vm->boot.methods.AccessibleObject.isAccessible, this) != JNI_OK)
+		return NULL;
+	if (env->retval.z)
+		goto accessible;
+
+	/* Check access */
+	switch (_jc_reflect_accessible(env, field->class,
+	    field->access_flags, &calling_class)) {
+	case -1:
+		_jc_throw_exception(env);
+	case 1:
+		break;
+	case 0:
+		_jc_post_exception_msg(env, _JC_IllegalAccessException,
+		    "`%s.%s' is not accessible from `%s'",
+		    field->class->name, field->name, calling_class->name);
+		_jc_throw_exception(env);
+	}
+
+accessible:
+	/* Initialize class if field is static */
+	if (is_static && _jc_initialize_type(env, field->class) != JNI_OK)
+		return NULL;
+
+	/* Return pointer to the field */
+	return is_static ?
+	    (char *)field->class->u.nonarray.class_fields + field->offset :
+	    (char *)obj + field->offset;
+}
+

Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/native/java_lang_reflect_Method.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/native/java_lang_reflect_Method.c?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/native/java_lang_reflect_Method.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/native/java_lang_reflect_Method.c Tue Oct  4 19:19:16 2005
@@ -0,0 +1,187 @@
+
+/*
+ * Copyright 2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ * 
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ * $Id: java_lang_reflect_Method.c,v 1.8 2005/05/15 21:41:01 archiecobbs Exp $
+ */
+
+#include "libjc.h"
+#include "java_lang_reflect_Method.h"
+
+/* Internal functions */
+static _jc_method	*_jc_check_method(_jc_env *env, _jc_object *this);
+
+/*
+ * public final native Class[] getExceptionTypes()
+ */
+_jc_object_array * _JC_JCNI_ATTR
+JCNI_java_lang_reflect_Method_getExceptionTypes(_jc_env *env, _jc_object *this)
+{
+	_jc_object_array *array;
+	_jc_method *method;
+
+	/* Get method */
+	method = _jc_check_method(env, this);
+
+	/* Get exception types */
+	if ((array = _jc_get_exception_types(env, method)) == NULL)
+		_jc_throw_exception(env);
+
+	/* Return array */
+	return array;
+}
+
+/*
+ * public final native int getModifiers()
+ */
+jint _JC_JCNI_ATTR
+JCNI_java_lang_reflect_Method_getModifiers(_jc_env *env, _jc_object *this)
+{
+	_jc_method *method;
+
+	/* Get method */
+	method = _jc_check_method(env, this);
+
+	/* Return flags */
+	return method->access_flags & _JC_ACC_MASK;
+}
+
+/*
+ * public final native Class[] getParameterTypes()
+ */
+_jc_object_array * _JC_JCNI_ATTR
+JCNI_java_lang_reflect_Method_getParameterTypes(_jc_env *env, _jc_object *this)
+{
+	_jc_object_array *array;
+	_jc_method *method;
+
+	/* Get method */
+	method = _jc_check_method(env, this);
+
+	/* Get parameter types */
+	if ((array = _jc_get_parameter_types(env, method)) == NULL)
+		_jc_throw_exception(env);
+
+	/* Return array */
+	return array;
+}
+
+/*
+ * public final native Class getReturnType()
+ */
+_jc_object * _JC_JCNI_ATTR
+JCNI_java_lang_reflect_Method_getReturnType(_jc_env *env, _jc_object *this)
+{
+	_jc_method *method;
+
+	/* Get method */
+	method = _jc_check_method(env, this);
+
+	/* Return return type Class instance */
+	return method->return_type->instance;
+}
+
+/*
+ * private final native Object invokeNative(Object, Object[], Class, int)
+ *      throws IllegalAccessException, InvocationTargetException
+ */
+_jc_object * _JC_JCNI_ATTR
+JCNI_java_lang_reflect_Method_invokeNative(_jc_env *env, _jc_object *this,
+	_jc_object *obj, _jc_object_array *params, _jc_object *cl, jint slot)
+{
+	_jc_jvm *const vm = env->vm;
+	_jc_type *calling_class;
+	_jc_object *return_obj;
+	_jc_method *method;
+	int rtype;
+
+	/* Get method */
+	method = _jc_check_method(env, this);
+
+	/* Check accessibility */
+	if (_jc_invoke_virtual(env,
+	    vm->boot.methods.AccessibleObject.isAccessible, this) != JNI_OK)
+		_jc_throw_exception(env);
+	if (env->retval.z)
+		goto accessible;
+
+	/* Check access */
+	switch (_jc_reflect_accessible(env, method->class,
+	    method->access_flags, &calling_class)) {
+	case -1:
+		_jc_throw_exception(env);
+	case 1:
+		break;
+	case 0:
+		_jc_post_exception_msg(env, _JC_IllegalAccessException,
+		    "`%s.%s%s' is not accessible from `%s'",
+		    method->class->name, method->name, method->signature,
+		    calling_class->name);
+		_jc_throw_exception(env);
+	}
+
+accessible:
+	/* Invoke method */
+	if (_jc_reflect_invoke(env, method, obj, params) != JNI_OK)
+		_jc_throw_exception(env);
+
+	/* Wrap return value */
+	rtype = (method->return_type->flags & _JC_TYPE_MASK);
+	switch (rtype) {
+	case _JC_TYPE_BOOLEAN:
+	case _JC_TYPE_BYTE:
+	case _JC_TYPE_CHAR:
+	case _JC_TYPE_SHORT:
+	case _JC_TYPE_INT:
+	case _JC_TYPE_LONG:
+	case _JC_TYPE_FLOAT:
+	case _JC_TYPE_DOUBLE:
+		if ((return_obj = _jc_wrap_primitive(env,
+		    rtype, &env->retval)) == NULL)
+			_jc_throw_exception(env);
+		break;
+	case _JC_TYPE_VOID:
+		return_obj = NULL;
+		break;
+	case _JC_TYPE_REFERENCE:
+		return_obj = env->retval.l;
+		break;
+	default:
+		_JC_ASSERT(JNI_FALSE);
+		return_obj = NULL;		/* silence compiler warning */
+		break;
+	}
+
+	/* Done */
+	return return_obj;
+}
+
+/*
+ * Find the _jc_method structure corresponding to a Method object.
+ */
+static _jc_method *
+_jc_check_method(_jc_env *env, _jc_object *this)
+{
+	/* Check for null */
+	if (this == NULL) {
+		_jc_post_exception(env, _JC_NullPointerException);
+		_jc_throw_exception(env);
+	}
+
+	/* Return method */
+	return _jc_get_method(env, this);
+}
+

Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/native/org_dellroad_jc_JCFinder.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/native/org_dellroad_jc_JCFinder.c?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/native/org_dellroad_jc_JCFinder.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/native/org_dellroad_jc_JCFinder.c Tue Oct  4 19:19:16 2005
@@ -0,0 +1,163 @@
+
+/*
+ * Copyright 2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ * 
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ * $Id: org_dellroad_jc_JCFinder.c,v 1.5 2005/05/15 21:41:01 archiecobbs Exp $
+ */
+
+#include "libjc.h"
+#include "org_dellroad_jc_JCFinder.h"
+
+/* Internal functions */
+static jint	get_class_info(_jc_env *env, _jc_object *nameString,
+			_jc_object *loaderObj, jlong *hashp,
+			_jc_classbytes **bytesp);
+
+/*
+ * private static native byte[] getClassfile(String, ClassLoader)
+ */
+_jc_byte_array * _JC_JCNI_ATTR
+JCNI_org_dellroad_jc_JCFinder_getClassfile(_jc_env *env,
+	_jc_object *nameString, _jc_object *loaderObj)
+{
+	_jc_jvm *const vm = env->vm;
+	_jc_byte_array *bytes = NULL;
+	_jc_classbytes *cbytes;
+
+	/* Get class file node */
+	if (get_class_info(env, nameString,
+	    loaderObj, NULL, &cbytes) != JNI_OK)
+		_jc_throw_exception(env);
+
+	/* Create new byte[] array and copy bytes into it */
+	if ((bytes = (_jc_byte_array *)_jc_new_array(env,
+	    vm->boot.types.prim_array[_JC_TYPE_BYTE], cbytes->length)) == NULL)
+		_jc_throw_exception(env);
+
+	/* Copy bytes */
+	memcpy(bytes->elems, cbytes->bytes, cbytes->length);
+
+	/* Unreference bytes */
+	_jc_free_classbytes(&cbytes);
+
+	/* Done */
+	return bytes;
+}
+
+/*
+ * private static native long getClassfileHash(String, ClassLoader)
+ */
+jlong _JC_JCNI_ATTR
+JCNI_org_dellroad_jc_JCFinder_getClassfileHash(_jc_env *env,
+	_jc_object *nameString, _jc_object *loaderObj)
+{
+	jlong hash;
+
+        /* Get class file node */
+	if (get_class_info(env, nameString,
+	    loaderObj, &hash, NULL) != JNI_OK)
+		_jc_throw_exception(env);
+
+	/* Return hash */
+	return hash;
+}
+
+/*
+ * Get a classfile. Caller must release the reference on it.
+ *
+ * Posts a NoClassDefFoundError if not found.
+ */
+static jint
+get_class_info(_jc_env *env, _jc_object *nameString, _jc_object *loaderObj,
+	jlong *hashp, _jc_classbytes **bytesp)
+{
+	_jc_jvm *const vm = env->vm;
+	_jc_class_node *node = NULL;
+	_jc_class_loader *loader;
+	jint status = JNI_ERR;
+	size_t name_len;
+	char *name;
+	int i;
+
+	/* Check for null */
+	if (nameString == NULL) {
+		_jc_post_exception(env, _JC_NullPointerException);
+		goto fail;
+	}
+
+	/* Convert name to UTF-8 */
+	name_len = _jc_decode_string_utf8(env, nameString, NULL);
+	if ((name = _JC_STACK_ALLOC(env, name_len + 1)) == NULL) {
+		_jc_post_exception_info(env);
+		goto fail;
+	}
+	_jc_decode_string_utf8(env, nameString, name);
+
+	/* Code generation must be enabled to retrieve class files */
+	if (!vm->generation_enabled) {
+		_jc_post_exception_msg(env, _JC_NoClassDefFoundError,
+		    "can't get class file bytes for `%s' because object"
+		    " file generation is disabled", name);
+		goto fail;
+	}
+
+	/* Replace dots -> slashes */
+	for (i = 0; name[i] != '\0'; i++) {
+		if (name[i] == '.')
+			name[i] = '/';
+	}
+
+        /* Get class loader */
+	if (loaderObj == NULL)
+		loader = vm->boot.loader;
+	else if ((loader = _jc_get_loader(env, loaderObj)) == NULL)
+		goto fail;
+
+	/* Acquire the class file and node */
+	if ((node = _jc_get_class_node(env, loader, name)) == NULL)
+		goto fail;
+
+	/* Copy hash value */
+	if (hashp != NULL)
+		*hashp = node->hash;
+
+	/*
+	 * Check whether the node comes with class file bytes.
+	 * If not, try the boot loader classpath as a last resort.
+	 */
+	if (bytesp != NULL) {
+		if (node->bytes != NULL)
+			*bytesp = _jc_dup_classbytes(node->bytes);
+		else if ((*bytesp = _jc_bootcl_find_classbytes(env,
+		    name, NULL)) == NULL) {
+			_jc_post_exception_info(env);
+			goto fail;
+		}
+	}
+
+	/* Done */
+	status = JNI_OK;
+
+fail:
+	/* Clean up */
+	_JC_MUTEX_LOCK(env, vm->mutex);
+	_jc_unref_class_node(vm, &node);
+	_JC_MUTEX_UNLOCK(env, vm->mutex);
+
+	/* Done */
+	return status;
+}
+

Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/native/org_dellroad_jc_cgen_SootCodeGenerator.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/native/org_dellroad_jc_cgen_SootCodeGenerator.c?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/native/org_dellroad_jc_cgen_SootCodeGenerator.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/native/org_dellroad_jc_cgen_SootCodeGenerator.c Tue Oct  4 19:19:16 2005
@@ -0,0 +1,92 @@
+
+/*
+ * Copyright 2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ * 
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ * $Id: org_dellroad_jc_cgen_SootCodeGenerator.c,v 1.8 2005/05/15 21:41:01 archiecobbs Exp $
+ */
+
+#include "libjc.h"
+#include "org_dellroad_jc_cgen_SootCodeGenerator.h"
+
+/*
+ * private static native void setField(Object, String, String, Object)
+ */
+void _JC_JCNI_ATTR
+JCNI_org_dellroad_jc_cgen_SootCodeGenerator_setField(_jc_env *env,
+	_jc_object *obj, _jc_object *nameString, _jc_object *sigString,
+	_jc_object *value)
+{
+	_jc_type *type;
+	size_t name_len;
+	size_t sig_len;
+	char *name;
+	char *signature;
+
+	/* Check for null */
+	if (obj == NULL || nameString == NULL || sigString == NULL) {
+		_jc_post_exception(env, _JC_NullPointerException);
+		_jc_throw_exception(env);
+	}
+
+	/* Convert name and signature to UTF-8 */
+	name_len = _jc_decode_string_utf8(env, nameString, NULL);
+	sig_len = _jc_decode_string_utf8(env, sigString, NULL);
+	if ((name = _JC_STACK_ALLOC(env, name_len + 1 + sig_len + 1)) == NULL) {
+		_jc_post_exception_info(env);
+		_jc_throw_exception(env);
+	}
+	signature = name + name_len + 1;
+	_jc_decode_string_utf8(env, nameString, name);
+	_jc_decode_string_utf8(env, sigString, signature);
+
+	/* Search for named field; it must also be compatible */
+	for (type = obj->type; type != NULL; type = type->superclass) {
+		_jc_field *field;
+
+		/* Search for field */
+		if ((field = _jc_get_declared_field(env,
+		    type, name, signature, JNI_FALSE)) == NULL)
+			continue;
+
+		/* Check compatibility */
+		if (_jc_sig_types[(u_char)*field->signature]
+		    != _JC_TYPE_REFERENCE)
+			continue;
+		if (value != NULL) {
+			switch (_jc_instance_of(env, value, field->type)) {
+			case 1:
+				break;
+			case 0:
+				continue;
+			case -1:
+				_jc_throw_exception(env);
+			default:
+				_JC_ASSERT(JNI_FALSE);
+			}
+		}
+
+		/* Assign new value */
+		*((_jc_object **)((char *)obj + field->offset)) = value;
+		return;
+	}
+
+	/* Not found */
+	_jc_post_exception_msg(env, _JC_NoSuchFieldError,
+	    "%s.%s, type %s, assignable from %s", obj->type->name, name,
+	    signature, value != NULL ? value->type->name : "null");
+	_jc_throw_exception(env);
+}
+

Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/native/org_dellroad_jc_vm_DebugThread.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/native/org_dellroad_jc_vm_DebugThread.c?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/native/org_dellroad_jc_vm_DebugThread.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/native/org_dellroad_jc_vm_DebugThread.c Tue Oct  4 19:19:16 2005
@@ -0,0 +1,241 @@
+
+/*
+ * Copyright 2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ * 
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ * $Id: org_dellroad_jc_vm_DebugThread.c,v 1.7 2005/05/15 21:41:01 archiecobbs Exp $
+ */
+
+#include "libjc.h"
+#include "org_dellroad_jc_vm_DebugThread.h"
+
+/* Internal functions */
+static void	_jc_dump_thread(_jc_env *env, _jc_env *thread);
+static void	_jc_dump_loader(_jc_env *env, _jc_class_loader *loader);
+static void	_jc_thread_headline(_jc_env *env, _jc_env *thread);
+static void	_jc_loader_headline(_jc_env *env, _jc_class_loader *loader);
+
+/*
+ * static native void dumpDebugInfo()
+ */
+void _JC_JCNI_ATTR
+JCNI_org_dellroad_jc_vm_DebugThread_dumpDebugInfo(_jc_env *env)
+{
+	_jc_jvm *const vm = env->vm;
+	_jc_class_loader *loader;
+	_jc_env *thread;
+
+	/* Stop the world */
+	_JC_MUTEX_LOCK(env, vm->mutex);
+	_jc_stop_the_world(env);
+	_JC_MUTEX_UNLOCK(env, vm->mutex);
+
+	/* Update my status */
+	snprintf(env->text_status, sizeof(env->text_status),
+	    "creating this debug printout");
+
+	/* Dump threads */
+	_jc_eprintf(vm, "\n[ Live threads ]\n\n");
+	LIST_FOREACH(thread, &vm->threads.alive_list, link)
+		_jc_dump_thread(env, thread);
+
+	/* Dump class loaders */
+	_jc_eprintf(vm, "\n[ Live class loaders ]\n\n");
+	LIST_FOREACH(loader, &vm->class_loaders, link)
+		_jc_dump_loader(env, loader);
+	_jc_eprintf(vm, "\n");
+
+	/* Resume the world */
+	_JC_MUTEX_LOCK(env, vm->mutex);
+	_jc_resume_the_world(env);
+	_JC_MUTEX_UNLOCK(env, vm->mutex);
+}
+
+/*
+ * Print out info about one thread.
+ */
+static void
+_jc_dump_thread(_jc_env *env, _jc_env *thread)
+{
+	_jc_jvm *const vm = env->vm;
+	_jc_saved_frame *frames = NULL;
+	int num_frames;
+
+	/* Print headline and status */
+	_jc_thread_headline(env, thread);
+	_jc_eprintf(vm, "    Status: %s\n", thread->text_status);
+
+	/* Grab thread's stack trace */
+	num_frames = _jc_save_stack_frames(env, thread, 0, NULL);
+	if ((frames = _JC_STACK_ALLOC(env,
+	    num_frames * sizeof(*frames))) == NULL)
+		num_frames = 0;
+	_jc_save_stack_frames(env, thread, num_frames, frames);
+
+	/* Print stack trace */
+	if (num_frames > 0) {
+		_jc_eprintf(vm, "    Java stack trace:\n");
+		_jc_print_stack_frames(env, stderr, num_frames, frames);
+	}
+
+	/* Print threads blocked waiting for me to release an object lock */
+	if (!SLIST_EMPTY(&thread->lock.owner.waiters)) {
+		_jc_env *waiter;
+
+		/* Lock waiter list */
+		_JC_MUTEX_LOCK(env, thread->lock.owner.mutex);
+
+		_jc_eprintf(vm, "    Other threads waiting for me:\n");
+		SLIST_FOREACH(waiter, &thread->lock.owner.waiters,
+		    lock.waiter.link) {
+			_jc_object *const obj = waiter->lock.waiter.object;
+			_jc_word lockword;
+
+			_jc_eprintf(vm, "\t");
+			_jc_thread_headline(env, waiter);
+			_jc_eprintf(vm, "\t  %s@%p\n", obj->type->name, obj);
+			lockword = obj->lockword;
+			_jc_eprintf(vm, "\t  lockword=0x%08x ", lockword);
+			if (_JC_LW_TEST(lockword, FAT)) {
+				const int lock_id
+				    = _JC_LW_EXTRACT(lockword, FAT_ID);
+				_jc_fat_lock *const lock
+				    = vm->fat_locks.by_id[lock_id];
+
+				_jc_eprintf(vm, "fat lock id=%d count=%d\n",
+				    lock_id, lock->recursion_count);
+			} else {
+				_JC_ASSERT(_JC_LW_EXTRACT(lockword,
+				    THIN_TID) == thread->thread_id);
+				_jc_eprintf(vm, "thin lock count=%d\n",
+				    _JC_LW_EXTRACT(lockword, THIN_COUNT) + 1);
+			}
+		}
+
+		/* Unlock waiter list */
+		_JC_MUTEX_UNLOCK(env, thread->lock.owner.mutex);
+	}
+}
+
+/*
+ * Print thread headline
+ */
+static void
+_jc_thread_headline(_jc_env *env, _jc_env *thread)
+{
+	_jc_jvm *const vm = env->vm;
+
+	_jc_eprintf(vm, "Thread %p [%d]: ", thread, thread->thread_id);
+	if (thread->instance != NULL) {
+		_jc_object *nameString;
+		char namebuf[128];
+
+		nameString = *_JC_VMFIELD(vm, thread->instance,
+		    Thread, name, _jc_object *);
+		if (nameString != NULL) {
+			char *name;
+			size_t len;
+
+			/* Convert name to UTF-8 */
+			len = _jc_decode_string_utf8(env, nameString, NULL);
+			if ((name = _JC_STACK_ALLOC(env, len + 1)) == NULL) {
+				snprintf(namebuf, sizeof(namebuf),
+				    "[error decoding name: %s%s%s]",
+				    _jc_vmex_names[env->ex.num],
+				    env->ex.msg != '\0' ? ": " : "",
+				    env->ex.msg);
+			} else {
+				_jc_decode_string_utf8(env, nameString, name);
+				snprintf(namebuf, sizeof(namebuf),
+				    "\"%s\"", name);
+			}
+		} else
+			snprintf(namebuf, sizeof(namebuf), "[no name]");
+		_jc_eprintf(vm, "%s (%s@%p)\n", namebuf,
+		    thread->instance->type->name, thread->instance);
+		return;
+	} else
+		_jc_eprintf(vm, "[thread with no Thread instance]");
+}
+
+/*
+ * Print info about a class loader
+ */
+static void
+_jc_dump_loader(_jc_env *env, _jc_class_loader *loader)
+{
+	_jc_jvm *const vm = env->vm;
+	_jc_uni_page_list *const mem = &loader->uni.pages;
+	_jc_class_loader *parent = NULL;
+	_jc_uni_pages *pages;
+	int unused_bytes;
+	int num_pages;
+
+	/* Print loader headline */
+	_jc_eprintf(vm, "Loader %p: ", loader);
+	_jc_loader_headline(env, loader);
+
+	/* Display number of loaded classes */
+	_jc_eprintf(vm, "%32s: %d\n",
+	    "Number of loaded classes", loader->defined_types.size);
+
+	/* Display number of pages of memory used */
+	num_pages = 0;
+	unused_bytes = 0;
+	TAILQ_FOREACH(pages, mem, link) {
+		num_pages += pages->num_pages;
+		unused_bytes += (pages->num_pages * _JC_PAGE_SIZE)
+		    - pages->offset;
+	}
+	_jc_eprintf(vm, "%32s: %d pages (%dK), %dK (%d%%) of that unused\n",
+	    "Total memory allocated", num_pages,
+	    (num_pages * _JC_PAGE_SIZE) / 1024, (unused_bytes + 513) / 1024,
+	    (unused_bytes * 100) / (num_pages * _JC_PAGE_SIZE));
+
+	/* Display parent class loader */
+	_jc_eprintf(vm, "%32s: ", "Parent class loader");
+	if (loader->instance != NULL) {
+		_jc_object *pinstance;
+
+		pinstance = *_JC_VMFIELD(vm, loader->instance,
+		    ClassLoader, parent, _jc_object *);
+		if (pinstance != NULL) {
+			parent = _jc_get_vm_pointer(pinstance,
+			    vm->boot.fields.ClassLoader.vmdata);
+		} else
+			parent = vm->boot.loader;
+	}
+	_jc_loader_headline(env, parent);
+}
+
+/*
+ * Print class loader headline
+ */
+static void
+_jc_loader_headline(_jc_env *env, _jc_class_loader *loader)
+{
+	_jc_jvm *const vm = env->vm;
+
+	if (loader == NULL)
+		_jc_eprintf(vm, "None\n");
+	else if (loader->instance == NULL)
+		_jc_eprintf(vm, "Bootstrap loader\n");
+	else {
+		_jc_object *const instance = loader->instance;
+
+		_jc_eprintf(vm, "%s@%p\n", instance->type->name, instance);
+	}
+}
+

Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/native/org_dellroad_jc_vm_FinalizerThread.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/native/org_dellroad_jc_vm_FinalizerThread.c?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/native/org_dellroad_jc_vm_FinalizerThread.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/native/org_dellroad_jc_vm_FinalizerThread.c Tue Oct  4 19:19:16 2005
@@ -0,0 +1,33 @@
+
+/*
+ * Copyright 2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ * 
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ * $Id: org_dellroad_jc_vm_FinalizerThread.c,v 1.3 2005/05/15 21:41:01 archiecobbs Exp $
+ */
+
+#include "libjc.h"
+#include "org_dellroad_jc_vm_FinalizerThread.h"
+
+/*
+ * static native void finalizeObjects()
+ */
+void _JC_JCNI_ATTR
+JCNI_org_dellroad_jc_vm_FinalizerThread_finalizeObjects(_jc_env *env)
+{
+	if (_jc_gc_finalize(env) != JNI_OK)
+		_jc_throw_exception(env);
+}
+

Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/native_lib.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/native_lib.c?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/native_lib.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/native_lib.c Tue Oct  4 19:19:16 2005
@@ -0,0 +1,406 @@
+
+/*
+ * Copyright 2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ * 
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ * $Id: native_lib.c,v 1.7 2005/03/16 21:07:48 archiecobbs Exp $
+ */
+
+#include "libjc.h"
+
+typedef jint	jni_onload_t(JavaVM *jvm, void *reserved);
+
+/*
+ * Invoke a native method.
+ *
+ * This function is called from the method "wrapper" function for
+ * a native method to invoke the actual native implementation function.
+ * It is also called by the interpreter to invoke native methods.
+ *
+ * The first parameter should be the instance object iff the method
+ * is non-static.
+ *
+ * 'values' is one of:
+ *	0	next parameter is a va_list
+ *	1	next parameter is a _jc_word *
+ *
+ * Posts an exception on failure.
+ */
+jint
+_jc_invoke_native_method(_jc_env *env, _jc_method *method, int values, ...)
+{
+	_jc_jvm *const vm = env->vm;
+	const jboolean is_static = _JC_ACC_TEST(method, STATIC);
+	_jc_object *this = NULL;
+	jboolean is_jni;
+	va_list args;
+	jint status;
+
+	/* Sanity check */
+	_JC_ASSERT(_JC_ACC_TEST(method, NATIVE));
+
+	/* Resolve method */
+	if (method->native_function == NULL
+	    && _jc_resolve_native_method(env, method) != JNI_OK)
+		return JNI_ERR;
+	_JC_ASSERT(method->native_function != NULL);
+	is_jni = !_JC_ACC_TEST(method, JCNI);
+
+	/* Initialize the class if necessary */
+	if (is_static
+	    && !_JC_FLG_TEST(method->class, INITIALIZED)
+	    && (status = _jc_initialize_type(env, method->class)) != JNI_OK)
+		return JNI_ERR;
+
+	/* Verbosity */
+	VERBOSE(JNI_INVOKE, vm, "invoking native method %s.%s%s (%s)",
+	    method->class->name, method->name, method->signature,
+	    is_jni ? "JNI" : "JCNI");
+
+	/* Invoke the native method */
+	va_start(args, values);
+	if (values) {
+		_jc_word *params;
+
+		/* Get parameters */
+		params = va_arg(args, _jc_word *);
+
+		/* Get instance object */
+		if (!is_static)
+			this = (_jc_object *)*params++;
+
+		/* Invoke method */
+		status = is_jni ?
+		    _jc_invoke_jni_a(env, method,
+		      method->native_function, this, params) :
+		    _jc_invoke_jcni_a(env, method,
+		      method->native_function, this, params);
+	} else {
+		va_list params;
+
+		/* Get parameters */
+		params = va_arg(args, va_list);
+
+		/* Get instance object */
+		if (!is_static)
+			this = va_arg(params, _jc_object *);
+
+		/* Invoke method */
+		status = _jc_invoke_v(env, method,
+		    method->native_function, this, params, is_jni); 
+	}
+	va_end(args);
+
+	/* Verbosity */
+	VERBOSE(JNI_INVOKE, vm, "%s from native method %s.%s%s",
+	    status == JNI_OK ? "returned" : env->head.pending->type->name,
+	    method->class->name, method->name, method->signature);
+
+	/* Done */
+	return status;
+}
+
+/*
+ * Load the native library with pathname "name" and associate
+ * it with the given class loader.
+ *
+ * If unsuccessful an exception is stored.
+ */
+jint
+_jc_load_native_library(_jc_env *env,
+	_jc_class_loader *loader, const char *name)
+{
+	_jc_jvm *const vm = env->vm;
+	_jc_native_lib *lib = NULL;
+	jboolean added_to_list = JNI_FALSE;
+	jboolean loader_locked = JNI_FALSE;
+	jni_onload_t *on_load;
+	void *handle = NULL;
+	const char *dlname;
+
+	/* Get dlopen() name */
+	dlname = (strcmp(name, _JC_INTERNAL_NATIVE_LIBRARY) == 0) ?
+	    NULL : name;
+
+	/* Lock loader */
+	_JC_MUTEX_LOCK(env, loader->mutex);
+	loader_locked = JNI_TRUE;
+
+retry:
+	/* See if library is already loaded or being loaded in another thread */
+	STAILQ_FOREACH(lib, &loader->native_libs, link) {
+
+		/* Does the name match? */
+		if (strcmp(lib->name, name) != 0)
+			continue;
+
+		/* Wait for other thread in progress to finish */
+		if (lib->handle == NULL) {
+			_jc_loader_wait(env, loader);
+			goto retry;
+		}
+
+		/* Done */
+		goto done;
+	}
+
+	/* Create new native library entry */
+	if ((lib = _jc_cl_zalloc(env, loader, sizeof(*lib))) == NULL
+	    || (lib->name = _jc_cl_strdup(env, loader, name)) == NULL)
+		goto fail;
+
+	/* Add native library to the list (note: lib->handle is still NULL) */
+	STAILQ_INSERT_TAIL(&loader->native_libs, lib, link);
+	added_to_list = JNI_TRUE;
+
+	/* Unlock loader */
+	_JC_MUTEX_UNLOCK(env, loader->mutex);
+	loader_locked = JNI_FALSE;
+
+	/* Verbosity */
+	if (loader == vm->boot.loader) {
+		VERBOSE(JNI, vm,
+		    "loading native library `%s' (boot loader)", name);
+	} else {
+		VERBOSE(JNI, vm,
+		    "loading native library `%s' (%s@%p)", name,
+		    loader->instance->type->name, loader->instance);
+	}
+
+	/* Try to open the shared library */
+	if ((handle = dlopen(dlname, RTLD_NOW)) == NULL) {
+		_JC_EX_STORE(env, UnsatisfiedLinkError,
+		    "failed to open native library `%s': %s", name, dlerror());
+		goto fail;
+	}
+
+	/* Invoke JNI_OnLoad() (if any) */
+	if ((on_load = dlsym(handle, "JNI_OnLoad")) != NULL) {
+		const char *vname = NULL;
+		jint version;
+
+		VERBOSE(JNI, vm, "invoking JNI_OnLoad() in `%s'", name);
+		version = (*on_load)(_JC_JVM2JNI(vm), NULL);
+		switch (version) {
+		case JNI_VERSION_1_1:
+			vname = "1.1";
+			break;
+		case JNI_VERSION_1_2:
+			vname = "1.2";
+			break;
+		case JNI_VERSION_1_4:
+			vname = "1.4";
+			break;
+		default:
+			_JC_EX_STORE(env, UnsatisfiedLinkError,
+			    "unrecognized JNI version %d required by"
+			    " native library `%s'", version, name);
+			goto fail;
+		}
+		VERBOSE(JNI, vm, "native library `%s' supports JNI version %s",
+		    name, vname);
+	}
+
+	/* Lock loader */
+	_JC_MUTEX_LOCK(env, loader->mutex);
+	loader_locked = JNI_TRUE;
+
+	/* Set handle, marking the loading of this library as complete */
+	lib->handle = handle;
+
+	/* Wake up any waiters */
+	if (loader->waiters) {
+		loader->waiters = JNI_FALSE;
+		_JC_COND_BROADCAST(loader->cond);
+	}
+
+done:
+	/* Unlock loader */
+	_JC_ASSERT(loader_locked);
+	_JC_MUTEX_UNLOCK(env, loader->mutex);
+
+	/* Done */
+	return JNI_OK;
+
+fail:
+	/* Lock loader */
+	if (!loader_locked)
+		_JC_MUTEX_LOCK(env, loader->mutex);
+
+	/* Clean up after failure */
+	if (added_to_list) {
+		_JC_ASSERT(lib->handle == NULL);
+		STAILQ_REMOVE(&loader->native_libs, lib, _jc_native_lib, link);
+	}
+	if (handle != NULL)
+		dlclose(handle);
+	if (lib != NULL) {
+		_jc_cl_unalloc(loader, &lib->name, strlen(lib->name) + 1);
+		_jc_cl_unalloc(loader, &lib, sizeof(*lib));
+	}
+
+	/* Unlock loader */
+	_JC_MUTEX_UNLOCK(env, loader->mutex);
+
+	/* Done */
+	return JNI_ERR;
+}
+
+/*
+ * Unload all native libraries associated with a class loader.
+ *
+ * This should only be called when a ClassLoader is being garbage
+ * collected. The memory for the _jc_native_lib structures will get
+ * freed automatically along with the rest of the per-loader memory.
+ */
+void
+_jc_unload_native_libraries(_jc_jvm *vm, _jc_class_loader *loader)
+{
+	while (!STAILQ_EMPTY(&loader->native_libs)) {
+		_jc_native_lib *const lib = STAILQ_FIRST(&loader->native_libs);
+		jni_onload_t *on_unload;
+
+		/* Verbosity */
+		VERBOSE(JNI, vm, "unloading native library `%s'", lib->name);
+
+		/* Unlink it */
+		STAILQ_REMOVE_HEAD(&loader->native_libs, link);
+
+		/* Invoke JNI_OnUnload() */
+		if ((on_unload = dlsym(lib->handle, "JNI_OnUnload")) != NULL) {
+			VERBOSE(JNI, vm, "invoking JNI_OnUnload() in native"
+			    " library `%s'", lib->name);
+			(*on_unload)(_JC_JVM2JNI(vm), NULL);
+		}
+
+		/* Close shared library */
+		if (dlclose(lib->handle) == -1) {
+			_jc_eprintf(vm, "%s(%s): %s\n",
+			    "dlclose", lib->name, dlerror());
+		}
+	}
+}
+
+/* 
+ * Resolve a native method.
+ *
+ * Posts an exception on failure.
+ */
+jint
+_jc_resolve_native_method(_jc_env *env, _jc_method *method)
+{
+	_jc_jvm *const vm = env->vm;
+	_jc_type *const class = method->class;
+	_jc_class_loader *const loader = class->loader;
+	const void *func = NULL;
+	_jc_native_lib *lib;
+	char *jni_name;
+	char *s;
+
+	/* Sanity check */
+	_JC_ASSERT(_JC_ACC_TEST(method, NATIVE));
+
+	/* Verbosity */
+	VERBOSE(JNI, vm, "resolving native method `%s.%s%s'",
+	    method->class->name, method->name, method->signature);
+
+	/* Allocate buffer to hold encoded name */
+	if ((jni_name = _JC_STACK_ALLOC(env,
+	      5 + _jc_jni_encode_length(class->name)
+	    + 1 + _jc_jni_encode_length(method->name)
+	    + 2 + _jc_jni_encode_length(method->signature) + 1)) == NULL) {
+		_jc_post_exception_info(env);
+		return JNI_ERR;
+	}
+
+	/* Generate short JNI function name */
+	s = jni_name;
+	_jc_jni_encode(&s, "Java/");
+	_jc_jni_encode(&s, class->name);
+	_jc_jni_encode(&s, "/");
+	_jc_jni_encode(&s, method->name);
+	*s = '\0';
+
+	/* Lock loader */
+	_JC_MUTEX_LOCK(env, loader->mutex);
+
+	/* Search native libraries associated with method's class loader */
+	STAILQ_FOREACH(lib, &loader->native_libs, link) {
+		if ((func = dlsym(lib->handle, jni_name)) != NULL) {
+			method->access_flags &= ~_JC_ACC_JCNI;
+			goto found;
+		}
+	}
+
+	/* Try short JCNI function name */
+	strncpy(jni_name, "JCNI", 4);
+	STAILQ_FOREACH(lib, &loader->native_libs, link) {
+		if ((func = dlsym(lib->handle, jni_name)) != NULL) {
+			method->access_flags |= _JC_ACC_JCNI;
+			goto found;
+		}
+	}
+
+	/* Generate long JNI function name */
+	_jc_jni_encode(&s, "//");
+	_jc_jni_encode(&s, method->signature);
+	*s = '\0';
+
+	/* Search native libraries associated with method's class loader */
+	strncpy(jni_name, "Java", 4);
+	STAILQ_FOREACH(lib, &loader->native_libs, link) {
+		if ((func = dlsym(lib->handle, jni_name)) != NULL) {
+			method->access_flags &= ~_JC_ACC_JCNI;
+			goto found;
+		}
+	}
+
+	/* Try long JCNI function name */
+	strncpy(jni_name, "JCNI", 4);
+	STAILQ_FOREACH(lib, &loader->native_libs, link) {
+		if ((func = dlsym(lib->handle, jni_name)) != NULL) {
+			method->access_flags |= _JC_ACC_JCNI;
+			goto found;
+		}
+	}
+
+	/* Unlock loader */
+	_JC_MUTEX_UNLOCK(env, loader->mutex);
+
+	/* Verbosity */
+	VERBOSE(JNI, vm, "native method `%s.%s%s' not found",
+	    method->class->name, method->name, method->signature);
+
+	/* Not found */
+	_jc_post_exception_msg(env, _JC_UnsatisfiedLinkError,
+	    "failed to resolve native method `%s.%s%s'", method->class->name,
+	    method->name, method->signature);
+	return JNI_ERR;
+
+found:
+	/* Unlock loader */
+	_JC_MUTEX_UNLOCK(env, loader->mutex);
+
+	/* Verbosity */
+	VERBOSE(JNI, vm, "found native method `%s.%s%s' at %p/%s in `%s'",
+	    method->class->name, method->name, method->signature, func,
+	    _JC_ACC_TEST(method, JCNI) ? "JCNI" : "JNI", lib->name);
+
+	/* Done */
+	method->native_function = func;
+	return JNI_OK;
+}
+
+

Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/native_ref.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/native_ref.c?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/native_ref.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/native_ref.c Tue Oct  4 19:19:16 2005
@@ -0,0 +1,428 @@
+
+/*
+ * Copyright 2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ * 
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ * $Id: native_ref.c,v 1.3 2004/07/05 21:03:27 archiecobbs Exp $
+ */
+
+#include "libjc.h"
+
+/*
+ * This file manages local and global native references.
+ * A native reference is a pointer to a pointer to an object.
+ * The inner pointer lives in a native reference frame, which
+ * itself lives in either the local (per-thread) or global
+ * (per VM) native reference frame list. These lists are
+ * scanned during garbage collection.
+ */ 
+
+/*
+ * Internal functions
+ */
+static void		_jc_pop_native_frame(_jc_native_frame_list *list);
+static jobject		_jc_new_native_ref(_jc_native_frame *frame);
+static void		_jc_free_native_ref(jobject obj);
+
+/*
+ * Get a new local native reference.
+ *
+ * Returns NULL if 'obj' is NULL or there are no more local references.
+ * In the latter case, an InternalError is posted as well.
+ */
+jobject
+_jc_new_local_native_ref(_jc_env *env, _jc_object *obj)
+{
+	_jc_native_frame *frame;
+	jobject ref = NULL;
+
+	/* Return NULL for NULL */
+	if (obj == NULL)
+		return NULL;
+	_JC_ASSERT((obj->lockword & _JC_LW_ODD_BIT) != 0);
+
+	/* Find a free reference in the current local native reference frame */
+	SLIST_FOREACH(frame, &env->native_locals, link) {
+		if ((ref = _jc_new_native_ref(frame)) != NULL)
+			break;
+		if ((frame->flags & _JC_NATIVE_REF_EXTENSION) == 0)
+			break;
+	}
+
+	/* If none found, bail, but avoid infinite recursion */
+	if (ref == NULL) {
+		_jc_native_frame stack_frame;
+
+		_jc_push_stack_local_native_frame(env, &stack_frame);
+		_jc_post_exception_msg(env, _JC_InternalError,
+		    "max number of local native references exceeded");
+		_jc_pop_local_native_frame(env, NULL);
+		return NULL;
+	}
+
+	/* Sanity check */
+	_JC_ASSERT(*ref == NULL);
+
+	/* Done */
+	*ref = obj;
+	return ref;
+}
+
+/*
+ * Free a local native reference and return the wrapped object.
+ *
+ * This function must not allow this thread to be blocked & GC'd.
+ */
+_jc_object *
+_jc_free_local_native_ref(jobject *refp)
+{
+	const jobject ref = *refp;
+	_jc_object *obj;
+
+	if (ref == NULL)
+		return NULL;
+	obj = *ref;
+	_JC_ASSERT(obj != NULL);
+	_jc_free_native_ref(ref);
+	*refp = NULL;
+	return obj;
+}
+
+/*
+ * Free all native locals. This is used when detaching a thread.
+ */
+void
+_jc_free_all_native_local_refs(_jc_env *env)
+{
+	while (!SLIST_EMPTY(&env->native_locals))
+		_jc_pop_native_frame(&env->native_locals);
+}
+
+/*
+ * Get a new global native reference.
+ *
+ * This causes a new native reference frame to be added if necessary.
+ * If unsuccessful, an exception is stored and NULL is returned.
+ *
+ * NOTE: The global VM mutex should not be acquired when calling this.
+ */
+jobject
+_jc_new_global_native_ref(_jc_env *env, _jc_object *obj)
+{
+	_jc_jvm *const vm = env->vm;
+	_jc_native_frame *frame;
+	jobject ref = NULL;
+
+	/* Return NULL for NULL */
+	if (obj == NULL)
+		return NULL;
+	_JC_ASSERT((obj->lockword & _JC_LW_ODD_BIT) != 0);
+
+	/* Acquire VM global mutex */
+	_JC_MUTEX_LOCK(env, vm->mutex);
+
+	/* Find a free reference in any global native reference frame */
+	SLIST_FOREACH(frame, &vm->native_globals, link) {
+		if ((ref = _jc_new_native_ref(frame)) != NULL)
+			break;
+	}
+
+	/* If none found, create a new frame */
+	if (ref == NULL) {
+		if ((frame = _jc_add_native_frame(env,
+		    &vm->native_globals)) == NULL)
+			goto fail;
+		ref = _jc_new_native_ref(frame);
+		_JC_ASSERT(ref != NULL);
+	}
+
+	/* Sanity check */
+	_JC_ASSERT(*ref == NULL);
+
+	/* Point reference at object */
+	*ref = obj;
+
+fail:
+	/* Release VM global mutex */
+	_JC_MUTEX_UNLOCK(env, vm->mutex);
+
+	/* Done */
+	return ref;
+}
+
+/*
+ * Free a global native reference and return the wrapped object.
+ *
+ * This function must not allow this thread to be blocked & GC'd.
+ *
+ * We could attempt to free unused global reference frames;
+ * instead, we just choose to cache them for possible re-use.
+ */
+_jc_object *
+_jc_free_global_native_ref(jobject *refp)
+{
+	const jobject ref = *refp;
+	_jc_object *obj;
+
+	if (ref == NULL)
+		return NULL;
+	obj = *ref;
+	_JC_ASSERT(obj != NULL);
+	_jc_free_native_ref(ref);
+	*refp = NULL;
+	return obj;
+}
+
+/*
+ * Free all native globals. This is used when destroying the VM.
+ */
+void
+_jc_free_all_native_global_refs(_jc_jvm *vm)
+{
+	while (!SLIST_EMPTY(&vm->native_globals))
+		_jc_pop_native_frame(&vm->native_globals);
+}
+
+/*
+ * Add a new native reference frame with the given number
+ * of references (or default if zero) to the current thread.
+ *
+ * Posts OutOfMemoryError if unable.
+ */
+jint
+_jc_push_local_native_frame(_jc_env *env, int num_refs)
+{
+	_jc_native_frame *frame;
+
+	/* Zero refs means "use the default" */
+	if (num_refs == 0)
+		num_refs = _JC_NATIVE_REFS_PER_FRAME;
+	_JC_ASSERT(num_refs > 0);
+
+	/* Allocate first frame */
+	if (_jc_add_native_frame(env, &env->native_locals) == NULL) {
+		_jc_post_exception_info(env);
+		return JNI_ERR;
+	}
+
+	/* Allocate additional extension frames as necessary */
+	while ((num_refs -= _JC_NATIVE_REFS_PER_FRAME) > 0) {
+		if ((frame = _jc_add_native_frame(env,
+		    &env->native_locals)) == NULL) {
+			_jc_pop_local_native_frame(env, NULL);	/* clean up */
+			_jc_post_exception_info(env);
+			return JNI_ERR;
+		}
+		frame->flags |= _JC_NATIVE_REF_EXTENSION;
+	}
+
+	/* Done */
+	return JNI_OK;
+}
+
+/*
+ * "Extend" the current local native reference frame by adding
+ * additional frame(s) with the _JC_NATIVE_REF_EXTENSION flag set.
+ *
+ * Posts OutOfMemoryError if unable.
+ */
+jint
+_jc_extend_local_native_frame(_jc_env *env, int num_refs)
+{
+	_jc_native_frame *frame;
+	int num_frames;
+
+	/* Add extension frames until we have enough new references */
+	for (num_frames = 0; num_refs > 0;
+	    num_frames++, num_refs -= _JC_NATIVE_REFS_PER_FRAME) {
+		if ((frame = _jc_add_native_frame(env,
+		    &env->native_locals)) == NULL) {
+			while (num_frames-- > 0)	/* clean up */
+				_jc_pop_native_frame(&env->native_locals);
+			_jc_post_exception_info(env);
+			return JNI_ERR;
+		}
+		frame->flags |= _JC_NATIVE_REF_EXTENSION;
+	}
+
+	/* Done */
+	return JNI_OK;
+}
+
+/*
+ * Initialize a new local native reference frame that is allocated
+ * on the stack of the caller. The calling function must free the frame
+ * by calling _jc_pop_local_native_frame() before returning.
+ */
+void
+_jc_push_stack_local_native_frame(_jc_env *env, _jc_native_frame *frame)
+{
+	memset(frame, 0, sizeof(*frame));
+	frame->flags = _JC_NATIVE_REF_FREE_BITS
+	    | _JC_NATIVE_REF_STACK_ALLOC | _JC_NATIVE_REF_ODD_BIT;
+	SLIST_INSERT_HEAD(&env->native_locals, frame, link);
+}
+
+/*
+ * Free the top-most (i.e., last) local native reference frame.
+ * If 'obj' is non-NULL, attempt to create a reference for the object
+ * in the local native reference frame one below the one we're popping
+ * and return it. Otherwise, return NULL.
+ *
+ * Note: this function must not allow this thread to be blocked & GC'd
+ * when 'obj' is NULL.
+ */
+jobject
+_jc_pop_local_native_frame(_jc_env *env, _jc_object *obj)
+{
+	_jc_native_frame *frame;
+	jboolean extension;
+
+again:
+	/* Get the top frame */
+	_JC_ASSERT(!SLIST_EMPTY(&env->native_locals));
+	frame = SLIST_FIRST(&env->native_locals);
+
+	/* Is this an extension of the previous frame? */
+	extension = (frame->flags & _JC_NATIVE_REF_EXTENSION) != 0;
+
+	/* Remove frame */
+	_jc_pop_native_frame(&env->native_locals);
+
+	/* If it was an extension of previous frame, pop another */
+	if (extension)
+		goto again;
+
+	/* Create a new reference for 'obj' in underlying frame if needed */
+	if (obj != NULL)
+		return _jc_new_local_native_ref(env, obj);
+	return NULL;
+}
+
+/*
+ * Add a new native reference frame to the given frame list.
+ *
+ * If unsuccessful, an exception is stored.
+ */
+_jc_native_frame *
+_jc_add_native_frame(_jc_env *env, _jc_native_frame_list *list)
+{
+	_jc_native_frame *frame;
+
+	/* Allocate new frame */
+	if ((frame = _jc_vm_zalloc(env, sizeof(*frame))) == NULL)
+		return NULL;
+
+	/* Initialize frame and add to list */
+	frame->flags = _JC_NATIVE_REF_FREE_BITS | _JC_NATIVE_REF_ODD_BIT;
+	SLIST_INSERT_HEAD(list, frame, link);
+
+	/* Done */
+	return frame;
+}
+
+/*
+ * Remove the first (i.e., top-most on the stack) native reference frame.
+ */
+static void
+_jc_pop_native_frame(_jc_native_frame_list *list)
+{
+	_jc_native_frame *frame;
+	int stack_alloc;
+
+	/* Sanity check frame list */
+	_JC_ASSERT(!SLIST_EMPTY(list));
+
+	/* Get frame */
+	frame = SLIST_FIRST(list);
+
+	/* Determine if frame is stack allocated */
+	stack_alloc = (frame->flags & _JC_NATIVE_REF_STACK_ALLOC) != 0;
+
+	/* Sanity check stack allocated frames are still on the stack */
+#if _JC_DOWNWARD_STACK
+	_JC_ASSERT(!stack_alloc || (char *)frame > (char *)&frame);
+#else
+	_JC_ASSERT(!stack_alloc || (char *)frame < (char *)&frame);
+#endif
+
+	/* Remove frame and explicitly free it if necessary */
+	SLIST_REMOVE_HEAD(list, link);
+	if (!stack_alloc)
+		_jc_vm_free(&frame);
+}
+
+/*
+ * Find a free native reference in the given native reference frame.
+ *
+ * Returns NULL (without posting any exceptions) if unable.
+ */
+static jobject
+_jc_new_native_ref(_jc_native_frame *frame)
+{
+	int i;
+
+	/* Any references free at all in this frame? */
+	if (!_JC_NATIVE_REF_ANY_FREE(frame))
+		return NULL;
+
+	/* Find the first free one */
+	i = ffs(frame->flags & _JC_NATIVE_REF_FREE_BITS) - 4;
+
+	/* Sanity check */
+	_JC_ASSERT(i >= 0 && i < _JC_NATIVE_REFS_PER_FRAME);
+
+	/* Mark reference in use */
+	_JC_NATIVE_REF_MARK_IN_USE(frame, i);
+
+	/* Done */
+	return &frame->refs[i];
+}
+
+/*
+ * Free a non-NULL native reference.
+ *
+ * We need to find the beginning of the native reference frame
+ * containing the given native reference. We can do this by looking
+ * backwards in memory.
+ *
+ * This works because while all native references are aligned pointers
+ * and therefore zero as the low-order bit, frame->flags always has
+ * one as its low-order bit.
+ */
+static void
+_jc_free_native_ref(jobject obj)
+{
+	_jc_native_frame *frame = NULL;
+	int i;
+
+	/* Invalidate the reference */
+	_JC_ASSERT(obj != NULL);
+	*obj = NULL;
+
+	/* Find the beginning of this native reference frame */
+	for (i = 0; i < _JC_NATIVE_REFS_PER_FRAME; i++) {
+		if (((_jc_word)(*--obj) & 0x1) != 0) {
+			frame = (_jc_native_frame *)((char *)obj
+			    - _JC_OFFSETOF(_jc_native_frame, flags));
+			break;
+		}
+	}
+	_JC_ASSERT(i < _JC_NATIVE_REFS_PER_FRAME);
+
+	/* Mark this reference as 'free' */
+	_JC_NATIVE_REF_MARK_FREE(frame, i);
+}
+

Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/new.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/new.c?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/new.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/new.c Tue Oct  4 19:19:16 2005
@@ -0,0 +1,481 @@
+
+/*
+ * Copyright 2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ * 
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ * $Id: new.c,v 1.12 2005/03/20 23:33:28 archiecobbs Exp $
+ */
+
+#include "libjc.h"
+
+/* Internal functions */
+static _jc_object	*_jc_initialize_object(void *mem, _jc_type *type,
+				_jc_word lockword, int nrefs, int prim_size,
+				jboolean skipword);
+
+/*
+ * Initialize a heap block containing an object, optionally including
+ * a "skip word" at the beginning. To ensure that the finalizer thread
+ * never sees a partially constructed object, we modify the first word last.
+ */
+static inline _jc_object *
+_jc_initialize_object(void *mem, _jc_type *type, _jc_word lockword,
+	int nrefs, int prim_size, jboolean skipword)
+{
+	_jc_object *obj;
+
+	/* Handle skipword vs. no skipword cases */
+	if (skipword) {
+		_jc_word *const obj_start = (_jc_word *)mem + 1;
+
+		/* Zero object's reference fields */
+		memset(obj_start, 0, nrefs * sizeof(void *));
+
+		/* Initialize object header */
+		obj = (_jc_object *)(obj_start + nrefs);
+		obj->lockword = lockword;
+		obj->type = type;
+
+		/* Zero non-reference fields */
+		memset((char *)obj + sizeof(*obj), 0, prim_size);
+
+		/* Lastly, set the skip word: skip refs and skip word itself */
+		_JC_ASSERT(nrefs + 1 < _JC_HEAP_MAX(SKIP));
+		*((volatile _jc_word *)mem)
+		    = ((nrefs + 1) << _JC_HEAP_SKIP_SHIFT)
+		      | (_JC_HEAP_BLOCK_SKIP << _JC_HEAP_BTYPE_SHIFT);
+	} else {
+		_jc_word *const obj_start = (_jc_word *)mem;
+
+		/* Zero all reference fields except the first */
+		if (nrefs > 1)
+			memset(obj_start + 1, 0, (nrefs - 1) * sizeof(void *));
+
+		/*
+		 * Initialize object header. In case the lockword is the
+		 * first word in the block, we must initialize it last so
+		 * the finalizer thread never sees an incomplete object.
+		 */
+		obj = (_jc_object *)(obj_start + nrefs);
+		obj->type = type;
+		obj->lockword = lockword;
+
+		/* Zero non-reference fields */
+		memset((char *)obj + sizeof(*obj), 0, prim_size);
+
+		/* Lastly, set the first reference field */
+		if (nrefs > 0)
+			*obj_start = 0;
+	}
+
+	/* Done */
+	return obj;
+}
+
+/************************************************************************
+ *			Object creation					*
+ ************************************************************************/
+
+/*
+ * Allocate a new non-array object from the heap and initialize it.
+ * This only initializes the memory, it doesn't execute any constructor.
+ * 'type' must not be an array type, abstract type, or interface.
+ *
+ * NOTE: The caller is responsible for ensuring that type->loader does
+ * not get unloaded during this function. I.e., it must be the boot loader
+ * or else a reference to the type's Class or ClassLoader object must be
+ * retained somehow.
+ */
+_jc_object *
+_jc_new_object(_jc_env *env, _jc_type *type)
+{
+	_jc_object *obj;
+	void *mem;
+	int bsi;
+
+	/* Sanity checks */
+	_JC_ASSERT(!_JC_FLG_TEST(type, ARRAY));
+	_JC_ASSERT((type->flags & _JC_TYPE_MASK) == _JC_TYPE_REFERENCE);
+
+	/* Check object type */
+	if ((type->access_flags & (_JC_ACC_ABSTRACT|_JC_ACC_INTERFACE)) != 0) {
+		_jc_post_exception_msg(env, _JC_InstantiationError,
+		    "class %s is %s", type->name,
+		    _JC_ACC_TEST(type, INTERFACE) ? "interface" : "abstract");
+		return NULL;
+	}
+
+	/* Initialize type */
+	if (!_JC_FLG_TEST(type, INITIALIZED)
+	    && _jc_initialize_type(env, type) != JNI_OK)
+		return NULL;
+	_JC_ASSERT((type->initial_lockword & _JC_LW_ODD_BIT) != 0);
+
+	/* Allocate memory from the heap and initialize it */
+	if ((bsi = type->u.nonarray.block_size_index) >= 0) {
+
+		/* Get a small page block */
+		if ((mem = _jc_heap_alloc_small_block(env, bsi)) == NULL)
+			return NULL;
+
+		/* Initialize object */
+		obj = _jc_initialize_object(mem, type, type->initial_lockword,
+		    type->u.nonarray.num_virtual_refs,
+		    type->u.nonarray.instance_size
+		      - (type->u.nonarray.num_virtual_refs * sizeof(void *))
+		      - sizeof(*obj), _JC_FLG_TEST(type, SKIPWORD));
+	} else {
+
+		/* Get a contiguous range of large pages */
+		if ((mem = _jc_heap_alloc_pages(env, -bsi)) == NULL)
+			return NULL;
+
+		/* Initialize object */
+		obj = _jc_initialize_object((char *)mem + _JC_HEAP_BLOCK_OFFSET,
+		    type, type->initial_lockword,
+		    type->u.nonarray.num_virtual_refs,
+		    type->u.nonarray.instance_size
+		      - (type->u.nonarray.num_virtual_refs * sizeof(void *))
+		      - sizeof(*obj), _JC_FLG_TEST(type, SKIPWORD));
+
+		/* Mark large page range as in use */
+		*((volatile _jc_word *)mem)
+		    = (_JC_HEAP_PAGE_LARGE << _JC_HEAP_PTYPE_SHIFT)
+		      | (-bsi << _JC_HEAP_NPAGES_SHIFT);
+	}
+
+	/* Done */
+	return obj;
+}
+
+/*
+ * Initialize a non-array object allocated on the stack.
+ */
+_jc_object *
+_jc_init_object(_jc_env *env, void *mem, _jc_type *type)
+{
+	_jc_object *obj;
+
+	/* Sanity checks */
+	_JC_ASSERT(!_JC_FLG_TEST(type, ARRAY));
+	_JC_ASSERT((type->flags & _JC_TYPE_MASK) == _JC_TYPE_REFERENCE);
+	_JC_ASSERT(!_JC_IN_HEAP(&env->vm->heap, mem));
+
+	/* Check object type */
+	if ((type->access_flags & (_JC_ACC_ABSTRACT|_JC_ACC_INTERFACE)) != 0) {
+		_jc_post_exception_msg(env, _JC_InstantiationError,
+		    "class %s is %s", type->name,
+		    _JC_ACC_TEST(type, INTERFACE) ? "interface" : "abstract");
+		return NULL;
+	}
+
+	/* Initialize type */
+	if (!_JC_FLG_TEST(type, INITIALIZED)
+	    && _jc_initialize_type(env, type) != JNI_OK)
+		return NULL;
+	_JC_ASSERT(_JC_LW_TEST(type->initial_lockword, ODD));
+	_JC_ASSERT(!_JC_LW_TEST(type->initial_lockword, FINALIZE));
+
+	/* Zero memory */
+	memset(mem, 0, type->u.nonarray.instance_size);
+
+	/* Initialize object header */
+	obj = (_jc_object *)((void **)mem + type->u.nonarray.num_virtual_refs);
+	obj->lockword = type->initial_lockword;
+	obj->type = type;
+
+	/* Another sanity check */
+	_JC_ASSERT(!_jc_subclass_of(obj, env->vm->boot.types.Reference));
+
+	/* Done */
+	return obj;
+}
+
+/*
+ * Initialize a new Class object previously allocated in loader memory.
+ * This only initializes the memory, it doesn't execute any constructor.
+ * We don't include skip words for Class objects because they are only
+ * useful for heap-allocated objects.
+ */
+_jc_object *
+_jc_initialize_class_object(_jc_env *env, void *mem)
+{
+	_jc_jvm *const vm = env->vm;
+	_jc_type *const type = vm->boot.types.Class;
+	_jc_object *obj;
+
+	/* Sanity checks */
+	_JC_ASSERT((type->initial_lockword & _JC_LW_ODD_BIT) != 0);
+	_JC_ASSERT(!_JC_FLG_TEST(type, ARRAY));
+	_JC_ASSERT(!_JC_IN_HEAP(&vm->heap, mem));
+
+	/* Initialize object */
+	return _jc_initialize_object(mem, type, type->initial_lockword,
+	    type->u.nonarray.num_virtual_refs,
+	    type->u.nonarray.instance_size
+	      - (type->u.nonarray.num_virtual_refs * sizeof(void *))
+	      - sizeof(*obj), JNI_FALSE);
+}
+
+/************************************************************************
+ *			Array creation					*
+ ************************************************************************/
+
+/*
+ * Create a new array instance.
+ */
+_jc_array *
+_jc_new_array(_jc_env *env, _jc_type *type, jint len)
+{
+	_jc_jvm *const vm = env->vm;
+	u_char elem_type;
+	_jc_array *array;
+	int array_size;
+	void *mem;
+	int bsi;
+
+	/* Sanity check */
+	_JC_ASSERT(_JC_FLG_TEST(type, ARRAY));
+	elem_type = (type->u.array.element_type->flags & _JC_TYPE_MASK);
+	_JC_ASSERT(elem_type != _JC_TYPE_INVALID);
+
+	/* Check for negative length */
+	if (len < 0) {
+		_jc_post_exception_msg(env,
+		    _JC_NegativeArraySizeException, "%d", (int)len);
+		return NULL;
+	}
+
+	/* Guard against arithmetic overflow */
+	if ((jlong)len >= _jc_type_max_array_length[elem_type]) {
+		_jc_post_exception_msg(env, _JC_OutOfMemoryError,
+		    "array length %d is too big for type `%s'",
+		    (int)len, type->name);
+		return NULL;
+	}
+
+	/* Compute size of the array object */
+	array_size = _jc_array_head_sizes[elem_type]
+	    + len * _jc_type_sizes[elem_type];
+
+	/* Get corresponding block size index */
+	bsi = _jc_heap_block_size(vm, array_size);
+
+	/* Allocate heap memory */
+	mem = (bsi >= 0) ?
+	    _jc_heap_alloc_small_block(env, bsi) :
+	    _jc_heap_alloc_pages(env, -bsi);
+	if (mem == NULL)
+		return NULL;
+
+	/* Point to start of object; skip page offset for large pages */
+	array = (_jc_array *)(bsi < 0 ?
+	    (char *)mem + _JC_HEAP_BLOCK_OFFSET : mem);
+
+	/* Initialize heap memory */
+	if (elem_type == _JC_TYPE_REFERENCE) {
+		const int ref_count_bits = (len < _JC_LW_MAX(REF_COUNT) - 1) ?
+		    len : _JC_LW_MAX(REF_COUNT) - 1;
+		int block_size;
+
+		/* Determine if we desire and have room for a skip word */
+		block_size = bsi < 0 ?
+		    ((-bsi * _JC_PAGE_SIZE) - _JC_HEAP_BLOCK_OFFSET) :
+		    vm->heap.sizes[bsi].size;
+
+		/* Initialize array object */
+		array = (_jc_array *)_jc_initialize_object(array, type,
+		    type->initial_lockword
+		      | (ref_count_bits << _JC_LW_REF_COUNT_SHIFT),
+		    len, 0, 
+		    (block_size >= array_size + sizeof(_jc_word)
+		      && len >= _JC_SKIPWORD_MIN_REFS));
+	} else {
+		array = (_jc_array *)_jc_initialize_object(array, type,
+		    type->initial_lockword, 0, array_size - sizeof(_jc_object),
+		    JNI_FALSE);
+	}
+
+	/* Initialize heap pages if we got large pages */
+	if (bsi < 0) {
+		*((volatile _jc_word *)mem)
+		    = (_JC_HEAP_PAGE_LARGE << _JC_HEAP_PTYPE_SHIFT)
+		      | (-bsi << _JC_HEAP_NPAGES_SHIFT);
+	}
+
+	/* Set length */
+	*((jint *)&array->length) = len;
+
+	/* Done */
+	return array;
+}
+
+/*
+ * Initialize an array instance allocated on the stack.
+ */
+_jc_array *
+_jc_init_array(_jc_env *env, void *mem, _jc_type *type, jint len)
+{
+	_jc_word lockword;
+	u_char elem_type;
+	_jc_array *array;
+
+	/* Sanity check */
+	_JC_ASSERT(_JC_FLG_TEST(type, ARRAY));
+	elem_type = (type->u.array.element_type->flags & _JC_TYPE_MASK);
+	_JC_ASSERT(elem_type != _JC_TYPE_INVALID);
+	_JC_ASSERT(!_JC_IN_HEAP(&env->vm->heap, mem));
+
+	/* Check for negative length */
+	if (len < 0) {
+		_jc_post_exception_msg(env,
+		    _JC_NegativeArraySizeException, "%d", (int)len);
+		return NULL;
+	}
+
+	/* Guard against arithmetic overflow */
+	if ((jlong)len >= _jc_type_max_array_length[elem_type]) {
+		_jc_post_exception_msg(env, _JC_OutOfMemoryError,
+		    "array length %d is too big for type `%s'",
+		    (int)len, type->name);
+		return NULL;
+	}
+
+	/* Initialize array header and zero array elements */
+	lockword = type->initial_lockword;
+	if (elem_type == _JC_TYPE_REFERENCE) {
+		const int ref_count_bits = (len < _JC_LW_MAX(REF_COUNT) - 1) ?
+		    len : _JC_LW_MAX(REF_COUNT) - 1;
+
+		memset(mem, 0, len * sizeof(void *));
+		array = (_jc_array *)((void **)mem + len);
+		array->lockword = type->initial_lockword
+		    | (ref_count_bits << _JC_LW_REF_COUNT_SHIFT);
+		array->type = type;
+	} else {
+		array = (_jc_array *)mem;
+		array->lockword = type->initial_lockword;
+		array->type = type;
+		memset((char *)array + _jc_array_head_sizes[elem_type],
+		    0, len * _jc_type_sizes[elem_type]);
+	}
+	*((jint *)&array->length) = len;
+
+	/* Done */
+	return array;
+}
+
+/*
+ * Recursively create a new multi-dimensional reference array.
+ */
+_jc_array *
+_jc_new_multiarray(_jc_env *env, _jc_type *type,
+	jint num_sizes, const jint *sizes)
+{
+	const jint len = sizes[0];
+	_jc_array *array;
+	jobject ref;
+	jint i;
+
+	/* Sanity check */
+	_JC_ASSERT(_JC_FLG_TEST(type, ARRAY));
+	_JC_ASSERT(num_sizes >= 0 && num_sizes <= type->u.array.dimensions);
+
+	/* Create new array */
+	if ((array = _jc_new_array(env, type, len)) == NULL)
+		return NULL;
+
+	/* Do we need to create sub-arrays? */
+	if (type->u.array.dimensions == 1 || len == 0 || num_sizes < 2) {
+
+		/* Check for any subsequent negative dimensions */
+		if (len == 0) {
+			for (i = 1; i < num_sizes; i++) {
+				if (sizes[i] < 0) {
+					_jc_post_exception_msg(env,
+					    _JC_NegativeArraySizeException,
+					    "%d", (int)sizes[i]);
+					return NULL;
+				}
+			}
+		}
+
+		/* Done */
+		return array;
+	}
+
+	/* Keep a native reference to 'array' while creating sub-arrays */
+	if ((ref = _jc_new_local_native_ref(env, (_jc_object *)array)) == NULL)
+		return NULL;
+
+	/* Create sub-arrays recursively */
+	for (i = 0; i < len; i++) {
+		_jc_array *subarray;
+
+		if ((subarray = _jc_new_multiarray(env,
+		    type->u.array.element_type,
+		    num_sizes - 1, sizes + 1)) == NULL) {
+			_jc_free_local_native_ref(&ref);
+			return NULL;
+		}
+		((_jc_object_array *)array)->elems[~i] = (_jc_object *)subarray;
+	}
+
+	/* Free native reference */
+	_jc_free_local_native_ref(&ref);
+
+	/* Done */
+	return array;
+}
+
+/*
+ * Initialize a stack-allocated multi-dimensional reference array.
+ */
+_jc_array *
+_jc_init_multiarray(_jc_env *env, void *mem, _jc_type *type,
+	jint num_sizes, const jint *sizes)
+{
+	const jint len = sizes[0];
+	_jc_array *array;
+	jint i;
+
+	/* Sanity check */
+	_JC_ASSERT(_JC_FLG_TEST(type, ARRAY));
+	_JC_ASSERT(num_sizes >= 0 && num_sizes <= type->u.array.dimensions);
+	_JC_ASSERT(!_JC_IN_HEAP(&env->vm->heap, mem));
+
+	/* Initialize new array */
+	if ((array = _jc_init_array(env, mem, type, len)) == NULL)
+		return NULL;
+
+	/* Do we need to create sub-arrays? */
+	if (type->u.array.dimensions == 1 || len == 0 || num_sizes < 2)
+		return array;
+
+	/* Create sub-arrays recursively */
+	for (i = 0; i < len; i++) {
+		_jc_array *subarray;
+
+		if ((subarray = _jc_new_multiarray(env,
+		    type->u.array.element_type,
+		    num_sizes - 1, sizes + 1)) == NULL)
+			return NULL;
+		((_jc_object_array *)array)->elems[~i] = (_jc_object *)subarray;
+	}
+
+	/* Done */
+	return array;
+}
+

Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/os_functions.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/os_functions.c?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/os_functions.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/os_functions.c Tue Oct  4 19:19:16 2005
@@ -0,0 +1,97 @@
+
+/*
+ * Copyright 2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ * 
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ * $Id: os_functions.c,v 1.1.1.1 2004/02/20 05:15:42 archiecobbs Exp $
+ */
+
+#include "libjc.h"
+
+/*
+
+This file contains O/S dependent (but architecture independent) functions.
+The following functions must be defined here:
+
+    int
+    _jc_num_cpus(_jc_env *env)
+
+	This function should return the number of CPU's. It is used
+	to implement the Runtime.availableProcessors() method.
+
+ */
+
+/************************************************************************
+ *				FreeBSD					*
+ ************************************************************************/
+
+#if defined(__FreeBSD__)
+
+#include <sys/sysctl.h>
+
+int
+_jc_num_cpus(_jc_env *env)
+{
+	static const char *const node = "hw.ncpu";
+	_jc_jvm *const vm = env->vm;
+	int num;
+
+        if (sysctlbyname(node, NULL, 0, &num, sizeof(num)) == -1) {
+		_jc_eprintf(vm, "sysctl(%s): %s", node, strerror(errno));
+		return 1;
+	}
+	return num;
+}
+
+/************************************************************************
+ *				Linux					*
+ ************************************************************************/
+
+#elif defined(__linux__)
+
+int
+_jc_num_cpus(_jc_env *env)
+{
+	_jc_jvm *const vm = env->vm;
+        static const char *const file = "/proc/cpuinfo";
+	char buf[64];
+	size_t len;
+	FILE *fp;
+	int num;
+	int ch;
+
+        if ((fp = fopen("/proc/cpuinfo", "r")) == NULL) {
+		_jc_eprintf(vm, "%s: %s", file, strerror(errno));
+		return 1;
+	}
+	for (num = 0; fgets(buf, sizeof(buf), fp) != NULL; ) {
+		len = strlen(buf);
+		if (len > 0 && buf[len - 1] != '\n')
+			while ((ch = getc(fp)) != '\n' && ch != EOF);
+		if (strncmp(buf, "processor", 9) == 0)
+			num++;
+	}
+	fclose(fp);
+	return num;
+}
+
+/************************************************************************
+ *				Others					*
+ ************************************************************************/
+
+#else
+#error "Unsupported operating system"
+#endif
+

Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/prepare.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/prepare.c?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/prepare.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/prepare.c Tue Oct  4 19:19:16 2005
@@ -0,0 +1,56 @@
+
+/*
+ * Copyright 2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ * 
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ * $Id: prepare.c,v 1.3 2005/02/27 04:52:59 archiecobbs Exp $
+ */
+
+#include "libjc.h"
+
+/*
+ * Prepare a type.
+ *
+ * NOTE: This assumes the caller is handling synchronization issues.
+ */
+jint
+_jc_prepare_type(_jc_env *env, _jc_type *type)
+{
+	jint status;
+
+	/* Already prepared? */
+	if (_JC_FLG_TEST(type, PREPARED)) {
+		_JC_ASSERT(_JC_FLG_TEST(type, LOADED));
+		_JC_ASSERT(_JC_FLG_TEST(type, VERIFIED));
+		return JNI_OK;
+	}
+
+	/* Sanity check */
+	_JC_ASSERT(!_JC_FLG_TEST(type, ARRAY));
+
+	/* Verify type first */
+	if (!_JC_FLG_TEST(type, VERIFIED)
+	    && (status = _jc_verify_type(env, type)) != JNI_OK)
+		return status;
+
+	/* Nothing to do for us */
+
+	/* Mark type as prepared */
+	type->flags |= _JC_TYPE_PREPARED;
+
+	/* Done */
+	return JNI_OK;
+}
+

Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/printf.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/printf.c?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/printf.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/printf.c Tue Oct  4 19:19:16 2005
@@ -0,0 +1,85 @@
+
+/*
+ * Copyright 2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ * 
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ * $Id: printf.c,v 1.2 2004/07/18 02:19:12 archiecobbs Exp $
+ */
+
+#include "libjc.h"
+
+/*
+ * Print something to standard output.
+ */
+int
+_jc_printf(_jc_jvm *vm, const char *fmt, ...)
+{
+	va_list args;
+	int r;
+
+	va_start(args, fmt);
+	r = (vm != NULL) ?
+	    (*vm->vfprintf)(stdout, fmt, args) :
+	    vfprintf(stdout, fmt, args);
+	va_end(args);
+	return r;
+}
+
+/*
+ * Print something to standard error.
+ */
+int
+_jc_eprintf(_jc_jvm *vm, const char *fmt, ...)
+{
+	va_list args;
+	int r;
+
+	va_start(args, fmt);
+	r = (vm != NULL) ?
+	    (*vm->vfprintf)(stderr, fmt, args) :
+	    vfprintf(stderr, fmt, args);
+	va_end(args);
+	return r;
+}
+
+/*
+ * Print something to wherever.
+ */
+int
+_jc_fprintf(_jc_jvm *vm, FILE *fp, const char *fmt, ...)
+{
+	va_list args;
+	int r;
+
+	va_start(args, fmt);
+	r = (vm != NULL) ?
+	    (*vm->vfprintf)(fp, fmt, args) :
+	    vfprintf(fp, fmt, args);
+	va_end(args);
+	return r;
+}
+
+/*
+ * Print out a string (e.g., class name) with dots instead of slashes.
+ */
+void
+_jc_fprint_noslash(_jc_jvm *vm, FILE *fp, const char *s)
+{
+	while (*s != '\0') {
+		_jc_fprintf(vm, fp, "%c", *s == '/' ? '.' : *s);
+		s++;
+	}
+}
+