This (rather large) set of patches adds the ability for parrot to use multiple operation libraries. It's currently adding 'obscure.ops' and 'vtable.ops' to the list of operations the interpreter can perform, though vtable.ops is not tested for obvious reasons.
While this likely should be done in the future with some sort of standalone compilation tool that builds libobscure.so &c, this will at least provide some sort of basic mechanism to let us test vtable operations once they're fully implemented. I've added a test for 'covers' from obscure.ops in t/op/trans.t to prove that the new optable is being included. Modified files: Makefile.in - Modified to link obscure_ops.o and vtable_ops.o in. Parrot/Assembler.pm - Altered patch that was previously posted to unify opcode entries disassemble.pl - Add Parrot::OpLib::{obscure.vtable} and add the new opcode lists. interpreter.h - Add 'destroy_interpreter(struct Parrot_Interp*)' to do final GC on the data structure that's been allocated inside the interpreter. interpreter.c - Change interpreter->opfunc and interpreter->opinfo to be dynamically allocated, so that more than one op table can be added. Also add code to do the copying. pbc2c.pl - Add the other opfiles here. t/op/trans.t - Add a test for 'covers', which is in the obscure.ops file test_main.c - Make sure the interpreter is destroyed *** WARNINGS Makefile.in - It's somewhat silly to have to modify three different points in the makefile to add the necessary dependencies, and this should probably be set up dynamically by the Configure.pl script or the like. Parrot/Assembler.pm - The patch might cause a problem should Parrot::OpLib::*::ops be used elsewhere. interpreter.c - The memory allocation should likely be done elsewhere. Currently it's done inside make_interpreter, and it should be factored out into a different function. pbc2c.pl - The patch breaks encapsulation by altering the {CODE} hash keys inside the OpsFile object -- --Jeff <[EMAIL PROTECTED]>
diff -ru parrot_orig/Makefile.in parrot/Makefile.in --- parrot_orig/Makefile.in Fri Nov 2 07:11:15 2001 +++ parrot/Makefile.in Sat Nov 3 23:59:22 2001 @@ -3,16 +3,22 @@ INC=include/parrot +OP_H_FILES = $(INC)/oplib/core_ops.h $(INC)/oplib/obscure_ops.h +$(INC)/oplib/vtable_ops.h +OP_O_FILES = core_ops$(O) obscure_ops$(O) vtable_ops$(O) +OP_PM_FILES = Parrot/OpLib/core.pm Parrot/OpLib/obscure.pm Parrot/OpLib/vtable.pm + H_FILES = $(INC)/config.h $(INC)/exceptions.h $(INC)/io.h $(INC)/op.h \ $(INC)/register.h $(INC)/string.h $(INC)/events.h $(INC)/interpreter.h \ $(INC)/memory.h $(INC)/parrot.h $(INC)/stacks.h $(INC)/packfile.h \ -$(INC)/global_setup.h $(INC)/vtable.h $(INC)/oplib/core_ops.h \ -$(INC)/runops_cores.h $(INC)/trace.h $(INC)/oplib/vtable_ops.h \ +$(INC)/global_setup.h $(INC)/vtable.h \ +$(OP_H_FILES) \ +$(INC)/runops_cores.h $(INC)/trace.h \ $(INC)/pmc.h $(INC)/resources.h $(INC)/platform.h O_FILES = global_setup$(O) interpreter$(O) parrot$(O) register$(O) \ -core_ops$(O) memory$(O) packfile$(O) stacks$(O) string$(O) encoding$(O) \ -chartype$(O) runops_cores$(O) trace$(O) vtable_ops$(O) classes/intclass$(O) \ +memory$(O) packfile$(O) stacks$(O) string$(O) encoding$(O) \ +$(OP_O_FILES) \ +chartype$(O) runops_cores$(O) trace$(O) classes/intclass$(O) \ encodings/singlebyte$(O) encodings/utf8$(O) encodings/utf16$(O) \ encodings/utf32$(O) chartypes/unicode$(O) chartypes/usascii$(O) resources$(O) \ platform$(O) @@ -42,7 +48,7 @@ libparrot.so: $(O_FILES) $(CC) -shared $(C_LIBS) -o $@ $(O_FILES) -$(TEST_PROG): test_main$(O) $(O_FILES) Parrot/OpLib/core.pm +$(TEST_PROG): test_main$(O) $(O_FILES) $(OP_PM_FILES) $(CC) $(CFLAGS) -o $(TEST_PROG) $(O_FILES) test_main$(O) $(C_LIBS) $(PDUMP): pdump$(O) $(O_FILES) @@ -56,8 +62,11 @@ Parrot/OpLib/core.pm: core.ops ops2pm.pl $(PERL) ops2pm.pl core.ops +Parrot/OpLib/obscure.pm: obscure.ops ops2pm.pl + $(PERL) ops2pm.pl obscure.ops + Parrot/OpLib/vtable.pm: vtable.ops ops2pm.pl - $(PERL) ops2pm.pl vtabls.ops + $(PERL) ops2pm.pl vtable.ops examples/assembly/mops.c: examples/assembly/mops.pbc pbc2c.pl $(PERL) pbc2c.pl examples/assembly/mops.pbc > examples/assembly/mops.c @@ -103,9 +112,14 @@ core_ops$(O): $(H_FILES) core_ops.c +obscure_ops$(O): $(H_FILES) obscure_ops.c + core_ops.c $(INC)/oplib/core_ops.h: core.ops ops2c.pl $(PERL) ops2c.pl core.ops +obscure_ops.c $(INC)/oplib/obscure_ops.h: obscure.ops ops2c.pl + $(PERL) ops2c.pl obscure.ops + vtable.ops: make_vtable_ops.pl $(PERL) make_vtable_ops.pl > vtable.ops @@ -130,14 +144,14 @@ cd docs; make clean: - $(RM_F) *$(O) *.s core_ops.c $(TEST_PROG) $(PDISASM) $(PDUMP) + $(RM_F) *$(O) *.s $(OP_C_FILES) $(TEST_PROG) $(PDISASM) $(PDUMP) $(RM_F) $(INC)/vtable.h - $(RM_F) $(INC)/oplib/core_ops.h - $(RM_F) $(INC)/oplib/vtable_ops.h vtable_ops.c vtable.ops + $(RM_F) $(OP_H_FILES) + $(RM_F) vtable.ops $(RM_F) $(TEST_PROG) $(PDISASM) $(PDUMP) $(RM_F) examples/assembly/mops$(EXE) examples/assembly/mops.c $(RM_F) examples/assembly/mops$(O) examples/assembly/mops.pbc - $(RM_F) Parrot/OpLib/core.pm + $(RM_F) $(OP_PM_FILES) cd docs; make clean distclean: diff -ru parrot_orig/Parrot/Assembler.pm parrot/Parrot/Assembler.pm --- parrot_orig/Parrot/Assembler.pm Sat Nov 3 22:50:04 2001 +++ parrot/Parrot/Assembler.pm Mon Nov 5 00:20:39 2001 @@ -301,10 +301,12 @@ s/\.pm// for @op_packages; { no strict 'refs'; - for(@op_packages) { + my $count; + for(sort @op_packages) { require "$oplib_path/$_.pm"; for(@${'Parrot::OpLib::'.$_.'::ops'}) { $opcodes{$_->full_name}=$_; + $opcodes{$_->full_name}{CODE}=$count++; } } } diff -ru parrot_orig/disassemble.pl parrot/disassemble.pl --- parrot_orig/disassemble.pl Fri Oct 19 08:36:16 2001 +++ parrot/disassemble.pl Mon Nov 5 00:22:18 2001 @@ -16,6 +16,8 @@ use Parrot::Config; use Parrot::OpLib::core; +use Parrot::OpLib::obscure; +use Parrot::OpLib::vtable; use Parrot::Op; use Parrot::Types; @@ -39,6 +41,8 @@ # my @opcodes = @$Parrot::OpLib::core::ops; +@opcodes=(@opcodes,@$Parrot::OpLib::obscure::ops); +@opcodes=(@opcodes,@$Parrot::OpLib::vtable::ops); #my $opcode_fingerprint = Parrot::Opcode::fingerprint(); diff -ru parrot_orig/include/parrot/interpreter.h parrot/include/parrot/interpreter.h --- parrot_orig/include/parrot/interpreter.h Fri Oct 26 14:58:02 2001 +++ parrot/include/parrot/interpreter.h Sun Nov 4 22:04:16 2001 @@ -58,6 +58,9 @@ make_interpreter(); void +destroy_interpreter(struct Parrot_Interp *); + +void runops_generic(); void diff -ru parrot_orig/interpreter.c parrot/interpreter.c --- parrot_orig/interpreter.c Fri Oct 26 14:58:02 2001 +++ parrot/interpreter.c Mon Nov 5 00:27:12 2001 @@ -13,6 +13,8 @@ #include "parrot/parrot.h" #include "parrot/interp_guts.h" #include "parrot/oplib/core_ops.h" +#include "parrot/oplib/obscure_ops.h" +#include "parrot/oplib/vtable_ops.h" #include "parrot/runops_cores.h" @@ -100,10 +102,10 @@ int i; if (interpreter->profile == NULL) { - interpreter->profile = (INTVAL *)mem_sys_allocate(core_numops * sizeof(INTVAL)); + interpreter->profile = (INTVAL +*)mem_sys_allocate((core_numops+obscure_numops+vtable_numops) * sizeof(INTVAL)); } - for (i = 0; i < core_numops; i++) { + for (i = 0; i < (core_numops+obscure_numops+vtable_numops); i++) { interpreter->profile[i] = 0; } } @@ -112,6 +114,31 @@ } } +static void +_init_interpreter_tables(struct Parrot_Interp *interpreter) { + int num_ops = core_numops + 1 + obscure_numops + vtable_numops; + interpreter->opcode_funcs = malloc(sizeof(core_opfunc[0])*num_ops); + interpreter->opcode_info = malloc(sizeof(core_opinfo[0])*num_ops); + + memcpy(interpreter->opcode_funcs,core_opfunc, + sizeof(core_opfunc[0])*core_numops); + memcpy(&interpreter->opcode_funcs[core_numops], + obscure_opfunc, + sizeof(core_opfunc[0])*obscure_numops); + memcpy(&interpreter->opcode_funcs[core_numops+obscure_numops], + vtable_opfunc, + sizeof(core_opfunc[0])*vtable_numops); + + memcpy(interpreter->opcode_info,core_opinfo, + sizeof(core_opinfo[0])*core_numops); + memcpy(&interpreter->opcode_info[core_numops], + obscure_opinfo, + sizeof(core_opinfo[0])*obscure_numops); + memcpy(&interpreter->opcode_info[core_numops+obscure_numops], + vtable_opinfo, + sizeof(core_opinfo[0])*vtable_numops); +} + /*=for api interpreter make_interpreter * Create the Parrot interpreter. Allocate memory and clear the registers. */ @@ -188,10 +215,9 @@ /* Need an empty stash */ interpreter->perl_stash = mem_allocate_new_stash(); - /* Load the core op func and info tables */ + /* Load the opfunc and info tables */ - interpreter->opcode_funcs = core_opfunc; - interpreter->opcode_info = core_opinfo; + _init_interpreter_tables(interpreter); /* In case the I/O system needs something */ Init_IO(interpreter); @@ -204,6 +230,12 @@ interpreter->resume_addr = (opcode_t *)NULL; return interpreter; +} + +void +destroy_interpreter(struct Parrot_Interp* interpreter) { + free(interpreter->opcode_funcs); + free(interpreter->opcode_info); } /* diff -ru parrot_orig/pbc2c.pl parrot/pbc2c.pl --- parrot_orig/pbc2c.pl Wed Oct 24 09:03:42 2001 +++ parrot/pbc2c.pl Mon Nov 5 00:30:47 2001 @@ -25,7 +25,18 @@ $Data::Dumper::Indent = 0; my $ops = new Parrot::OpsFile 'core.ops'; +my $ops2 = new Parrot::OpsFile 'obscure.ops'; +my $ops3 = new Parrot::OpsFile 'vtable.ops'; +my $count = @{$ops->{OPS}}; +for(@{$ops2->{OPS}}) { + push @{$ops->{OPS}},$_; + $_->{CODE}=$count++; +} +for(@{$ops3->{OPS}}) { + push @{$ops->{OPS}},$_; + $_->{CODE}=$count++; +} # # dump_const_table() diff -ru parrot_orig/t/op/trans.t parrot/t/op/trans.t --- parrot_orig/t/op/trans.t Sat Oct 13 20:43:50 2001 +++ parrot/t/op/trans.t Mon Nov 5 00:06:55 2001 @@ -1,7 +1,14 @@ #!/usr/local/bin/perl -w -use Parrot::Test tests => 18; +use Parrot::Test tests => 19; use Math::Trig qw( tan sec atan asin acos asec cosh sinh tanh sech ); + +output_is(<<"CODE",sprintf("%f",1.0-sin(1.0)),"covers"); + set N1,1 + covers N0,N1 + print N0 + end +CODE output_is( <<"CODE", sprintf( "%f%f", sin(1.0), sin(1.0) ), "sin" ); set N1, 1.0 diff -ru parrot_orig/test_main.c parrot/test_main.c --- parrot_orig/test_main.c Mon Oct 22 17:43:25 2001 +++ parrot/test_main.c Sun Nov 4 23:04:30 2001 @@ -13,6 +13,8 @@ #include "parrot/parrot.h" #include "parrot/oplib/core_ops.h" +#include "parrot/oplib/obscure_ops.h" +#include "parrot/oplib/vtable_ops.h" int main(int argc, char **argv) { @@ -152,6 +154,8 @@ printf(" %5d %-12s %12d\n", op_count, "", call_count); } } + + destroy_interpreter(interpreter); return 0; }