You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-dev@db.apache.org by Kathey Marsden <km...@sbcglobal.net> on 2005/12/13 20:47:30 UTC

Question about MethodBuilder.pushThis()

I have a  few  newbie  questions about MethodBuilder and BaseActivation
and  ClassBuilder

If I look at this code in ExpressionClassBuilder:

void pushPVSReference(MethodBuilder mb)
    {
        mb.pushThis();
        mb.getField(ClassName.BaseActivation, "pvs",
ClassName.ParameterValueSet);
    }

it would seem that pushThis()  pushes an instance of  BaseActivation 
onto the stack.  How exactly does that happen?
In BCMethod  pushThis seems to push a  ClassBuilder.   I don't see how
BaseActivation gets there.

And a big  picture question:
What is the relationship between QueryTreeNode, ClassBuilder,
MethodBuilder  and BaseActivation?


Some background on why I am asking this ...
I pulled my patch for this DERBY-739 am not sure I completely understand
why what I did works, even though it did seem to work.  In addition to
adding the method to BaseActivation as described in the bug description
I made these simple changes in ParamaterNode
    - I call mb.pushThis()   to get the BaseActivation pushed on the stack.
   -  Call the new getParameter method in BaseActivation instead of the
getParameter  method on the ParameterValueSet interface.

I am not really comfortable with my fix because I don't understand how
mb.pushThis() gives me a BaseActivation.

@@ -384,12 +363,10 @@

 
         /* Generate the return value */
 
-        /* First, get the field that holds the ParameterValueSet */
-        acb.pushPVSReference(mb);
-
+        mb.pushThis();
         mb.push(parameterNumber); // arg
 
-        mb.callMethod(VMOpcode.INVOKEINTERFACE, (String) null,
"getParameter",
+        mb.callMethod(VMOpcode.INVOKEVIRTUAL, (String) null,
"getParameter",
                       ClassName.DataValueDescriptor, 1);


Attached is the full patch for anyone with interest.


Kathey


Re: Question about MethodBuilder.pushThis()

Posted by Daniel John Debrunner <dj...@debrunners.com>.
Kathey Marsden wrote:

> I have a  few  newbie  questions about MethodBuilder and BaseActivation
> and  ClassBuilder
> 
> If I look at this code in ExpressionClassBuilder:
> 
> void pushPVSReference(MethodBuilder mb)
>     {
>         mb.pushThis();
>         mb.getField(ClassName.BaseActivation, "pvs",
> ClassName.ParameterValueSet);
>     }
> 
> it would seem that pushThis()  pushes an instance of  BaseActivation 
> onto the stack.  How exactly does that happen?
> In BCMethod  pushThis seems to push a  ClassBuilder.   I don't see how
> BaseActivation gets there.

I'm not sure what you are seeing in BCMethod.pushThis().

The first line is:

myCode.addInstr(VMOpcode.ALOAD_0);

This adds the instruction ALOAD_0 which is the instruction
that will push 'this' onto the operand stack.

The second line is:

growStack(1, cb.classType);

This is code that in the byte code builder maintains track of the types
of the operands that are on the operand stack. Pushing 'this' onto the
operand stack will put a reference of type X, where X is the name of the
generated class, e.g. org.apache.derby.exe.ac435340402342342. Here
'cb.classType' represents the class name of the generated class.

Thus pushThis() pushes a Java reference corresponding to 'this' and it
will be of type org.apache.derby.exe.ac435340402342342 (as an example name).

Now at the language level, e.g. pushPVSReference, it is known that the
generated class is a sub-class of BaseActivation, since the language
layer declared/created the generated class using BaseActivation as its
super-class.

>         mb.getField(ClassName.BaseActivation, "pvs",
> ClassName.ParameterValueSet);

Now the first argument to getField here is the *declared* class of the
field. If the argument is null, then the declared class of the field is
taken from the type of the operand on the stack.
In this case the pvs field is declared in BaseActivation, so the jvm
class format requires that the description of the field is its declared
type, thus BaseActivation is needed. Basically the use of
ClassName.BaseActivation here is an "up cast". In Java language it's:

    ((BaseActivation) this).pvs;

If you were writing Java code, then you would just use:

    this.pvs

but the Java compiler would perform the resolution of the field and
generate code that represents:  ((BaseActivation) this).pvs.

The Derby byte code compiler does not perform field or method resolution
like the Java compiler, it expects the caller (the language layer) to
provide correct field and method descriptors.

Hope this helps,
Dan.



Re: Question about MethodBuilder.pushThis()

Posted by Daniel John Debrunner <dj...@debrunners.com>.
Kathey Marsden wrote:


> And a big  picture question:
> What is the relationship between QueryTreeNode, ClassBuilder,
> MethodBuilder  and BaseActivation?
      private static boolean largeUnionSelect(Connection con, String
viewName,

QueryTreeNode - reprsents an element of the compiled SQL statement plan.
Has generate methods that use MethodBuilder to generate Java byte code
that executes the statenment plan.

ClassBuilder - The top-level interface for the package that provides the
service of how to build a generated Java class, provides the ability to
add methods, fields, thrown exceptions etc.

MethodBuilder - an interface within the ClassBuilder package that
supports building a Java byte code stream (a method).

BaseActivation - the sub-class of all generated classes for the
*language* layer, ie. for generated classes that represent SQL
statements. Implements Activation which represents the runtime state of
an active execution for a SQL statement.

Dan.