GHC的设计基于一种名为STG的东西,它代表"无骨架,无标签G机".
现在G-machine显然是"图形缩减机"的缩写,它定义了如何实现懒惰.未评估的thunk被存储为表达式树,并且执行该程序涉及将这些减少到正常形式.(树是非循环图,但Haskell的普遍递归意味着Haskell表达式形成一般图,因此图减少而不是树减少.)
不太清楚的是术语"无骨"和"无标记".
我认为 "无脊椎"指的是功能应用程序没有功能应用程序节点的"脊椎"这一事实.相反,您有一个对象,该对象命名所调用的函数并指向其所有参数.那是对的吗?
我认为"无标签"指的是构造函数节点没有用构造函数ID"标记",而是使用跳转指令解析case-expression.但现在我不确定这是否正确.相反,它似乎指的是节点没有用其评估状态标记的事实.谁能澄清这些解释中哪些(如果有的话)是正确的?
您可以使用字节码执行任何操作,您可以在本机代码中轻松快速地执行此操作.理论上,您甚至可以通过在字节码中分发程序和库然后在安装时编译为本机代码而不是JIT来保持平台和语言独立性.
所以一般来说,你什么时候想要执行字节码而不是本机?
在最近提出的一个问题中,我简单的回答强调了我对Java,JVM以及代码如何编译和运行的许多误解.这使我产生了将我的理解提升到较低水平的愿望.像汇编这样的低层次理解我没有问题字节码和JVM如何让我感到困惑.面向对象的代码如何在低级别上分解对我来说是丢失的.我想知道是否有人对如何了解JVM,字节码和Java的低级功能有任何建议.是否有任何实用程序允许您直接编写和运行字节码,因为我相信亲身体验某些东西是理解它的最佳方式?此外,我们将不胜感激地阅读有关该主题的建议.
编辑:次要问题.所以我有一个小问题,答案给了我一个有趣的想法来了解jvm,写一个非常简单的语言如brainf**k或Ook的合理性只是用一种可读的语法(也许我甚至可以开发它)最终支持oo)编译成字节码是什么?这会是一个很好的学习经历吗?
我正在尝试编译一个调用一些导出函数的lua脚本,将生成的字节码保存到文件然后加载此字节码并执行它,但我还没有找到任何关于如何执行此操作的示例.有没有关于如何做到这一点的例子?我怎样才能做到这一点?
编辑:我正在使用Lua + Luabind(C++)
如果你看一下字节码
Consumer<String> println = System.out::println;
Run Code Online (Sandbox Code Playgroud)
Java 8更新121生成的字节代码是
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
DUP
INVOKEVIRTUAL java/lang/Object.getClass ()Ljava/lang/Class;
POP
INVOKEDYNAMIC accept(Ljava/io/PrintStream;)Ljava/util/function/Consumer; [
// handle kind 0x6 : INVOKESTATIC
java/lang/invoke/LambdaMetafactory.metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
// arguments:
(Ljava/lang/Object;)V,
// handle kind 0x5 : INVOKEVIRTUAL
java/io/PrintStream.println(Ljava/lang/String;)V,
(Ljava/lang/String;)V
]
ASTORE 1
Run Code Online (Sandbox Code Playgroud)
getClass()
正在调用该方法System.out
,结果被忽略.
这是间接空引用检查吗?
当然,如果你跑
PrintStream out = null;
Consumer<String> println = out::println;
Run Code Online (Sandbox Code Playgroud)
这会触发NullPointerException.
有一个学习JVM字节码指令集的好地方.规范也许也许是一些教程?
我问,因为我想为它设计一个生成JVM字节码的玩具语言和编译器.
感谢您的知识,也许谷歌搜索.
根据Scala 2.10,与1.6的默认发射相比,JVM 1.7发射字节码有什么优势(如果有的话)?
我正在用Java编写一个解释器,用于具有某些脚本功能的特定于域的语言.我已经实现了一个解析器,现在需要做一个后端.为此,我正在考虑编写自己的解释器(使用抽象语法树或使用一些自定义字节码)或目标JVM(在运行时发出并执行Java字节码).
在这方面有更多经验的人是否可以说针对JVM的方法有多可行?您建议使用哪些库来发布Java字节码?
在Java的String类中,trim方法包含:
int off = offset; /* avoid getfield opcode */
char[] val = value; /* avoid getfield opcode */
Run Code Online (Sandbox Code Playgroud)
我对评论"避免getfield操作码"感到有些困惑......
这是什么意思?(我认为这可以避免在字节码中使用getfield,但为什么这是一个Good Thing [TM]?)
难道是防止万一对象创建微调不会做任何事情(因此该返回)或?
我有一段简单的Java代码:
public static void main(String[] args) {
String testStr = "test";
String rst = testStr + 1 + "a" + "pig" + 2;
System.out.println(rst);
}
Run Code Online (Sandbox Code Playgroud)
使用Eclipse Java编译器对其进行编译,然后使用AsmTools检查字节码。表明:
该方法中包含三个局部变量。参数位于插槽0中,并且代码假定使用插槽1和2。但是我认为2个局部变量就足够了-索引0仍然是参数,并且代码仅需要一个变量。
为了查看我的想法是否正确,我编辑了文本字节码,将局部变量的数量减少到2,并调整了一些相关指令:
我用AsmTools重新编译了它,效果很好!
那么,为什么Javac或Eclipse编译器不进行这种优化以使用最小局部变量呢?