Message5992
So the interpretation of the virtual machine specification doesn't say that static final fields must be written before instances of classes can be created. If this were so then it would be impossible to make singleton instances of classes. Also putstatic may write to a final field in the same class from any method - from the virtual machine specification. So from this Jython's code looks valid and passes bytecode verification (-Xverify in HotSpot).
The Java Language Specification:
http://java.sun.com/docs/books/jls/third_edition/html/memory.html#17.5.1
details what the meaning of final is and here it can be seen why what jython is doing is buggy, although a discussion of class initializers isn't provided in this context - my discussion follows what happen in HotSpot (the reference Java implementation). A static final field is initialized by the class initializer. A freeze event occurs when the class initializer completes. Readers of the static final once a class is initialized can assume that it is constant, with some exceptions such as when the field is modified through a specialist mechanism such as reflection. The reader of the static final field (especially when -Xcomp is switched on) is the HotSpot compiler.
Consider jython generated code such as:
public sre_constants$py(java.lang.String);
Code:
Stack=13, Locals=3, Args_size=2
0: aload_0
1: invokespecial #645; //Method org/python/core/PyFunctionTable."<init>":()V
4: aload_0
5: putstatic #649; //Field self:Lsre_constants$py;
...
1045: iconst_1
1046: iconst_1
1047: anewarray #543; //class java/lang/String
1050: astore_2
1051: aload_2
1052: iconst_0
1053: ldc_w #858; //String a
1056: aastore
1057: aload_2
1058: aload_1
1059: ldc_w #860; //String <lambda>
1062: sipush 222
1065: iconst_0
1066: iconst_0
1067: getstatic #649; //Field self:Lsre_constants$py;
1070: iconst_4
1071: aconst_null
1072: aconst_null
1073: iconst_0
1074: sipush 4097
1077: invokestatic #840; //Method org/python/core/Py.newCode:(I[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IZZLorg/python/core/PyFunctionTable;I[Ljava/lang/String;[Ljava/lang/String;II)Lorg/python/core/PyCode;
1080: putstatic #538; //Field f$4:Lorg/python/core/PyCode;
1083: return
The:
5: putstatic #649; //Field self:Lsre_constants$py;
occurs after the class initialization freeze event. The compiler compiles:
1067: getstatic #649; //Field self:Lsre_constants$py;
And because the field is considered frozen the value NULL is loaded and passed through to the subsequent call. Eventually this results in a NullPointerException. |
|
Date |
User |
Action |
Args |
2010-08-20 18:06:49 | irogers | set | messageid: <1282327609.92.0.37264397008.issue1611@psf.upfronthosting.co.za> |
2010-08-20 18:06:49 | irogers | set | recipients:
+ irogers, draghuram, alexey |
2010-08-20 18:06:49 | irogers | link | issue1611 messages |
2010-08-20 18:06:46 | irogers | create | |
|