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