Oh, right. The patch. Here it is.
Index: .cvsignore =================================================================== RCS file: /cvs/public/parrot/.cvsignore,v retrieving revision 1.19 diff -p -u -a -r1.19 .cvsignore --- .cvsignore 14 Jul 2002 10:25:55 -0000 1.19 +++ .cvsignore 4 Sep 2002 22:18:25 -0000 @@ -16,3 +16,4 @@ vtable.ops vtable_ops.c platform.c jit_cpu.c +core_pmcs.c Index: MANIFEST =================================================================== RCS file: /cvs/public/parrot/MANIFEST,v retrieving revision 1.207 diff -p -u -a -r1.207 MANIFEST --- MANIFEST 4 Sep 2002 03:48:26 -0000 1.207 +++ MANIFEST 4 Sep 2002 22:18:27 -0000 @@ -546,7 +549,6 @@ pbc2c.pl pdb.c pdump.c pmc.c -pmc_pm.pl pxs.c register.c resources.c Index: pmc_pm.pl =================================================================== RCS file: pmc_pm.pl diff -N pmc_pm.pl --- pmc_pm.pl 22 Aug 2002 00:33:58 -0000 1.3 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,27 +0,0 @@ -#!/usr/bin/perl - -open (IN, "include/parrot/pmc.h") or die $!; -open (OUT, ">lib/Parrot/PMC.pm") or die $!; - -print OUT <<'EOF'; -package Parrot::PMC; -use vars qw(@ISA %pmc_types @EXPORT_OK); - -@ISA = qw( Exporter ); -@EXPORT_OK = qw( %pmc_types); - -%pmc_types = ( -EOF - -$num = 0; -while (<IN>) { - if (/enum_class_(\S+)/) { - my $name = $1; - $name =~ s/,$//; - last if $name eq "max"; - print OUT "\t$name => $num,\n"; - $num++; - } -} -print OUT ");\n\n1;\n"; - Index: classes/default.pmc =================================================================== RCS file: /cvs/public/parrot/classes/default.pmc,v retrieving revision 1.31 diff -p -u -a -r1.31 default.pmc --- classes/default.pmc 19 Aug 2002 23:15:20 -0000 1.31 +++ classes/default.pmc 4 Sep 2002 22:18:39 -0000 @@ -13,7 +13,7 @@ #define INT2KEY(i,k) ((k) ? key_new_integer((i), *(k)) : NULL) -pmclass default noinit { +pmclass default abstract noinit { void init () { } Index: classes/pmc2c.pl =================================================================== RCS file: /cvs/public/parrot/classes/pmc2c.pl,v retrieving revision 1.16 diff -p -u -a -r1.16 pmc2c.pl --- classes/pmc2c.pl 8 Aug 2002 20:57:48 -0000 1.16 +++ classes/pmc2c.pl 4 Sep 2002 22:18:42 -0000 @@ -364,7 +364,7 @@ A preamble, consisting of code to be cop =item 2. -pmclass PMCNAME [extends PMCNAME] { +pmclass PMCNAME [extends PMCNAME] [abstract] [extension] [noinit] { =item 3. Index: config/inter/pmc.pl =================================================================== RCS file: /cvs/public/parrot/config/inter/pmc.pl,v retrieving revision 1.3 diff -p -u -a -r1.3 pmc.pl --- config/inter/pmc.pl 22 Jul 2002 06:44:22 -0000 1.3 +++ config/inter/pmc.pl 4 Sep 2002 22:18:42 -0000 @@ -43,9 +43,33 @@ END }eg; # build list of libraries for link line in Makfile (my $pmc_classes_o = $pmc_o) =~ s/^| / classes\//g; - + + # Gather the actual names (with MixedCase) of all of the + # non-abstract built-in PMCs (which currently means everything but + # 'default'.) + my @names; + PMC: foreach my $pmc_file (split(/ /, $pmc)) { + my $name; + open(PMC, "classes/$pmc_file") or die "open classes/$pmc_file: $!"; + while (<PMC>) { + if (/^pmclass (\w+)(.*)/) { + $name = $1; + my $decl = $2; + $decl .= <PMC> until ($decl =~ s/\{.*//); + next PMC if $decl =~ /\babstract\b/; + next PMC if $decl =~ /\bextension\b/; + last; + } + } + close PMC; + die "No pmclass declaration found in $pmc_file" + if ! defined $name; + push @names, $name; + } + Configure::Data->set( pmc => $pmc, + pmc_names => join(" ", @names), pmc_o => $pmc_o, pmc_build => $pmc_build, pmc_classes_o => $pmc_classes_o Index: docs/vtables.pod =================================================================== RCS file: /cvs/public/parrot/docs/vtables.pod,v retrieving revision 1.12 diff -p -u -a -r1.12 vtables.pod --- docs/vtables.pod 29 Aug 2002 20:02:46 -0000 1.12 +++ docs/vtables.pod 4 Sep 2002 22:18:43 -0000 @@ -26,7 +26,7 @@ runtime error. =item * -To be perfect honest, this is a slightly flawed example, since it's +To be perfectly honest, this is a slightly flawed example, since it's unlikely that there will be a distinct "Python scalar" PMC class. The Python compiler could well type-inference variables such that C<a> would be a C<PythonString> and C<b> would be a C<PythonNumber>. @@ -91,9 +91,11 @@ containing all the methods. Now you'll have to do something a little different depending on whether you're writing a built-in class or an extension class. If you're writing a built-in class, then you'll see a reference to -C<enum_class_FoobyNumber> in the C<init> function. This is something -that you need to add to the C<enum> of built-in classes located in -F<pmc.h>. If you're not writing a built-in class, you need to change the +C<enum_class_FoobyNumber> in the C<init> function. For built-in classes, +this is automatically defined in F<pmc.h> when you run Configure.pl. +If you're not writing a built-in class, you need to indicate this by +using the 'extension' keyword after the 'pmclass YOURCLASS' declaration +in classes/YOURCLASS.pmc. Then, change the type of the C<init> function to return C<struct _vtable>, and then return C<temp_base_vtable> instead of assigning to the C<Parrot_base_vtables> array. @@ -108,25 +110,7 @@ Add classes/YOURCLASS.pmc to MANIFEST. =item 2. -Add enum_class_YOURCLASS to the enumeration in include/parrot/pmc.h. - -=item 3. - -Add Parrot_YOURCLASS_class_init to the list in include/parrot/global_setup.h. - -=item 4. - -Add a call to Parrot_YOURCLASS_class_init() to init_world() in -global_setup.c. - -=item 5. - -Add your PMC class to the classname hash at the end of global_setup.c. - -=item 6. - -Rerun perl Configure.pl (or perl Configure.pl --debugging) to -regenerate the makefiles with your new PMC. +Rerun Configure.pl to add your new PMC to the set of built-in PMCs. =back Index: include/parrot/pmc.h =================================================================== RCS file: /cvs/public/parrot/include/parrot/pmc.h,v retrieving revision 1.38 diff -p -u -a -r1.38 pmc.h --- include/parrot/pmc.h 19 Aug 2002 23:15:52 -0000 1.38 +++ include/parrot/pmc.h 4 Sep 2002 22:18:44 -0000 @@ -13,25 +13,8 @@ #if !defined(PARROT_PMC_H_GUARD) #define PARROT_PMC_H_GUARD -enum { - enum_class_Array, - enum_class_Boolean, - enum_class_PerlUndef, - enum_class_PerlInt, - enum_class_PerlNum, - enum_class_PerlString, - enum_class_PerlArray, - enum_class_PerlHash, - enum_class_Pointer, - enum_class_IntQueue, - enum_class_Sub, - enum_class_Coroutine, - enum_class_Continuation, - enum_class_CSub, - enum_class_MultiArray, - enum_class_Key, - enum_class_max = 100 -}; +#include "parrot/core_pmcs.h" + VAR_SCOPE VTABLE Parrot_base_vtables[enum_class_max]; VAR_SCOPE PMC *Parrot_base_classname_hash; Index: include/parrot/.cvsignore =================================================================== RCS file: /cvs/public/parrot/include/parrot/.cvsignore,v retrieving revision 1.9 diff -p -u -a -r1.9 .cvsignore --- include/parrot/.cvsignore 7 Jun 2002 01:16:46 -0000 1.9 +++ include/parrot/.cvsignore 4 Sep 2002 22:18:44 -0000 @@ -4,3 +4,4 @@ vtable.h platform.h jit_struct.h jit_emit.h +core_pmcs.h Index: config/gen/makefiles/root.in =================================================================== RCS file: /cvs/public/parrot/config/gen/makefiles/root.in,v retrieving revision 1.34 diff -p -u -a -r1.34 root.in --- config/gen/makefiles/root.in 4 Sep 2002 04:17:50 -0000 1.34 +++ config/gen/makefiles/root.in 4 Sep 2002 22:18:47 -0000 @@ -29,7 +29,8 @@ GEN_MAKEFILES = Makefile classes/Makefil languages/jako/Makefile languages/miniperl/Makefile languages/scheme/Makefile GEN_CONFIGS = include/parrot/config.h include/parrot/platform.h \ - lib/Parrot/Config.pm platform.c + lib/Parrot/Config.pm lib/Parrot/PMC.pm platform.c \ + include/parrot/core_pmcs.h core_pmcs.c STICKY_FILES = $(GEN_CONFIGS) $(GEN_MAKEFILES) myconfig @@ -51,7 +52,7 @@ $(INC)/oplib/core_ops_prederef.h GEN_SOURCES = core_ops.c core_ops_prederef.c -GEN_MODULES = lib/Parrot/Jit.pm lib/Parrot/PMC.pm lib/Parrot/OpLib/core.pm +GEN_MODULES = lib/Parrot/Jit.pm lib/Parrot/OpLib/core.pm FLUID_FILES = $(GEN_OPSFILES) $(GEN_HEADERS) $(GEN_SOURCES) $(GEN_MODULES) @@ -67,8 +68,9 @@ $(INC)/register.h $(INC)/string.h $(INC) $(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)/oplib/core_ops_prederef.h $(INC)/runops_cores.h $(INC)/trace.h \ -$(INC)/pmc.h $(INC)/key.h $(INC)/hash.h $(INC)/resources.h $(INC)/platform.h ${cg_h} \ -$(INC)/interp_guts.h $(INC)/rx.h $(INC)/rxstacks.h \ +$(INC)/pmc.h $(INC)/key.h $(INC)/hash.h $(INC)/resources.h \ +$(INC)/core_pmcs.h $(INC)/platform.h ${cg_h} \ +$(INC)/interp_guts.h $(INC)/rx.h $(INC)/rxstacks.h \ $(INC)/embed.h $(INC)/warnings.h $(INC)/misc.h $(INC)/pmc.h \ $(INC)/key.h $(INC)/hash.h $(INC)/smallobject.h $(INC)/headers.h $(INC)/dod.h \ $(INC)/method_util.h @@ -92,7 +94,8 @@ INTERP_O_FILES = exceptions$(O) global_s register$(O) core_ops$(O) core_ops_prederef$(O) memory$(O) \ packfile$(O) stacks$(O) string$(O) sub$(O) encoding$(O) \ chartype$(O) runops_cores$(O) trace$(O) pmc$(O) key$(O) hash$(O) \ - platform$(O) ${jit_o} resources$(O) rx$(O) rxstacks$(O) \ + core_pmcs$(O) platform$(O) ${jit_o} \ + resources$(O) rx$(O) rxstacks$(O) \ embed$(O) warnings$(O) misc$(O) ${cg_o} \ packout$(O) byteorder$(O) debug$(O) smallobject$(O) \ headers$(O) dod$(O) method_util$(O) @@ -160,7 +163,7 @@ all : $(TEST_PROG) docs mops : examples/assembly/mops${exe} examples/mops/mops${exe} -$(TEST_PROG) : test_main$(O) $(GEN_HEADERS) $(O_DIRS) $(O_FILES) lib/Parrot/OpLib/core.pm lib/Parrot/PMC.pm +$(TEST_PROG) : test_main$(O) $(GEN_HEADERS) $(O_DIRS) $(O_FILES) +lib/Parrot/OpLib/core.pm $(LD) ${ld_out}$(TEST_PROG) $(LDFLAGS) $(O_FILES) test_main$(O) $(C_LIBS) lib_deps_object : $(O_DIRS) $(O_FILES) @@ -196,7 +199,7 @@ blib/lib/libparrot$(A) : blib/lib $(O_DI blib/lib/libparrot$(SO) : blib/lib $(O_DIRS) $(O_FILES) $(LD) $(LD_SHARED) $(LD_SHARED_FLAGS) $(LDFLAGS) $(LD_OUT)blib/lib/libparrot$(SO) $(O_FILES) $(C_LIBS) -$(TEST_PROG_SO) : test_main$(O) blib/lib/libparrot$(SO) lib/Parrot/OpLib/core.pm lib/Parrot/PMC.pm +$(TEST_PROG_SO) : test_main$(O) blib/lib/libparrot$(SO) lib/Parrot/OpLib/core.pm $(LD) $(LDFLAGS) $(LD_OUT)$(TEST_PROG) test_main$(O) blib/lib/libparrot$(A) $(C_LIBS) # XXX The dependancies on SO.MAJOR.MINOR and SO.VERSION are removed @@ -273,9 +276,6 @@ test_main$(O) : test_main.c $(GENERAL_H_ lib/Parrot/OpLib/core.pm : $(OPS_FILES) ops2pm.pl lib/Parrot/OpsFile.pm lib/Parrot/Op.pm $(PERL) ops2pm.pl $(OPS_FILES) -lib/Parrot/PMC.pm : include/parrot/pmc.h pmc_pm.pl - $(PERL) pmc_pm.pl - ############################################################################### # # Examples (Assembly): @@ -339,6 +339,8 @@ dod$(O) : $(GENERAL_H_FILES) resources$(O) : $(GENERAL_H_FILES) platform$(O) : $(GENERAL_H_FILES) + +core_pmcs$(O) : $(GENERAL_H_FILES) debug$(O) : $(GENERAL_H_FILES) $(INC)/debug.h Index: lib/Parrot/Configure/RunSteps.pm =================================================================== RCS file: /cvs/public/parrot/lib/Parrot/Configure/RunSteps.pm,v retrieving revision 1.10 diff -p -u -a -r1.10 RunSteps.pm --- lib/Parrot/Configure/RunSteps.pm 4 Sep 2002 03:50:33 -0000 1.10 +++ lib/Parrot/Configure/RunSteps.pm 4 Sep 2002 22:18:47 -0000 @@ -32,6 +32,7 @@ use vars qw(@steps); gen/myconfig.pl gen/platform.pl gen/libparrot_def.pl + gen/core_pmcs.pl ); # auto/alignptrs.pl Index: global_setup.c =================================================================== RCS file: /cvs/public/parrot/global_setup.c,v retrieving revision 1.35 diff -p -u -a -r1.35 global_setup.c --- global_setup.c 2 Sep 2002 20:58:49 -0000 1.35 +++ global_setup.c 4 Sep 2002 22:20:34 -0000 @@ -14,30 +14,9 @@ #define INSIDE_GLOBAL_SETUP #include "parrot/parrot.h" -/* Needed because this might get compiled before pmcs have been built */ -extern void Parrot_PerlUndef_class_init(INTVAL); -extern void Parrot_PerlInt_class_init(INTVAL); -extern void Parrot_PerlNum_class_init(INTVAL); -extern void Parrot_PerlString_class_init(INTVAL); -extern void Parrot_Array_class_init(INTVAL); -extern void Parrot_Boolean_class_init(INTVAL); -extern void Parrot_PerlArray_class_init(INTVAL); -extern void Parrot_PerlHash_class_init(INTVAL); -extern void Parrot_Pointer_class_init(INTVAL); -extern void Parrot_IntQueue_class_init(INTVAL); -extern void Parrot_Sub_class_init(INTVAL); -extern void Parrot_Coroutine_class_init(INTVAL); -extern void Parrot_Continuation_class_init(INTVAL); -extern void Parrot_CSub_class_init(INTVAL); -extern void Parrot_MultiArray_class_init(INTVAL); -extern void Parrot_Key_class_init(INTVAL); - -static void register_pmc(PMC* registry, int pmc_id) -{ - PMC* key; - key = key_new_string(NULL, Parrot_base_vtables[pmc_id].name(NULL,NULL)); - registry->vtable->set_integer_keyed(NULL, registry, key, pmc_id); -} +/* These functions are defined in the auto-generated file core_pmcs.c */ +extern void Parrot_initialize_core_pmcs(void); +extern void Parrot_register_core_pmcs(PMC* registry); void init_world(void) @@ -45,46 +24,16 @@ init_world(void) PMC* key; string_init(); /* Set up the string subsystem */ - /* Call base vtable class constructor methods! */ - Parrot_Array_class_init(enum_class_Array); - Parrot_Boolean_class_init(enum_class_Boolean); - Parrot_PerlUndef_class_init(enum_class_PerlUndef); - Parrot_PerlInt_class_init(enum_class_PerlInt); - Parrot_PerlNum_class_init(enum_class_PerlNum); - Parrot_PerlString_class_init(enum_class_PerlString); - Parrot_PerlArray_class_init(enum_class_PerlArray); - Parrot_PerlHash_class_init(enum_class_PerlHash); - Parrot_Pointer_class_init(enum_class_Pointer); - Parrot_IntQueue_class_init(enum_class_IntQueue); - Parrot_Sub_class_init(enum_class_Sub); - Parrot_Coroutine_class_init(enum_class_Coroutine); - Parrot_CSub_class_init(enum_class_CSub); - Parrot_Continuation_class_init(enum_class_Continuation); - Parrot_MultiArray_class_init(enum_class_MultiArray); - Parrot_Key_class_init(enum_class_Key); + /* Call base vtable class constructor methods */ + Parrot_initialize_core_pmcs(); /* Now register the names of the PMCs */ /* We need a hash */ Parrot_base_classname_hash = pmc_new(NULL, enum_class_PerlHash); - /* Now start filling the hash */ - register_pmc(Parrot_base_classname_hash, enum_class_Array); - register_pmc(Parrot_base_classname_hash, enum_class_Boolean); - register_pmc(Parrot_base_classname_hash, enum_class_PerlUndef); - register_pmc(Parrot_base_classname_hash, enum_class_PerlInt); - register_pmc(Parrot_base_classname_hash, enum_class_PerlNum); - register_pmc(Parrot_base_classname_hash, enum_class_PerlString); - register_pmc(Parrot_base_classname_hash, enum_class_PerlArray); - register_pmc(Parrot_base_classname_hash, enum_class_PerlHash); - register_pmc(Parrot_base_classname_hash, enum_class_Pointer); - register_pmc(Parrot_base_classname_hash, enum_class_IntQueue); - register_pmc(Parrot_base_classname_hash, enum_class_Sub); - register_pmc(Parrot_base_classname_hash, enum_class_Coroutine); - register_pmc(Parrot_base_classname_hash, enum_class_CSub); - register_pmc(Parrot_base_classname_hash, enum_class_Continuation); - register_pmc(Parrot_base_classname_hash, enum_class_MultiArray); - register_pmc(Parrot_base_classname_hash, enum_class_Key); + /* Now fill the hash */ + Parrot_register_core_pmcs(Parrot_base_classname_hash); } /* Index: config/gen/core_pmcs.pl =================================================================== RCS file: config/gen/core_pmcs.pl diff -N config/gen/core_pmcs.pl --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ config/gen/core_pmcs.pl 4 Sep 2002 22:24:26 -0000 @@ -0,0 +1,133 @@ +package Configure::Step; + +use strict; +use vars qw($description @args); +use Parrot::Configure::Step ':gen'; + +$description="Generating core pmc list..."; + +@args=(); + +sub runstep { + generate_h(); + generate_c(); + generate_pm(); +} + +sub generate_h { + my $file = "include/parrot/core_pmcs.h"; + open(OUT, ">$file.tmp"); + + print OUT <<"END"; +/* + * DO NOT EDIT THIS FILE + * + * Automatically generated by config/gen/core_pmcs.pl + */ + +enum { +END + + my @pmcs = split(/ /, Configure::Data->get('pmc_names')); + print OUT " enum_class_$_,\n" foreach (@pmcs); + print OUT <<"END"; + enum_class_max = 100 +}; +END + + close OUT; + + copy_if_diff("$file.tmp", $file); +} + +sub generate_c { + my $file = "core_pmcs.c"; + my @pmcs = split(/ /, Configure::Data->get('pmc_names')); + + open(OUT, ">$file.tmp"); + + print OUT <<"END"; +/* + * DO NOT EDIT THIS FILE + * + * Automatically generated by config/gen/core_pmcs.pl + */ + +#include "parrot/parrot.h" + +END + + print OUT "extern void Parrot_${_}_class_init(int);\n" + foreach (@pmcs); + + print OUT <<"END"; + +extern void Parrot_initialize_core_pmcs(void); +void Parrot_initialize_core_pmcs(void) +{ +END + + print OUT " Parrot_${_}_class_init(enum_class_${_});\n" + foreach (@pmcs); + print OUT <<"END"; +}; + +static void register_pmc(PMC* registry, int pmc_id) +{ + PMC* key; + key = key_new_string(NULL, Parrot_base_vtables[pmc_id].name(NULL,NULL)); + registry->vtable->set_integer_keyed(NULL, registry, key, pmc_id); +} + +extern void Parrot_register_core_pmcs(PMC* registry); +void Parrot_register_core_pmcs(PMC* registry) +{ +END + + print OUT " register_pmc(registry, enum_class_$_);\n" + foreach (@pmcs); + print OUT <<"END"; +} +END + + close OUT; + + copy_if_diff("$file.tmp", $file); +} + +sub generate_pm { + my $file = "lib/Parrot/PMC.pm"; + my @pmcs = split(/ /, Configure::Data->get('pmc_names')); + + open(OUT, ">$file.tmp"); + + print OUT <<'END'; +# DO NOT EDIT THIS FILE +# +# Automatically generated by config/gen/core_pmcs.pl + +package Parrot::PMC; +use vars qw(@ISA %pmc_types @EXPORT_OK); + +@ISA = qw( Exporter ); +@EXPORT_OK = qw( %pmc_types); + +%pmc_types = ( +END + + for my $num (0..$#pmcs) { + print OUT "\t$pmcs[$num] => $num,\n"; + } + + print OUT <<"END"; +); + +1; +END + + close OUT; + + copy_if_diff("$file.tmp", $file); +} + +1;