Author Topic: function pointers and anon funcs  (Read 833 times)

Offline silenus

  • BFF
  • ***
  • Posts: 144
    • View Profile
function pointers and anon funcs
« on: October 31, 2015, 01:46:19 PM »
I am wondering if it would make sense to try to make function pointers persist and save like other types of data in lpc. I am not entirely sure how to go about this after looking at the code- but it would seem to be possible in almost all if not all cases. The main issue is that the object file might become out of sync with the program file and make no sense when calling the lfun index or offset or in the case of efuns or simul efuns if the driver or simul efun object is updated. There are currently 5 types of function pointers defined in lpc excluding the bindable flags. This also seems like a lot in modern times since I dont think the efficiency gains in terms of having bare function pointers to lfuns and efuns/simuls offer much in terms of performance savings. Would it make sense to more or less merge all these into a single case?

Offline quixadhal

  • BFF
  • ***
  • Posts: 618
    • View Profile
    • A Waste of Time
Re: function pointers and anon funcs
« Reply #1 on: October 31, 2015, 04:23:17 PM »
One thing to note here is that (unless I'm remembering wrong) LPC is designed so that when an object is updated, it always gets a new chunk of code attached to it, but retains its old data structures.

IE: If I modify a daemon (such as /secure/daemons/chat.c), and recompile it, the running object will now be using the new code, but still keep its existing data structures (IE: list of people who said something).

So, if you're going to start using raw function pointers in objects, you need to ensure that those pointers are always updated to point to the newest version of the object's code.  Otherwise, you will end up with some objects using the new version, but still having call_out()'s or call_other()'s pointing at older code revisions.

I don't know how FluffOS implements this behavior, so it may be a non-issue... but it's the first thing that came to mind with your suggestion as a potential gotcha.

Offline Dworkin

  • Acquaintance
  • *
  • Posts: 29
    • View Profile
Re: function pointers and anon funcs
« Reply #2 on: November 01, 2015, 03:12:56 AM »
I think you are misremembering, Quixadhal. Fluffos doesn't allow recompilation of an object while retaining its data. DGD does, and that's one of the reasons why DGD has no function pointers.

Offline silenus

  • BFF
  • ***
  • Posts: 144
    • View Profile
Re: function pointers and anon funcs
« Reply #3 on: November 01, 2015, 07:23:52 AM »
I might be wrong about this but I suspect that function pointers in dgd work be okay if you assume a sort of late binding i.e. make the function point just hold the object or program on which the pointer is called plus a string and arguments. I.e. a sort of on demand delayed call_other with no guarantees that it points to anything of if it ever did. I am not sure however with object upgrades how lambda closures (anon-funcs) could be made to work since in principle you either carry the code with the variable or compile the code into an object which is nameless and point to it. Could you not have an nameless object hold the code and have the function pointer point to the code in a nameless object that gets compiled on the fly? Depending on the copy semantics one could perhaps even use an lwo.

As for upgrades- I know dgd currently automatically restores the data, but I wonder if another approach might be to pass the old version of the object to the new object in the upgrade() function and use some form of reflection variables(), set_variable(), fetch_variable() to get at the old data and xlate it across. This would allow for the new recompiled versions of the object to construct new lambda objects using new code making it possible to upgrade the code pointed to by the anon funcs given the old functions with perhaps the right reflection routines. If the closures hold data i.e. are collectors this might be a bit complicated though.

Offline Dworkin

  • Acquaintance
  • *
  • Posts: 29
    • View Profile
Re: function pointers and anon funcs
« Reply #4 on: November 01, 2015, 08:45:51 AM »
I might be wrong about this but I suspect that function pointers in dgd work be okay if you assume a sort of late binding i.e. make the function point just hold the object or program on which the pointer is called plus a string and arguments. I.e. a sort of on demand delayed call_other with no guarantees that it points to anything of if it ever did. I am not sure however with object upgrades how lambda closures (anon-funcs) could be made to work since in principle you either carry the code with the variable or compile the code into an object which is nameless and point to it. Could you not have an nameless object hold the code and have the function pointer point to the code in a nameless object that gets compiled on the fly? Depending on the copy semantics one could perhaps even use an lwo.

This discussion is wandering far afield, but the difficulty in combining object upgrading with anonymous functions is that you cannot unambiguously match an anonymous function reference to code in a newly upgraded object. Thus anonymous functions cannot be automatically upgraded.

None of this pertains to Fluffos, which doesn't have object upgrading.

Offline silenus

  • BFF
  • ***
  • Posts: 144
    • View Profile
Re: function pointers and anon funcs
« Reply #5 on: November 01, 2015, 09:46:10 AM »
Thanks Dworkin. I was at one point interested in trying to implement some sort of anon funcs into dgd hence the question. The issues I suspect are somewhat similar- since to save an anon func means also that the save file has a lifespan perhaps exceeding that of the program from which it is generated. For function pointers the problem might be resolvable by down stepping the method index reference back into a function name as a string and re-resolving it when the pointer is loaded from storage. The more general solution would be to keep a string representation of the code handy and recompile it on load. That might be quite a lot of work since one would have to hack into the compiler as well. I havent explored yet as to how difficult it would be to get the existing code base to do this- I am still tracing out the execution paths between the interpreter and the f_function_constructor and the functions module as well as looking at what the AST generation and code generation does.

Offline Dworkin

  • Acquaintance
  • *
  • Posts: 29
    • View Profile
Re: function pointers and anon funcs
« Reply #6 on: November 01, 2015, 03:09:36 PM »
Does it make sense for function pointers to persist when object references don't?

Offline silenus

  • BFF
  • ***
  • Posts: 144
    • View Profile
Re: function pointers and anon funcs
« Reply #7 on: November 01, 2015, 07:09:55 PM »
I was actually beginning to wonder about that after I posted that but I suspect there might be a way to have function pointer forms persist through save/restore_variable like reflection functions. The idea would be to have a function_info return a call_other representation of the function pointer including the arguments and leave it up to the user as to how to best to serialize the information. As for code I suspect that functionals don't have an object context (I don't think anonymous functions do either) so they could more or less be floating blocks of code.

Offline quixadhal

  • BFF
  • ***
  • Posts: 618
    • View Profile
    • A Waste of Time
Re: function pointers and anon funcs
« Reply #8 on: November 01, 2015, 07:12:46 PM »
Thanks Dworkin!

You are correct.  In fluffos, the "update" command just recompiles the new code which may call restore_object(), and if that works... destructs the old version.  Not actually upgrading the in-place object at all, but making a new one.

In that respect, the only place function points can be an issue would be if you tried to optimize lookups like CHAT_D->get_chat_color(), which is a synonym for "/secure/daemons/chat"->get_chat_color(), or call_other("/secure/daemons/chat", "get_chat_color");

If you were to cache those and not properly update the cache, you'd get either an error if the old copy were destructed, or unhappiness if you expected a daemon to be a singleton, but somehow ended up with multiple copies anyways.