cvsuser 02/12/03 02:42:10
Modified: . MANIFEST build_nativecall.pl
jit/i386 jit_emit.h
include/parrot jit.h
t/pmc nci.t
Added: . nci_test.c libnci.def
Log:
integration of native nci build_call_func for i386
Revision Changes Path
1.265 +2 -0 parrot/MANIFEST
Index: MANIFEST
===================================================================
RCS file: /cvs/public/parrot/MANIFEST,v
retrieving revision 1.264
retrieving revision 1.265
diff -u -w -r1.264 -r1.265
--- MANIFEST 30 Nov 2002 16:36:17 -0000 1.264
+++ MANIFEST 3 Dec 2002 10:42:05 -0000 1.265
@@ -1571,6 +1571,7 @@
lib/Test/More.pm
lib/Test/Simple.pm
lib/Text/Balanced.pm
+libnci.def
list.c
make.pl
malloc.c
@@ -1579,6 +1580,7 @@
memory.c
method_util.c
misc.c
+nci_test.c
obscure.ops
ops2c.pl
ops2cgc.pl
1.6 +9 -2 parrot/build_nativecall.pl
Index: build_nativecall.pl
===================================================================
RCS file: /cvs/public/parrot/build_nativecall.pl,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -w -r1.5 -r1.6
--- build_nativecall.pl 30 Nov 2002 03:12:07 -0000 1.5
+++ build_nativecall.pl 3 Dec 2002 10:42:05 -0000 1.6
@@ -65,7 +65,7 @@
/* nci.c
* Copyright: 2001, 2002 Yet Another Society
* CVS Info
- * $Id: build_nativecall.pl,v 1.5 2002/11/30 03:12:07 josh Exp $
+ * $Id: build_nativecall.pl,v 1.6 2002/12/03 10:42:05 leo Exp $
* Overview:
* Native Call Interface routines. The code needed to build a
* parrot to C call frame is in here
@@ -90,6 +90,11 @@
#define PMC_REG(x) interpreter->ctx.pmc_reg.registers[x]
#endif
+#if defined(HAS_JIT) && defined(I386)
+# include "parrot/jit.h"
+# define CAN_BUILD_CALL_FRAMES
+#endif
+
#if !defined(CAN_BUILD_CALL_FRAMES)
/* All our static functions that call in various ways. Yes, terribly
hackish, but that's just fine */
@@ -139,7 +144,9 @@
#if defined(CAN_BUILD_CALL_FRAMES)
/* This would be a good place to put the code that builds the
frames. Undoubtedly painfully platform-dependent */
- abort("Oh, no you can't!");
+
+ return Parrot_jit_build_call_func(interpreter, signature);
+
#else
/* And in here is the platform-independent way. Which is to say
"here there be hacks" */
1.1 parrot/nci_test.c
Index: nci_test.c
===================================================================
#include <stdio.h>
/*
* cc -shared -fpic nci_test.c -o libnci.so -g
* export LD_LIBRARY_PATH=.
*/
double nci_dd(double d) {
return d * 2.0;
}
short nci_ssc(short l1, char l2) {
return l1 * l2;
}
int nci_csc(short l1, char l2) {
return l1 * l2;
}
int nci_isc(short l1, char l2) {
return l1 * l2;
}
float nci_fff(float l1, float l2) {
return l1 * l2;
}
/* test calls this with a string */
int nci_ip(void *p) {
printf("%c%c\n", (*(char**) p)[1], (*(char **) p)[0]);
return 2;
}
int nci_it(void *p) {
printf("%c%c\n", ((char*) p)[1], ((char *) p)[0]);
return 2;
}
static char s[] = "xx worked\n";
char *nci_tt(void *p) {
s[0] = ((char*) p)[1];
s[1] = ((char*) p)[0];
return s;
}
void * nci_pp(void *p) {
return p;
}
#ifdef TEST
char l2 = 4;
float f2 = 4.0;
int main() {
short l1 = 3;
float f, f1 = 3.0;
int l = nci_ssc(l1, l2);
printf("%d\n", l);
f = nci_fff(f1, f2);
printf("%f\n", f);
return 0;
}
#endif
1.1 parrot/libnci.def
Index: libnci.def
===================================================================
LIBRARY libnci
DESCRIPTION 'Parrot nci test support lib'
EXPORTS
nci_dd
nci_ssc
nci_csc
nci_isc
nci_fff
nci_ip
nci_it
nci_tt
nci_pp
1.39 +27 -4 parrot/jit/i386/jit_emit.h
Index: jit_emit.h
===================================================================
RCS file: /cvs/public/parrot/jit/i386/jit_emit.h,v
retrieving revision 1.38
retrieving revision 1.39
diff -u -w -r1.38 -r1.39
--- jit_emit.h 2 Dec 2002 16:45:21 -0000 1.38
+++ jit_emit.h 3 Dec 2002 10:42:07 -0000 1.39
@@ -3,7 +3,7 @@
*
* i386
*
- * $Id: jit_emit.h,v 1.38 2002/12/02 16:45:21 leo Exp $
+ * $Id: jit_emit.h,v 1.39 2002/12/03 10:42:07 leo Exp $
*/
#include <assert.h>
@@ -2034,6 +2034,7 @@
char *sig, *pc;
int next_n = 5;
int next_p = 5;
+ int next_s = 5;
int next_i = 5;
int st = 0;
@@ -2091,6 +2092,14 @@
case 'v':
st -= 4; /* undo default stack usage */
break;
+ case 't': /* string, pass a cstring */
+ jit_emit_mov_rm_i(pc, emit_EAX, &STR_REG(next_s++));
+ emitm_pushl_r(pc, emit_EAX);
+ emitm_pushl_i(pc, interpreter);
+ emitm_calll(pc, (char*)string_to_cstring - pc - 4);
+ emitm_addb_i_r(pc, 8, emit_ESP);
+ emitm_pushl_r(pc, emit_EAX);
+ break;
default:
internal_exception(1,
"Parrot_jit_build_call_func: unimp argument\n");
@@ -2110,7 +2119,7 @@
emitm_addb_i_r(pc, st, emit_ESP);
/* now place return value in registers */
- next_i = next_n = next_p = 5;
+ next_i = next_n = next_p = next_s = 5;
/* first in signature is the return value */
switch (*sig) {
case 'f':
@@ -2149,6 +2158,20 @@
offsetof(struct PMC, data));
jit_emit_mov_mr_i(pc, &PMC_REG(next_p++), emit_EAX);
break;
+ case 't': /* string, determine length, make string */
+ emitm_pushl_i(pc, 0);
+ emitm_pushl_i(pc, 0);
+ emitm_pushl_i(pc, 0);
+ emitm_pushl_r(pc, emit_EAX);
+ emitm_calll(pc, (char*)strlen - pc - 4);
+ emitm_popl_r(pc, emit_EDX);
+ emitm_pushl_r(pc, emit_EAX);
+ emitm_pushl_r(pc, emit_EDX);
+ emitm_pushl_i(pc, interpreter);
+ emitm_calll(pc, (char*)string_make - pc - 4);
+ emitm_addb_i_r(pc, 24, emit_ESP);
+ jit_emit_mov_mr_i(pc, &STR_REG(next_s++), emit_EAX);
+ break;
default:
internal_exception(1,
"Parrot_jit_build_call_func: unimp return value\n");
@@ -2158,7 +2181,7 @@
jit_emit_mov_mi_i(pc, &INT_REG(0), 0);
/* set return values in I,S,P,N regs */
jit_emit_mov_mi_i(pc, &INT_REG(1), next_i-5);
- jit_emit_mov_mi_i(pc, &INT_REG(2), 0);
+ jit_emit_mov_mi_i(pc, &INT_REG(2), next_s-5);
jit_emit_mov_mi_i(pc, &INT_REG(3), next_p-5);
jit_emit_mov_mi_i(pc, &INT_REG(4), next_n-5);
1.29 +3 -1 parrot/include/parrot/jit.h
Index: jit.h
===================================================================
RCS file: /cvs/public/parrot/include/parrot/jit.h,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -w -r1.28 -r1.29
--- jit.h 29 Nov 2002 09:00:23 -0000 1.28
+++ jit.h 3 Dec 2002 10:42:08 -0000 1.29
@@ -1,7 +1,7 @@
/*
* jit.h
*
- * $Id: jit.h,v 1.28 2002/11/29 09:00:23 leo Exp $
+ * $Id: jit.h,v 1.29 2002/12/03 10:42:08 leo Exp $
*/
#ifndef JIT_H_GUARD
@@ -231,6 +231,8 @@
struct Parrot_Interp *interpreter, int reg, char *mem);
void Parrot_jit_emit_mov_rm(
struct Parrot_Interp *interpreter, int reg, char *mem);
+
+void *Parrot_jit_build_call_func(struct Parrot_Interp *, String *signature);
#endif /* JIT_H_GUARD */
1.3 +277 -9 parrot/t/pmc/nci.t
Index: nci.t
===================================================================
RCS file: /cvs/public/parrot/t/pmc/nci.t,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -w -r1.2 -r1.3
--- nci.t 30 Nov 2002 10:16:44 -0000 1.2
+++ nci.t 3 Dec 2002 10:42:10 -0000 1.3
@@ -1,19 +1,63 @@
-use Parrot::Test tests => 1;
+use Parrot::Test tests => 9;
+use Test::More qw/skip/;
+use Parrot::Config;
-TODO: {
- local $TODO="t/pmc/nci doesn't work on Windows" if $^O =~ /Win32/;
- $TODO=$TODO; #warnings
+SKIP: {
+if ($PConfig{jitcpuarch} eq 'i386' && -e "libnci" . $PConfig{so}) {
+ $ENV{LD_LIBRARY_PATH} = '.';
+}
+else {
+ skip('needs jit/i386 and libnci'.$PConfig{so}, 9);
+}
-output_is(<<'CODE', <<'OUTPUT', "nic_d_d");
- loadlib P1, "libm.so"
+sub gen_test($) {
+ local $_ = shift;
+ s/\.so/$PConfig{so}/;
+ $_;
+}
+
+output_is(gen_test(<<'CODE'), <<'OUTPUT', "nci_d_d");
+ loadlib P1, "libnci.so"
+ print "loaded\n"
+ dlfunc P0, P1, "nci_dd", "dd"
+ print "dlfunced\n"
+ set I0, 1 # prototype used - unchecked
+ set I1, 0 # items on stack - unchecked
+ set N5, 4.0
+ invoke
+ ne N5, 8.0, nok_1
+ print "ok 1\n"
+ ne I0, 0, nok_2 # test return value convention
+ ne I1, 0, nok_2
+ ne I2, 0, nok_2
+ ne I3, 0, nok_2
+ ne I4, 1, nok_2
+ print "ok 2\n"
+ end
+nok_1: print "nok 1\n"
+ print N5
+ print "\n"
+ end
+nok_2: print "nok 2\n"
+ end
+CODE
+loaded
+dlfunced
+ok 1
+ok 2
+OUTPUT
+
+output_is(<<'CODE', <<'OUTPUT', "nci_f_ff");
+ loadlib P1, "libnci.so"
print "loaded\n"
- dlfunc P0, P1, "sqrt", "dd"
+ dlfunc P0, P1, "nci_fff", "fff"
print "dlfunced\n"
set I0, 1 # prototype used - unchecked
set I1, 0 # items on stack - unchecked
set N5, 4.0
+ set N6, 3.0
invoke
- ne N5, 2.0, nok_1
+ ne N5, 12.0, nok_1
print "ok 1\n"
ne I0, 0, nok_2 # test return value convention
ne I1, 0, nok_2
@@ -35,6 +79,230 @@
ok 2
OUTPUT
+output_is(<<'CODE', <<'OUTPUT', "nci_i_sc");
+ loadlib P1, "libnci.so"
+ print "loaded\n"
+ dlfunc P0, P1, "nci_isc", "isc"
+ print "dlfunced\n"
+ set I0, 1 # prototype used - unchecked
+ set I1, 0 # items on stack - unchecked
+ set I5, 2
+ set I6, 3
+ invoke
+ ne I5, 6, nok_1
+ print "ok 1\n"
+ ne I0, 0, nok_2 # test return value convention
+ ne I1, 1, nok_2
+ ne I2, 0, nok_2
+ ne I3, 0, nok_2
+ ne I4, 0, nok_2
+ print "ok 2\n"
+ end
+nok_1: print "nok 1\n"
+ print I5
+ print "\n"
+ end
+nok_2: print "nok 2\n"
+ end
+CODE
+loaded
+dlfunced
+ok 1
+ok 2
+OUTPUT
+
+
+output_is(<<'CODE', <<'OUTPUT', "nci_s_sc");
+ loadlib P1, "libnci.so"
+ print "loaded\n"
+ dlfunc P0, P1, "nci_ssc", "ssc"
+ print "dlfunced\n"
+ set I0, 1 # prototype used - unchecked
+ set I1, 0 # items on stack - unchecked
+ set I5, 2
+ set I6, 3
+ invoke
+ ne I5, 6, nok_1
+ print "ok 1\n"
+ ne I0, 0, nok_2 # test return value convention
+ ne I1, 1, nok_2
+ ne I2, 0, nok_2
+ ne I3, 0, nok_2
+ ne I4, 0, nok_2
+ print "ok 2\n"
+ end
+nok_1: print "nok 1\n"
+ print I5
+ print "\n"
+ end
+nok_2: print "nok 2\n"
+ end
+CODE
+loaded
+dlfunced
+ok 1
+ok 2
+OUTPUT
+
+output_is(<<'CODE', <<'OUTPUT', "nci_c_sc");
+ loadlib P1, "libnci.so"
+ print "loaded\n"
+ dlfunc P0, P1, "nci_csc", "csc"
+ print "dlfunced\n"
+ set I0, 1 # prototype used - unchecked
+ set I1, 0 # items on stack - unchecked
+ set I5, 64
+ set I6, 2
+ invoke
+ ne I5, -128, nok_1
+ print "ok 1\n"
+ ne I0, 0, nok_2 # test return value convention
+ ne I1, 1, nok_2
+ ne I2, 0, nok_2
+ ne I3, 0, nok_2
+ ne I4, 0, nok_2
+ print "ok 2\n"
+ end
+nok_1: print "nok 1\n"
+ print I5
+ print "\n"
+ end
+nok_2: print "nok 2\n"
+ end
+CODE
+loaded
+dlfunced
+ok 1
+ok 2
+OUTPUT
+
+output_is(<<'CODE', <<'OUTPUT', "nci_i_p");
+ loadlib P1, "libnci.so"
+ print "loaded\n"
+ dlfunc P0, P1, "nci_ip", "ip"
+ print "dlfunced\n"
+ set I0, 1 # prototype used - unchecked
+ set I1, 0 # items on stack - unchecked
+ new P5, .PerlString
+ set P5, "ko\n"
+ invoke
+ ne I5, 2, nok_1
+ ne I0, 0, nok_2 # test return value convention
+ ne I1, 1, nok_2
+ ne I2, 0, nok_2
+ ne I3, 0, nok_2
+ ne I4, 0, nok_2
+ print "ok 2\n"
+ end
+nok_1: print "nok 1\n"
+ print I5
+ print "\n"
+ end
+nok_2: print "nok 2\n"
+ end
+CODE
+loaded
+dlfunced
+ok
+ok 2
+OUTPUT
+
+output_is(<<'CODE', <<'OUTPUT', "nci_p_p");
+ loadlib P1, "libnci.so"
+ print "loaded\n"
+ dlfunc P0, P1, "nci_pp", "pp"
+ print "dlfunced\n"
+ set I0, 1 # prototype used - unchecked
+ set I1, 0 # items on stack - unchecked
+ new P5, .PerlString
+ set P5, "ko\n"
+ invoke # cant test ret value yet, print it
+ dlfunc P0, P1, "nci_ip", "ip"
+ print "dlfunced\n"
+ invoke
+ ne I5, 2, nok_1
+ ne I0, 0, nok_2 # test return value convention
+ ne I1, 1, nok_2
+ ne I2, 0, nok_2
+ ne I3, 0, nok_2
+ ne I4, 0, nok_2
+ print "ok 2\n"
+ end
+nok_1: print "nok 1\n"
+ print I5
+ print "\n"
+ end
+nok_2: print "nok 2\n"
+ end
+CODE
+loaded
+dlfunced
+dlfunced
+ok
+ok 2
+OUTPUT
+
+output_is(<<'CODE', <<'OUTPUT', "nci_i_t");
+ loadlib P1, "libnci.so"
+ print "loaded\n"
+ dlfunc P0, P1, "nci_it", "it"
+ print "dlfunced\n"
+ set I0, 1 # prototype used - unchecked
+ set I1, 0 # items on stack - unchecked
+ set S5, "ko\n"
+ invoke
+ ne I5, 2, nok_1
+ ne I0, 0, nok_2 # test return value convention
+ ne I1, 1, nok_2
+ ne I2, 0, nok_2
+ ne I3, 0, nok_2
+ ne I4, 0, nok_2
+ print "ok 2\n"
+ end
+nok_1: print "nok 1\n"
+ print I5
+ print "\n"
+ end
+nok_2: print "nok 2\n"
+ end
+CODE
+loaded
+dlfunced
+ok
+ok 2
+OUTPUT
+
+output_is(<<'CODE', <<'OUTPUT', "nci_t_t");
+ loadlib P1, "libnci.so"
+ print "loaded\n"
+ dlfunc P0, P1, "nci_tt", "tt"
+ print "dlfunced\n"
+ set I0, 1 # prototype used - unchecked
+ set I1, 0 # items on stack - unchecked
+ set S5, "ko\n"
+ invoke
+ print S5
+ ne I0, 0, nok_2 # test return value convention
+ ne I1, 0, nok_2
+ ne I2, 1, nok_2
+ ne I3, 0, nok_2
+ ne I4, 0, nok_2
+ print "ok 2\n"
+ end
+nok_1: print "nok 1\n"
+ print I5
+ print "\n"
+ end
+nok_2: print "nok 2\n"
+ end
+CODE
+loaded
+dlfunced
+ok worked
+ok 2
+OUTPUT
+
+}
-} # TODO
+1;