classpath
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Classpath build process and VM-specific issues


From: Etienne Gagnon
Subject: Re: Classpath build process and VM-specific issues
Date: Tue, 06 Apr 2004 16:17:28 -0400
User-agent: Mozilla/5.0 (X11; U; Linux ppc; en-US; rv:1.6) Gecko/20040402 Debian/1.6-4

Andrew Haley wrote:
Maybe, but that's not the only thing.  It's possible to define jbyte
so that it is an 8 bit signed value but not a character type, and JNI
does not forbid this.  I suspect that all the platforms we use define
jbyte to be a character type, but I can see no overpowering reason to
introduce a dependency on that.

"jbyte" must have a single platform-specific definition, as all JVMs on that
platform should be able to execute the same JNI library code (no recompilation
required).  I would argue that if a char type has 8 bits on a platform, there
is a strong case for it to be defined as "typedef signed char jbyte", and I 
would
gues VM implementors would be veery unhappy if Sum (or any other) decided to
define jbyte otherwise on that platform.

BUT....  I agree, it could be false on some system.  So, assuming the worst-case
scenario, I have attached an updated version of my byte array proposal that
is, as far as I can tell, robust across all possible platforms.

It contains 2 utility "inline" functions: wrap and unwrap.  I provide 2 versions
of each, one version for systems where jbyte == signed char, and one version
for systems where jbyte != signed char.  A test function, ideal for use in
an autoconf macro, is provided that issues a warning when jbyte != signed char.

So, Andrew, does this version pass the portability test?

I would really like to see the native counterpart of your opaque types and
compare the "theoretical" performance of it relative to the byte array
proposal.

Etienne

--
Etienne M. Gagnon, Ph.D.             http://www.info.uqam.ca/~egagnon/
SableVM:                                       http://www.sablevm.org/
SableCC:                                       http://www.sablecc.org/
/* Put in the public domain by Etienne M. Gagnon <address@hidden> */

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class JNITest */

#ifndef _Included_JNITest
#define _Included_JNITest
#ifdef __cplusplus
extern "C"
{
#endif
/*
 * Class:     JNITest
 * Method:    getPtr
 * Signature: ()[B
 */
  JNIEXPORT jbyteArray JNICALL Java_JNITest_getPtr (JNIEnv *, jclass);

/*
 * Class:     JNITest
 * Method:    testPtr
 * Signature: ([B)V
 */
  JNIEXPORT void JNICALL Java_JNITest_testPtr (JNIEnv *, jclass, jbyteArray);

#ifdef __cplusplus
}
#endif
#endif
/* Put in the public domain by Etienne M. Gagnon <address@hidden> */

public class JNITest
{
    static
    {
        System.loadLibrary("test");
    }

    public static void main(String[] args)
    {
        byte[] nativePtr = getPtr();
        testPtr(nativePtr);
    }

    private static native byte[] getPtr();
    private static native void testPtr(byte[] nativPtr);
}
/* Put in the public domain by Etienne M. Gagnon <address@hidden> */

#include <jni.h>
#include <stdio.h>
#include <stdlib.h>

#include "wrap.c"

/*
 * Class:     JNITest
 * Method:    getPtr
 * Signature: ()[B
 */
JNIEXPORT jbyteArray JNICALL
Java_JNITest_getPtr (JNIEnv *env, jclass class)
{
  int *int_ptr;

  int_ptr = (int *) malloc (sizeof (int));
  *int_ptr = 0x47;

  return wrap (env, int_ptr);
}

/*
 * Class:     JNITest
 * Method:    testPtr
 * Signature: ([B)V
 */
JNIEXPORT void JNICALL
Java_JNITest_testPtr (JNIEnv *env, jclass class, jbyteArray nativePtr)
{
  int *int_ptr = unwrap (env, nativePtr);

  printf ("value = %x\n", *int_ptr);
}
#include <jni.h>
#include <stdio.h>
#include <stddef.h>
#include <limits.h>

/* On platforms where jbyte != signed char, you must
 * define JBYTE_IS_NOT_SIGNED_CHAR. 
 *
 * See the "test" function below that causes compiler
 * warnings when jbyte != signed char to remind you
 * of defining JBYTE_IS_NOT_SIGNED_CHAR in such case.
 *
 * On most platforms, this shouldn't matter.
 */

/* Uncomment the following if necessary. */
/* #define JBYTE_IS_NOT_SIGNED_CHAR 1 */

#ifndef JBYTE_IS_NOT_SIGNED_CHAR


/* Assuming that jbyte == signed char */

/* test function (unused).  This function will cause a compiler
 * warning when jbyte != signed char */
static void
test ()
{
  jbyte *j = NULL;

  /*
   * IMPORTANT
   * =========
   *
   * If you get a warning for the assignment below, you *MUST* define
   * JBYTE_IS_NOT_UNSIGNED_CHAR.
   */
  signed char *k = j;

  /* just to get rid of compile warnings */
  j = k;
  test ();
}

/* ----------------------------------------------------------------
   wrap: wraps a pointer into a jbyteArray in order to store in into a
   Java object instance.
   ---------------------------------------------------------------- */

inline static jbyteArray
wrap (JNIEnv *env, void *ptr)
{
  jbyteArray nativePtr;

  nativePtr = (*env)->NewByteArray (env, (jint) sizeof (void *));

  if (nativePtr == NULL)        /* Exception raised */
    return NULL;

  (*env)->SetByteArrayRegion (env, nativePtr, 0, (jint) sizeof (void *),
                              (jbyte *) &ptr);

  return nativePtr;
}

/* ----------------------------------------------------------------
   unwrap: unwraps a pointer stored in a jbyteArray.
   ---------------------------------------------------------------- */

inline static void *
unwrap (JNIEnv *env, jbyteArray nativePtr)
{
  void *ptr;

  (*env)->GetByteArrayRegion (env, nativePtr, 0, (jint) sizeof (void *),
                              (jbyte *) &ptr);

  return ptr;
}


#else /* JBYTE_IS_NOT_SIGNED_CHAR */


/* Assuming that jbyte != signed char */

#define PTRDIFF_BIT (sizeof(ptrdiff_t) * CHAR_BIT)
#define BARRAY_SIZE ((PTRDIFF_BIT + 7) / 8)

/* ----------------------------------------------------------------
   wrap: wraps a pointer into a jbyteArray in order to store in into a
   Java object instance.
   ---------------------------------------------------------------- */

inline static jbyteArray
wrap (JNIEnv *env, void *ptr)
{
  jbyteArray nativePtr;
  jbyte bytes[BARRAY_SIZE];

  /* make a robust integer out of pointer value */
  ptrdiff_t value = (char *) ptr - (char *) 0;
  size_t i;

  for (i = 0; i < BARRAY_SIZE; i++)
    {
      bytes[i] = (value & 0x0ff);
      value >>= 8;
    }

  nativePtr = (*env)->NewByteArray (env, (jint) BARRAY_SIZE);

  if (nativePtr == NULL)        /* Exception raised */
    return NULL;

  (*env)->SetByteArrayRegion (env, nativePtr, 0, (jint) BARRAY_SIZE, bytes);

  return nativePtr;
}

/* ----------------------------------------------------------------
   unwrap: unwraps a pointer stored in a jbyteArray.
   ---------------------------------------------------------------- */

inline static void *
unwrap (JNIEnv *env, jbyteArray nativePtr)
{
  jbyte bytes[BARRAY_SIZE];
  ptrdiff_t value = 0;
  size_t i;
  void *ptr;

  (*env)->GetByteArrayRegion (env, nativePtr, 0, (jint) BARRAY_SIZE, bytes);


  for (i = BARRAY_SIZE; i > 0; i--)
    {
      value <<= 8;
      value |= (bytes[i - 1] & 0x0ff);
    }

  /* retrieve pointer from robust integer */
  ptr = value + (char *) 0;
  return ptr;
}

#endif /* JBYTE_IS_NOT_SIGNED_CHAR */

reply via email to

[Prev in Thread] Current Thread [Next in Thread]