Ticket #556 (closed bug: invalid)

Opened 5 years ago

Last modified 4 years ago

setref on derived pmc aggregate class loses data on return

Reported by: bsdz Owned by: kjs
Priority: major Milestone:
Component: core Version: trunk
Severity: high Keywords:
Cc: Language:
Patch status: Platform: all

Description

When deriving from PMC aggregate, data appears to be lost on return from sub after using setref opcode.

Here is an example code: -

.include 'library/dumper.pir'

.namespace [ 'MyRPA' ]
.sub '__dump' :method
    .param pmc dumper
    .param pmc label
    dumper.'genericArray'(label, self)
.end

.namespace []
.sub '' :main

    $P0 = subclass 'ResizablePMCArray', 'MyRPA'

    $P1 = new 'ResizablePMCArray'
    'pass_by_ref'($P1)
    _dumper($P1, 'RPA after')
    
    $P2 = new 'MyRPA'
    'pass_by_ref'($P2)
    _dumper($P2, 'MyRPA after') 
    
.end

.sub 'pass_by_ref'
    .param pmc p
    p[0] = 'hello'
    _dumper(p, 'before setref')
    setref p, p   
.end

The output is as follow: -

"before setref" => ResizablePMCArray (size:1) [
    "hello"
]
"RPA after" => ResizablePMCArray (size:1) [
    "hello"
]
"before setref" => PMC 'MyRPA' MyRPA (size:1) [
    "hello"
]
"MyRPA after" => PMC 'MyRPA' MyRPA (size:1) [
    null
]

The expected outcome should really be : -

"before setref" => ResizablePMCArray (size:1) [
    "hello"
]
"RPA after" => ResizablePMCArray (size:1) [
    "hello"
]
"before setref" => PMC 'MyRPA' MyRPA (size:1) [
    "hello"
]
"MyRPA after" => PMC 'MyRPA' MyRPA (size:1) [
    "hello"
]

Attachments

test.pir Download (0.6 KB) - added by bsdz 5 years ago.
Example pir code demonstrating bug.

Change History

Changed 5 years ago by bsdz

Example pir code demonstrating bug.

Changed 4 years ago by plobsing

  • status changed from new to closed
  • component changed from pirc to core
  • resolution set to invalid

The setref op does not mean pass by reference. Specifically, setref on FixedPMCArray and descendants (including ResizablePMCArray) is an extremely internal-ish operation that users should *not* be using.

The example code now segfaults. The segfault has nothing to do with the return (the _dumper call can be moved to immediately after the setref for the same effect) and everything to do with poking things that shouldn't be poked.

Note: See TracTickets for help on using tickets.