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++;
+ }
+}
+