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

Reply via email to