ext/B/ramblings/reg.alloc Compiler ramblings: register allocation
ext/B/ramblings/runtime.porting Compiler ramblings: porting PP enging
ext/B/typemap Compiler backend interface types
+ext/ByteLoader/ByteLoader.pm Bytecode loader Perl module
+ext/ByteLoader/ByteLoader.xs Bytecode loader external subroutines
+ext/ByteLoader/Makefile.PL Bytecode loader makefile writer
ext/DB_File/Changes Berkeley DB extension change log
ext/DB_File/DB_File.pm Berkeley DB extension Perl module
ext/DB_File/DB_File.xs Berkeley DB extension external subroutines
utils/h2ph.PL A thing to turn C .h files into perl .ph files
utils/h2xs.PL Program to make .xs files from C header files
utils/perlbug.PL A simple tool to submit a bug report
+utils/perlbc.PL Front-end for bytecode compiler
utils/perlcc.PL Front-end for compiler
utils/perldoc.PL A simple tool to find & display perl's documentation
utils/pl2pm.PL A pl to pm translator
o->op_ppaddr = PL_ppaddr[arg]; \
} STMT_END
#define BSET_op_ppaddr(o, arg) croak("op_ppaddr not yet implemented")
-#define BSET_curpad(pad, arg) pad = AvARRAY(arg)
+#define BSET_curpad(pad, arg) STMT_START { \
+ PL_comppad = (AV *)arg; \
+ pad = AvARRAY(arg); \
+ } STMT_END
#define BSET_OBJ_STORE(obj, ix) \
(I32)ix > PL_bytecode_obj_list_fill ? \
cop_seq cCOP->cop_seq U32
cop_arybase cCOP->cop_arybase I32
cop_line cCOP->cop_line line_t
+cop_warnings cCOP->cop_warnings svindex
main_start PL_main_start opindex
main_root PL_main_root opindex
curpad PL_curpad svindex x
cCOP->cop_line = arg;
break;
}
- case INSN_MAIN_START: /* 116 */
+ case INSN_COP_WARNINGS: /* 116 */
+ {
+ svindex arg;
+ BGET_svindex(arg);
+ cCOP->cop_warnings = arg;
+ break;
+ }
+ case INSN_MAIN_START: /* 117 */
{
opindex arg;
BGET_opindex(arg);
PL_main_start = arg;
break;
}
- case INSN_MAIN_ROOT: /* 117 */
+ case INSN_MAIN_ROOT: /* 118 */
{
opindex arg;
BGET_opindex(arg);
PL_main_root = arg;
break;
}
- case INSN_CURPAD: /* 118 */
+ case INSN_CURPAD: /* 119 */
{
svindex arg;
BGET_svindex(arg);
};
#endif /* INDIRECT_BGET_MACROS */
-#ifndef PERL_OBJECT
void *bset_obj_store _((void *, I32));
-#endif
enum {
INSN_RET, /* 0 */
INSN_COP_SEQ, /* 113 */
INSN_COP_ARYBASE, /* 114 */
INSN_COP_LINE, /* 115 */
- INSN_MAIN_START, /* 116 */
- INSN_MAIN_ROOT, /* 117 */
- INSN_CURPAD, /* 118 */
- MAX_INSN = 118
+ INSN_COP_WARNINGS, /* 116 */
+ INSN_MAIN_START, /* 117 */
+ INSN_MAIN_ROOT, /* 118 */
+ INSN_CURPAD, /* 119 */
+ MAX_INSN = 119
};
enum {
#define dofindlabel CPerlObj::Perl_dofindlabel
#define dofindlabel CPerlObj::Perl_dofindlabel
#define doform CPerlObj::Perl_doform
+#define doopen CPerlObj::Perl_doopen
#define doparseform CPerlObj::Perl_doparseform
#define dopoptoeval CPerlObj::Perl_dopoptoeval
#define dopoptoeval CPerlObj::Perl_dopoptoeval
dopoptosub_at
save_lines
doeval
+ doopen
sv_ncmp
sv_i_ncmp
amagic_ncmp
#define COP_cop_seq(o) o->cop_seq
#define COP_arybase(o) o->cop_arybase
#define COP_line(o) o->cop_line
+#define COP_warnings(o) o->cop_warnings
MODULE = B PACKAGE = B::COP PREFIX = COP_
COP_line(o)
B::COP o
+B::SV
+COP_warnings(o)
+ B::COP o
+
MODULE = B PACKAGE = B::SV PREFIX = Sv
U32
$insn_data{cop_seq} = [113, \&PUT_U32, "GET_U32"];
$insn_data{cop_arybase} = [114, \&PUT_I32, "GET_I32"];
$insn_data{cop_line} = [115, \&PUT_U16, "GET_U16"];
-$insn_data{main_start} = [116, \&PUT_opindex, "GET_opindex"];
-$insn_data{main_root} = [117, \&PUT_opindex, "GET_opindex"];
-$insn_data{curpad} = [118, \&PUT_svindex, "GET_svindex"];
+$insn_data{cop_warnings} = [116, \&PUT_svindex, "GET_svindex"];
+$insn_data{main_start} = [117, \&PUT_opindex, "GET_opindex"];
+$insn_data{main_root} = [118, \&PUT_opindex, "GET_opindex"];
+$insn_data{curpad} = [119, \&PUT_svindex, "GET_svindex"];
my ($insn_name, $insn_data);
while (($insn_name, $insn_data) = each %insn_data) {
my $filegv = $op->filegv;
my $filegvix = $filegv->objix;
my $line = $op->line;
+ my $warnings = $op->warnings;
+ my $warningsix = $warnings->objix;
if ($debug_bc) {
printf "# line %s:%d\n", $filegv->SV->PV, $line;
}
cop_filegv $filegvix
cop_arybase %d
cop_line $line
+cop_warnings $warningsix
EOT
$filegv->bytecode;
$stash->bytecode;
my ($op) = @_;
$op->B::OP::debug();
my ($filegv) = $op->filegv;
- printf <<'EOT', $op->label, ${$op->stash}, $$filegv, $op->seq, $op->arybase, $op->line;
+ printf <<'EOT', $op->label, ${$op->stash}, $$filegv, $op->seq, $op->arybase, $op->line, ${$op->warnings};
cop_label %s
cop_stash 0x%x
cop_filegv 0x%x
cop_seq %d
cop_arybase %d
cop_line %d
+ cop_warnings 0x%x
EOT
$filegv->debug;
}
--- /dev/null
+package ByteLoader;
+
+use strict;
+use vars qw($VERSION @ISA);
+
+require DynaLoader;
+
+@ISA = qw(DynaLoader);
+
+$VERSION = 0.01;
+
+bootstrap ByteLoader $VERSION;
+
+# Preloaded methods go here.
+
+1;
+__END__
+
+=head1 NAME
+
+ByteLoader - load byte compiled perl code
+
+=head1 SYNOPSIS
+
+ use ByteLoader 0.01;
+ <byte code>
+
+ use ByteLoader 0.01;
+ <byte code>
+
+=head1 DESCRIPTION
+
+This module is used to load byte compiled perl code. It uses the source
+filter mechanism to read the byte code and insert it into the compiled
+code at the appropriate point.
+
+=head1 AUTHOR
+
+Tom Hughes <tom@compton.nu> based on the ideas of Tim Bunce and others.
+
+=head1 SEE ALSO
+
+perl(1).
+
+=cut
--- /dev/null
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+
+#include "byterun.c"
+
+/* defgv must be accessed differently under threaded perl */
+/* DEFSV et al are in 5.004_56 */
+#ifndef DEFSV
+#define DEFSV GvSV(defgv)
+#endif
+
+static I32
+#ifdef PERL_OBJECT
+byteloader_filter(CPerlObj *pPerl, int idx, SV *buf_sv, int maxlen)
+#else
+byteloader_filter(int idx, SV *buf_sv, int maxlen)
+#endif
+{
+ OP *saveroot = PL_main_root;
+ OP *savestart = PL_main_start;
+
+#ifdef INDIRECT_BGET_MACROS
+ struct bytesream bs;
+
+ bs.data = PL_rsfp;
+ bs.fgetc = (int(*) _((void*)))fgetc;
+ bs.fread = (int(*) _((char*,size_t,size_t,void*)))fread;
+ bs.freadpv = freadpv;
+#else
+ byterun(PL_rsfp);
+#endif
+
+ if (PL_in_eval) {
+ OP *o;
+
+ PL_eval_start = PL_main_start;
+
+ o = newSVOP(OP_CONST, 0, newSViv(1));
+ PL_eval_root = newLISTOP(OP_LINESEQ, 0, PL_main_root, o);
+ PL_main_root->op_next = o;
+ PL_eval_root = newUNOP(OP_LEAVEEVAL, 0, PL_eval_root);
+ o->op_next = PL_eval_root;
+
+ PL_main_root = saveroot;
+ PL_main_start = savestart;
+ }
+
+ return 0;
+}
+
+MODULE = ByteLoader PACKAGE = ByteLoader
+
+PROTOTYPES: ENABLE
+
+void
+import(...)
+ PPCODE:
+ filter_add(byteloader_filter, NULL);
+
+void
+unimport(...)
+ PPCODE:
+ filter_del(byteloader_filter);
--- /dev/null
+use ExtUtils::MakeMaker;
+# See lib/ExtUtils/MakeMaker.pm for details of how to influence
+# the contents of the Makefile that is written.
+WriteMakefile(
+ 'NAME' => 'ByteLoader',
+ 'VERSION_FROM' => 'ByteLoader.pm', # finds $VERSION
+ 'LIBS' => [''], # e.g., '-lm'
+ 'DEFINE' => '', # e.g., '-DHAVE_SOMETHING'
+ 'INC' => '-I$(PERL_SRC)', # e.g., '-I/usr/include/other'
+);
#define dofindlabel pPerl->Perl_dofindlabel
#undef doform
#define doform pPerl->Perl_doform
+#undef doopen
+#define doopen pPerl->Perl_doopen
#undef doparseform
#define doparseform pPerl->Perl_doparseform
#undef dopoptoeval
{
dTHR;
if (PL_in_eval) {
+ if (PL_eval_root)
+ return;
PL_eval_root = newUNOP(OP_LEAVEEVAL, ((PL_in_eval & 4) ? OPf_SPECIAL : 0), o);
PL_eval_start = linklist(PL_eval_root);
PL_eval_root->op_next = 0;
static I32 sortcv _((SV *a, SV *b));
static void qsortsv _((SV **array, size_t num_elts, I32 (*fun)(SV *a, SV *b)));
static OP *doeval _((int gimme, OP** startop));
+static PerlIO *doopen _((const char *name, const char *mode));
static I32 sv_ncmp _((SV *a, SV *b));
static I32 sv_i_ncmp _((SV *a, SV *b));
static I32 amagic_ncmp _((SV *a, SV *b));
RETURNOP(PL_eval_start);
}
+static PerlIO *
+doopen(const char *name, const char *mode)
+{
+ STRLEN namelen = strlen(name);
+ PerlIO *fp;
+
+ if (namelen > 3 && strcmp(name + namelen - 3, ".pm") == 0) {
+ SV *pmcsv = newSVpvf("%s%c", name, 'c');
+ char *pmc = SvPV_nolen(pmcsv);
+ Stat_t pmstat;
+ Stat_t pmcstat;
+ if (PerlLIO_stat(pmc, &pmcstat) < 0) {
+ fp = PerlIO_open(name, mode);
+ } else {
+ if (PerlLIO_stat(name, &pmstat) < 0 ||
+ pmstat.st_mtime < pmcstat.st_mtime) {
+ fp = PerlIO_open(pmc, mode);
+ } else {
+ fp = PerlIO_open(name, mode);
+ }
+ }
+ SvREFCNT_dec(pmcsv);
+ } else {
+ fp = PerlIO_open(name, mode);
+ }
+
+ return fp;
+}
+
PP(pp_require)
{
djSP;
)
{
tryname = name;
- tryrsfp = PerlIO_open(name,PERL_SCRIPT_MODE);
+ tryrsfp = doopen(name,PERL_SCRIPT_MODE);
}
else {
AV *ar = GvAVn(PL_incgv);
#endif
TAINT_PROPER("require");
tryname = SvPVX(namesv);
- tryrsfp = PerlIO_open(tryname, PERL_SCRIPT_MODE);
+ tryrsfp = doopen(tryname, PERL_SCRIPT_MODE);
if (tryrsfp) {
if (tryname[0] == '.' && tryname[1] == '/')
tryname += 2;
I32 dopoptosub_at _((PERL_CONTEXT* cxstk, I32 startingblock));
void save_lines _((AV *array, SV *sv));
OP *doeval _((int gimme, OP** startop));
+PerlIO *doopen _((const char *name, const char *mode));
I32 sv_ncmp _((SV *a, SV *b));
I32 sv_i_ncmp _((SV *a, SV *b));
I32 amagic_ncmp _((SV *a, SV *b));
# Files to be built with variable substitution after miniperl is
# available. Dependencies handled manually below (for now).
-pl = c2ph.PL h2ph.PL h2xs.PL perlbug.PL perldoc.PL pl2pm.PL splain.PL perlcc.PL
-plextract = c2ph h2ph h2xs perlbug perldoc pl2pm splain perlcc
-plextractexe = c2ph.exe h2ph.exe h2xs.exe perlbug.exe perldoc.exe pl2pm.exe splain.exe perlcc.exe
+pl = c2ph.PL h2ph.PL h2xs.PL perlbug.PL perldoc.PL pl2pm.PL splain.PL perlcc.PL perlbc.PL
+plextract = c2ph h2ph h2xs perlbug perldoc pl2pm splain perlcc perlbc
+plextractexe = c2ph.exe h2ph.exe h2xs.exe perlbug.exe perldoc.exe pl2pm.exe splain.exe perlcc.exe perlbc.exe
all: $(plextract)
splain: splain.PL ../config.sh ../lib/diagnostics.pm
-perlcc: perlcc.PL ../config.sh
+perlcc: perlcc.PL ../config.sh
+
+perlbc: perlbc.PL ../config.sh
clean:
--- /dev/null
+#!/usr/local/bin/perl
+
+use Config;
+use File::Basename qw(&basename &dirname);
+use Cwd;
+
+# List explicitly here the variables you want Configure to
+# generate. Metaconfig only looks for shell variables, so you
+# have to mention them as if they were shell variables, not
+# %Config entries. Thus you write
+# $startperl
+# to ensure Configure will look for $Config{startperl}.
+# Wanted: $archlibexp
+
+# This forces PL files to create target in same directory as PL file.
+# This is so that make depend always knows where to find PL derivatives.
+$origdir = cwd;
+chdir dirname($0);
+$file = basename($0, '.PL');
+$file .= '.com' if $^O eq 'VMS';
+
+open OUT,">$file" or die "Can't create $file: $!";
+
+print "Extracting $file (with variable substitutions)\n";
+
+# In this section, perl variables will be expanded during extraction.
+# You can use $Config{...} to use Configure variables.
+
+print OUT <<"!GROK!THIS!";
+$Config{startperl}
+ eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}'
+ if \$running_under_some_shell;
+!GROK!THIS!
+
+# In the following, perl variables are not expanded during extraction.
+
+print OUT <<'!NO!SUBS!';
+
+use strict;
+use warning;
+no warning qw(once);
+
+use Config;
+
+require ByteLoader;
+
+foreach my $infile (@ARGV)
+{
+ if ($infile =~ /\.p[ml]$/)
+ {
+ my $outfile = $infile . "c";
+
+ open(OUT,"> $outfile") || die "Can't open $outfile: $!";
+
+ if ($infile =~ /\.pl$/)
+ {
+ print OUT "$Config{startperl}\n";
+ print OUT " eval 'exec $Config{perlpath} -S \$0 \${1+\"\$@\"}'\n";
+ print OUT " if \$running_under_some_shell;\n\n";
+ }
+
+ print OUT "use ByteLoader $ByteLoader::VERSION;\n";
+
+ close(OUT);
+
+ print "$^X -MO=Bytecode $infile >> $outfile\n";
+
+ system("$^X -MO=Bytecode $infile >> $outfile");
+ }
+ else
+ {
+ warn "Don't know how to byte compile $infile";
+ }
+}
+!NO!SUBS!
+
+close OUT or die "Can't close $file: $!";
+chmod 0755, $file or die "Can't reset permissions for $file: $!\n";
+exec("$Config{'eunicefix'} $file") if $Config{'eunicefix'} ne ':';
+chdir $origdir;
!ENDIF
DYNAMIC_EXT = Socket IO Fcntl Opcode SDBM_File POSIX attrs Thread B re \
- Data/Dumper Devel/Peek
+ Data/Dumper Devel/Peek ByteLoader
STATIC_EXT = DynaLoader
NONXS_EXT = Errno
DUMPER = $(EXTDIR)\Data\Dumper\Dumper
ERRNO = $(EXTDIR)\Errno\Errno
PEEK = $(EXTDIR)\Devel\Peek\Peek
+BYTELOADER = $(EXTDIR)\ByteLoader
SOCKET_DLL = $(AUTODIR)\Socket\Socket.dll
FCNTL_DLL = $(AUTODIR)\Fcntl\Fcntl.dll
DUMPER_DLL = $(AUTODIR)\Data\Dumper\Dumper.dll
PEEK_DLL = $(AUTODIR)\Devel\Peek\Peek.dll
RE_DLL = $(AUTODIR)\re\re.dll
+BYTELOADER_DLL = $(AUTODIR)\ByteLoader\ByteLoader.dll
ERRNO_PM = $(LIBDIR)\Errno.pm
$(RE).c \
$(DUMPER).c \
$(PEEK).c \
- $(B).c
+ $(B).c \
+ $(BYTELOADER).c
EXTENSION_DLL = \
$(SOCKET_DLL) \
$(ATTRS_DLL) \
$(DUMPER_DLL) \
$(PEEK_DLL) \
- $(B_DLL)
+ $(B_DLL) \
+ $(BYTELOADER_DLL)
EXTENSION_PM = \
$(ERRNO_PM)
$(MAKE)
cd ..\..\win32
+$(BYTELOADER_DLL): $(PERLEXE) $(BYTELOADER).xs
+ cd $(EXTDIR)\$(*B)
+ ..\..\miniperl -I..\..\lib Makefile.PL INSTALLDIRS=perl
+ $(MAKE)
+ cd ..\..\win32
+
$(ERRNO_PM): $(PERLEXE) $(ERRNO)_pm.PL
cd $(EXTDIR)\$(*B)
..\..\miniperl -I..\..\lib Makefile.PL INSTALLDIRS=perl
-del /f $(LIBDIR)\ops.pm $(LIBDIR)\Safe.pm $(LIBDIR)\Thread.pm
-del /f $(LIBDIR)\SDBM_File.pm $(LIBDIR)\Socket.pm $(LIBDIR)\POSIX.pm
-del /f $(LIBDIR)\B.pm $(LIBDIR)\O.pm $(LIBDIR)\re.pm
- -del /f $(LIBDIR)\Data\Dumper.pm
+ -del /f $(LIBDIR)\Data\Dumper.pm $(LIBDIR)\ByteLoader.pm
-del /f $(LIBDIR)\Devel\Peek.pm
-rmdir /s /q $(LIBDIR)\IO || rmdir /s $(LIBDIR)\IO
-rmdir /s /q $(LIBDIR)\Thread || rmdir /s $(LIBDIR)\Thread
.ENDIF
DYNAMIC_EXT = Socket IO Fcntl Opcode SDBM_File POSIX attrs Thread B re \
- Data/Dumper Devel/Peek
+ Data/Dumper Devel/Peek ByteLoader
STATIC_EXT = DynaLoader
NONXS_EXT = Errno
DUMPER = $(EXTDIR)\Data\Dumper\Dumper
ERRNO = $(EXTDIR)\Errno\Errno
PEEK = $(EXTDIR)\Devel\Peek\Peek
+BYTELOADER = $(EXTDIR)\ByteLoader
SOCKET_DLL = $(AUTODIR)\Socket\Socket.dll
FCNTL_DLL = $(AUTODIR)\Fcntl\Fcntl.dll
DUMPER_DLL = $(AUTODIR)\Data\Dumper\Dumper.dll
PEEK_DLL = $(AUTODIR)\Devel\Peek\Peek.dll
RE_DLL = $(AUTODIR)\re\re.dll
+BYTELOADER_DLL = $(AUTODIR)\ByteLoader\ByteLoader.dll
ERRNO_PM = $(LIBDIR)\Errno.pm
$(RE).c \
$(DUMPER).c \
$(PEEK).c \
- $(B).c
+ $(B).c \
+ $(BYTELOADER).c
EXTENSION_DLL = \
$(SOCKET_DLL) \
$(ATTRS_DLL) \
$(DUMPER_DLL) \
$(PEEK_DLL) \
- $(B_DLL)
+ $(B_DLL) \
+ $(BYTELOADER_DLL)
EXTENSION_PM = \
$(ERRNO_PM)
..\..\miniperl -I..\..\lib Makefile.PL INSTALLDIRS=perl
cd $(EXTDIR)\$(*B) && $(MAKE)
+$(BYTELOADER_DLL): $(PERLEXE) $(BYTELOADER).xs
+ cd $(EXTDIR)\$(*B) && \
+ ..\..\miniperl -I..\..\lib Makefile.PL INSTALLDIRS=perl
+ cd $(EXTDIR)\$(*B) && $(MAKE)
+
$(ERRNO_PM): $(PERLEXE) $(ERRNO)_pm.PL
cd $(EXTDIR)\$(*B) && \
..\..\miniperl -I..\..\lib Makefile.PL INSTALLDIRS=perl
-del /f $(LIBDIR)\ops.pm $(LIBDIR)\Safe.pm $(LIBDIR)\Thread.pm
-del /f $(LIBDIR)\SDBM_File.pm $(LIBDIR)\Socket.pm $(LIBDIR)\POSIX.pm
-del /f $(LIBDIR)\B.pm $(LIBDIR)\O.pm $(LIBDIR)\re.pm
- -del /f $(LIBDIR)\Data\Dumper.pm
+ -del /f $(LIBDIR)\Data\Dumper.pm $(LIBDIR)\ByteLoader.pm
-del /f $(LIBDIR)\Devel\Peek.pm
-rmdir /s /q $(LIBDIR)\IO || rmdir /s $(LIBDIR)\IO
-rmdir /s /q $(LIBDIR)\Thread || rmdir /s $(LIBDIR)\Thread