对字节码和对象的澄清 [英] Clarifications on Bytecode and objects

查看:128
本文介绍了对字节码和对象的澄清的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写一个字节码指导员。现在,我试图找出在对象存在的情况下如何做到这一点。我想对我在JVMS中读到的两行进行澄清(第4.9.4节):

I am writing a Bytecode instrumenter. Right now, I am trying to find out how to do that in the presence of objects. I would like some clarifications on two lines I read in the JVMS (section 4.9.4):


1)验证者拒绝代码在初始化
之前使用新对象。

1) "The verifier rejects code that uses the new object before it has been initialized."

我的问题是,使用是什么意思?我猜这意味着:将它作为方法属性传递,在其上调用 GETFIELD PUTFIELD ,或者调用它上面的任何实例方法。他们的其他禁止用途?我相信它遵循其他指令,如 DUP LOAD STORE

My question is, what does "uses" mean here? I'm guessing that it means: passing it as a method attribute, calling GETFIELD and PUTFIELD on it, or calling any instance method on it. Are their other forbidden uses? And I believe that it follows that other instructions such as DUP, LOAD and STORE are allowed.


2)在该方法之前调用
myClass或其直接的另一个实例初始化方法
上的超类这个,
方法可以执行的唯一操作是分配在myClass中声明的
字段。

2) "Before that method invokes another instance initialization method of myClass or its direct superclass on this, the only operation the method can perform on this is assigning fields declared within myClass."

这意味着在< init> 方法中,GETFIELD和PUTFIELD在另一个< init> 被调用。但是,在Java中,在调用 super() this()结果之前对实例字段执行任何操作在编译错误。有人可以澄清这个吗?

Which means that in an <init> method, GETFIELD and PUTFIELD are allowed before another <init> is called. However, in Java, doing any operation on an instance field before a call to super() or this() results in a compilation error. Could someone clarify this?

3)我还有一个问题。对象引用何时初始化,因此可以自由使用?通过阅读JVMS,我想出了一个对象是否被初始化的答案,取决于每种方法。在某个时间点,可以为方法初始化对象,但不能为另一个方法初始化对象。具体来说,当该方法返回的< init> 调用时,对象会被初始化。

3) I have one more question. When does an object reference becomes initialized, and hence, ready to be freely used? From reading the JVMS, I came up with the answer that whether an object is initialized or not, is up to each method. At a certain point in time, the object can be initialized for a method but not for the other. Specifically, an object becomes initialized for a method when <init> called by that method returns.

例如,考虑 main()方法创建了一个对象并调用< init> 然后调用超类的< INIT> 。从 super()返回后,该对象现在被< init> 初始化,但尚未初始化对于 main()。这是否意味着,在< init> 之后,我可以将对象作为参数传递给方法,甚至在从main()返回之前。

For example, consider that the main() method created an object and called <init> which then called the superclass's <init>. After returning from super(), the object is now considered initialized by <init> , but is not yet initialized for main(). Does this mean, in <init> after super(), I can pass the object as a parameter to a method, even before returning from to main().

有人可以确认整个分析是否属实?感谢您的时间。

Could someone confirm that this whole analysis is true? Thank you for your time.

ps:我实际上已经向Sun论坛发布了同样的问题但是回复了。我希望我能在这里有更多的运气。谢谢。

ps: I have actually posted the same question to the Sun forums but with on response. I hope I'll have more luck here. Thank you.

更新

首先,感谢您的回答和时间。虽然我没有得到一个明确的答案(我有很多问题,其中一些有点模糊),但你的答案和例子,以及随后的实验,对于我更深入地了解JVM如何工作非常有用。

First thank you for your answers and time. Although I didn't get a clear-cut answer (I had many questions and some of them were a bit vague), your answers and examples, and the subsequent experiments, were extremely useful for me in understanding more deeply how the JVM works.

我发现的主要问题是Verifier的行为因不同的实现和版本而不同(这使得字节码操作的工作变得更加复杂)。问题在于不符合JVMS,或者验证者的开发人员缺乏文档,或者JVMS在验证者的区域中有一些微妙的模糊性。

The main thing I discovered is that the Verifier's behavior differ with different implementations and versions (which makes the job of bytecode manipulation much more complicated). The problem lies in either a non-conformity to the JVMS, or a lack of documentation from the verifier's developers, or the JVMS has some subtle vagueness in the verifier's area.

最后一件事,SO Rocks !!!我在官方的Sun JVM规范论坛上发布了同样的问题,直到现在我仍然没有答案。

One last thing, SO Rocks!!! I posted the same question in the official Sun JVM Specifications forum, and I still got no answer till now.

推荐答案

我建议你您下载OpenJDK源的副本并查看验证程序实际检查的内容。如果不出意外,这可能会帮助您理解JMV规范所说的内容。

I suggest that you download a copy of the OpenJDK sources and look at what the verifier is actually checking. If nothing else, that may help you understand what the JMV specification is saying.

(但是,@ Joachim是对的。依赖于验证器实现的功能,而不是规范说风险很大。)

(However, @Joachim is right. Relying on what the verifier implementation does rather than what the specification says is rather risky.)

这篇关于对字节码和对象的澄清的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆