[Jifty-commit] r5454 - Method-Inline/lib/Class/Accessor

Jifty commits jifty-commit at lists.jifty.org
Sat May 10 16:02:08 EDT 2008


Author: clkao
Date: Sat May 10 16:02:07 2008
New Revision: 5454

Modified:
   Method-Inline/lib/Class/Accessor/Inline.pm

Log:
inline mutator.

Modified: Method-Inline/lib/Class/Accessor/Inline.pm
==============================================================================
--- Method-Inline/lib/Class/Accessor/Inline.pm	(original)
+++ Method-Inline/lib/Class/Accessor/Inline.pm	Sat May 10 16:02:07 2008
@@ -27,6 +27,7 @@
     my $caller_op = B::OP::parent_op($lv);
     my $return_op = B::OP::return_op($lv);
     my $tree = find_detachable( $caller_op, $return_op );
+#    B::Concise::compile('', $cv)->(); use B::Concise;
 
     $cvme->rewrite($tree);
 
@@ -37,39 +38,56 @@
 
 sub find_detachable {
     my ( $parent_cop, $return_op ) = @_;
-    my ($parent, $prev, $prevsibling, $thisop);
+    my ($parent, $prev, $prevsibling, $thisop, $entry);
     local *B::OP::my_visit = sub { my $op = shift;
                                    $thisop = $op if ${$op->next} == $$return_op;
+                               };
+    B::walkoptree( $_, 'my_visit' ) for $parent_cop->sibling;
+
+    local *B::OP::my_visit = sub { my $op = shift;
                                    $parent = $op if $op->can('first') && ${$op->first} == $$thisop;
                                    $prevsibling = $op if ${$op->sibling} == $$thisop;
-                               };
+                                   };
     B::walkoptree( $_, 'my_visit' ) for $parent_cop->sibling, $parent_cop;
 
+    my $visited;
+    local *B::OP::my_visit = sub { my $op = shift;
+                                   $visited->{$$op} = 1;
+                               };
+    Carp::confess unless $thisop;
+    B::walkoptree( $_, 'my_visit' ) for $thisop;
+
     local *B::OP::my_visit = sub { my $op = shift;
-                                   $prev = $op if ${$op->next} == ${$thisop->first};
+                                   if (!$visited->{$$op} && $visited->{${$op->next}}) {
+                                       $entry = $op->next;
+                                       $prev = $op;
+                                   }
                                };
     B::walkoptree( $_, 'my_visit' ) for $parent_cop, $parent_cop->sibling;
 
     return { return => $return_op,
-             thisop => $thisop,
-             parent => $parent,
-             prev => $prev,
-             prevsibling => $prevsibling,
-           };
+        parent_cop  => $parent_cop,
+        thisop      => $thisop,
+        parent      => $parent,
+        prev        => $prev,
+        prevsibling => $prevsibling,
+        entry       => $entry,
+        sibling     => $thisop->sibling->isa('B::NULL') ? undef : $thisop->sibling,
+    };
 }
 
 package Class::Accessor::Inline::accessor;
 use strict;
-use B qw(OPf_WANT_SCALAR OPf_STACKED OPf_KIDS OPf_REF OPpDEREF_HV);
+use B qw(OPf_WANT_SCALAR OPf_STACKED OPf_KIDS OPf_REF OPpDEREF_HV OPpCONST_BARE);
 
 sub null {
     my $op = shift;
     return B::class($op) eq "NULL";
 }
 
-
 sub rewrite {
     my ($self, $tree) = @_;
+
     my $op = $tree->{thisop}->first->sibling;
 
     my $mname;
@@ -77,15 +95,24 @@
     my $self_op = $op; $op = $op->sibling;
     my $rv2hv = B::UNOP->new( "rv2hv", OPf_WANT_SCALAR|OPf_KIDS|OPf_REF, $self_op);
 
+    my $valop;
+    my $method_op;
     for ( ; not null $op; $op = $op->sibling ) {
         if ($op->name eq 'method_named') {
+            $method_op = $op;
             $mname = ${$op->sv->object_2svref};
-            $key = B::SVOP->new( "const", $op->flags, $mname);
+            $key = B::SVOP->new( "const", 64, $mname);
         }
         else { # with arg, this should be hash assign.
-            return; # bail out for now;
+            $valop = $op;
         }
     };
+
+    my $valtree;
+    if ($valop) {
+        $valtree = Class::Accessor::Inline::find_detachable($tree->{parent_cop}, $method_op);
+    }
+
     # self-contained floating $helem tree
     my $helem = B::BINOP->new( "helem", OPf_WANT_SCALAR, $rv2hv, $key);
     $self_op->flags( ($self_op->flags | OPpDEREF_HV) & ~OPf_STACKED);
@@ -94,12 +121,31 @@
     $rv2hv->next($key);
     $key->next($helem);
 
-    # reconnect helem to replace $tree
-    $helem->next($tree->{return});
-    $tree->{parent}->first( $helem ) if $tree->{parent};
-    $tree->{prev}->next( $self_op );
-    $tree->{prevsibling}->sibling( $helem ) if $tree->{prevsibling};
-
+    if ($valop) {
+        my $sassign = B::BINOP->new( "sassign", OPf_WANT_SCALAR|OPf_KIDS|OPf_STACKED, $helem, $valop);
+        $sassign->next($tree->{return});
+        $sassign->next($tree->{sibling}) if $tree->{sibling};
+
+        $helem->next($sassign);
+        $valtree->{thisop}->next($self_op);
+
+        $tree->{prev}->next( $valtree->{entry} );
+        $tree->{prevsibling}->sibling( $sassign ) if $tree->{prevsibling};
+
+    }
+    else {
+#        for (keys %$tree) {
+#            next unless $tree->{$_};
+#            warn "=== $_: @{[ $tree->{$_}->name ]} ( @{[ $tree->{$_}->seq ]}) ";
+#        }
+        # reconnect helem to replace $tree
+        $helem->next($tree->{return});
+        $helem->sibling($tree->{sibling}) if $tree->{sibling};
+
+        $tree->{parent}->first( $helem ) if $tree->{parent};
+        $tree->{prev}->next( $self_op );
+        $tree->{prevsibling}->sibling( $helem ) if $tree->{prevsibling};
+    }
 
 }
 


More information about the Jifty-commit mailing list