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: 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


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