This is the mail archive of the
kawa@sources.redhat.com
mailing list for the Kawa project.
Re: IllegalAccessError in latest cvs version
- To: tk at research dot att dot com
- Subject: Re: IllegalAccessError in latest cvs version
- From: Per Bothner <per at bothner dot com>
- Date: 24 Oct 2000 16:04:41 -0700
- Cc: kawa at sourceware dot cygnus dot com
- References: <14837.64834.466025.4480@bual.research.att.com>
> 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/