| 1 | BEGIN {
|
|---|
| 2 | push @INC, './lib';
|
|---|
| 3 | require 'regen_lib.pl';
|
|---|
| 4 | }
|
|---|
| 5 | use strict;
|
|---|
| 6 | my %alias_to = (
|
|---|
| 7 | U32 => [qw(line_t)],
|
|---|
| 8 | PADOFFSET => [qw(STRLEN SSize_t)],
|
|---|
| 9 | U16 => [qw(OPCODE short)],
|
|---|
| 10 | U8 => [qw(char)],
|
|---|
| 11 | );
|
|---|
| 12 |
|
|---|
| 13 | my @optype= qw(OP UNOP BINOP LOGOP LISTOP PMOP SVOP PADOP PVOP LOOP COP);
|
|---|
| 14 |
|
|---|
| 15 | # Nullsv *must* come first in the following so that the condition
|
|---|
| 16 | # ($$sv == 0) can continue to be used to test (sv == Nullsv).
|
|---|
| 17 | my @specialsv = qw(Nullsv &PL_sv_undef &PL_sv_yes &PL_sv_no pWARN_ALL pWARN_NONE);
|
|---|
| 18 |
|
|---|
| 19 | my (%alias_from, $from, $tos);
|
|---|
| 20 | while (($from, $tos) = each %alias_to) {
|
|---|
| 21 | map { $alias_from{$_} = $from } @$tos;
|
|---|
| 22 | }
|
|---|
| 23 |
|
|---|
| 24 | my $c_header = <<'EOT';
|
|---|
| 25 | /* -*- buffer-read-only: t -*-
|
|---|
| 26 | *
|
|---|
| 27 | * Copyright (c) 1996-1999 Malcolm Beattie
|
|---|
| 28 | *
|
|---|
| 29 | * You may distribute under the terms of either the GNU General Public
|
|---|
| 30 | * License or the Artistic License, as specified in the README file.
|
|---|
| 31 | *
|
|---|
| 32 | */
|
|---|
| 33 | /*
|
|---|
| 34 | * This file is autogenerated from bytecode.pl. Changes made here will be lost.
|
|---|
| 35 | */
|
|---|
| 36 | EOT
|
|---|
| 37 |
|
|---|
| 38 | my $perl_header;
|
|---|
| 39 | ($perl_header = $c_header) =~ s{[/ ]?\*/?}{#}g;
|
|---|
| 40 |
|
|---|
| 41 | safer_unlink "ext/ByteLoader/byterun.c", "ext/ByteLoader/byterun.h", "ext/B/B/Asmdata.pm";
|
|---|
| 42 |
|
|---|
| 43 | #
|
|---|
| 44 | # Start with boilerplate for Asmdata.pm
|
|---|
| 45 | #
|
|---|
| 46 | open(ASMDATA_PM, ">ext/B/B/Asmdata.pm") or die "ext/B/B/Asmdata.pm: $!";
|
|---|
| 47 | binmode ASMDATA_PM;
|
|---|
| 48 | print ASMDATA_PM $perl_header, <<'EOT';
|
|---|
| 49 | package B::Asmdata;
|
|---|
| 50 |
|
|---|
| 51 | our $VERSION = '1.01';
|
|---|
| 52 |
|
|---|
| 53 | use Exporter;
|
|---|
| 54 | @ISA = qw(Exporter);
|
|---|
| 55 | @EXPORT_OK = qw(%insn_data @insn_name @optype @specialsv_name);
|
|---|
| 56 | our(%insn_data, @insn_name, @optype, @specialsv_name);
|
|---|
| 57 |
|
|---|
| 58 | EOT
|
|---|
| 59 | print ASMDATA_PM <<"EOT";
|
|---|
| 60 | \@optype = qw(@optype);
|
|---|
| 61 | \@specialsv_name = qw(@specialsv);
|
|---|
| 62 |
|
|---|
| 63 | # XXX insn_data is initialised this way because with a large
|
|---|
| 64 | # %insn_data = (foo => [...], bar => [...], ...) initialiser
|
|---|
| 65 | # I get a hard-to-track-down stack underflow and segfault.
|
|---|
| 66 | EOT
|
|---|
| 67 |
|
|---|
| 68 | #
|
|---|
| 69 | # Boilerplate for byterun.c
|
|---|
| 70 | #
|
|---|
| 71 | open(BYTERUN_C, ">ext/ByteLoader/byterun.c") or die "ext/ByteLoader/byterun.c: $!";
|
|---|
| 72 | binmode BYTERUN_C;
|
|---|
| 73 | print BYTERUN_C $c_header, <<'EOT';
|
|---|
| 74 |
|
|---|
| 75 | #define PERL_NO_GET_CONTEXT
|
|---|
| 76 | #include "EXTERN.h"
|
|---|
| 77 | #include "perl.h"
|
|---|
| 78 | #define NO_XSLOCKS
|
|---|
| 79 | #include "XSUB.h"
|
|---|
| 80 |
|
|---|
| 81 | #include "byterun.h"
|
|---|
| 82 | #include "bytecode.h"
|
|---|
| 83 |
|
|---|
| 84 |
|
|---|
| 85 | static const int optype_size[] = {
|
|---|
| 86 | EOT
|
|---|
| 87 | my $i = 0;
|
|---|
| 88 | for ($i = 0; $i < @optype - 1; $i++) {
|
|---|
| 89 | printf BYTERUN_C " sizeof(%s),\n", $optype[$i], $i;
|
|---|
| 90 | }
|
|---|
| 91 | printf BYTERUN_C " sizeof(%s)\n", $optype[$i], $i;
|
|---|
| 92 | print BYTERUN_C <<'EOT';
|
|---|
| 93 | };
|
|---|
| 94 |
|
|---|
| 95 | void *
|
|---|
| 96 | bset_obj_store(pTHX_ struct byteloader_state *bstate, void *obj, I32 ix)
|
|---|
| 97 | {
|
|---|
| 98 | if (ix > bstate->bs_obj_list_fill) {
|
|---|
| 99 | Renew(bstate->bs_obj_list, ix + 32, void*);
|
|---|
| 100 | bstate->bs_obj_list_fill = ix + 31;
|
|---|
| 101 | }
|
|---|
| 102 | bstate->bs_obj_list[ix] = obj;
|
|---|
| 103 | return obj;
|
|---|
| 104 | }
|
|---|
| 105 |
|
|---|
| 106 | int
|
|---|
| 107 | byterun(pTHX_ register struct byteloader_state *bstate)
|
|---|
| 108 | {
|
|---|
| 109 | register int insn;
|
|---|
| 110 | U32 ix;
|
|---|
| 111 | SV *specialsv_list[6];
|
|---|
| 112 |
|
|---|
| 113 | BYTECODE_HEADER_CHECK; /* croak if incorrect platform */
|
|---|
| 114 | Newx(bstate->bs_obj_list, 32, void*); /* set op objlist */
|
|---|
| 115 | bstate->bs_obj_list_fill = 31;
|
|---|
| 116 | bstate->bs_obj_list[0] = NULL; /* first is always Null */
|
|---|
| 117 | bstate->bs_ix = 1;
|
|---|
| 118 |
|
|---|
| 119 | EOT
|
|---|
| 120 |
|
|---|
| 121 | for my $i ( 0 .. $#specialsv ) {
|
|---|
| 122 | print BYTERUN_C " specialsv_list[$i] = $specialsv[$i];\n";
|
|---|
| 123 | }
|
|---|
| 124 |
|
|---|
| 125 | print BYTERUN_C <<'EOT';
|
|---|
| 126 |
|
|---|
| 127 | while ((insn = BGET_FGETC()) != EOF) {
|
|---|
| 128 | switch (insn) {
|
|---|
| 129 | EOT
|
|---|
| 130 |
|
|---|
| 131 |
|
|---|
| 132 | my (@insn_name, $insn_num, $insn, $lvalue, $argtype, $flags, $fundtype);
|
|---|
| 133 |
|
|---|
| 134 | while (<DATA>) {
|
|---|
| 135 | if (/^\s*#/) {
|
|---|
| 136 | print BYTERUN_C if /^\s*#\s*(?:if|endif|el)/;
|
|---|
| 137 | next;
|
|---|
| 138 | }
|
|---|
| 139 | chop;
|
|---|
| 140 | next unless length;
|
|---|
| 141 | if (/^%number\s+(.*)/) {
|
|---|
| 142 | $insn_num = $1;
|
|---|
| 143 | next;
|
|---|
| 144 | } elsif (/%enum\s+(.*?)\s+(.*)/) {
|
|---|
| 145 | create_enum($1, $2); # must come before instructions
|
|---|
| 146 | next;
|
|---|
| 147 | }
|
|---|
| 148 | ($insn, $lvalue, $argtype, $flags) = split;
|
|---|
| 149 | my $rvalcast = '';
|
|---|
| 150 | if ($argtype =~ m:(.+)/(.+):) {
|
|---|
| 151 | ($rvalcast, $argtype) = ("($1)", $2);
|
|---|
| 152 | }
|
|---|
| 153 | $insn_name[$insn_num] = $insn;
|
|---|
| 154 | $fundtype = $alias_from{$argtype} || $argtype;
|
|---|
| 155 |
|
|---|
| 156 | #
|
|---|
| 157 | # Add the case statement and code for the bytecode interpreter in byterun.c
|
|---|
| 158 | #
|
|---|
| 159 | printf BYTERUN_C "\t case INSN_%s:\t\t/* %d */\n\t {\n",
|
|---|
| 160 | uc($insn), $insn_num;
|
|---|
| 161 | my $optarg = $argtype eq "none" ? "" : ", arg";
|
|---|
| 162 | if ($optarg) {
|
|---|
| 163 | printf BYTERUN_C "\t\t$argtype arg;\n\t\tBGET_%s(arg);\n", $fundtype;
|
|---|
| 164 | }
|
|---|
| 165 | if ($flags =~ /x/) {
|
|---|
| 166 | print BYTERUN_C "\t\tBSET_$insn($lvalue$optarg);\n";
|
|---|
| 167 | } elsif ($flags =~ /s/) {
|
|---|
| 168 | # Store instructions store to bytecode_obj_list[arg]. "lvalue" field is rvalue.
|
|---|
| 169 | print BYTERUN_C "\t\tBSET_OBJ_STORE($lvalue$optarg);\n";
|
|---|
| 170 | }
|
|---|
| 171 | elsif ($optarg && $lvalue ne "none") {
|
|---|
| 172 | print BYTERUN_C "\t\t$lvalue = ${rvalcast}arg;\n";
|
|---|
| 173 | }
|
|---|
| 174 | print BYTERUN_C "\t\tbreak;\n\t }\n";
|
|---|
| 175 |
|
|---|
| 176 | #
|
|---|
| 177 | # Add the initialiser line for %insn_data in Asmdata.pm
|
|---|
| 178 | #
|
|---|
| 179 | print ASMDATA_PM <<"EOT";
|
|---|
| 180 | \$insn_data{$insn} = [$insn_num, \\&PUT_$fundtype, "GET_$fundtype"];
|
|---|
| 181 | EOT
|
|---|
| 182 |
|
|---|
| 183 | # Find the next unused instruction number
|
|---|
| 184 | do { $insn_num++ } while $insn_name[$insn_num];
|
|---|
| 185 | }
|
|---|
| 186 |
|
|---|
| 187 | #
|
|---|
| 188 | # Finish off byterun.c
|
|---|
| 189 | #
|
|---|
| 190 | print BYTERUN_C <<'EOT';
|
|---|
| 191 | default:
|
|---|
| 192 | Perl_croak(aTHX_ "Illegal bytecode instruction %d\n", insn);
|
|---|
| 193 | /* NOTREACHED */
|
|---|
| 194 | }
|
|---|
| 195 | }
|
|---|
| 196 | return 0;
|
|---|
| 197 | }
|
|---|
| 198 |
|
|---|
| 199 | /* ex: set ro: */
|
|---|
| 200 | EOT
|
|---|
| 201 |
|
|---|
| 202 | #
|
|---|
| 203 | # Write the instruction and optype enum constants into byterun.h
|
|---|
| 204 | #
|
|---|
| 205 | open(BYTERUN_H, ">ext/ByteLoader/byterun.h") or die "ext/ByteLoader/byterun.h: $!";
|
|---|
| 206 | binmode BYTERUN_H;
|
|---|
| 207 | print BYTERUN_H $c_header, <<'EOT';
|
|---|
| 208 | struct byteloader_fdata {
|
|---|
| 209 | SV *datasv;
|
|---|
| 210 | int next_out;
|
|---|
| 211 | int idx;
|
|---|
| 212 | };
|
|---|
|
|---|