[kaffe] sysdepCallMethod() tests galore

Gwenole Beauchesne gbeauchesne at mandrakesoft.com
Mon May 26 07:28:01 PDT 2003


On Fri, 16 May 2003, Timothy Stack wrote:

> I'd like to add this to the test/internal directory, but I need to know 
> what a correct run is supposed to look like.  Can you send what the output 
> is supposed to look like, or better, make the test do the checks itself 
> with assert().

OK, I updated the tests with a few checks against the returned value 
through sysdepCallMethod, then abort() if that differs.

Steps to reproduce:
- Kaffe is configured
- Be in developers, and sh ./test_sysdepCallMethod.c ;-)
- ./test_sysdepCallMethod

[...]

# add_fidjffijddjjiidfd: f, 1, i, 2, d, 3, j, 4, f, 5, f, 6, i, 7, j, 8, 
d, 9, d, 10, j, 11, j, 12, i, 13, i, 14, d, 15, f, 16, d, 17 => i
returns: 153
returns: 153

However, I only tested that on IA-64 and AMD64 so some changes may be 
needed to accomodate other ports. Besides, I found some sort of TestNative 
in test/regression but I couldn't test it.

Bye,
Gwenole.
-------------- next part --------------
#if 0
exec ${CC:-gcc} $CFLAGS -I.. -I../include -I../config -I../kaffe $0 -o ${0%%.c}
#endif

#include <stdio.h>
#include <stdint.h>
#include <limits.h>
#include <float.h>
#include <math.h>

#define NEED_sysdepCallMethod 1
#include "kaffevm/gtypes.h"
#include "kaffevm/support.h"
#include "md.h"

static const char char_v = 'V';
static const char char_c = 'C';
static const char char_s = 'S';
static const char char_i = 'I';
static const char char_j = 'J';
static const char char_f = 'F';
static const char char_d = 'D';
#define JTYPECHAR(T) (char_##T)

static int argsize(char type) {
  int s = 0;
  switch (type) {
  case 'V':
    s = 0;
    break;
  case 'C':
  case 'S':
  case 'I':
  case 'F':
    s = 1;
    break;
  case 'J':
  case 'D':
    s = 2;
    break;
  default:
    abort();
  }
  return s;
}

static void print_jvalue(const char *msg, const jvalue *value, char type) {
  if (msg)
    printf("%s", msg);
  switch (type) {
  case 'V':
    printf("void");
    break;
  case 'C':
    printf("%c", value->c);
    break;
  case 'S':
    printf("%d", value->s);
    break;
  case 'I':
    printf("%d", value->i);
    break;
  case 'J':
    printf("%lld", value->j);
    break;
  case 'F':
    printf("%f", value->f);
    break;
  case 'D':
    printf("%lf", value->d);
    break;
  default:
    abort();
  }
}

#define CALL_INVOKE_DO_PREPARE_N(ARGNO, TYPE, VAL)	\
  args[ARGNO].TYPE = VAL;				\
  call.callsize[ARGNO] = argsize(JTYPECHAR(TYPE));	\
  call.calltype[ARGNO] = JTYPECHAR(TYPE);

#define CALL_INVOKE_PREPARE_0(...)		/* nothing */
#define CALL_INVOKE_PREPARE_1(TYPE, VAL, ...)	CALL_INVOKE_DO_PREPARE_N(0, TYPE, VAL)
#define CALL_INVOKE_PREPARE_2(TYPE, VAL, ...)	CALL_INVOKE_DO_PREPARE_N(1, TYPE, VAL); CALL_INVOKE_PREPARE_1(__VA_ARGS__)
#define CALL_INVOKE_PREPARE_3(TYPE, VAL, ...)	CALL_INVOKE_DO_PREPARE_N(2, TYPE, VAL); CALL_INVOKE_PREPARE_2(__VA_ARGS__)
#define CALL_INVOKE_PREPARE_4(TYPE, VAL, ...)	CALL_INVOKE_DO_PREPARE_N(3, TYPE, VAL); CALL_INVOKE_PREPARE_3(__VA_ARGS__)
#define CALL_INVOKE_PREPARE_5(TYPE, VAL, ...)	CALL_INVOKE_DO_PREPARE_N(4, TYPE, VAL); CALL_INVOKE_PREPARE_4(__VA_ARGS__)
#define CALL_INVOKE_PREPARE_6(TYPE, VAL, ...)	CALL_INVOKE_DO_PREPARE_N(5, TYPE, VAL); CALL_INVOKE_PREPARE_5(__VA_ARGS__)
#define CALL_INVOKE_PREPARE_7(TYPE, VAL, ...)	CALL_INVOKE_DO_PREPARE_N(6, TYPE, VAL); CALL_INVOKE_PREPARE_6(__VA_ARGS__)
#define CALL_INVOKE_PREPARE_8(TYPE, VAL, ...)	CALL_INVOKE_DO_PREPARE_N(7, TYPE, VAL); CALL_INVOKE_PREPARE_7(__VA_ARGS__)
#define CALL_INVOKE_PREPARE_9(TYPE, VAL, ...)	CALL_INVOKE_DO_PREPARE_N(8, TYPE, VAL); CALL_INVOKE_PREPARE_8(__VA_ARGS__)
#define CALL_INVOKE_PREPARE_10(TYPE, VAL, ...)	CALL_INVOKE_DO_PREPARE_N(9, TYPE, VAL); CALL_INVOKE_PREPARE_9(__VA_ARGS__)
#define CALL_INVOKE_PREPARE_11(TYPE, VAL, ...)	CALL_INVOKE_DO_PREPARE_N(10, TYPE, VAL); CALL_INVOKE_PREPARE_10(__VA_ARGS__)
#define CALL_INVOKE_PREPARE_12(TYPE, VAL, ...)	CALL_INVOKE_DO_PREPARE_N(11, TYPE, VAL); CALL_INVOKE_PREPARE_11(__VA_ARGS__)
#define CALL_INVOKE_PREPARE_13(TYPE, VAL, ...)	CALL_INVOKE_DO_PREPARE_N(12, TYPE, VAL); CALL_INVOKE_PREPARE_12(__VA_ARGS__)
#define CALL_INVOKE_PREPARE_14(TYPE, VAL, ...)	CALL_INVOKE_DO_PREPARE_N(13, TYPE, VAL); CALL_INVOKE_PREPARE_13(__VA_ARGS__)
#define CALL_INVOKE_PREPARE_15(TYPE, VAL, ...)	CALL_INVOKE_DO_PREPARE_N(14, TYPE, VAL); CALL_INVOKE_PREPARE_14(__VA_ARGS__)
#define CALL_INVOKE_PREPARE_16(TYPE, VAL, ...)	CALL_INVOKE_DO_PREPARE_N(15, TYPE, VAL); CALL_INVOKE_PREPARE_15(__VA_ARGS__)
#define CALL_INVOKE_PREPARE_17(TYPE, VAL, ...)	CALL_INVOKE_DO_PREPARE_N(16, TYPE, VAL); CALL_INVOKE_PREPARE_16(__VA_ARGS__)
#define CALL_INVOKE_PREPARE_18(TYPE, VAL, ...)	CALL_INVOKE_DO_PREPARE_N(17, TYPE, VAL); CALL_INVOKE_PREPARE_17(__VA_ARGS__)
#define CALL_INVOKE_PREPARE_19(TYPE, VAL, ...)	CALL_INVOKE_DO_PREPARE_N(18, TYPE, VAL); CALL_INVOKE_PREPARE_18(__VA_ARGS__)
#define CALL_INVOKE_PREPARE_20(TYPE, VAL, ...)	CALL_INVOKE_DO_PREPARE_N(19, TYPE, VAL); CALL_INVOKE_PREPARE_19(__VA_ARGS__)
#define CALL_INVOKE_PREPARE(NARGS, ...)		CALL_INVOKE_PREPARE_##NARGS(__VA_ARGS__)

#define SWAP(X, Y) do {				\
  typeof(X) T = X;				\
  X = Y;					\
  Y = T;					\
} while (0)

#define RETVAL_OK_v(RET, RETVAL)	1
#define RETVAL_OK_c(RET, RETVAL)	((RET).c == (RETVAL))
#define RETVAL_OK_s(RET, RETVAL)	((RET).s == (RETVAL))
#define RETVAL_OK_i(RET, RETVAL)	((RET).i == (RETVAL))
#define RETVAL_OK_j(RET, RETVAL)	((RET).j == (RETVAL))
#define RETVAL_OK_f(RET, RETVAL)	((RET).f == (RETVAL))
#define RETVAL_OK_d(RET, RETVAL)	((RET).d == (RETVAL))

#define CALL_INVOKE(FUNC, RETTYPE, RETVAL, NARGS, ...) do {	\
  jvalue args[NARGS];						\
  jvalue ret;							\
  callMethodInfo call;						\
  int i, s = 0;							\
  call.function = &FUNC;					\
  call.ret = &ret;						\
  call.retsize = argsize(JTYPECHAR(RETTYPE));			\
  call.rettype = JTYPECHAR(RETTYPE);				\
  call.nrargs = NARGS;						\
  call.args = args;						\
  CALL_INVOKE_PREPARE(NARGS, ##__VA_ARGS__, 1);			\
  for (i = 0; i < NARGS; i++)					\
    s += call.callsize[i];					\
  /* reverse arguments */					\
  for (i = 0; i < NARGS/2; i++) {				\
    const int x = i, y = NARGS - i - 1;				\
    SWAP(args[x], args[y]);					\
    SWAP(call.callsize[x], call.callsize[y]);			\
    SWAP(call.calltype[x], call.calltype[y]);			\
  }								\
  call.argsize = s;						\
  sysdepCallMethod(&call);					\
  print_jvalue("returns: ", &ret, call.rettype);		\
  if (call.rettype != 'V' && !RETVAL_OK_##RETTYPE(ret, RETVAL))	\
    abort();							\
  printf("\n");							\
} while (0)

#define CALL_DIRECT_EXPAND_0(...)		/* nothing */
#define CALL_DIRECT_EXPAND_1(TYPE, VAL)		VAL
#define CALL_DIRECT_EXPAND_2(TYPE, VAL, ...)	VAL, CALL_DIRECT_EXPAND_1(__VA_ARGS__)
#define CALL_DIRECT_EXPAND_3(TYPE, VAL, ...)	VAL, CALL_DIRECT_EXPAND_2(__VA_ARGS__)
#define CALL_DIRECT_EXPAND_4(TYPE, VAL, ...)	VAL, CALL_DIRECT_EXPAND_3(__VA_ARGS__)
#define CALL_DIRECT_EXPAND_5(TYPE, VAL, ...)	VAL, CALL_DIRECT_EXPAND_4(__VA_ARGS__)
#define CALL_DIRECT_EXPAND_6(TYPE, VAL, ...)	VAL, CALL_DIRECT_EXPAND_5(__VA_ARGS__)
#define CALL_DIRECT_EXPAND_7(TYPE, VAL, ...)	VAL, CALL_DIRECT_EXPAND_6(__VA_ARGS__)
#define CALL_DIRECT_EXPAND_8(TYPE, VAL, ...)	VAL, CALL_DIRECT_EXPAND_7(__VA_ARGS__)
#define CALL_DIRECT_EXPAND_9(TYPE, VAL, ...)	VAL, CALL_DIRECT_EXPAND_8(__VA_ARGS__)
#define CALL_DIRECT_EXPAND_10(TYPE, VAL, ...)	VAL, CALL_DIRECT_EXPAND_9(__VA_ARGS__)
#define CALL_DIRECT_EXPAND_11(TYPE, VAL, ...)	VAL, CALL_DIRECT_EXPAND_10(__VA_ARGS__)
#define CALL_DIRECT_EXPAND_12(TYPE, VAL, ...)	VAL, CALL_DIRECT_EXPAND_11(__VA_ARGS__)
#define CALL_DIRECT_EXPAND_13(TYPE, VAL, ...)	VAL, CALL_DIRECT_EXPAND_12(__VA_ARGS__)
#define CALL_DIRECT_EXPAND_14(TYPE, VAL, ...)	VAL, CALL_DIRECT_EXPAND_13(__VA_ARGS__)
#define CALL_DIRECT_EXPAND_15(TYPE, VAL, ...)	VAL, CALL_DIRECT_EXPAND_14(__VA_ARGS__)
#define CALL_DIRECT_EXPAND_16(TYPE, VAL, ...)	VAL, CALL_DIRECT_EXPAND_15(__VA_ARGS__)
#define CALL_DIRECT_EXPAND_17(TYPE, VAL, ...)	VAL, CALL_DIRECT_EXPAND_16(__VA_ARGS__)
#define CALL_DIRECT_EXPAND_18(TYPE, VAL, ...)	VAL, CALL_DIRECT_EXPAND_17(__VA_ARGS__)
#define CALL_DIRECT_EXPAND_19(TYPE, VAL, ...)	VAL, CALL_DIRECT_EXPAND_18(__VA_ARGS__)
#define CALL_DIRECT_EXPAND_20(TYPE, VAL, ...)	VAL, CALL_DIRECT_EXPAND_19(__VA_ARGS__)
#define CALL_DIRECT_ARGS(NARGS, ...)		CALL_DIRECT_EXPAND_##NARGS(__VA_ARGS__)

#define CALL_DIRECT_RET_v(RETVAL, TYPE, FUNC)	FUNC
#define CALL_DIRECT_RET_x(RETVAL, TYPE, FUNC)	RETVAL.TYPE = FUNC
#define CALL_DIRECT_RET_c			CALL_DIRECT_RET_x
#define CALL_DIRECT_RET_s			CALL_DIRECT_RET_x
#define CALL_DIRECT_RET_i			CALL_DIRECT_RET_x
#define CALL_DIRECT_RET_j			CALL_DIRECT_RET_x
#define CALL_DIRECT_RET_f			CALL_DIRECT_RET_x
#define CALL_DIRECT_RET_d			CALL_DIRECT_RET_x

#define DO_CALL_DIRECT(FUNC, RETVAL, RETTYPE, NARGS, ...) \
  CALL_DIRECT_RET_##RETTYPE(RETVAL, RETTYPE, FUNC)(CALL_DIRECT_ARGS(NARGS, __VA_ARGS__))

#define CALL_DIRECT(FUNC, RETTYPE, RETVAL, NARGS, ...) do {		\
  jvalue retval;							\
  char rettype = JTYPECHAR(RETTYPE);					\
  DO_CALL_DIRECT(FUNC, retval, RETTYPE, NARGS, __VA_ARGS__);		\
  print_jvalue("returns: ", &retval, rettype);				\
  printf("\n");								\
} while (0)

#define CALL(FUNC, RETTYPE, RETVAL, NARGS, ...)		      		\
  printf("# %s: %s => %s\n", #FUNC, #__VA_ARGS__, #RETTYPE);		\
  CALL_DIRECT(FUNC, RETTYPE, RETVAL, NARGS, __VA_ARGS__);		\
  CALL_INVOKE(FUNC, RETTYPE, RETVAL, NARGS, __VA_ARGS__);		\
  printf("\n");
  

static void f_v_v(void)
{
}

static void f_v_i(jint i)
{
  printf("%d\n", i);
}

static void f_v_ij(jint i, jlong j)
{
  printf("%d, %lld\n", i, j);
}

static void f_v_cij(jchar c, jint i, jlong j)
{
  printf("%c, %d, %lld\n", c, i, j);
}

static void f_v_csijfd(jchar c, jshort s, jint i, jlong j, jfloat f, jdouble d)
{
  printf("%c, %d, %d, %lld, %f, %lf\n", c, s, i, j, f, d);
}

static void f_v_ffffffffffffffff(jfloat p1, jfloat p2, jfloat p3, jfloat p4,
								 jfloat p5, jfloat p6, jfloat p7, jfloat p8,
								 jfloat p9, jfloat p10, jfloat p11, jfloat p12,
								 jfloat p13, jfloat p14, jfloat p15, jfloat p16)
{
  printf("%f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f\n",
		 p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16);
}

static void f_v_iiiiiiiiii(jint p1, jint p2, jint p3, jint p4, jint p5,
			   jint p6, jint p7, jint p8, jint p9, jint p10)
{
  printf("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n",
	 p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
}

static void f_v_fidjffijddjjiidfd(jfloat p1, jint p2, jdouble p3, jlong p4, jfloat p5,
				  jfloat p6, jint p7, jlong p8, jdouble p9, jdouble p10,
				  jlong p11, jlong p12, jint p13, jint p14, jdouble p15,
				  jfloat p16, jdouble p17)
{
  printf("%f, %d, %lf, %lld, %f, %f, %d, %lld, %lf, %lf, %lld, %lld, %d, %d, %lf, %f, %lf\n",
	 p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17);
}

static jchar f_c_c(jchar c)
{
  printf("%c\n", c);
  return c + 'A' - 'a';
}

static jshort f_s_ii(jint x, jint y)
{
  printf("%d, %d\n", x, y);
  return x + y;
}

static jint add_2i(jint p1, jint p2)
{
  printf("%d, %d\n", p1, p2);
  return p1 + p2;
}

static jlong add_2j(jlong p1, jlong p2)
{
  printf("%lld, %lld\n", p1, p2);
  return p1 + p2;
}

static jint add_12i(jint p1, jint p2, jint p3, jint p4,
		   jint p5, jint p6, jint p7, jint p8,
		   jint p9, jint p10, jint p11, jint p12)
{
  return p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9 + p10 + p11 + p12;
}

static jfloat add_2f(jfloat p1, jfloat p2)
{
  return p1 + p2;
}

static jfloat add_10f(jfloat p1, jfloat p2, jfloat p3, jfloat p4, jfloat p5,
		     jfloat p6, jfloat p7, jfloat p8, jfloat p9, jfloat p10) {
  return p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9 + p10;
}

static jdouble add_10d(jdouble p1, jdouble p2, jdouble p3, jdouble p4, jdouble p5,
		      jdouble p6, jdouble p7, jdouble p8, jdouble p9, jdouble p10) {
  return p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9 + p10;
}

static jfloat add_20f(jfloat p1, jfloat p2, jfloat p3, jfloat p4, jfloat p5,
		     jfloat p6, jfloat p7, jfloat p8, jfloat p9, jfloat p10,
		     jfloat p11, jfloat p12, jfloat p13, jfloat p14, jfloat p15,
		     jfloat p16, jfloat p17, jfloat p18, jfloat p19, jfloat p20)
{
  return p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9 + p10 + p11 + p12 + p13 +
    p14 + p15 + p16 + p17 + p18 + p19 + p20;
}

static jlong add_jijiijiiji(jlong p1, jint p2, jlong p3, jint p4, jint p5,
			    jlong p6, jint p7, jint p8, jlong p9, jint p10)
{
  return p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9 + p10;
}

static jlong add_ijijjijjij(jint p1, jlong p2, jint p3, jlong p4, jlong p5,
			    jint p6, jlong p7, jlong p8, jint p9, jlong p10)
{
  return p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9 + p10;
}

static jdouble add_ffddffddfdf(jfloat p1, jfloat p2, jdouble p3, jdouble p4,
			       jfloat p5, jfloat p6, jdouble p7, jdouble p8,
			       jfloat p9, jdouble p10, jfloat p11)
{
  return p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9 + p10 + p11;
}

static jint add_fidjffijddjjiidfd(jfloat p1, jint p2, jdouble p3, jlong p4, jfloat p5,
				  jfloat p6, jint p7, jlong p8, jdouble p9, jdouble p10,
				  jlong p11, jlong p12, jint p13, jint p14, jdouble p15,
				  jfloat p16, jdouble p17)
{
  return p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9
    + p10 + p11 + p12 + p13 + p14 + p15 + p16 + p17;
}

int main(void) {
  CALL(f_v_v, v, 0, 0);
  CALL(f_v_i, v, 0, 1, i, 1);
  CALL(f_v_ij, v, 0, 2, i, 1, j, 2);
  CALL(f_v_cij, v, 0, 3, c, 'c', i, 1, j, 2);
  CALL(f_v_csijfd, v, 0, 6, c, 'c', s, 16384, i, 1073741823, j, 4611686018427387903, f, 1.0, d, 3.14);
  CALL(f_c_c, c, 'Z', 1, c, 'z');
  CALL(f_s_ii, s, 3, 2, i, 1, i, 2);

  // print many ints
  CALL(f_v_iiiiiiiiii,
       v, 0,
       10,
       i, 1, i, 2, i, 3, i, 4, i, 5, i, 6, i, 7, i, 8, i, 9, i, 10);

  // print many floats
  CALL(f_v_ffffffffffffffff,
       v, 0,
       16,
       f, FLT_MIN, f, FLT_MAX, f, M_E, f, M_LOG2E, f, M_LOG10E,
       f, M_LN2, f, M_LN10, f, M_PI, f, M_PI_2, f, M_PI_4,
       f, M_1_PI, f, M_PI_2, f, FLT_MIN, f, FLT_MAX,
       f, M_SQRT2, f, M_SQRT1_2);

  // print mixed floats, doubles, ints and longs
  CALL(f_v_fidjffijddjjiidfd,
       v, 0,
       17,
       f, 1, i, 2, d, 3, j, 4, f, 5, f, 6, i, 7, j, 8, d, 9,
       d, 10, j, 11, j, 12, i, 13, i, 14, d, 15, f, 16, d, 17);

  // add two ints
  CALL(add_2i, i, 3, 2, i, 1, i, 2);

  // add two longs
  CALL(add_2j, j, 3, 2, j, 1, j, 2);

  // add many ints
  CALL(add_12i, i, 78, 12, i, 1, i, 2, i, 3, i, 4, i, 5, i, 6, i, 7, i, 8, i, 9, i, 10, i, 11, i, 12);

  // add two floats
  CALL(add_2f, f, 3.0, 2, f, 1.0, f, 2.0);

  // add many floats
  CALL(add_10f,
       f, 55.0,
       10,
       f, 1, f, 2, f, 3, f, 4, f, 5, f, 6, f, 7, f, 8, f, 9, f, 10);

  // add many doubles
  CALL(add_10d,
       d, 55,
       10,
       d, 1, d, 2, d, 3, d, 4, d, 5, d, 6, d, 7, d, 8, d, 9, d, 10);

  // add many many floats
  CALL(add_20f,
       f, 210,
       20,
       f, 1, f, 2, f, 3, f, 4, f, 5, f, 6, f, 7, f, 8, f, 9, f, 10,
       f, 11, f, 12, f, 13, f, 14, f, 15, f, 16, f, 17, f, 18, f, 19, f, 20);

  // add mixed ints
  CALL(add_jijiijiiji,
       j, 55,
       10,
       j, 1, i, 2, j, 3, i, 4, i, 5, j, 6, i, 7, i, 8, j, 9, i, 10);

  // add mixed ints 2
  CALL(add_ijijjijjij,
       j, 55,
       10,
       i, 1, j, 2, i, 3, j, 4, j, 5, i, 6, j, 7, j, 8, i, 9, j, 10);

  // add mixed floats
  CALL(add_ffddffddfdf,
       d, 66,
       11,
       f, 1, f, 2, d, 3, d, 4, f, 5, f, 6, d, 7, d, 8, f, 9, d, 10, f, 11);

  // add mixed floats, doubles, ints and longs
  CALL(add_fidjffijddjjiidfd,
       i, 153,
       17,
       f, 1, i, 2, d, 3, j, 4, f, 5, f, 6, i, 7, j, 8, d, 9,
       d, 10, j, 11, j, 12, i, 13, i, 14, d, 15, f, 16, d, 17);
}


More information about the kaffe mailing list