2011-10-28 26 views
9

tôi nghi ngờ bất cứ ai có thể giúp đỡ với câu hỏi này bởi vì những điều sau đây trong Erlang's compile documentation:Làm thế nào để sửa đổi lắp ráp Erlang? Có tài nguyên nào không?

Lưu ý rằng định dạng của file lắp ráp không được ghi nhận, và có thể thay đổi giữa các phiên bản - tùy chọn này chủ yếu là để sử dụng gỡ lỗi nội bộ.

... nhưng chỉ trong trường hợp, ở đây đi stack trace của câu chuyện:

  • biên dịch: file/2 với [ 'S'] để tạo mã lắp ráp
  • tập tin
  • đọc .S và tạo một cấu trúc dữ liệu khóa-giá trị với khóa là các hàm 'hàm' trong tệp .S và giá trị là phần thân của hàm, nghĩa là các lệnh lắp ráp thực hiện hàm.
  • Sửa đổi cấu trúc dữ liệu bằng cách thêm assembly để thực hiện cuộc gọi hàm bên ngoài trong một số chức năng nhất định.
  • vụ tai nạn ...

Đáng tiếc là tôi chỉ nhanh chóng lướt các tập tin .S tạo ra khi biên soạn một module chứa các chức năng sau đây, có và không có biểu hiện đầu tiên trong chức năng chú thích:

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

Khi tôi làm điều đó, tôi nghĩ rằng điều duy nhất thay đổi là bộ đồ:

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

... vì vậy tôi giả định rằng điều duy nhất cần thiết để tiêm một cuộc gọi hàm trong hội đồng là thêm tuple ... nhưng bây giờ tôi đã thực sự tiêm tuple ... rằng lắp ráp tạo ra có một số hướng dẫn thêm:

Without 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}}. 

với 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}}. 

tôi có thể không chỉ kết luận rằng việc thêm một cái gì đó như:

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

đến từng chức năng tôi muốn tiêm một chức năng cuộc gọi bên ngoài vào, sẽ làm các trick.

  1. vì tôi không chắc chắn nếu đó mã lắp ráp áp dụng cho tất cả các chức năng tôi muốn tiêm vào (ví dụ là {phân bổ, 1,1} luôn ok)
  2. bởi vì nếu bạn có một cái nhìn gần gũi hơn ở phần còn lại của hội đồng, nó thay đổi một chút (ví dụ: {call_ext_only, 3, {extfunc, erlang, spawn, 3}}. }).

Vì vậy, bây giờ câu hỏi là, có bất kỳ tài nguyên nào ở đó tôi có thể sử dụng để hiểu và thao tác lắp ráp được tạo bởi biên dịch của Erlang: tệp/2 không?

Tôi đang đặt câu hỏi này chỉ trong trường hợp. Tôi nghi ngờ có một nguồn lực cho điều này vì tài liệu rõ ràng nói rằng không có, nhưng tôi không có gì để mất tôi đoán. Ngay cả khi có, nó có vẻ như thao tác mã lắp ráp sẽ là phức tạp hơn tôi muốn nó được. Sử dụng parse_transform/2 chắc chắn là dễ dàng hơn, và tôi đã có được một cái gì đó tương tự để làm việc với nó ... chỉ cần thử các lựa chọn thay thế khác nhau.

Cảm ơn thời gian của bạn.

+0

(Kể từ kiểm tra, không phải từ nguồn đọc.) '{allocate, 1,1}' phân bổ một vị trí trên ngăn xếp y. Các x stack là ngăn xếp "bình thường", các thanh ghi. Ngăn xếp y là một ngăn xếp phụ trợ. '{move, {x, 0}, {y, 0}}' di chuyển đỉnh trên cùng x đến mặt đáy y (ít nhất là chúng phát triển theo chiều ngược lại). Tệp thử nghiệm của tôi: http://pastebin.com/R21ZJ29Q. Kết quả của nó: http://pastebin.com/jULjMCV0. – kay

+0

Cảm ơn bạn đã giúp đỡ kay. Có vẻ như việc tìm ra hội đồng sẽ mất quá nhiều thời gian, nên tôi không định giải mã nó. Chúc mừng. – justin

Trả lời

3

các công cụ duy nhất tôi biết rằng việc sử dụng t ông chùm asm là HiPE, có rất nhiều ví dụ mã và như vậy trong https://github.com/erlang/otp/tree/master/lib/hipe/icode, mặc dù tôi sẽ không khuyên bạn nên làm nhiều với định dạng này vì nó đang thay đổi tất cả các thời gian.

+1

Điểm chụp. Làm việc với các đại diện lắp ráp là yêu cầu cho sự cố. Chúc mừng. – justin

2

Tôi không chắc chắn bạn đang cố gắng đạt được điều gì, nhưng cốt lõi erlang có thể là cấp độ tốt hơn để thực hiện thao tác mã. Đây là tài liệu (cũng một phiên bản của nó dù sao đi nữa, nhưng đây vẫn là tốt hơn so với không có gì) ở đây (và có những chỉ hơn google cho lõi erlang):

Để biên dịch đến và đi từ sử dụng lõi erlang của to_core 'và 'from_core'(tiếc là không có cơ sở) lựa chọn:

c(my_module, to_core). %%this generates my_module.core 
c(my_module, from_core). %%this loads my_module.core 
+1

Tôi nghĩ rằng cốt lõi erlang là những gì được sử dụng bởi lfe (https://github.com/rvirding/lfe), bạn có thể tìm thấy một số thông tin hữu ích ở đó – Lukas

+0

hmm ye Tôi nhanh chóng đọc bài báo đó nhưng không thử sử dụng lõi Erlang . Tôi đoán tôi sẽ xem xét nó nhiều hơn một chút. Cảm ơn con trỏ TamasNagy. – justin

+0

lfe sử dụng lõi erlang huh. Cool, tất cả các lý do hơn để kiểm tra xem nó ra. Cảm ơn Lukas. – justin

1

Dường như với tôi rằng những gì bạn đang cố gắng làm có thể dễ dàng được giải quyết bằng cách thao tác mã trừu tượng. Chỉ cần viết mô-đun parse_transform trong đó bạn có thể chèn lệnh gọi hàm vào các hàm đang được đề cập đến.

Tôi đã viết một ?funclog dựa trên erlang decorators. xem https://github.com/nicoster/erl-decorator-pt#funclog

Các vấn đề liên quan