This is the mail archive of the
kawa@sources.redhat.com
mailing list for the Kawa project.
Re: Different results with eval and compileToFiles()
Per Bothner <per@bothner.com> wrote:
> If you send me the output, I can probably point you in the correct
> direction.
Actually, once I saw the output, I quickly found that there was no code
generated for the SetExp. (I have included the output below, FWIW, anyway).
It appears that a few things are going on:
* The eval process is simply punting and putting the variable in the
global environment, even though I placed a Declaration entry for it in
ModuleExp. (In fact, the eval() method in SetExp doesn't appear to
allow use of it for non-globals).
* My declaration entry may very well not be following the "rules", I just
set the flags to what I "thought" I wanted them to be (see below).
* The SetExp is completely ignored in SetExp, because it hits this
piece in SetExp.java:
else if (decl.context instanceof ModuleExp
&& (new_value instanceof QuoteExp)
&& ! decl.isPrivate() && ! comp.immediate
&& decl.getValue() != null)
{ // This is handled in ModuleExp's allocFields method.
Of course, the field *does* get allocated in ModuleExp.java, but I
wanted it to be more than allocated---I wanted to be able to set it via
SetExps in the body of methods in that module.
In detail, what I want is the following:
Perl's "globals" are actually bound to a particular module. So, If I
have the scalar value $x ($ denotes that it is scalar), and I am
currently in package foo, that means that the "full name" is $foo::x,
but:
"package foo; $x = 5;" is roughly equivalent to
"package something_else; $foo::x = 5;".
I would like to set things up so that there is a class for each Perl package
(compiled to ModuleExp), and each class has static variables (using
Declaration fields in the ModuleExp) for all these "global" variables.
I realize that could do it all in the global environment, and use fully
qualified names. This seemed less elegant, and also less of a semantic
match. It'd be nice to say in Java, if you know the Perl program has a
package variable called $foo::x, to say "Foo.x = new Scalar("my setting");"
Of course, adding fields at Java runtime would be harder in this scenario
(reflection would be needed), but I would think that it would be unlikely
that the programmer in other languages would need to add variables to the
Perl modules.
I am open to ideas on how to address this. However, I am unable to find a
way to place static variable Declarations into the ModuleExp and then assign
them within the code of the modules (at least with SetExp) (which is what
I'd currently prefer ;).
###############################################################################
Here's the output, anyway, in case you still wanted to see it.
The Perl program is:
$x = "GO"; print $x, "\n";
From this, I generate the ModuleExp (I added more verbose output about
Declarations):
(#%module/1/ (
Declaration[scalar_x/1/,TYPE=ClassType gnu.perl.lang.Scalar,STATIC]
) (#%begin
(#%set! scalar_x[Binding=Declaration[scalar_x/1/,TYPE=ClassTypegnu.perl.lang.Scalar,STATIC]] (#%quote (#%Scalar "GO")))
(#%apply (#%quote #<primitive procedure int gnu.perl.lang.Functions.print$V(java.lang.Object[])>) (#%ref/1/ scalar_x[Binding=Declaration[scalar_x/1/,TYPE=ClassType gnu.perl.lang.Scalar,STATIC]]) (#%quote (#%Scalar "
")))))
Here's the class file:
#1: Utf8: "gnu/expr/ModuleBody"
#2: Class name: 1=gnu.expr.ModuleBody
#3: Utf8: "<init>"
#4: Utf8: "()V"
#5: NameAndType name: 3=<init>, signature: 4=()void
#6: Method class: 2=gnu.expr.ModuleBody name_and_type: 5=<<init> ()void>
#7: Utf8: "gnu/perl/lang/Perl"
#8: Class name: 7=gnu.perl.lang.Perl
#9: Utf8: "registerEnvironment"
#10: NameAndType name: 9=registerEnvironment, signature: 4=()void
#11: Method class: 8=gnu.perl.lang.Perl name_and_type: 10=<registerEnvironment ()void>
#12: Utf8: "PerlMain"
#13: Class name: 12=PerlMain
#14: Method class: 13=PerlMain name_and_type: 5=<<init> ()void>
#15: Utf8: "$instance"
#16: Utf8: "LPerlMain;"
#17: NameAndType name: 15=$instance, signature: 16=PerlMain
#18: Field class: 13=PerlMain name_and_type: 17=<$instance PerlMain>
#19: Utf8: "java/lang/Object"
#20: Class name: 19=java.lang.Object
#21: Utf8: "scalar_x"
#22: Utf8: "Lgnu/perl/lang/Scalar;"
#23: NameAndType name: 21=scalar_x, signature: 22=gnu.perl.lang.Scalar
#24: Field class: 13=PerlMain name_and_type: 23=<scalar_x gnu.perl.lang.Scalar>
#25: Utf8: "Lit0"
#26: NameAndType name: 25=Lit0, signature: 22=gnu.perl.lang.Scalar
#27: Field class: 13=PerlMain name_and_type: 26=<Lit0 gnu.perl.lang.Scalar>
#28: Utf8: "gnu/perl/lang/Functions"
#29: Class name: 28=gnu.perl.lang.Functions
#30: Utf8: "print$V"
#31: Utf8: "([Ljava/lang/Object;)I"
#32: NameAndType name: 30=print$V, signature: 31=(java.lang.Object[])int
#33: Method class: 29=gnu.perl.lang.Functions name_and_type: 32=<print$V (java.lang.Object[])int>
#34: Utf8: "gnu/perl/lang/Scalar"
#35: Class name: 34=gnu.perl.lang.Scalar
#36: Utf8: "\n"
#37: String 36="\n"
#38: Utf8: "(Ljava/lang/String;Z)V"
#39: NameAndType name: 3=<init>, signature: 38=(java.lang.String,boolean)void
#40: Method class: 35=gnu.perl.lang.Scalar name_and_type: 39=<<init> (java.lang.String,boolean)void>
#41: Utf8: "runAsMain"
#42: Utf8: "([Ljava/lang/String;)V"
#43: NameAndType name: 41=runAsMain, signature: 42=(java.lang.String[])void
#44: Method class: 2=gnu.expr.ModuleBody name_and_type: 43=<runAsMain (java.lang.String[])void>
#45: Utf8: "Code"
#46: Utf8: "<clinit>"
#47: Utf8: "main"
Access flags: public
This class: 13=PerlMain super: 2=gnu.expr.ModuleBody
Interfaces (count: 0):
Fields (count: 3):
Field name: 15=$instance static final Signature: 16=PerlMain
Field name: 21=scalar_x public static Signature: 22=gnu.perl.lang.Scalar
Field name: 25=Lit0 static final Signature: 22=gnu.perl.lang.Scalar
Methods (count: 3):
Method name:3="<init>" public Signature: 4=()void
Attribute "Code", length:17, max_stack:1, max_locals:1, code_length:5
0: aload_0
1: invokespecial #6=<Method gnu.expr.ModuleBody.<init> ()void>
4: return
Method name:46="<clinit>" public static Signature: 4=()void
Attribute "Code", length:64, max_stack:5, max_locals:0, code_length:52
0: invokestatic #11=<Method gnu.perl.lang.Perl.registerEnvironment ()void>
3: new #13=<Class PerlMain>
6: dup
7: invokespecial #14=<Method PerlMain.<init> ()void>
10: putstatic #18=<Field PerlMain.$instance PerlMain>
13: goto 36
16: iconst_2
17: anewarray #20=<Class java.lang.Object>
20: dup
21: iconst_0
22: getstatic #24=<Field PerlMain.scalar_x gnu.perl.lang.Scalar>
25: aastore
26: dup
27: iconst_1
28: getstatic #27=<Field PerlMain.Lit0 gnu.perl.lang.Scalar>
31: aastore
32: invokestatic #33=<Method gnu.perl.lang.Functions.print$V (java.lang.Object[])int>
35: return
36: new #35=<Class gnu.perl.lang.Scalar>
39: dup
40: ldc #37=<String "\n">
42: iconst_0
43: invokespecial #40=<Method gnu.perl.lang.Scalar.<init> (java.lang.String,boolean)void>
46: putstatic #27=<Field PerlMain.Lit0 gnu.perl.lang.Scalar>
49: goto 16
Method name:47="main" public static Signature: 42=(java.lang.String[])void
Attribute "Code", length:24, max_stack:2, max_locals:1, code_length:12
0: new #13=<Class PerlMain>
3: dup
4: invokespecial #14=<Method PerlMain.<init> ()void>
7: aload_0
8: invokevirtual #44=<Method gnu.expr.ModuleBody.runAsMain (java.lang.String[])void>
11: return
Attributes (count: 0):
--
Bradley M. Kuhn - http://www.ebb.org/bkuhn
PGP signature