简体   繁体   English

如何在SICStus Prolog中检查WAM代码

[英]How can I inspect WAM code in SICStus Prolog

In the context of hacking on I want to glimpse at the code generated by SICStus Prolog. 的黑客攻击的背景下,我想瞥一下SICStus Prolog生成的代码。 As an example, let's dissect the following predicate! 举个例子,让我们剖析下面的谓词!

is_list([]).
is_list([_|Es]) :- is_list(Es).

Here's what I'm doing now: 这就是我现在正在做的事情:

  1. Split the 2 clauses of is_list/1 into 2 separate predicates and prepend 2 dummy clauses: is_list/1的2个子句拆分为2个单独的谓词,并添加2个虚拟子句:

    \nis_list__clause1(dummy1). is_list__clause1(dummy1)。 % dummy clause %dummy子句\nis_list __clause1 ([]). is_list __clause1 ([])。\n\nis_list__clause2(dummy2). is_list__clause2(dummy2)。 % dummy clause %dummy子句\nis_list __clause2 ([_|Es]) :- is_list(Es). is_list __clause2 ([_ | Es]): -  is_list(Es)。\n
  2. (Ab-)use the SICStus like so: (ab-)像这样使用SICStus

    \n| | ?- is_list__clause1(X). ? - is_list__clause1(X)。\nX = dummy1 ? X = dummy1? t Ť\n ...\n0x7eff37281300: GET_NIL_X0 0x7eff37281300:GET_NIL_X0 \n0x7eff37281304: PROCEED 0x7eff37281304:继续 \n0x7eff37281308: END_OF_CLAUSEQ user:is_list__clause1/1 0x7eff37281308:END_OF_CLAUSEQ用户:is_list__clause1 / 1\n ...\n| | ?- is_list__clause2(X). ? - is_list__clause2(X)。\nX = dummy2 ? X = dummy2? t Ť\n ...\n0x7eff37281150: GET_LIST_X0 0x7eff37281150:GET_LIST_X0 \n0x7eff37281154: U2_VOID_XVAR 1,x(0) 0x7eff37281154:U2_VOID_XVAR 1,x(0)\n0x7eff37281160: EXECUTEQ user:is_list/1 0x7eff37281160:EXECUTEQ用户:is_list / 1\n0x7eff37281170: END_OF_CLAUSEQ user:is_list__clause2/1 0x7eff37281170:END_OF_CLAUSEQ用户:is_list__clause2 / 1\n ... 

This output—albeit somewhat cryptic—is giving me a feel of what's going on at the WAM level. 这个输出 - 虽然有些神秘 - 让我感受到WAM级别正在发生的事情。 I like! 我喜欢!

But there has got to a simpler way... please help! 但是, 已经一个更简单的方法...请帮助!

There is a simpler way: the undocumented, unsupported, library(disassembler) . 有一种更简单的方法:未记录的,不受支持的library(disassembler)

You can use this for programmatically getting information about first-argument indexing in addition to the WAM instructions. 除了WAM指令之外,您还可以使用它以编程方式获取有关第一个参数索引的信息。 See the source for more information. 有关更多信息,请参阅源代码。

| ?- use_module(library(disassembler)).
% ...
yes
| ?- [user].
% compiling user...
| foo([],Ys,Ys). foo([X|Xs],Ys,[X|Zs]) :- foo(Xs,Ys,Zs). end_of_file.
% compiled user in module user, 89 msec 599696 bytes
yes
| ?- disassemble(foo/3).
% Predicate: user:foo/3 (user)
% Varcase: [4343940512-4343958960,4346212208-4343221120]
% Lstcase: [4346212212]
% Switch: [[]=4343940516], default: failcode
% clause indexed [var,number,atom,structure] (user)
%    4343940512: 'GET_NIL_X0'
%    4343940516: 'GET_X_VALUE_PROCEED'(x(1),x(2))
%    4343940528: 'END_OF_CLAUSEQ'(user:foo/3)
% clause indexed [var,list] (user)
%    4346212208: 'GET_LIST_X0'
%    4346212212: 'U2_XVAR_XVAR'(x(3,0),x(0,0))
%    4346212224: 'GET_LIST'(x(2))
%    4346212232: 'U2_XVAL_XVAR'(x(3),x(2,0))
%    4346212244: 'EXECUTE'(user:foo/3)
%    4346212256: 'END_OF_CLAUSEQ'(user:foo/3)
yes
| ?- 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM