Ticket #1991 (closed RFC: wontfix)

Opened 4 years ago

Last modified 3 years ago

simplify 'new_callback' op

Reported by: jimmy Owned by:
Priority: normal Milestone:
Component: none Version: 3.0.0
Severity: medium Keywords:
Cc: Language:
Patch status: Platform:

Description (last modified by jimmy) (diff)

Hello,

I would like to simplify 'new_callback' op. first please see  https://github.com/parrot/parrot/blob/master/t/pmc/nci.t#L1545-#L1606-1551. there are lines:

    .local pmc user_data
    user_data = new ['Integer']
    user_data = 42

    # A Sub that can be given to the library
    # this callback function will eventually by called by the library
    .const 'Sub' cb = "_call_back"
    .local pmc cb_wrapped
    cb_wrapped = new_callback cb, user_data, "vtU"  # Z in pdd16
    print "created a callback sub\n"

    # now call the external sub, that takes a callback and user data
    .local pmc libnci_test
    libnci_test = loadlib "libnci_test"
    .local pmc nci_cb_C1
    nci_cb_C1 = dlfunc libnci_test, "nci_cb_C1", "vpP"
    print "loaded a function that takes a callback\n"
    nci_cb_C1( cb_wrapped, user_data )

passing the value of user_data into new_callback is useless and unused, because it's finally invoked and used by this code:

nci_cb_C1( cb_wrapped, user_data )

So consider:

    .local pmc user_data
    user_data = new ['Integer']

    # A Sub that can be given to the library
    # this callback function will eventually by called by the library
    .const 'Sub' cb = "_call_back"
    .local pmc cb_wrapped
    user_data = 42
    cb_wrapped = new_callback cb, user_data, "vtU"  # Z in pdd16
    print "created a callback sub\n"

    # now call the external sub, that takes a callback and user data
    .local pmc libnci_test
    libnci_test = loadlib "libnci_test"
    .local pmc nci_cb_C1
    nci_cb_C1 = dlfunc libnci_test, "nci_cb_C1", "vpP"
    print "loaded a function that takes a callback\n"
    user_data = 44   # user_data is changed here.
    nci_cb_C1( cb_wrapped, user_data )

so passing user_data = 42 to new_callback is redundant, I would like to simplify it to this one:

    cb_wrapped = new_callback cb, "vtU"

Change History

Changed 4 years ago by jimmy

  • description modified (diff)

Changed 4 years ago by jimmy

  • description modified (diff)

Changed 4 years ago by jimmy

  • description modified (diff)

Changed 4 years ago by plobsing

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

The userdata parameter of a callback is critical to the use of the callback because it carries critical information about the future invocation of the callback including the interpreter to use, how to invoke the callback, and the sub PMC to use. Recall that a C callback does not necessarily know about the Parrot interpreter and that the parrot interpreter, upon re-entering has no idea about the nature of the callback being called. The userdata parameter has a a prophash stuffed with this data which ensures that the appropriate parts of the parrot invocation are assembled correctly. Please read src/interp/inter_cb.c for more details.

In the alternative suggested, the only opportunity to stuff the userdata's prophash would be when the NCI is invoked, which requires the NCI layer to know about the callback at that point. This requires either additional NCI parameter signature types that do almost the exact same thing as existing ones, or deep introspection of NCI arguments; neither of which are good options.

Another alternative, trampolining, would eliminate parrot's reliance on userdata callback parameters to get things straight. Unfortunately, to my knowledge, this cannot be accomplished portably, so we are stuck, in the general case, with this interface.

Changed 3 years ago by jimmy

see TT #1548

Note: See TracTickets for help on using tickets.