dudo que alguien puede ayudar con esta pregunta por lo siguiente en Erlang's compile documentation:¿Cómo modificar el ensamblaje de Erlang? ¿Hay algún recurso disponible?
Tenga en cuenta que el formato de los archivos de ensamblador no está documentada, y puede cambiar entre versiones - esta opción es principalmente para uso interno de depuración.
... pero por si acaso, aquí va seguimiento de la pila de la historia:
- de compilación: archivo/2 con [ 'S'] para generar el código de montaje archivo
- Leer .S y crear una estructura de datos clave-valor con la clave siendo las tuplas 'función' en el archivo .S, y el valor es el cuerpo de la función, es decir, las instrucciones de ensamblaje que implementan la función.
- Modifica la estructura de datos agregando el conjunto para realizar una llamada de función externa en ciertas funciones.
- accidente ...
desgracia acabo rápidamente desnatada los archivos .S generados al compilar un módulo que contiene la función siguiente, con y sin la primera expresión de la función comentada:
spawn_worker(Which) ->
%syner:sync_pt(),
case Which of
?NAIVE -> spawn(err1, naive_worker_loop, [])
end.
Cuando lo hice, pensé que lo único que cambió fue la tupla:
{call_ext, 0, {extfunc, syner, sync_pt, 0}}.
... así que supuse que lo único necesario inyectar una llamada de función en la asamblea fue la de añadir esa n ... pero ahora que llegué a la inyección de la tupla realidad ... estoy viendo que el montaje generado tiene algunas instrucciones adicionales:
Sin 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}}.
Con 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}}.
Simplemente no se puede concluir que algo así como la adición:
{allocate,1,1}.
{move,{x,0},{y,0}}.
{call_ext,0,{extfunc,syner,sync_pt,0}}.
a cada función Quiero inyectar una llamada a la función externa en, hará el truco.
- , porque no estoy seguro de si eso código de montaje se aplica a todas las funciones que quiero para inyectar en (por ejemplo, es {asignar, 1,1} siempre bien)
- porque si usted toma una mirada más cercana en el resto del conjunto, cambia ligeramente (por ejemplo, {call_ext_only, 3, {extfunc, erlang, spawn, 3}}. cambios en {call_ext_last, 3, {extfunc, erlang, spawn, 3}, 1 }.).
Así que ahora la pregunta es, ¿hay algún recurso que pueda usar para comprender y manipular el ensamblado generado por la compilación de Erlang: archivo/2?
Estoy haciendo esta pregunta por las dudas. Dudo que haya un recurso para esto, ya que la documentación establece claramente que no existe, pero no tengo nada que perder, supongo. Incluso si hubiera, parece que manipular el código ensamblador va a ser más complicado de lo que me gustaría. Usar parse_transform/2 es definitivamente más fácil, y logré obtener algo similar para trabajar con él ... simplemente probando diferentes alternativas.
Gracias por su tiempo.
(Según las pruebas, no de fuentes de lectura) '' {allocate, 1,1} 'asigna un lugar en la pila y. La pila x es la pila "normal", los registros. La pila y es una pila auxiliar. '{movimiento, {x, 0}, {y, 0}}' mueve la x superior a la más inferior y (al menos cree que crecen en dirección inversa). Mi archivo de prueba: http://pastebin.com/R21ZJ29Q. Su resultado: http://pastebin.com/jULjMCV0. – kay
Gracias por la ayuda kay. Parece que calcular el montaje me tomará demasiado tiempo, así que no estoy planeando descifrarlo. Aclamaciones. – justin