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                      []
  
  
  

Reply via email to