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: