Author: leo
Date: Tue Jan 17 16:19:14 2006
New Revision: 11235

Modified:
   trunk/include/parrot/sub.h
   trunk/src/classes/closure.pmc
   trunk/src/packfile.c
Log:
lexicals - experimental support for autoclosing - .pbc support

* preserve SUB_FLAG_IS_OUTER flag in .pbc
* PMC references like sub->outer_sub aren't recreated when loading .pbc
* work around these current deficiencies in packfile with ugly code in
  Closure.thawfinish() 
* add a longish comment about that problem and some intermediate fixes


Modified: trunk/include/parrot/sub.h
==============================================================================
--- trunk/include/parrot/sub.h  (original)
+++ trunk/include/parrot/sub.h  Tue Jan 17 16:19:14 2006
@@ -36,7 +36,7 @@ typedef enum {
     SUB_FLAG_PF_IMMEDIATE = PObj_private6_FLAG,
     SUB_FLAG_PF_POSTCOMP  = PObj_private7_FLAG,
 
-    SUB_FLAG_PF_MASK      = 0xf8   /* anon ... postcomp */
+    SUB_FLAG_PF_MASK      = 0xfa   /* anon ... postcomp, is_outer*/
 
 } sub_flags_enum;
 

Modified: trunk/src/classes/closure.pmc
==============================================================================
--- trunk/src/classes/closure.pmc       (original)
+++ trunk/src/classes/closure.pmc       Tue Jan 17 16:19:14 2006
@@ -125,6 +125,56 @@ Invokes the closure.
         }
         return next;
     }
+
+    void thawfinish(visit_info *info) {
+        struct Parrot_sub * sub = PMC_sub(SELF);
+        PMC *outer;
+        opcode_t i, ci;
+        struct PackFile_FixupTable *ft;
+        struct PackFile_ConstTable *ct;
+
+        /*
+         * XXX TODO
+         *
+         * A Sub PMC is frozen/thawed per item, OTOH it can refer to other
+         * subs via the outer_sub (:outer) syntax. This outer though, is 
created
+         * independently when running from .pbc, which breaks referential
+         * integrity.
+         *
+         * The only fix (except this ugly and slow code) is to freeze/thaw
+         * a code segment as one structure, which will take care of all
+         * refs and self-refs. 
+         *
+         * TODO - intermediate step:
+         *
+         * Investigate if we can:
+         * - freeze array of subs (instead of the useless fixup seg)
+         * - do we need the Sub constant in the const seg as PMC constant?  
+         */
+
+        if (PMC_IS_NULL(sub->outer_sub))
+            return;
+        ft = sub->seg->fixups;
+        ct = sub->seg->const_table;
+        for (i = 0; i < ft->fixup_count; i++) {
+            switch (ft->fixups[i]->type) {
+                case enum_fixup_sub:
+                    ci = ft->fixups[i]->offset;
+                    if (ci < 0 || ci >= ct->const_count - 1)
+                        return; /* not yet thawed */
+                    if (ct->constants[ci]->type != PFC_PMC)
+                        return; /* same */
+                    outer = ct->constants[ci]->u.key;
+                    if (PMC_IS_NULL(outer))
+                        continue;
+                    if (0 == string_equal(INTERP, PMC_sub(outer)->name,
+                                PMC_sub(sub->outer_sub)->name)) {
+                        sub->outer_sub = outer;
+                        break;
+                    }
+            } 
+        }
+    }
 }
 
 /*

Modified: trunk/src/packfile.c
==============================================================================
--- trunk/src/packfile.c        (original)
+++ trunk/src/packfile.c        Tue Jan 17 16:19:14 2006
@@ -220,6 +220,9 @@ sub_pragma(Parrot_Interp interpreter, in
     int pragmas = PObj_get_FLAGS(sub_pmc) & SUB_FLAG_PF_MASK;
     int todo = 0;
 
+    pragmas &= ~SUB_FLAG_IS_OUTER;
+    if (!pragmas)
+        return 0;
     switch (action) {
         case PBC_PBC:
         case PBC_MAIN:

Reply via email to