由于我似乎将 95% 的编码时间实际上花在了 F# 的 FSI 上,因此我绕道(参见:Distracted)并想编写一些实用函数。
我感兴趣的特定实用程序是一个“反汇编”(http://www.cons.org/cmucl/doc/reading-disassembly.html)函数,它可以为给定函数转储IL,稍后可能会计算指令,基本的静态分析等,通常这只是分散注意力的天堂。我已经编写了将 byteArrayIL 映射到 MSIL 名称的代码(几乎)。
这是用于从当前模块获取函数名称的代码段:
let dec_c = MethodBase.GetCurrentMethod().DeclaringType
System.Reflection.Assembly.GetAssembly(dec_c).GetTypes()
|> Seq.map (fun x -> x.FullName) //, get_function_instructions x)
这几乎可以正常工作,因为 x.FullName 反映了实际的函数名称:
FSI_0001
<StartupCode$FSI_0001>.$FSI_0001
FSI_0002
FSI_0002+instructions_of_bytes@24
FSI_0002+remove_null_function_body_bytes@32
FSI_0002+remove_null_function_body_bytes@31-1
FSI_0002+resolve_IL_from_bytes@38
FSI_0002+resolve_IL_from_bytes@36-1
FSI_0002+it@49
FSI_0002+it@50-1
<StartupCode$FSI_0002>.$FSI_0002
FSI_0003
FSI_0003+it@49-2
FSI_0003+it@50-3
<StartupCode$FSI_0003>.$FSI_0003
所以我们可以很容易地编写一个函数来根据我们的函数名进行过滤。
不幸的是(可能由于我的误解),似乎并非所有函数都以这种方式可用,例如,如果我们定义以下简单函数然后重新运行转储:
(* reload FSI *)
let simple_add x = x + 1
(* rerun the function name dumping *)
FSI_0001
<StartupCode$FSI_0001>.$FSI_0001
FSI_0002
FSI_0002+instructions_of_bytes@24
FSI_0002+remove_null_function_body_bytes@32
FSI_0002+remove_null_function_body_bytes@31-1
FSI_0002+resolve_IL_from_bytes@38
FSI_0002+resolve_IL_from_bytes@36-1
FSI_0002+it@50
FSI_0002+it@51-1
<StartupCode$FSI_0002>.$FSI_0002
奇怪的是,结果文本中不存在“simple_add”函数。
思考: 1. 可能simple_add这个函数不是通过反射实现的,直到看到被使用?听起来很奇怪。2. 可能是那些“FSI_0002+it”字符串之一实际上是我们的函数。
问题: 1. 为什么输出没有反映所有的函数名?2.有没有更好的方法来做到这一点?