Ticket #1425 (closed bug: fixed)

Opened 4 years ago

Last modified 4 years ago

pbc_merge does not correctly adjust constant offsets for parameter names

Reported by: Austin_Hastings Owned by:
Priority: normal Milestone:
Component: none Version: 2.0.0
Severity: fatal Keywords:
Cc: Language:
Patch status: Platform:

Description

I have some PIR code (NQP generated) that contains this line:

    $P519."new_class"("Foo::Child", "Foo::Parent" :named("parent"))

When I dump the generated bytecode from that single file, using pbc_dump -d, I get:

 0070:  00000023 00000022                                     set_args_pc
 0076:  00000024 0000000f                                     get_results_pc
 0078:  000002c4 00000001 0000001f                            callmethodcc_p_sc
 007b:  00000026 0000000f                                     set_returns_pc

Using pbc_dump (no -d) yields:

 0070:  00000023 00000022 00000001 0000001e 00000020 00000026 00000024 0000000f 
 0078:  000002c4 00000001 0000001f 00000026 0000000f 00000020 0000030f 00000002 

Thanks to Whiteknight++, I know that the 00000020 references the String-constant-parameter-name. When I look at the dumped constants table (noting that 00000020 = 32), I find:

    # 32:
    [ 'PFC_STRING', {
        FLAGS => 0x61100 (is_string,external,live,on_free_list)
        CHARSET  => 134667160,
        SIZE     => 6,
        DATA     => "parent"
    } ],

When I use pbc_merge to merge my bytecode file with krt0.pbc, a runtime startup file, via:

pbc_merge --output=foo.pbc library/krt0.pbc t/Pmc/Array.pbc

I dump the result and find my same code at a different offset:

 00a8:  00000023 0000003e                                     set_args_pc
 00ae:  00000024 0000002b                                     get_results_pc
 00b0:  000002c4 00000001 0000003b                            callmethodcc_p_sc
 00b3:  00000026 0000002b                                     set_returns_pc

Dumping again without -d shows:

 00a8:  00000023 0000003e 00000001 0000003a 00000020 00000042 00000024 0000002b 
 00b0:  000002c4 00000001 0000003b 00000026 0000002b 00000020 0000030f 00000002 

And I see the 4 parameter values (PMC invocant, string "Foo::Child", string "parent", string "Foo::Parent") but note that 2 of those values have not been changed.

The 00000001 is a P-register reference (the invocant) and I don't expect it to change. The 00000020 is an argument name, in this case a string constant, and I *do* expect it to change.

Looking in the constants table for krt0.pbc I find #27 is the highest offset (28 entries), so I would expect 32+28 = 60 to be the new offset of "parent" in the merged file.

In fact, going to the merged foo.pbc file, I find offset #60 contains:

    # 60:
    [ 'PFC_STRING', {
        FLAGS => 0x61100 (is_string,external,live,on_free_list)
        CHARSET  => 134667160,
        SIZE     => 6,
        DATA     => "parent"
    } ],

exactly what I expect, but offset #32 now has:

    # 32:
    [ 'PFC_STRING', {
        FLAGS => 0x61100 (is_string,external,live,on_free_list)
        CHARSET  => 134667160,
        SIZE     => 4,
        DATA     => "main"
    } ],

I subsequently modified the p6object code to print out the "main" named-parameter, and sure enough I saw "Foo::Parent" come out.

Change History

Changed 4 years ago by Austin_Hastings

Upon further investigation, I think the problem lies in the switch statement at line 700 in pbc_merge.c:

        switch (VTABLE_get_integer_keyed_int(interp, sig, cur_arg)) {

There is no masking of bits, and so an array entry "17" (CONST + STRING) is treated correctly, but an array entry of "529" (NAME + CONST + STRING) is not recognized as needing adjustment.

Changed 4 years ago by cotto

  • status changed from new to closed
  • resolution set to fixed

Thanks to Austin this bug was fixed in r43767.

Note: See TracTickets for help on using tickets.