All -- I've been tinkering with loading oplibs via dlopen(). This patch works on one of my test machines, although I'd expect your mileage to vary somewhat.
You may have to play with your LD_LIBRARY_PATH environment variable to get the libcore_ops.so file findable by dlopen(). I had to add '.' to it. Anyway, if we can make a version of this that actually works on all the target platforms, then we can work on the structures necessary to allow us to open multiple oplibs and to create merged opfunc and opinfo tables from them. Comments? Suggestions? Critiques? Regards, -- Gregor
? t/op/integer2.out ? t/op/integer2.pasm Index: Makefile.in =================================================================== RCS file: /home/perlcvs/parrot/Makefile.in,v retrieving revision 1.35 diff -a -u -r1.35 Makefile.in --- Makefile.in 2001/10/18 11:33:47 1.35 +++ Makefile.in 2001/10/20 14:28:59 @@ -9,10 +9,12 @@ $(INC)/global_setup.h $(INC)/vtable.h $(INC)/oplib/core_ops.h \ $(INC)/runops_cores.h $(INC)/trace.h $(INC)/oplib/vtable_ops.h +STRING_OBJS=string$(O) strnative$(O) strutf8$(O) strutf16$(O) strutf32$(O) \ +transcode$(O) + O_FILES = global_setup$(O) interpreter$(O) parrot$(O) register$(O) \ -core_ops$(O) memory$(O) packfile$(O) stacks$(O) string$(O) strnative$(O) \ -strutf8$(O) strutf16$(O) strutf32$(O) transcode$(O) runops_cores$(O) \ -trace$(O) vtable_ops$(O) +core_ops$(O) memory$(O) packfile$(O) stacks$(O) runops_cores$(O) \ +trace$(O) vtable_ops$(O) $(STRING_OBJS) #DO NOT ADD C COMPILER FLAGS HERE #Add them in Configure.pl--look for the @@ -39,8 +41,14 @@ libparrot.so: $(O_FILES) $(CC) -shared $(C_LIBS) -o $@ $(O_FILES) +libcore_ops.so: core_ops$(O) + $(CC) -shared -o $@ core_ops$(O) + +libparrot_string.so: $(STRING_OBJS) + $(CC) -shared -o $@ $(STRING_OBJS) + $(TEST_PROG): test_main$(O) $(O_FILES) Parrot/OpLib/core.pm - $(CC) $(CFLAGS) -o $(TEST_PROG) $(O_FILES) test_main$(O) $(C_LIBS) + $(CC) -rdynamic $(CFLAGS) -o $(TEST_PROG) $(O_FILES) test_main$(O) $(C_LIBS) +-ldl $(PDUMP): pdump$(O) packfile$(O) memory$(O) global_setup$(O) string$(O) strnative$(O) strutf8$(O) strutf16$(O) strutf32$(O) transcode$(O) $(CC) $(CFLAGS) -o $(PDUMP) pdump$(O) packfile$(O) memory$(O) global_setup$(O) string$(O) strnative$(O) strutf8$(O) strutf16$(O) strutf32$(O) transcode$(O) $(C_LIBS) Index: interpreter.c =================================================================== RCS file: /home/perlcvs/parrot/interpreter.c,v retrieving revision 1.32 diff -a -u -r1.32 interpreter.c --- interpreter.c 2001/10/18 01:15:11 1.32 +++ interpreter.c 2001/10/20 14:28:59 @@ -12,10 +12,15 @@ #include "parrot/parrot.h" #include "parrot/interp_guts.h" -#include "parrot/oplib/core_ops.h" +/* #include "parrot/oplib/core_ops.h" */ #include "parrot/runops_cores.h" +#include "parrot/op.h" +#include <dlfcn.h> +#define OP_LIB "core_ops" + + /*=for api interpreter check_fingerprint * TODO: Not really part of the API, but here's the docs. * Check the bytecode's opcode table fingerprint. @@ -100,10 +105,10 @@ int i; if (interpreter->profile == NULL) { - interpreter->profile = (INTVAL *)mem_sys_allocate(core_numops * sizeof(INTVAL)); + interpreter->profile = (INTVAL *)mem_sys_allocate(interpreter->numops +* sizeof(INTVAL)); } - for (i = 0; i < core_numops; i++) { + for (i = 0; i < interpreter->numops; i++) { interpreter->profile[i] = 0; } } @@ -117,7 +122,10 @@ */ struct Parrot_Interp * make_interpreter() { - struct Parrot_Interp *interpreter; + struct Parrot_Interp * interpreter; + void * oplib_handle; + INTVAL * numops_ptr; + /* Get an empty interpreter from system memory */ interpreter = mem_sys_allocate((INTVAL)sizeof(struct Parrot_Interp)); /* Set up the memory allocation system */ @@ -179,10 +187,41 @@ /* Need an empty stash */ interpreter->perl_stash = mem_allocate_new_stash(); - /* Load the core op func and info tables */ + /* Load the oplib */ + + oplib_handle = dlopen("libcore_ops.so", RTLD_LAZY); + if (oplib_handle == NULL) { + fprintf(stderr, "parrot: Unable to open 'libcore_ops.so' library: %s.\n", +dlerror()); + exit(1); + } + + numops_ptr = dlsym(oplib_handle, "core_numops"); + + if (numops_ptr == NULL) { + fprintf(stderr, "parrot: Unable to locate 'core_numops' member: %s.\n", +dlerror()); + dlclose(oplib_handle); + exit(1); + } + + interpreter->numops = *numops_ptr; + + interpreter->opcode_funcs = dlsym(oplib_handle, "core_opfunc"); + + if (interpreter->opcode_funcs == NULL) { + fprintf(stderr, "parrot: Unable to locate 'core_opfunc' member: %s.\n", +dlerror()); + dlclose(oplib_handle); + exit(1); + } + + interpreter->opcode_info = dlsym(oplib_handle, "core_opinfo"); + + if (interpreter->opcode_info == NULL) { + fprintf(stderr, "parrot: Unable to locate 'core_opinfo' member: %s.\n", +dlerror()); + dlclose(oplib_handle); + exit(1); + } - interpreter->opcode_funcs = core_opfunc; - interpreter->opcode_info = core_opinfo; +/* dlclose(oplib_handle); */ /* In case the I/O system needs something */ Init_IO(interpreter); Index: include/parrot/interpreter.h =================================================================== RCS file: /home/perlcvs/parrot/include/parrot/interpreter.h,v retrieving revision 1.12 diff -a -u -r1.12 interpreter.h --- include/parrot/interpreter.h 2001/10/18 01:15:11 1.12 +++ include/parrot/interpreter.h 2001/10/20 14:28:59 @@ -33,8 +33,10 @@ struct Arenas *arena_base; /* Pointer to this */ /* interpreter's arena */ + INTVAL numops; /* The number of opcodes */ op_info_t * opcode_info; /* Opcode info table (name, nargs, arg types) */ opcode_t *(**opcode_funcs)(); /* Opcode function table */ + STRING_FUNCS *(**string_funcs)(); /* String function table */ INTVAL flags; /* Various interpreter flags that signal that runops