[erlang-questions] Obtain abstract forms from a module loaded using code:load_binary/3
Edmond Begumisa
ebegumisa@REDACTED
Mon Feb 19 19:38:04 CET 2018
Hello all,
Is there a way to obtain the abstract forms back from a module loaded with
code:load_binary/3? Are the abstract forms not kept somewhere for the
debugger?
To elaborate, I'm doing some metaprogramming where a module evolves over
time after being initially loaded from disk. For a simplified contrived
example [1], say I have a module...
-module(dynamic).
-export([get/1]).
get(foo) -> 1.
dynamic.beam is compiled with debug_info and distributed as part of my OTP
app. Then, at runtime, I have code I call once in a while which
conceptually resembles the following...
update_get(Incr) when is_integer(Incr) ->
{_,PrevObjCode,_} = code:get_get_object_code(dynamic),
% ^^^ NOPE! Gets original obj code from disk
{ok,{_,[{abstract_code,{_,Forms0}}]}} =
beam_lib:chunks(PrevObjCode, [abstract_code]),
Forms1 =
...
merl code to replace get return literal in Forms0
with the value incremented by Incr
...
{ok,_,UpdObjCode} = compile:forms(Forms1, [binary,debug_info]),
% ^^^ What happens to
these after loading?
{module,_} = code:load_binary(dynamic, code:which(dynamic),
UpdObjCode).
update_get/1 won't work when called multiple times because PrevObjCode
always contains 1 as the return value of dynamic:get/1.
One solution is to keep UpdObjCode somewhere as state and use that the
next time update_get/1 is called instead of calling
code:get_object_code/1. However, I can't do that because my use case is
such that I can't really keep track of what's supposed to be the current
code. update_get/1 needs to only use knowledge from whatever the current
version is of the module it's updating.
The solution I'm currently using is to store the Forms1 in the updated
module by compiling it in when calling compile:forms/2. I'm using a module
attribute for this. I'm trying to see if there's an alternative to abusing
module attributes to store code.
- Edmond -
[1] My actual use case is code that performs infrequent write transactions
on frequently read data stored in the constant pool so that it's and
accessible from thousands of processes in a concurrency-friendly manner.
--
Using Opera's mail client: http://www.opera.com/mail/
More information about the erlang-questions
mailing list