On Fri, 31 Dec 2004, Leopold Toetsch wrote:
> Simon Glover <[EMAIL PROTECTED]> wrote:
>
> > new P0, .ResizablePMCArray
> > set P0, 1
> > clone P1, P0
> > eq P0, P1, L1
> > print "not "
> > L1: print "ok"
> > print "\n"
> > end
>
> > prints "not ok".
>
> This is a different issue. The ResizablePMCArray doesn't properly
> inherit the is_equal multi method from FixedPMCArray and as far as I can
> see, there is no Undef involved at all. Empty array slots are filled
> with PMCNULL, which is a singleton. The example works for FixedPMCArray.
In the case of the ResizablePMCArray, the Undef comes into it because
of this loop in is_equal():
for (j = 0; j < n; ++j) {
PMC *item1, *item2;
item1 = DYNSELF.get_pmc_keyed_int(j);
item2 = VTABLE_get_pmc_keyed_int(INTERP, value, j);
if (item1 == item2)
continue;
if (!mmd_dispatch_i_pp(INTERP, item1, item2, MMD_EQ))
return 0;
}
and this code in get_pmc_keyed_int:
data = PMC_data(SELF);
if (data[key] == PMCNULL)
data[key] = pmc_new(INTERP, enum_class_Undef);
return data[key];
When is_equal calls get_pmc_keyed_int to do the comparison, it creates
and returns an Undef PMC, rather than simply returing PMCNULL, and
since Undef != Undef, this ultimately causes the comparison to fail.
In the case of FixedPMCArray, the test passes because the
implementation of get_pmc_keyed_int doesn't have the test for PMCNULL
-- instead, it just does:
data = (PMC **)PMC_data(SELF);
return data[key];
Hence, if the entry is PMCNULL, the code actually returns PMCNULL,
and since PMCNULL == PMCNULL, the comparison succeeds and the test
passes.
I guess the real question is should we be creating that Undef PMC;
i.e. should fetching an undefined element return a fully-fledged
Undef value, or simply a PMCNULL, which may later be promoted to a
real Undef?
Simon