[eeps] allow external function as literals

Björn-Egil Dahlberg egil@REDACTED
Thu Oct 2 17:03:16 CEST 2014


On 2014-10-02 12:39, Tony Rogvall wrote:
>>> I developed a patch produced to patch function return values:
>>>
>>> '__ffe_sqr'() -> <<"sqr">>.
>>>
>>> here I replaced <<"sqr">>.
>>> with
>>>   { 0, <<"sqr">>, fun ffe:docol/4, fun ffe:dupe/0, fun ffe:star/0, fun ffe:semis/0 }.
>>>
>>> in the literal section of the beam file using beam_lib and a simple match.
>>>
>>> The loader worked and the code now return constant tuples with functions in them.
>> Could you use these literals? Even if the  external module wasn't loaded?
>>
> Yupp. This is handled by the external format, which is the format used by the literal table. And also the reason why my
> workaround works.

Ofc, all literals are handled via term_<->_binary.

>> I only checked the code briefly but I think that if you load an external as a literal you have to make a stub for the module if it isn't loaded, so the
>> error handler can load the module later on. But you are a savvy person, I think you can figure it out. =)
>>
> When literal table is loaded the EXPORT_EXT (external.c: around 3490) it will create the stub needed.
> This is of course the same mechanism used by binary_to_term et al.

yep

>
> My worry is that there are some intricate detail in code loading that will stop my scheme from working flawlessly,
> it may have been forgotten for some good reason?
>
>> I'm sure there are other things to consider as well.
>>
> One reason I can think of is that is "trick" to add this form of literal in the assembler format (not impossible) and
> is possibly not backwards compatible.
>
> Lets say we want to produce a literal with a export entry fun in it,  we can not use fun key word since funs are
> not terms. We need to whip together a term somehow.
>
> For a list / string
> 	{move, {literal, {hello, 0, {erlang,foo,0}}}, {x,0}}
>
> wont work
>
> Some kind of expression format may do the trick (choose some, this is abstract format without line numbers)
>
> 	{move, {literal_expr, {tuple, [{atom,hello},{integer,0},{'fun',{function,{atom,erlang},{atom,display},{integer,1}}} ] }}}
>
> The literal_expr must then be parsed by the assembler and then converted to "normal" term before packed into
> the literal section of the beam file.
>
> Not to difficult. And a bit more general than the {literal, X} thing.

I think this is the main thing. You cannot describe a fun export as a 
literal .. literally. =) You cannot describe processes, ports or 
references either.
Even normal funs has problems with environment and a process id which 
renders such things impossible to "literalify".

I see no reason why it shouldn't be possible to load fun exports as 
literals though .. just need a nice way to describe it.
As long as you go through  erts_export_get_or_make_stub(..) when you 
load the literal you should be fine.

However, I don't really like

     {literal_expr, {tuple, [{atom,hello},{integer,0},{'fun',{function,{atom,erlang},{atom,display},{integer,1}}} ] }}

All we need is an 'eval' instruction to the loader .. soon we won't even 
need the compiler. But, I digress ..

Is there any other potential literals that are needed. I don't think so, 
perhaps only solve this for fun exports and not the general case .. If 
it needs solving that is.

// Björn-Egil




More information about the eeps mailing list