This is the mail archive of the kawa@sources.redhat.com mailing list for the Kawa project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: IllegalAccessError in latest cvs version


> This error does _not_ occur with the Sun JVM, so it's not clear that this
> isn't a microsoft bug, but it wasn't a problem with 1.6.70.

It's a gray area.  The problem is that Kawa generates:

  static final gnu.expr.ModuleMethod Lambda$Fn1;

and then it generates a putstatic instruction to initialize the field.
The problem is this instruction is in the instance initializer
(<init>) method, rather than the class initializer (<clinit>) method.
I checked the VM spec, and technically this is not prohibited.
Still, it is not a good.

One fix should be to not set the "final" flag on the field, but a
better fix would be to put the putstatic in <clinit>.  Unfortunately,
ModuleMethod requires a ModuleBody instance, which is the current
compiled class.  So things are a little messy.

The reason is that it works fine when "a variable from an
enclosing let is referenced within the lambda" is that in that case
the field is forced to be non-static, since it imports a non-static
variable.

We want to make the field static when we can, because that generates
better code, so making the field per-instance is a bad option.

This patch should work.  It's not very elegant, I admit.

Index: LambdaExp.java
===================================================================
RCS file: /cvs/kawa/kawa/gnu/expr/LambdaExp.java,v
retrieving revision 1.43
diff -u -r1.43 LambdaExp.java
--- LambdaExp.java	2000/10/15 18:51:05	1.43
+++ LambdaExp.java	2000/10/24 23:04:48
@@ -521,7 +521,13 @@
     if (nameDecl != null && nameDecl.context instanceof ModuleExp)
       {
 	if (nameDecl.getFlag(Declaration.STATIC_SPECIFIED))
-	  fflags |= Access.STATIC;
+          {
+            fflags |= Access.STATIC;
+            // If there is no instanceField, then the field gets initialized in
+            // <init>, not <clinit>, which is bad for a "static final" field.
+            if (! ((ModuleExp) nameDecl.context).isStatic())
+              fflags &= ~Access.FINAL;
+          }
 	if (! nameDecl.isPrivate())
 	  fflags |= Access.PUBLIC;
       }
@@ -529,7 +535,7 @@
       {
 	fname = fname + "$Fn" + ++comp.localFieldIndex;
 	if (! getNeedsClosureEnv())
-	  fflags |= Access.STATIC;
+	  fflags = (fflags | Access.STATIC) & ~Access.FINAL;
       }
     Type rtype = Compilation.getMethodProcType(comp.mainClass);
     Field field = comp.mainClass.addField (fname, rtype, fflags);

-- 
	--Per Bothner
per@bothner.com   http://www.bothner.com/~per/

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]