Как изменить сборку Erlang? Доступны ли какие-либо ресурсы?

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

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

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

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

К сожалению, я быстро просмотрел файлы .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}. ).

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

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

Спасибо за уделенное время.

8
задан kay 29 October 2011 в 07:38
поделиться