Hi there,

Here's a proposed patch (for review, not application) to generate
src/extend.c from vtable.tbl.  It has some limitations:

- I'm not sure if the Makefile magic is perfect
- it doesn't pick up all of the C types used in vtable.tbl
- it makes everything it understands in that file available
- it doesn't include behavioral documentation

I think the correct approach is to annotate vtable.tbl with more
information -- including the documentation strings -- to make generating
files easier.

Comments welcome.

-- c


Index: MANIFEST
===================================================================
--- MANIFEST	(revision 9501)
+++ MANIFEST	(working copy)
@@ -42,6 +42,7 @@
 build_tools/pbc2c.pl                              [devel]
 build_tools/pmc2c.pl                              []
 build_tools/revision_c.pl                         [devel]
+build_tools/vtable_extend.pl                      []
 build_tools/vtable_h.pl                           []
 charset/ascii.c                                   []
 charset/ascii.h                                   []
Index: config/gen/makefiles/root.in
===================================================================
--- config/gen/makefiles/root.in	(revision 9501)
+++ config/gen/makefiles/root.in	(working copy)
@@ -235,7 +235,8 @@
     $(SRC_DIR)/parrot_config.c \
     $(SRC_DIR)/null_config.c \
     $(SRC_DIR)/install_config.c \
-    $(SRC_DIR)/exec_cpu.c
+    $(SRC_DIR)/exec_cpu.c \
+    $(SRC_DIR)/extend.c
 
 GEN_MODULES = \
     lib/Parrot/OpLib/core.pm
@@ -896,6 +897,9 @@
 
 $(SRC_DIR)/exec_cpu$(O) : $(GENERAL_H_FILES) ${TEMP_exec_h} ${TEMP_jit_h} $(INC_DIR)/jit_emit.h
 
+$(SRC_DIR)/vtable.h : vtable.tbl $(BUILD_TOOLS_DIR)/vtable_extend.pl lib/Parrot/Vtable.pm
+	$(PERL) $(BUILD_TOOLS_DIR)/vtable_extend.pl
+
 $(SRC_DIR)/exec_start$(O) : $(GENERAL_H_FILES) ${TEMP_exec_h}
 
 $(SRC_DIR)/exec_save$(O) : $(GENERAL_H_FILES) ${TEMP_exec_h}
Index: lib/Parrot/Vtable.pm
===================================================================
--- lib/Parrot/Vtable.pm	(revision 9501)
+++ lib/Parrot/Vtable.pm	(working copy)
@@ -293,6 +293,8 @@
 {
     my $vtable = shift;
 
+    my $funcs  = '';
+
     for my $entry (@$vtable)
     {
         my ($return_type, $name, $params, $section, $mmd) = @$entry;
@@ -302,28 +304,45 @@
         my @sig       = ( 'Parrot_INTERP interp', 'Parrot_PMC pmc' );
         my @args      = ( 'interp', 'pmc' );
 
+		
         while (my ($type, $name) = splice( @params, 0, 2 ))
         {
-            push @sig, find_type( $type ) . ' ' . $name;
-            push @args, $name;
+           eval
+           {
+               push @sig, find_type( $type ) . ' ' . $name;
+               push @args, $name;
+            };
         }
 
+        next if $@;
+
         my $signature = join( ', ', @sig  );
         my $arguments = join( ', ', @args );
 
         my $ret_type  = find_type( $return_type );
 
-        printf 
-"%s Parrot_PMC_%s( %s )
+        $funcs .= sprintf 
+"/*
+
+=item C<%s
+%s(%s)>
+
+=cut
+
+*/
+
+%s Parrot_PMC_%s( %s )
 {
     %s retval;
     PARROT_CALLIN_START( interp );
     retval = VTABLE_%s( %s );
     PARROT_CALLIN_END( interp );
     return retval;
-}\n\n", $ret_type, $name, $signature, $ret_type, $name, $arguments;
+}\n\n", ($ret_type, $name, $signature) x 2, $ret_type, $name, $arguments;
 
     }
+
+    return $funcs;
 }
 
 sub find_type
@@ -339,6 +358,7 @@
         'FLOATVAL' => 'Parrot_Float',
         'void'     => 'void',
         'UINTVAL'  => 'Parrot_Int',
+        'size_t'   => 'size_t',
     );
 
     die "Unknown type $type\n" unless exists $typemap{ $type };
--- /dev/null	1969-12-31 16:00:00.000000000 -0800
+++ build_tools/vtable_extend.pl	2005-10-17 11:16:00.000000000 -0700
@@ -0,0 +1,113 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use lib 'lib';
+use Parrot::Vtable;
+
+my $vtable = parse_vtable( 'vtable.tbl' );
+
+open OUT, ">src/extend.c" or die $!;
+
+print OUT <<'EOF';
+/*
+** !!!!!!!   DO NOT EDIT THIS FILE   !!!!!!!
+**
+** This file is generated automatically from 'vtable.tbl' by 
+** build_tools/vtable_extend.pl
+*/
+
+/*
+Copyright: 2001-2003, 2005 The Perl Foundation.  All Rights Reserved.
+
+=head1 NAME
+
+src/extend.c - Parrot extension interface
+
+=head1 DESCRIPTION
+
+These are the functions that Parrot extensions (that is, Parrot subroutines
+written in C, or some other compiled language, rather than in Parrot
+bytecode) may access.
+
+There is a deliberate distancing from the internals here. Don't go
+peeking inside -- you've as much access as bytecode does, but no more,
+so we can provide backwards compatibility for as long as we possibly
+can.
+
+=head2 Functions
+
+=over 4
+
+=cut
+
+*/
+
+/* Some internal notes. Parrot will die a horrible and bizarre death
+   if the stack start pointer's not set and a DOD run is
+   triggered. The pointer *will* be set by the interpreter if the
+   interpreter calls code which calls these functions, so most
+   extension code is safe, no problem.
+
+   The problem comes in if these routines are called from *outside*
+   an interpreter. This happens when an embedding application calls
+   them to do stuff with PMCs, STRINGS, interpreter contents, and
+   suchlike things. This is perfectly legal -- in fact it's what
+   we've documented should be done -- but the problem is that the
+   stack base pointer will be NULL. This is Very Bad.
+
+   To deal with this there are two macros that are defined to handle
+   the problem.
+
+   PARROT_CALLIN_START(interpreter) will figure out if the stack
+   anchor needs setting and, if so, will set it. It must *always*
+   come immediately after the last variable declared in the block
+   making the calls into the interpreter, as it declares a variable
+   and has some code.
+
+   PARROT_CALLIN_END(interpreter) will put the stack anchor back to
+   the way it was, and should always be the last statement before a
+   return. (If you have multiple returns have it in multiple times)
+
+   Not doing this is a good way to introduce bizarre heisenbugs, so
+   just do it. This is the only place they ought to have to be put
+   in, and most of the functions are already written, so it's not
+   like it's an onerous requirement.
+
+*/
+
+#include "parrot/parrot.h"
+#include "parrot/extend.h"
+
+EOF
+
+print OUT vtbl_embed( $vtable );
+
+print OUT <<'EOF';
+/*
+
+=back
+
+=head1 SEE ALSO
+
+See F<include/parrot/extend.h> and F<docs/pdds/pdd11_extending.pod>.
+
+=head1 HISTORY
+
+Initial version by Dan Sugalski.
+
+=cut
+
+*/
+
+/*
+ * Local variables:
+ * c-indentation-style: bsd
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vim: expandtab shiftwidth=4:
+ */
+EOF

Reply via email to