cvsuser 04/09/07 22:25:22
Modified: config/gen makefiles.pl
classes pmc2c2.pl
config/init data.pl
config/gen/makefiles dynclasses.in
dynclasses README
. MANIFEST
Added: config/gen/makefiles dynclasses.pl.in
Log:
Implement interdepent dynamic PMC groups. See dynclasses/README for
brief usage instructions.
Revision Changes Path
1.35 +3 -1 parrot/config/gen/makefiles.pl
Index: makefiles.pl
===================================================================
RCS file: /cvs/public/parrot/config/gen/makefiles.pl,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -w -r1.34 -r1.35
--- makefiles.pl 19 Jun 2004 09:33:09 -0000 1.34
+++ makefiles.pl 8 Sep 2004 05:25:10 -0000 1.35
@@ -1,6 +1,6 @@
#! perl -w
# Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
-# $Id: makefiles.pl,v 1.34 2004/06/19 09:33:09 leo Exp $
+# $Id: makefiles.pl,v 1.35 2004/09/08 05:25:10 sfink Exp $
=head1 NAME
@@ -81,6 +81,8 @@
commentType => '#', replace_slashes => 1);
genfile('config/gen/makefiles/dynclasses.in', 'dynclasses/Makefile',
commentType => '#', replace_slashes => 1);
+ genfile('config/gen/makefiles/dynclasses.pl.in', 'dynclasses/build.pl',
+ commentType => '#', replace_slashes => 0);
genfile('config/gen/makefiles/dynoplibs.in', 'dynoplibs/Makefile',
commentType => '#', replace_slashes => 1);
genfile('config/gen/makefiles/parrot_compiler.in',
'languages/parrot_compiler/Makefile',
1.17 +14 -8 parrot/classes/pmc2c2.pl
Index: pmc2c2.pl
===================================================================
RCS file: /cvs/public/parrot/classes/pmc2c2.pl,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -w -r1.16 -r1.17
--- pmc2c2.pl 22 Aug 2004 09:15:51 -0000 1.16
+++ pmc2c2.pl 8 Sep 2004 05:25:12 -0000 1.17
@@ -1,6 +1,6 @@
#! perl -w
# Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
-# $Id: pmc2c2.pl,v 1.16 2004/08/22 09:15:51 leo Exp $
+# $Id: pmc2c2.pl,v 1.17 2004/09/08 05:25:12 sfink Exp $
=head1 NAME
@@ -135,12 +135,6 @@
Used with C<abstract>: No C<class_init> code is generated.
-=item C<dynpmc>
-
-The class is a dynamic class. These have a special C<class_init>
-routine suitable for dynamic loading at runtime. See the F<dynclasses>
-directory for an example.
-
=item C<const_too>
Classes with this flag get 2 vtables and 2 enums, one pair with
@@ -164,6 +158,18 @@
library
ref
+=item C<dynpmc>
+
+The class is a dynamic class. These have a special C<class_init>
+routine suitable for dynamic loading at runtime. See the F<dynclasses>
+directory for an example.
+
+=item C<group GROUP>
+
+The class is part of a group of interrelated PMCs that should be
+compiled together into a single shared library of the given name. Only
+valid for dynamic PMCs.
+
=back
=item 3.
@@ -318,7 +324,7 @@
my $c = shift;
$$c =~ s/^(.*?^\s*)pmclass ([\w]*)//ms;
my ($pre, $classname) = ($1, $2);
- my %has_value = ( does => 1, extends => 1 );
+ my %has_value = ( does => 1, extends => 1, group => 1 );
my %flags;
# look through the pmc declaration header for flags such as noinit
1.32 +6 -1 parrot/config/init/data.pl
Index: data.pl
===================================================================
RCS file: /cvs/public/parrot/config/init/data.pl,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -w -r1.31 -r1.32
--- data.pl 10 Jul 2004 07:13:43 -0000 1.31
+++ data.pl 8 Sep 2004 05:25:13 -0000 1.32
@@ -1,6 +1,6 @@
#! perl -w
# Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
-# $Id: data.pl,v 1.31 2004/07/10 07:13:43 leo Exp $
+# $Id: data.pl,v 1.32 2004/09/08 05:25:13 sfink Exp $
=head1 NAME
@@ -32,6 +32,7 @@
package Configure::Data;
use Config;
use Data::Dumper;
+ use FindBin; # see build_dir
# We need a Glossary somewhere!
@@ -40,6 +41,8 @@
optimize => $optimize ? $Config{optimize} : '',
verbose => $verbose,
+ build_dir => $FindBin::Bin,
+
# Compiler -- used to turn .c files into object files.
# (Usually cc or cl, or something like that.)
cc => $Config{cc},
@@ -104,6 +107,7 @@
ar_out => '', # for Win32
ar_extra => '', # for Borland C
ranlib => $Config{ranlib},
+ rpath => '-Wl,-rpath=',
make => $Config{make},
make_set_make => $Config{make_set_make},
make_and => '&&',
@@ -125,6 +129,7 @@
configdate => scalar localtime,
PQ => "'",
+ dquote => "\\\"",
# yacc = Automatic parser generator
# lex = Automatic lexer generator
1.6 +14 -28 parrot/config/gen/makefiles/dynclasses.in
Index: dynclasses.in
===================================================================
RCS file: /cvs/public/parrot/config/gen/makefiles/dynclasses.in,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -w -r1.5 -r1.6
--- dynclasses.in 25 Apr 2004 10:47:41 -0000 1.5
+++ dynclasses.in 8 Sep 2004 05:25:18 -0000 1.6
@@ -1,41 +1,27 @@
-#
-# sample Makefile
-#
-LD = ${ld}
-LD_SHARED = ${ld_shared}
PERL = ${perl}
RM_F = ${rm_f}
SO = ${so}
-CFLAGS = ${ccflags} ${cc_debug} ${ccwarn} ${cc_hasjit} ${cg_flag} ${gc_flag}
-
# add your dynamic pmcs here
-all: foo$(SO) subproxy$(SO) \
-tclobject$(SO) tclstring$(SO) tclint$(SO) tclfloat$(SO) \
-tcllist$(SO) tclarray$(SO)
-
-.SUFFIXES: .pmc .c $(SO)
-
-# preserve .c if needed
-.PRECIOUS: %.c
-
-%.c : %.pmc
- $(PERL) ..${slash}classes${slash}pmc2c2.pl --dump $<
- $(PERL) ..${slash}classes${slash}pmc2c2.pl --c $<
-
-%$(SO) : %.c
- $(LD) $(CFLAGS) $(LD_SHARED) $(LD_SHARED_FLAGS) $(LDFLAGS) \
- ${cc_o_out}$@ \
- -I..${slash}include -I..${slash}classes \
- -L..${slash}blib${slash}lib -lparrot $<
- $(PERL) -MFile::Copy=cp -e ${PQ}cp q|$@|, q|../runtime/parrot/dynext/$@|${PQ}
+PMCS = foo subproxy \
+tclobject tclstring tclint tclfloat \
+tcllist tclarray \
+match matchrange
+
+BUILD = ${perl} build.pl
+
+all :
+ $(BUILD) generate $(PMCS)
+ $(BUILD) compile $(PMCS)
+ $(BUILD) linklibs $(PMCS)
+ $(BUILD) copy --destination=../runtime/parrot/dynext $(PMCS)
clean :
- $(RM_F) *.c *.h *$(SO) *.dump
+ $(RM_F) *.c *.h *$(SO) *.dump lib-*
realclean: clean
- $(RM_F) Makefile
+ $(RM_F) Makefile build.pl
distclean: realclean
1.1 parrot/config/gen/makefiles/dynclasses.pl.in
Index: dynclasses.pl.in
===================================================================
use strict;
use File::Copy qw(copy move);
# Config stuff
our $CC = "${cc} -c";
our $LD = "${ld}";
our $LD_SHARED = "${ld_shared}";
our $LD_SHARED_FLAGS = "${ld_shared_flags}";
our $LDFLAGS = "${ldflags}";
our $PERL = "${perl}";
our $SO = "${so}";
our $O = "${o}";
our $CFLAGS = "${ccflags} ${cc_debug} ${ccwarn} ${cc_hasjit} ${cg_flag} ${gc_flag}";
our $PMC2C = "$PERL ${build_dir}${slash}classes${slash}pmc2c2.pl";
# Actual commands
sub compile_shared_cmd {
my ($target, $source) = @_;
"$LD $CFLAGS $LD_SHARED $LD_SHARED_FLAGS $LDFLAGS " .
"${cc_o_out}" . $target . " " .
"-I${build_dir}${slash}include -I${build_dir}${slash}classes " .
"-L${build_dir}${slash}blib${slash}lib -lparrot " .
$source;
};
sub compile_cmd {
my ($target, $source) = @_;
"$CC $CFLAGS " .
"${cc_o_out}" . $target . " " .
"-I${build_dir}${slash}include -I${build_dir}${slash}classes " .
$source;
};
sub partial_link_cmd {
my ($target, @sources) = @_;
"$LD $CFLAGS $LD_SHARED $LD_SHARED_FLAGS $LDFLAGS ".
"${cc_o_out}" . $target . " " .
join(" ", @sources);
}
our $NOW = time;
################### MAIN PROGRAM ################
my ($mode, @pmcs) = @ARGV;
if ($mode eq 'generate') {
# Convert X.pmc -> X.dump and X.c and also create any lib-GROUP.c files
generate_dump($_) foreach (@pmcs);
generate_c($_) foreach (@pmcs);
my ($group_files, $pmc_group) = gather_groups(@pmcs);
while (my ($group, $pmcs) = each %$group_files) {
my $pmcfiles = join(" ", map { "$_.pmc" } @$pmcs);
run("$PMC2C --library $group --c $pmcfiles")
or die "pmc2c library creation failed ($?)\n";
}
} elsif ($mode eq 'compile') {
my ($group_files, $pmc_group) = gather_groups(@pmcs);
my @grouped_pmcs = grep { exists $pmc_group->{$_} } @pmcs;
my @ungrouped_pmcs = grep { ! exists $pmc_group->{$_} } @pmcs;
# Convert X.c -> X.so for all non-grouped X.c
compile_shared($_) foreach (@ungrouped_pmcs);
# Convert X.c -> X.o for all grouped X.c
compile($_) foreach (@grouped_pmcs);
# lib-GROUP.c
for my $group (keys %$group_files) {
compile("$group", "lib-$group")
or die "compile $group.c failed ($?)\n";
}
} elsif ($mode eq 'linklibs') {
my ($group_files, $pmc_group) = gather_groups(@pmcs);
# Convert lib-GROUP.so + A.so + B.so ... -> GROUP.so
while (my ($group, $pmcs) = each %$group_files) {
partial_link($group, "lib-$group", @$pmcs)
or die "partial link of $group failed ($?)\n";
}
} elsif ($mode eq 'copy') {
# Copy *.so -> destination, where destination is the first
# argument, given as --destination=DIRECTORY
shift(@pmcs) =~ /--destination=(.*)/
or die "copy command requires destination";
my $dest = $1;
my ($group_files, $pmc_group) = gather_groups(@pmcs);
foreach (@pmcs, keys %$group_files) {
copy("$_$SO", $dest) or die "Copy $_$SO failed ($?)\n";
}
} else {
die "invalid command '$mode'\nmust be one of generate, compile, linklibs, or
copy\n";
}
sub run {
print join(" ", @_), "\n";
return system(@_) == 0;
}
sub gather_groups {
my %group_files;
my %pmc_group;
for my $pmc (@_) {
our $class;
require "$pmc.dump";
my $group = $class->{flags}{group}
or next;
($group) = keys %$group;
$pmc_group{$pmc} = $group;
push @{ $group_files{$group} }, $pmc;
}
return (\%group_files, \%pmc_group);
}
sub modtime {
my $ago = (-M shift);
if (defined $ago) {
return $NOW - $ago;
} else {
return;
}
}
sub needs_build {
my ($target, @sources) = @_;
my $target_mod = modtime($target)
or return 1;
for my $source (@sources) {
return 1 if modtime($source) >= $target_mod;
}
return 0;
}
sub generate_dump {
my ($pmc) = @_;
if (needs_build("$pmc.dump", "$pmc.pmc")) {
run("$PMC2C --dump $pmc.pmc")
or die "pmc2c dump failed ($?)\n";
} else {
print "$pmc.dump is up to date\n";
}
}
sub generate_c {
my ($pmc) = @_;
if (needs_build("$pmc.c", "$pmc.pmc")) {
run("$PMC2C --c $pmc.pmc")
or die "pmc2c code generation failed ($?)\n";
}
}
sub compile {
my ($src_stem, $dest_stem) = @_;
$dest_stem ||= $src_stem;
if (needs_build("$dest_stem$O", "$src_stem.c")) {
run(compile_cmd("$dest_stem$O", "$src_stem.c"))
or die "compile $src_stem.c failed ($?)\n";
}
}
sub compile_shared {
my ($src_stem, $dest_stem) = @_;
$dest_stem ||= $src_stem;
if (needs_build("$dest_stem$SO", "$src_stem.c")) {
run(compile_shared_cmd("$dest_stem$SO", "$src_stem.c"))
or die "compile $src_stem.c failed ($?)\n";
} else {
print "$dest_stem$SO is up to date\n";
}
}
sub partial_link {
my ($group, @stems) = @_;
my @sources = map { "$_$O" } @stems;
if (needs_build("$group$SO", @sources)) {
run(partial_link_cmd("$group$SO", @sources))
or die "partial link $group$SO failed ($?)\n";
}
}
1.5 +20 -17 parrot/dynclasses/README
Index: README
===================================================================
RCS file: /cvs/public/parrot/dynclasses/README,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -w -r1.4 -r1.5
--- README 13 Apr 2004 07:07:08 -0000 1.4
+++ README 8 Sep 2004 05:25:21 -0000 1.5
@@ -19,17 +19,13 @@
pmclass TclString extends tclobject dynpmc { ... }
-Currently, it is also required that you generate a placeholder C<#define>
-for your class so that the construct C file can compile. For example, the
-PMC C<TclString> requires a C<#define TclString -1> in the PMC file. This is
-a result of using the same PMC generation code for both static and dynamic
-PMCs. (For static PMCs, this constant is generated at compile-time.)
-
-Since this value is just a placeholder, a different value is assigned at
-runtime - so, when you refer to the type of the class , you must dynamically
-determine the PMC type. So, while C<perlscalar> (a bultin) has the
-luxury of knowing at compile time what the class number of its
-child C<PerlString> is, for example:
+Note that regular (non-dynamic) PMCs have a type id
+C<enum_class_PMCNAME>, but dynamic PMCs obviously cannot use the same
+thing. Instead, a dynamically-chosen value is assigned at runtime -
+so, when you refer to the type of the class , you must dynamically
+determine the PMC type. So, while C<perlscalar> (a builtin) has the
+luxury of knowing at compile time what the class number of its child
+C<PerlString> is, for example:
if (type == enum_class_PerlString) {
@@ -41,9 +37,16 @@
string_from_cstring(interpreter, "TclString", 9))
)
-A final note - there's currently no easy easy to deal with dynamic PMCs
-that are indeterdependant. See the various Tcl PMCs for an example of
-a workaround.
+Finally, if you have a group of PMCs that are interdependent, use the
+C<group GROUPNAME> syntax to trigger a group library to built. You
+will use the group name as the name of the library to load using the
+PASM op C<loadlib>.
+
+ pmclass Match extends PerlHash dynpmc group match_group { ... }
+
+and then in your .imc or .pasm file:
+
+ loadlib $P0, "match_group"
=item 2
@@ -51,9 +54,9 @@
the build target.
$ export LD_LIBRARY_PATH=.:blib/lib
- $ make -s
+ $ make
$ make shared
- $ make -C dynclasses
+ $ cd dynclasses; make
=item 3
@@ -70,4 +73,4 @@
If anything changes inside parrot, be sure to:
- $ make -C dynclasses clean
+ $ cd dynclasses; make clean
1.728 +1 -0 parrot/MANIFEST
Index: MANIFEST
===================================================================
RCS file: /cvs/public/parrot/MANIFEST,v
retrieving revision 1.727
retrieving revision 1.728
diff -u -w -r1.727 -r1.728
--- MANIFEST 6 Sep 2004 16:41:11 -0000 1.727
+++ MANIFEST 8 Sep 2004 05:25:22 -0000 1.728
@@ -182,6 +182,7 @@
config/gen/makefiles/cola.in []
config/gen/makefiles/docs.in []
config/gen/makefiles/dynclasses.in []
+config/gen/makefiles/dynclasses.pl.in []
config/gen/makefiles/dynoplibs.in []
config/gen/makefiles/imcc.in []
config/gen/makefiles/jako.in []