dslinux/user/perl/ext/B B.pm B.xs Makefile.PL NOTES O.pm README TESTS Todo defsubs_h.PL typemap

cayenne dslinux_cayenne at user.in-berlin.de
Mon Dec 4 17:59:07 CET 2006


Update of /cvsroot/dslinux/dslinux/user/perl/ext/B
In directory antilope:/tmp/cvs-serv17422/ext/B

Added Files:
	B.pm B.xs Makefile.PL NOTES O.pm README TESTS Todo 
	defsubs_h.PL typemap 
Log Message:
Adding fresh perl source to HEAD to branch from

--- NEW FILE: TESTS ---
Test results from compiling t/*/*.t
		C		Bytecode	CC

base/cond.t	OK		ok		OK
base/if.t	OK		ok		OK
base/lex.t	OK		ok		OK
base/pat.t	OK		ok		OK
base/term.t	OK		ok		OK
cmd/elsif.t	OK		ok		OK
cmd/for.t	OK		ok		ok 1, 2, 3, panic: pp_iter
cmd/mod.t	OK		ok		ok
cmd/subval.t	OK		ok		1..34, not ok 27,28 (simply
						because filename changes).
cmd/switch.t	OK		ok		ok
cmd/while.t	OK		ok		ok
io/argv.t	OK		ok		ok
io/dup.t	OK		ok		ok
io/fs.t		OK		ok		ok
io/inplace.t	OK		ok		ok
io/pipe.t	OK		ok		ok with -umain
io/print.t	OK		ok		ok
io/tell.t	OK		ok		ok
op/append.t	OK		ok		OK
op/array.t	OK		ok		1..36, not ok 7,10 (no $[)
op/auto.t	OK		ok		OK
op/chop.t	OK		ok		OK
op/cond.t	OK		ok		OK
op/delete.t	OK		ok		OK
op/do.t		OK		ok		OK
op/each.t	OK		ok		OK
op/eval.t	OK		ok		ok 1-6 of 16 then exits
op/exec.t	OK		ok		OK
op/exp.t	OK		ok		OK
op/flip.t	OK		ok		OK
op/fork.t	OK		ok		OK
op/glob.t	OK		ok		OK
op/goto.t	OK		ok		1..9, Can't find label label1.
op/groups.t	OK (s/ucb/bin/ under Linux)	OK 1..0 for now.
op/index.t	OK		ok		OK
op/int.t	OK		ok		OK
op/join.t	OK		ok		OK
op/list.t	OK		ok		OK
op/local.t	OK		ok		OK
op/magic.t	OK		ok		OK
op/misc.t	no DATA filehandle so succeeds trivially with 1..0
op/mkdir.t	OK		ok		OK
op/my.t		OK		ok		OK
op/oct.t	OK		ok		OK (C large const warnings)
op/ord.t	OK		ok		OK
op/overload.t	Mostly not ok	Mostly not ok	C errors.
op/pack.t	OK		ok		OK
op/pat.t	omit 26 (reset)	ok		[lots of memory for compile]
op/push.t	OK		ok		OK
op/quotemeta.t	OK		ok		OK
op/rand.t	OK		ok		
op/range.t	OK		ok		OK
op/read.t	OK		ok		OK
op/readdir.t	OK		ok		OK (substcont works too)
op/ref.t	omits "ok 40" (lex destruction)	ok (Bytecode)
						CC: need -u for OBJ,BASEOBJ,
						UNIVERSAL,WHATEVER,main.
						1..41, ok1-33,36-38,
						then ok 41, ok 39.DESTROY probs
op/regexp.t	OK		ok		ok (trivially all eval'd)
op/repeat.t	OK		ok		ok
op/sleep.t	OK		ok		ok
op/sort.t	OK		ok		1..10, ok 1, Out of memory!
op/split.t	OK		ok		ok
op/sprintf.t	OK		ok		ok
op/stat.t	OK		ok		ok
op/study.t	OK		ok		ok
op/subst.t	OK		ok		ok
op/substr.t	OK		ok		ok1-22 except 7-9,11 (all $[)
op/time.t	OK		ok		ok
op/undef.t	omit 21		ok		ok
op/unshift.t	OK		ok		ok
op/vec.t	OK		ok		ok
op/write.t	not ok 3 (no CvOUTSIDE lex from runtime eval). CC: 1..3, hang

--- NEW FILE: Makefile.PL ---
use ExtUtils::MakeMaker;
use Config;
use File::Spec;

my $e = $Config{'exe_ext'};
my $o = $Config{'obj_ext'};
my $exeout_flag = '-o ';
if ($^O eq 'MSWin32') {
    if ($Config{'cc'} =~ /^cl/i) {
	$exeout_flag = '-Fe';
    }
    elsif ($Config{'cc'} =~ /^bcc/i) {
	$exeout_flag = '-e';
    }
}

WriteMakefile(
    NAME	    => "B",
    VERSION_FROM    => "B.pm",
    PL_FILES	    => { 'defsubs_h.PL' => 'defsubs.h' },
    MAN3PODS	    => {},
    clean	    => {
	FILES	    => "perl$e *$o B.c defsubs.h *~"
    }
);

package MY;

sub post_constants {
    "\nLIBS = $Config::Config{libs}\n"
}

sub upupfile {
    File::Spec->catfile(File::Spec->updir,
			File::Spec->updir, $_[0]);
}

sub MY::postamble {
    my $op_h   = upupfile('op.h');
    my $cop_h  = upupfile('cop.h');
    my $noecho = shift->{NOECHO};
"
B\$(OBJ_EXT) : defsubs.h

defsubs.h :: $op_h $cop_h defsubs_h.PL
	\$(PERL) -I\$(INST_ARCHLIB) -I\$(INST_LIB) -I\$(PERL_ARCHLIB) -I\$(PERL_LIB) defsubs_h.PL defsubs.h
"
}

--- NEW FILE: B.pm ---
#      B.pm
#
#      Copyright (c) 1996, 1997, 1998 Malcolm Beattie
#
#      You may distribute under the terms of either the GNU General Public
#      License or the Artistic License, as specified in the README file.
#
package B;

our $VERSION = '1.09_01';

use XSLoader ();
require Exporter;
@ISA = qw(Exporter);

# walkoptree_slow comes from B.pm (you are there),
# walkoptree comes from B.xs
@EXPORT_OK = qw(minus_c ppname save_BEGINs
		class peekop cast_I32 cstring cchar hash threadsv_names
[...1072 lines suppressed...]
=item file

=item cop_seq

=item arybase

=item line

=item warnings

=item io

=back


=head1 AUTHOR

Malcolm Beattie, C<mbeattie at sable.ox.ac.uk>

=cut

--- NEW FILE: NOTES ---
C backend invocation
	If there are any non-option arguments, they are taken to be
	names of objects to be saved (probably doesn't work properly yet).
	Without extra arguments, it saves the main program.
	-ofilename	Output to filename instead of STDOUT
	-v		Verbose (currently gives a few compilation statistics)
	--		Force end of options
	-uPackname	Force apparently unused subs from package Packname to
			be compiled. This allows programs to use eval "foo()"
			even when sub foo is never seen to be used at compile
			time. The down side is that any subs which really are
			never used also have code generated. This option is
			necessary, for example, if you have a signal handler
			foo which you initialise with $SIG{BAR} = "foo".
			A better fix, though, is just to change it to
			$SIG{BAR} = \&foo. You can have multiple -u options.
	-D		Debug options (concat or separate flags like perl -D)
		o	OPs, prints each OP as it's processed
		c	COPs, prints COPs as processed (incl. file & line num)
		A	prints AV information on saving
		C	prints CV information on saving
		M	prints MAGIC information on saving
	-f		Force optimisations on or off one at a time.
		cog	Copy-on-grow: PVs declared and initialised statically
		no-cog	No copy-on-grow
	-On		Optimisation level (n = 0, 1, 2, ...). -O means -O1.
			Currently, -O1 and higher set -fcog.

Examples
	perl -MO=C foo.pl > foo.c
	perl cc_harness -o foo foo.c

	perl -MO=C,-v,-DcA bar.pl > /dev/null

CC backend invocation
	If there are any non-option arguments, they are taken to be names of
	subs to be saved. Without extra arguments, it saves the main program.
	-ofilename	Output to filename instead of STDOUT
	--		Force end of options
	-uPackname	Force apparently unused subs from package Packname to
			be compiled. This allows programs to use eval "foo()"
			even when sub foo is never seen to be used at compile
			time. The down side is that any subs which really are
			never used also have code generated. This option is
			necessary, for example, if you have a signal handler
			foo which you initialise with $SIG{BAR} = "foo".
			A better fix, though, is just to change it to
			$SIG{BAR} = \&foo. You can have multiple -u options.
	-mModulename	Instead of generating source for a runnable executable,
			generate source for an XSUB module. The
			boot_Modulename function (which DynaLoader can look
			for) does the appropriate initialisation and runs the
			main part of the Perl source that is being compiled.
	-pn		Generate code for perl patchlevel n (e.g. 3 or 4).
			The default is to generate C code which will link
			with the currently executing version of perl.
			running the perl compiler.
	-D		Debug options (concat or separate flags like perl -D)
		r	Writes debugging output to STDERR just as it's about
			to write to the program's runtime (otherwise writes
			debugging info as comments in its C output).
		O	Outputs each OP as it's compiled
		s	Outputs the contents of the shadow stack at each OP
		p	Outputs the contents of the shadow pad of lexicals as
			it's loaded for each sub or the main program.
		q	Outputs the name of each fake PP function in the queue
			as it's about to processes.
		l	Output the filename and line number of each original
			line of Perl code as it's processed (pp_nextstate).
		t	Outputs timing information of compilation stages
	-f		Force optimisations on or off one at a time.
		[
		cog	Copy-on-grow: PVs declared and initialised statically
		no-cog	No copy-on-grow
		These two not in CC yet.
		]
		freetmps-each-bblock	Delays FREETMPS from the end of each
					statement to the end of the each basic
					block.
		freetmps-each-loop	Delays FREETMPS from the end of each
					statement to the end of the group of
					basic blocks forming a loop. At most
					one of the freetmps-each-* options can
					be used.
		omit-taint		Omits generating code for handling
					perl's tainting mechanism.
	-On		Optimisation level (n = 0, 1, 2, ...). -O means -O1.
			Currently, -O1 sets -ffreetmps-each-bblock and -O2
			sets -ffreetmps-each-loop.

Example
	perl -MO=CC,-O2,-ofoo.c foo.pl
	perl cc_harness -o foo foo.c

	perl -MO=CC,-mFoo,-oFoo.c Foo.pm
	perl cc_harness -shared -c -o Foo.so Foo.c


Bytecode backend invocation

	If there are any non-option arguments, they are taken to be
	names of objects to be saved (probably doesn't work properly yet).
	Without extra arguments, it saves the main program.
	-ofilename	Output to filename instead of STDOUT.
	--		Force end of options.
	-f		Force optimisations on or off one at a time.
			Each can be preceded by no- to turn the option off.
		compress-nullops
			Only fills in the necessary fields of ops which have
			been optimised away by perl's internal compiler.
		omit-sequence-numbers
			Leaves out code to fill in the op_seq field of all ops
			which is only used by perl's internal compiler.
		bypass-nullops
			If op->op_next ever points to a NULLOP, replaces the
			op_next field with the first non-NULLOP in the path
			of execution.
		strip-syntax-tree
			Leaves out code to fill in the pointers which link the
			internal syntax tree together. They're not needed at
			run-time but leaving them out will make it impossible
			to recompile or disassemble the resulting program.
			It will also stop "goto label" statements from working.
	-On		Optimisation level (n = 0, 1, 2, ...). -O means -O1.
			-O1 sets -fcompress-nullops -fomit-sequence numbers.
			-O6 adds -fstrip-syntax-tree.
	-D		Debug options (concat or separate flags like perl -D)
		o	OPs, prints each OP as it's processed.
		b	print debugging information about bytecompiler progress
		a	tells the assembler to include source assembler lines
			in its output as bytecode comments.
		C	prints each CV taken from the final symbol tree walk.
	-S		Output assembler source rather than piping it
			through the assembler and outputting bytecode.
	-m		Compile as a module rather than a standalone program.
			Currently this just means that the bytecodes for
			initialising main_start, main_root and curpad are
			omitted.

Example
	perl -MO=Bytecode,-O6,-o,foo.plc foo.pl

	perl -MO=Bytecode,-S foo.pl > foo.S
	assemble foo.S > foo.plc
	byteperl foo.plc

	perl -MO=Bytecode,-m,-oFoo.pmc Foo.pm

Backends for debugging
	perl -MO=Terse,exec foo.pl
	perl -MO=Debug bar.pl

O module
	Used with "perl -MO=Backend,foo,bar prog.pl" to invoke the backend
	B::Backend with options foo and bar. O invokes the sub
	B::Backend::compile() with arguments foo and bar at BEGIN time.
	That compile() sub must do any inital argument processing replied.
	If unsuccessful, it should return a string which O arranges to be
	printed as an error message followed by a clean error exit. In the
	normal case where any option processing in compile() is successful,
	it should return a sub ref (usually a closure) to perform the
	actual compilation. When O regains control, it ensures that the
	"-c" option is forced (so that the program being compiled doesn't
	end up running) and registers a CHECK block to call back the sub ref
	returned from the backend's compile(). Perl then continues by
	parsing prog.pl (just as it would with "perl -c prog.pl") and after
	doing so, assuming there are no parse-time errors, the CHECK block
	of O gets called and the actual backend compilation happens. Phew.

--- NEW FILE: O.pm ---
package O;

our $VERSION = '1.00';

use B qw(minus_c save_BEGINs);
use Carp;

sub import {
    my ($class, @options) = @_;
    my ($quiet, $veryquiet) = (0, 0);
    if ($options[0] eq '-q' || $options[0] eq '-qq') {
	$quiet = 1;
	open (SAVEOUT, ">&STDOUT");
	close STDOUT;
	open (STDOUT, ">", \$O::BEGIN_output);
	if ($options[0] eq '-qq') {
	    $veryquiet = 1;
	}
	shift @options;
    }
    my $backend = shift (@options);
    eval q[
	BEGIN {
	    minus_c;
	    save_BEGINs;
	}

	CHECK {
	    if ($quiet) {
		close STDOUT;
		open (STDOUT, ">&SAVEOUT");
		close SAVEOUT;
	    }

	    # Note: if you change the code after this 'use', please
	    # change the fudge factors in B::Concise (grep for
	    # "fragile kludge") so that its output still looks
	    # nice. Thanks. --smcc
	    use B::].$backend.q[ ();
	    if ($@) {
		croak "use of backend $backend failed: $@";
	    }


	    my $compilesub = &{"B::${backend}::compile"}(@options);
	    if (ref($compilesub) ne "CODE") {
		die $compilesub;
	    }

	    local $savebackslash = $\;
	    local ($\,$",$,) = (undef,' ','');
	    &$compilesub();

	    close STDERR if $veryquiet;
	}
    ];
    die $@ if $@;
}

1;

__END__

=head1 NAME

O - Generic interface to Perl Compiler backends

=head1 SYNOPSIS

	perl -MO=[-q,]Backend[,OPTIONS] foo.pl

=head1 DESCRIPTION

This is the module that is used as a frontend to the Perl Compiler.

If you pass the C<-q> option to the module, then the STDOUT
filehandle will be redirected into the variable C<$O::BEGIN_output>
during compilation.  This has the effect that any output printed
to STDOUT by BEGIN blocks or use'd modules will be stored in this
variable rather than printed. It's useful with those backends which
produce output themselves (C<Deparse>, C<Concise> etc), so that
their output is not confused with that generated by the code
being compiled.

The C<-qq> option behaves like C<-q>, except that it also closes
STDERR after deparsing has finished. This suppresses the "Syntax OK"
message normally produced by perl.

=head1 CONVENTIONS

Most compiler backends use the following conventions: OPTIONS
consists of a comma-separated list of words (no white-space).
The C<-v> option usually puts the backend into verbose mode.
The C<-ofile> option generates output to B<file> instead of
stdout. The C<-D> option followed by various letters turns on
various internal debugging flags. See the documentation for the
desired backend (named C<B::Backend> for the example above) to
find out about that backend.

=head1 IMPLEMENTATION

This section is only necessary for those who want to write a
compiler backend module that can be used via this module.

The command-line mentioned in the SYNOPSIS section corresponds to
the Perl code

    use O ("Backend", OPTIONS);

The C<import> function which that calls loads in the appropriate
C<B::Backend> module and calls the C<compile> function in that
package, passing it OPTIONS. That function is expected to return
a sub reference which we'll call CALLBACK. Next, the "compile-only"
flag is switched on (equivalent to the command-line option C<-c>)
and a CHECK block is registered which calls CALLBACK. Thus the main
Perl program mentioned on the command-line is read in, parsed and
compiled into internal syntax tree form. Since the C<-c> flag is
set, the program does not start running (excepting BEGIN blocks of
course) but the CALLBACK function registered by the compiler
backend is called.

In summary, a compiler backend module should be called "B::Foo"
for some foo and live in the appropriate directory for that name.
It should define a function called C<compile>. When the user types

    perl -MO=Foo,OPTIONS foo.pl

that function is called and is passed those OPTIONS (split on
commas). It should return a sub ref to the main compilation function.
After the user's program is loaded and parsed, that returned sub ref
is invoked which can then go ahead and do the compilation, usually by
making use of the C<B> module's functionality.

=head1 BUGS

The C<-q> and C<-qq> options don't work correctly if perl isn't
compiled with PerlIO support : STDOUT will be closed instead of being
redirected to C<$O::BEGIN_output>.

=head1 AUTHOR

Malcolm Beattie, C<mbeattie at sable.ox.ac.uk>

=cut

--- NEW FILE: defsubs_h.PL ---
# Do not remove the following line; MakeMaker relies on it to identify
# this file as a template for defsubs.h
# Extracting defsubs.h (with variable substitutions)
#!perl
my ($out) = __FILE__ =~ /(^.*)\.PL/i;
$out =~ s/_h$/.h/;
open(OUT,">$out") || die "Cannot open $file:$!";
print "Extracting $out...\n";
print OUT <<"END";
/*
 !!! Don't modify this file - it's autogenerated from $0 !!!
 */
END

foreach my $const (qw(
		      AVf_REAL
		      CVf_ANON
		      CVf_ASSERTION
		      CVf_CLONE
		      CVf_CLONED
		      CVf_CONST
		      CVf_LOCKED
		      CVf_LVALUE
		      CVf_METHOD
		      CVf_NODEBUG
		      CVf_OLDSTYLE
		      CVf_UNIQUE
		      CVf_WEAKOUTSIDE
		      GVf_IMPORTED_AV
		      GVf_IMPORTED_CV
		      GVf_IMPORTED_HV
		      GVf_IMPORTED_SV
		      HEf_SVKEY
		      SVTYPEMASK
		      SVf_FAKE
		      SVf_IOK
		      SVf_IVisUV
		      SVf_NOK
		      SVf_POK
		      SVf_READONLY
		      SVf_ROK
		      SVp_IOK
		      SVp_NOK
		      SVp_POK
		      SVpad_OUR
		      SVs_RMG
		      SVs_SMG
		      SVt_PVGV
		      SVt_PVHV
		      ))
 {
  doconst($const);
 }
foreach my $file (qw(op.h cop.h))
 {
  my $path = $^O eq 'MacOS' ? ":::$file" : "../../$file";
  open(OPH,"$path") || die "Cannot open $path:$!";
  while (<OPH>)
   {  
    doconst($1) if (/#define\s+(\w+)\s+([\(\)\|\dx]+)\s*(?:$|\/\*)/);
   }  
  close(OPH);
 }
close(OUT);
               
sub doconst
{
 my $sym = shift;
 my $l = length($sym);
 print OUT <<"END";
 newCONSTSUB(stash,"$sym",newSViv($sym)); 
 av_push(export_ok,newSVpvn("$sym",$l));
END
}

--- NEW FILE: B.xs ---
/*	B.xs
 *
 *	Copyright (c) 1996 Malcolm Beattie
 *
 *	You may distribute under the terms of either the GNU General Public
 *	License or the Artistic License, as specified in the README file.
 *
 */

#define PERL_NO_GET_CONTEXT
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

#ifdef PerlIO
typedef PerlIO * InputStream;
#else
typedef FILE * InputStream;
#endif
[...1677 lines suppressed...]

B::PMOP
HvPMROOT(hv)
	B::HV	hv

void
HvARRAY(hv)
	B::HV	hv
    PPCODE:
	if (HvKEYS(hv) > 0) {
	    SV *sv;
	    char *key;
	    I32 len;
	    (void)hv_iterinit(hv);
	    EXTEND(sp, HvKEYS(hv) * 2);
	    while ((sv = hv_iternextsv(hv, &key, &len))) {
		PUSHs(newSVpvn(key, len));
		PUSHs(make_sv_object(aTHX_ sv_newmortal(), sv));
	    }
	}

--- NEW FILE: README ---
		  Perl Compiler Kit, Version alpha4

		 Copyright (c) 1996, 1997, Malcolm Beattie

    This program is free software; you can redistribute it and/or modify
    it under the terms of either:

	a) the GNU General Public License as published by the Free
	Software Foundation; either version 1, or (at your option) any
	later version, or

	b) the "Artistic License" which comes with this kit.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See either
    the GNU General Public License or the Artistic License for more details.

    You should have received a copy of the Artistic License with this kit,
    in the file named "Artistic".  If not, you can get one from the Perl
    distribution. You should also have received a copy of the GNU General
    Public License, in the file named "Copying". If not, you can get one
    from the Perl distribution or else write to the Free Software Foundation,
    Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.

CHANGES

New since alpha3
    Anonymous subs work properly with C and CC.
    Heuristics for forcing compilation of apparently unused subs/methods.
    Subs which use the AutoLoader module are forcibly loaded at compile-time.
    Slightly faster compilation.
    Handles slightly more complex code within a BEGIN { }.
    Minor bug fixes.

New since alpha2
    CC backend now supports ".." and s//e.
    Xref backend generates cross-reference reports
    Cleanups to fix benign but irritating "-w" warnings
    Minor cxstack fix
New since alpha1
    Working CC backend
    Shared globs and pre-initialised hash support
    Some XSUB support
    Assorted bug fixes

INSTALLATION

(1) You need perl5.002 or later.

(2) If you want to compile and run programs with the C or CC backends
which undefine (or redefine) subroutines, then you need to apply a
one-line patch to perl itself. One or two of the programs in perl's
own test suite do this. The patch is in file op.patch. It prevents
perl from calling free() on OPs with the magic sequence number (U16)-1.
The compiler declares all OPs as static structures and uses that magic
sequence number.

(3) Type
    perl Makefile.PL
to write a personalised Makefile for your system. If you want the
bytecode modules to support reading bytecode from strings (instead of
just from files) then add the option
    -DINDIRECT_BGET_MACROS
into the middle of the definition of the CCCMD macro in the Makefile.
Your C compiler may need to be able to cope with Standard C for this.
I haven't tested this option yet with an old pre-Standard compiler.

(4) If your platform supports dynamic loading then just type
    make
and you can then use
    perl -Iblib/arch -MO=foo bar
to use the compiler modules (see later for details).
If you need/want instead to make a statically linked perl which
contains the appropriate modules, then type
    make perl
    make byteperl
and you can then use
    ./perl -MO=foo bar
to use the compiler modules.    
In both cases, the byteperl executable is required for running standalone
bytecode programs. It is *not* a standard perl+XSUB perl executable.

USAGE

As of the alpha3 release, the Bytecode, C and CC backends are now all
functional enough to compile almost the whole of the main perl test
suite. In the case of the CC backend, any failures are all due to
differences and/or known bugs documented below. See the file TESTS.
In the following examples, you'll need to replace "perl" by
    perl -Iblib/arch
if you have built the extensions for a dynamic loading platform but
haven't installed the extensions completely. You'll need to replace
"perl" by
    ./perl
if you have built the extensions into a statically linked perl binary.

(1) To compile perl program foo.pl with the C backend, do
    perl -MO=C,-ofoo.c foo.pl
Then use the cc_harness perl program to compile the resulting C source:
    perl cc_harness -O2 -o foo foo.c

If you are using a non-ANSI pre-Standard C compiler that can't handle
pre-declaring static arrays, then add -DBROKEN_STATIC_REDECL to the
options you use:
    perl cc_harness -O2 -o foo -DBROKEN_STATIC_REDECL foo.c
If you are using a non-ANSI pre-Standard C compiler that can't handle
static initialisation of structures with union members then add
-DBROKEN_UNION_INIT to the options you use. If you want command line
arguments passed to your executable to be interpreted by perl (e.g. -Dx)
then compile foo.c with -DALLOW_PERL_OPTIONS. Otherwise, all command line
arguments passed to foo will appear directly in @ARGV.  The resulting
executable foo is the compiled version of foo.pl. See the file NOTES for
extra options you can pass to -MO=C.

There are some constraints on the contents on foo.pl if you want to be
able to compile it successfully. Some problems can be fixed fairly easily
by altering foo.pl; some problems with the compiler are known to be
straightforward to solve and I'll do so soon. The file Todo lists a
number of known problems. See the XSUB section lower down for information
about compiling programs which use XSUBs.

(2) To compile foo.pl with the CC backend (which generates actual
optimised C code for the execution path of your perl program), use
    perl -MO=CC,-ofoo.c foo.pl

and proceed just as with the C backend. You should almost certainly
use an option such as -O2 with the subsequent cc_harness invocation
so that your C compiler uses optimisation. The C code generated by
the Perl compiler's CC backend looks ugly to humans but is easily
optimised by C compilers.

To make the most of this compiler backend, you need to tell the
compiler when you're using int or double variables so that it can
optimise appropriately (although this part of the compiler is the most
buggy). You currently do that by naming lexical variables ending in
"_i" for ints, "_d" for doubles, "_ir" for int "register" variables or
"_dr" for double "register" variables. Here "register" is a promise
that you won't pass a reference to the variable into a sub which then
modifies the variable. The compiler ought to catch attempts to use
"\$i" just as C compilers catch attempts to do "&i" for a register int
i but it doesn't at the moment. Bugs in the CC backend may make your
program fail in mysterious ways and give wrong answers rather than just
crash in boring ways. But, hey, this is an alpha release so you knew
that anyway. See the XSUB section lower down for information about
compiling programs which use XSUBs.

If your program uses classes which define methods (or other subs which
are not exported and not apparently used until runtime) then you'll
need to use -u compile-time options (see the NOTES file) to force the
subs to be compiled. Future releases will probably default the other
way, do more auto-detection and provide more fine-grained control.

Since compiled executables need linking with libperl, you may want
to turn libperl.a into a shared library if your platform supports
it. For example, with Digital UNIX, do something like
    ld -shared -o libperl.so -all libperl.a -none -lc
and with Linux/ELF, rebuild the perl .c files with -fPIC (and I
also suggest -fomit-frame-pointer for Linux on Intel architetcures),
do "make libperl.a" and then do
    gcc -shared -Wl,-soname,libperl.so.5 -o libperl.so.5.3 `ar t libperl.a`
and then
    # cp libperl.so.5.3 /usr/lib
    # cd /usr/lib
    # ln -s libperl.so.5.3 libperl.so.5
    # ln -s libperl.so.5 libperl.so
    # ldconfig
When you compile perl executables with cc_harness, append -L/usr/lib
otherwise the -L for the perl source directory will override it. For
example,
    perl -Iblib/arch -MO=CC,-O2,-ofoo3.c foo3.bench
    perl cc_harness -o foo3 -O2 foo3.c -L/usr/lib
    ls -l foo3
    -rwxr-xr-x   1 mbeattie xzdg        11218 Jul  1 15:28 foo3
You'll probably also want to link your main perl executable against
libperl.so; it's nice having an 11K perl executable.

(3) To compile foo.pl into bytecode do
    perl -MO=Bytecode,-ofoo foo.pl
To run the resulting bytecode file foo as a standalone program, you
use the program byteperl which should have been built along with the
extensions.
    ./byteperl foo
Any extra arguments are passed in as @ARGV; they are not interpreted
as perl options. If you want to load chunks of bytecode into an already
running perl program then use the -m option and investigate the
byteload_fh and byteload_string functions exported by the B module.
See the NOTES file for details of these and other options (including
optimisation options and ways of getting at the intermediate "assembler"
code that the Bytecode backend uses).

(3) There are little Bourne shell scripts and perl programs to aid with
some common operations: assemble, disassemble, run_bytecode_test,
run_test, cc_harness, test_harness, test_harness_bytecode.

(4) Walk the op tree in execution order printing terse info about each op
    perl -MO=Terse,exec foo.pl

(5) Walk the op tree in syntax order printing lengthier debug info about
each op. You can also append ",exec" to walk in execution order, but the
formatting is designed to look nice with Terse rather than Debug.
    perl -MO=Debug foo.pl

(6) Produce a cross-reference report of the line numbers at which all
variables, subs and formats are defined and used.
    perl -MO=Xref foo.pl

XSUBS

The C and CC backends can successfully compile some perl programs which
make use of XSUB extensions. [I'll add more detail to this section in a
later release.] As a prerequisite, such extensions must not need to do
anything in their BOOT: section which needs to be done at runtime rather
than compile time. Normally, the only code in the boot_Foo() function is
a list of newXS() calls which xsubpp puts there and the compiler handles
saving those XS subs itself. For each XSUB used, the C and CC compiler
will generate an initialiser in their C output which refers to the name
of the relevant C function (XS_Foo_somesub). What is not yet automated
is the necessary commands and cc command-line options (e.g. via
"perl cc_harness") which link against the extension libraries. For now,
you need the XSUB extension to have installed files in the right format
for using as C libraries (e.g. Foo.a or Foo.so). As the Foo.so files (or
your platform's version) aren't suitable for linking against, you will
have to reget the extension source and rebuild it as a static extension
to force the generation of a suitable Foo.a file. Then you need to make
a symlink (or copy or rename) of that file into a libFoo.a suitable for
cc linking. Then add the appropriate -L and -l options to your
"perl cc_harness" command line to find and link against those libraries.
You may also need to fix up some platform-dependent environment variable
to ensure that linked-against .so files are found at runtime too.

DIFFERENCES

The result of running a compiled Perl program can sometimes be different
from running the same program with standard perl. Think of the compiler
as having a slightly different implementation of the language Perl.
Unfortunately, since Perl has had a single implementation until now,
there are no formal standards or documents defining what behaviour is
guaranteed of Perl the language and what just "happens to work".
Some of the differences below are almost impossible to change because of
the way the compiler works. Others can be changed to produce "standard"
perl behaviour if it's deemed proper and the resulting performance hit
is accepted. I'll use "standard perl" to mean the result of running a
Perl program using the perl executable from the perl distribution.
I'll use "compiled Perl program" to mean running an executable produced
by this compiler kit ("the compiler") with the CC backend.

Loops
    Standard perl calculates the target of "next", "last", and "redo"
    at run-time. The compiler calculates the targets at compile-time.
    For example, the program

        sub skip_on_odd { next NUMBER if $_[0] % 2 }
        NUMBER: for ($i = 0; $i < 5; $i++) {
            skip_on_odd($i);
            print $i;
        }

    produces the output
        024
    with standard perl but gives a compile-time error with the compiler.

Context of ".."
    The context (scalar or array) of the ".." operator determines whether
    it behaves as a range or a flip/flop. Standard perl delays until
    runtime the decision of which context it is in but the compiler needs
    to know the context at compile-time. For example,
	@a = (4,6,1,0,0,1);
	sub range { (shift @a)..(shift @a) }
	print range();
	while (@a) { print scalar(range()) }
    generates the output
        456123E0
    with standard Perl but gives a compile-time error with compiled Perl.

Arithmetic
    Compiled Perl programs use native C arithemtic much more frequently
    than standard perl. Operations on large numbers or on boundary
    cases may produce different behaviour.

Deprecated features
    Features of standard perl such as $[ which have been deprecated
    in standard perl since version 5 was released have not been
    implemented in the compiler.

Others
    I'll add to this list as I remember what they are.

BUGS

Here are some things which may cause the compiler problems.

The following render the compiler useless (without serious hacking):
* Use of the DATA filehandle (via __END__ or __DATA__ tokens)
* Operator overloading with %OVERLOAD
* The (deprecated) magic array-offset variable $[ does not work
* The following operators are not yet implemented for CC
    goto
    sort with a non-default comparison (i.e. a named sub or inline block)
* You can't use "last" to exit from a non-loop block.

The following may give significant problems:
* BEGIN blocks containing complex initialisation code
* Code which is only ever referred to at runtime (e.g. via eval "..." or
  via method calls): see the -u option for the C and CC backends.
* Run-time lookups of lexical variables in "outside" closures

The following may cause problems (not thoroughly tested):
* Dependencies on whether values of some "magic" Perl variables are
  determined at compile-time or runtime.
* For the C and CC backends: compile-time strings which are longer than
  your C compiler can cope with in a single line or definition.
* Reliance on intimate details of global destruction
* For the Bytecode backend: high -On optimisation numbers with code
  that has complex flow of control.
* Any "-w" option in the first line of your perl program is seen and
  acted on by perl itself before the compiler starts. The compiler
  itself then runs with warnings turned on. This may cause perl to
  print out warnings about the compiler itself since I haven't tested
  it thoroughly with warnings turned on.

There is a terser but more complete list in the Todo file.

Malcolm Beattie
2 September 1996

--- NEW FILE: Todo ---
* Fixes

CC backend: goto, sort with non-default comparison. last for non-loop blocks.
Version checking
improve XSUB handling (both static and dynamic)
sv_magic can do SvREFCNT_inc(obj) which messes up precalculated refcounts
allocation of XPV[INAHC]V structures needs fixing: Perl tries to free
them whereas the compiler expects them to be linked to a xpv[inahc]v_root
list the same as X[IPR]V structures.
ref counts
perl_parse replacement
fix cstring for long strings
compile-time initialisation of AvARRAYs
signed/unsigned problems with NV (and IV?) initialisation and elsewhere?
CvOUTSIDE for ordinary subs
DATA filehandle for standalone Bytecode program (easy)
DATA filehandle for multiple bytecode-compiled modules (harder)
DATA filehandle for C-compiled program (yet harder)

* Features

type checking
compile time v. runtime initialisation
save PMOPs in compiled form
selection of what to dump
options for cutting out line info etc.
comment output
shared constants
module dependencies

* Optimisations
collapse LISTOPs to UNOPs or BASEOPs
compile-time qw(), constant subs
global analysis of variables, type hints etc.
demand-loaded bytecode (leader of each basic block replaced by an op
which loads in bytecode for its block)
fast sub calls for CC backend

--- NEW FILE: typemap ---
TYPEMAP

B::OP		T_OP_OBJ
B::UNOP		T_OP_OBJ
B::BINOP	T_OP_OBJ
B::LOGOP	T_OP_OBJ
B::LISTOP	T_OP_OBJ
B::PMOP		T_OP_OBJ
B::SVOP		T_OP_OBJ
B::PADOP	T_OP_OBJ
B::PVOP		T_OP_OBJ
B::LOOP		T_OP_OBJ
B::COP		T_OP_OBJ

B::SV		T_SV_OBJ
B::PV		T_SV_OBJ
B::IV		T_SV_OBJ
B::NV		T_SV_OBJ
B::PVMG		T_SV_OBJ
B::PVLV		T_SV_OBJ
B::BM		T_SV_OBJ
B::RV		T_SV_OBJ
B::GV		T_SV_OBJ
B::CV		T_SV_OBJ
B::HV		T_SV_OBJ
B::AV		T_SV_OBJ
B::IO		T_SV_OBJ
B::FM		T_SV_OBJ

B::MAGIC	T_MG_OBJ
SSize_t		T_IV
STRLEN		T_UV
PADOFFSET	T_UV

INPUT
T_OP_OBJ
	if (SvROK($arg)) {
	    IV tmp = SvIV((SV*)SvRV($arg));
	    $var = INT2PTR($type,tmp);
	}
	else
	    croak(\"$var is not a reference\")

T_SV_OBJ
	if (SvROK($arg)) {
	    IV tmp = SvIV((SV*)SvRV($arg));
	    $var = INT2PTR($type,tmp);
	}
	else
	    croak(\"$var is not a reference\")

T_MG_OBJ
	if (SvROK($arg)) {
	    IV tmp = SvIV((SV*)SvRV($arg));
	    $var = INT2PTR($type,tmp);
	}
	else
	    croak(\"$var is not a reference\")

OUTPUT
T_OP_OBJ
	sv_setiv(newSVrv($arg, cc_opclassname(aTHX_ (OP*)$var)), PTR2IV($var));

T_SV_OBJ
	make_sv_object(aTHX_ ($arg), (SV*)($var));


T_MG_OBJ
	sv_setiv(newSVrv($arg, "B::MAGIC"), PTR2IV($var));




More information about the dslinux-commit mailing list