Как изменить сборку Erlang? Доступны ли какие-либо ресурсы? - PullRequest
8 голосов
/ 29 октября 2011

Я сомневаюсь, что кто-то может помочь с этим вопросом из-за следующего в документации по компиляции Эрланга :

Обратите внимание, что формат файлов ассемблера не задокументирован, и может изменяться междуReleases - эта опция предназначена в основном для внутренней отладки.

... но на всякий случай здесь идет трассировка стека истории:

  • compile: file / 2 with['S'], чтобы сгенерировать ассемблерный код
  • Считать файл .S и создать структуру данных ключ-значение, где ключом является кортеж 'function' в файле .S, а значением является тело функции, т.е.инструкции по сборке, которые реализуют функцию.
  • Измените структуру данных, добавив сборку для выполнения внешнего вызова функции в определенных функциях.
  • crash ...

К сожалению, я просто быстро просмотрел файлы .S, сгенерированные при компиляции модуля, содержащего следующую функцию, с закомментированным первым выражением в функции и без него:

spawn_worker(Which) ->
    %syner:sync_pt(),
    case Which of
            ?NAIVE -> spawn(err1, naive_worker_loop, [])
    end.

Когда я это сделал, я подумал, что единственное, что изменилось, это кортеж:

{call_ext, 0, {extfunc, syner, sync_pt, 0}}.

... поэтому я предположил, что единственное, что необходимо для внедрения вызова функции в сборку, это добавить этот кортеж ... но теперь, когда я действительно должен внедрить кортеж ... я вижучто в сгенерированной сборке есть несколько дополнительных инструкций:

Без syner: sync_pt () :

{function, spawn_worker, 1, 4}.
{label,3}.
    {func_info,{atom,err1},{atom,spawn_worker},1}.
{label,4}.
    {test,is_eq_exact,{f,5},[{x,0},{atom,naive}]}.
    {move,{atom,naive_worker_loop},{x,1}}.
    {move,nil,{x,2}}.
    {move,{atom,err1},{x,0}}.
    {call_ext_only,3,{extfunc,erlang,spawn,3}}.
{label,5}.
    {case_end,{x,0}}.

С syner: sync_pt () :

{function, spawn_worker, 1, 4}.
{label,3}.
    {func_info,{atom,err1},{atom,spawn_worker},1}.
{label,4}.
    {allocate,1,1}.
    {move,{x,0},{y,0}}.
    {call_ext,0,{extfunc,syner,sync_pt,0}}.
    {test,is_eq_exact,{f,5},[{y,0},{atom,naive}]}.
    {move,{atom,naive_worker_loop},{x,1}}.
    {move,nil,{x,2}}.
    {move,{atom,err1},{x,0}}.
    {call_ext_last,3,{extfunc,erlang,spawn,3},1}.
{label,5}.
    {case_end,{y,0}}.

Я не могу просто заключить, что добавление чего-то вроде:

   {allocate,1,1}.
   {move,{x,0},{y,0}}.
   {call_ext,0,{extfunc,syner,sync_pt,0}}.

к каждой функции, в которую я хочу внедрить вызов внешней функции, сделает свое дело.

  1. , потому что я не уверен, применим ли этот ассемблерный код ко всем функциям, в которые я хочу вставить (например, {allocate, 1,1} всегда в порядке)
  2. потому что, если вы присмотритесь к остальной части сборки, она немного изменится (например, {call_ext_only, 3, {extfunc, erlang, spawn, 3}}. изменится на {call_ext_last, 3, {extfunc, erlang, spawn, 3}, 1}. ).

Итак, вопрос в том, есть ли какой-нибудь ресурс, который я могу использовать, чтобы понять иманипулировать сборкой, сгенерированной компиляцией Эрланга: file / 2?

Я задаю этот вопрос на всякий случай.Я сомневаюсь, что для этого есть ресурс, так как в документации четко сказано, что его нет, но мне нечего терять.Даже если бы и было, кажется, что манипулирование ассемблерным кодом будет сложнее, чем хотелось бы.Использование parse_transform / 2 определенно проще, и мне удалось получить что-то похожее для работы с ним ... просто пробовал разные варианты.

Спасибо за ваше время.

Ответы [ 3 ]

2 голосов
/ 29 октября 2011

Единственный известный мне инструмент, использующий ассемблер луча, - это HiPE, в https://github.com/erlang/otp/tree/master/lib/hipe/icode, есть много примеров кода и тому подобное, хотя я бы не советовал делать много с этим форматом, поскольку он постоянно меняется.

2 голосов
/ 29 октября 2011

Я не уверен, что вы пытаетесь достичь с этим, но ядро ​​erlang может быть лучшим уровнем для манипулирования кодом. Это задокументировано (ну, во всяком случае, одна версия, но это все же лучше, чем ничего) здесь (и это больше, чем просто Google для ядра erlang):

Для компиляции в и из ядра erlang используйте опции to_core и from_core (к сожалению, недокументированные):

c(my_module, to_core). %%this generates my_module.core
c(my_module, from_core). %%this loads my_module.core
1 голос
/ 06 апреля 2017

Мне показалось, что то, что вы пытаетесь сделать, можно легко решить, манипулируя абстрактным кодом. Просто напишите модуль parse_transform, внутри которого вы можете вставить вызов функции в рассматриваемые функции.

Я написал ?funclog на основе erlang decorators. см https://github.com/nicoster/erl-decorator-pt#funclog

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...