On Thu, Feb 07, 2002 at 01:15:44AM -0500, Josh Wilmes wrote:
>
> +sub goto_address {
> + return "return NULL; /* THIS IS BROKEN, but this op is for pbc2c.pl, so pre
> deref isn't used yet. */";
> +}
> +
Hrm. I don't like that much, because my .ops file uses the goto
ADDRESS() form for several things. Here's a much more extensive patch
that fixes it to work properly, and deletes a bazillion casts as well.
It also points to the question "can we make the byte_code be an
opcode_t* already?"
Oh, and it makes some of the formatting prettier, so it's gotta be
good.
Index: lib/Parrot/Op.pm
===================================================================
RCS file: /home/perlcvs/parrot/lib/Parrot/Op.pm,v
retrieving revision 1.6
diff -a -u -r1.6 Op.pm
--- lib/Parrot/Op.pm 30 Jan 2002 23:19:46 -0000 1.6
+++ lib/Parrot/Op.pm 7 Feb 2002 20:10:53 -0000
@@ -162,6 +162,45 @@
return $body;
}
+sub _substitute {
+ my $self = shift;
+ local $_ = shift;
+ my $trans = shift;
+
+ s/{{([a-z]+)\@([^{]*?)}}/ $trans->access_arg($1, $2, $self); /me;
+ s/{{\@([^{]*?)}}/ $trans->access_arg($self->arg_type($1), $1, $self); /me;
+
+ s/{{=0,=([^{]*?)}}/ $trans->restart_address($1) . "; {{=0}}"; /me;
+ s/{{=0,\+=([^{]*?)}}/ $trans->restart_offset($1) . "; {{=0}}"; /me;
+ s/{{=0,-=([^{]*?)}}/ $trans->restart_offset(-$1) . "; {{=0}}"; /me;
+
+ s/{{=\*}}/ $trans->goto_pop(); /me;
+
+ s/{{\+=([^{]*?)}}/ $trans->goto_offset($1); /me;
+ s/{{-=([^{]*?)}}/ $trans->goto_offset(-$1); /me;
+ s/{{=([^*][^{]*?)}}/ $trans->goto_address($1); /me;
+
+ s/{{\^\+([^{]*?)}}/ $trans->expr_offset($1); /me;
+ s/{{\^-([^{]*?)}}/ $trans->expr_offset(-$1); /me;
+ s/{{\^([^{]*?)}}/ $trans->expr_address($1); /me;
+
+ return $_;
+}
+
+# Correctly handle nested substitions for {{...}} by making sure the ...
+# never contains '{', and repeating over the whole string until no more
+# substitutions can be made.
+sub rewrite_body {
+ my ($self, $body, $trans) = @_;
+
+ while (1) {
+ my $new_body = $self->_substitute($body, $trans);
+ last if $body eq $new_body;
+ $body = $new_body;
+ }
+
+ return $body;
+}
#
# source()
@@ -170,27 +209,7 @@
sub source
{
my ($self, $trans) = @_;
-
- my $full_body = $self->full_body;
-
- $full_body =~ s/{{([a-z]+)\@(.*?)}}/ $trans->access_arg($1, $2, $self); /mge;
- $full_body =~ s/{{\@(.*?)}}/ $trans->access_arg($self->arg_type($1), $1, $self);
/mge;
-
- $full_body =~ s/{{=0,=(.*?)}}/ $trans->restart_address($1) . "; " .
$trans->goto_address(0); /mge;
- $full_body =~ s/{{=0,\+=(.*?)}}/ $trans->restart_offset($1) . "; " .
$trans->goto_address(0); /mge;
- $full_body =~ s/{{=0,-=(.*?)}}/ $trans->restart_offset(-$1) . "; " .
$trans->goto_address(0); /mge;
-
- $full_body =~ s/{{=\*}}/ $trans->goto_pop(); /mge; # NOTE: MUST BE FIRST
-
- $full_body =~ s/{{\+=(.*?)}}/ $trans->goto_offset($1); /mge;
- $full_body =~ s/{{-=(.*?)}}/ $trans->goto_offset(-$1); /mge;
- $full_body =~ s/{{=(.*?)}}/ $trans->goto_address($1); /mge;
-
- $full_body =~ s/{{\^\+(.*?)}}/ $trans->expr_offset($1); /mge;
- $full_body =~ s/{{\^-(.*?)}}/ $trans->expr_offset(-$1); /mge;
- $full_body =~ s/{{\^(.*?)}}/ $trans->expr_address($1); /mge;
-
- return $full_body;
+ return $self->rewrite_body($self->full_body, $trans);
}
Index: lib/Parrot/OpsFile.pm
===================================================================
RCS file: /home/perlcvs/parrot/lib/Parrot/OpsFile.pm,v
retrieving revision 1.16
diff -a -u -r1.16 OpsFile.pm
--- lib/Parrot/OpsFile.pm 30 Jan 2002 23:19:46 -0000 1.16
+++ lib/Parrot/OpsFile.pm 7 Feb 2002 20:10:54 -0000
@@ -283,24 +283,24 @@
$jumps ||= $body =~ s/\bgoto\s+OFFSET\(\( (.*?) \)\)/{{+=$1}}/mg;
$jumps ||= $body =~ s/\bgoto\s+ADDRESS\(\( (.*?) \)\)/{{=$1}}/mg;
- $body =~ s/\bexpr\s+OFFSET\(\( (.*?) \)\)/{{^+$1}}/mg;
- $body =~ s/\bexpr\s+ADDRESS\(\( (.*?) \)\)/{{^$1}}/mg;
+ $body =~ s/\bexpr\s+OFFSET\(\( (.*?) \)\)/{{^+$1}}/mg;
+ $body =~ s/\bexpr\s+ADDRESS\(\( (.*?) \)\)/{{^$1}}/mg;
$jumps ||= $body =~ s/\bgoto\s+OFFSET\((.*?)\)/{{+=$1}}/mg;
- $body =~ s/\bgoto\s+NEXT\(\)/{{+=$op_size}}/mg;
+ $body =~ s/\bgoto\s+NEXT\(\)/{{+=$op_size}}/mg;
$jumps ||= $body =~ s/\bgoto\s+ADDRESS\((.*?)\)/{{=$1}}/mg;
$jumps ||= $body =~ s/\bgoto\s+POP\(\)/{{=*}}/mg;
- $body =~ s/\bexpr\s+OFFSET\((.*?)\)/{{^+$1}}/mg;
- $body =~ s/\bexpr\s+NEXT\(\)/{{^+$op_size}}/mg;
- $body =~ s/\bexpr\s+ADDRESS\((.*?)\)/{{^$1}}/mg;
- $body =~ s/\bexpr\s+POP\(\)/{{^*}}/mg;
+ $body =~ s/\bexpr\s+OFFSET\((.*?)\)/{{^+$1}}/mg;
+ $body =~ s/\bexpr\s+NEXT\(\)/{{^+$op_size}}/mg;
+ $body =~ s/\bexpr\s+ADDRESS\((.*?)\)/{{^$1}}/mg;
+ $body =~ s/\bexpr\s+POP\(\)/{{^*}}/mg;
- $body =~ s/\bHALT\(\)/{{=0}}/mg;
+ $body =~ s/\bHALT\(\)/{{=0}}/mg;
$jumps ||= $body =~ s/\brestart\s+OFFSET\((.*?)\)/{{=0,+=$1}}/mg;
- $body =~ s/\brestart\s+NEXT\(\)/{{=0,+=$op_size}}/mg;
+ $body =~ s/\brestart\s+NEXT\(\)/{{=0,+=$op_size}}/mg;
- $body =~ s/\$(\d+)/{{\@$1}}/mg;
+ $body =~ s/\$(\d+)/{{\@$1}}/mg;
$op->body(qq{#line $line "$file"\n}.$body);
@@ -388,15 +388,10 @@
s/goto\s+POP\(\)/{{=*}}/mg;
s/HALT\(\)/{{=0}}/mg;
- #borrowed from Parrot::Op
- s/{{=\*}}/ $trans->goto_pop(); /mge;
- s/{{=(.*?)}}/ $trans->goto_address($1); /mge;
- s/{{\+=(.*?)}}/ $trans->goto_offset($1); /mge;
- s/{{-=(.*?)}}/ $trans->goto_offset(-$1); /mge;
- s/{{\^\*}}/ $trans->expr_pop(); /mge;
- s/{{\^(.*?)}}/ $trans->expr_address($1); /mge;
- s/{{\^\+(.*?)}}/$trans->expr_offset($1); /mge;
- s/{{\^-(.*?)}}/ $trans->expr_offset(-$1); /mge;
+ # FIXME: This ought to throw errors when attempting to rewrite $n
+ # argument accesses and other things that make no sense in the
+ # preamble.
+ $_ = Parrot::Op->rewrite_body($_, $trans);
}
return $_;
Index: lib/Parrot/OpTrans/CPrederef.pm
===================================================================
RCS file: /home/perlcvs/parrot/lib/Parrot/OpTrans/CPrederef.pm,v
retrieving revision 1.5
diff -a -u -r1.5 CPrederef.pm
--- lib/Parrot/OpTrans/CPrederef.pm 15 Jan 2002 16:10:46 -0000 1.5
+++ lib/Parrot/OpTrans/CPrederef.pm 7 Feb 2002 20:10:54 -0000
@@ -24,6 +24,25 @@
return <<END;
#define REL_PC ((size_t)(cur_opcode - interpreter->prederef_code))
#define CUR_OPCODE (((opcode_t *)interpreter->code->byte_code) + REL_PC)
+
+static inline opcode_t* prederef_to_opcode(struct Parrot_Interp* interpreter,
+ void** prederef_addr)
+{
+ ssize_t offset_in_ops;
+ if (prederef_addr == NULL) return NULL;
+ offset_in_ops = prederef_addr - interpreter->prederef_code;
+ return (opcode_t*) interpreter->code->byte_code + offset_in_ops;
+}
+
+static inline void** opcode_to_prederef(struct Parrot_Interp* interpreter,
+ opcode_t* opcode_addr)
+{
+ ssize_t offset_in_ops;
+ if (opcode_addr == NULL) return NULL;
+ offset_in_ops = opcode_addr - (opcode_t*) interpreter->code->byte_code;
+ return interpreter->prederef_code + offset_in_ops;
+}
+
END
}
@@ -48,7 +67,13 @@
sub expr_pop
{
my ($self) = @_;
- return "(((opcode_t *)pop_dest(interpreter) - (opcode_t
*)interpreter->code->byte_code) + interpreter->prederef_code)";
+ return "opcode_to_prederef(interpreter, pop_dest(interpreter))";
+}
+
+sub expr_address
+{
+ my ($self, $addr) = @_;
+ return "opcode_to_prederef(interpreter, $addr)";
}
# expr_offset and goto_offset
@@ -67,6 +92,11 @@
sub goto_offset {
my ($self, $offset) = @_;
return "return cur_opcode + $offset";
+}
+
+sub goto_address {
+ my ($self, $addr) = @_;
+ return "return opcode_to_prederef(interpreter, $addr)";
}
#