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: Handling the Perl VM's "list" op with Kawa IR


"Bradley M. Kuhn" <bkuhn@ebb.org> writes:

> Perl's "virtual machine" has basically two components: 
> 
>    * a syntax tree of OP codes
>    * a temporary array, used to hold values between one operation to the
>      next.  

The high-level question is:  Can you and do you want to "compile away"
the temporay array?  Compare the Java expression stack.  To compile
Java bytecodes you have two options:  (1) Compile to a environment that
preserves the stack, and does stack operations at run-time; or (2)
compile away the stack, by simulating pushes and pops at compile-time.
Better JVM compilers do (2).  So the question is:  Can you do something
similar with the Perl temporary array - an dif so, should you?  Have
people worked on compiling Perl IR to C code?  If so, what did they do?

If the temporary array is predictable way, only within a given statement,
and you know when "marks" are pushed/popped, then presumably you can
compile away the temporary array.  I assume you can, since there is
nothing in the Perl *semantics* that uses this temporary array - right?

Of course it doesn't follow that you *should* compile away the
temporary array, even if you can.  The reason is that if this array
(stack) persists for a while, you may save on object allocation.

An idea:

Consider a builtin operation Op that can be called in both scalar and
vector context.  We can implement this using a class like:

public class Op extends PerlOp
{
  public Object applyN(...) { return scalar result; }

  public void apply(..., java.util.Stack result)
  { evaluate, leave results on result; }
}

Then print something that takes takes a list argument would be
implemented as:

public class Print extends PerlCmd
{
   public void apply(java.util.Stack input)
   {
      print results from stack;
   }
}

But how do we compile this?  The secret is to use Kawa's Target
classes.  Look at gnu.expr.ConsumerTarget, which does something similar.
You basically need a new class:

public class PerlListTarget extends Target
{
  Declaration temporaryArray;

  public void compileFromStack(Compilation comp, Type stackType)
  {
    // Argument of type stackType has been evaluated as scalar.
    Generate code to push argument on temporaryArray;
  }
}

Then for something like the qw or listoperation:

public class ListOp extends PerlOp implements Inlineable
{
  public void applyN(...);

  public void compile (ApplyExp exp, Compilation comp, Target target)
  {
    if (target instanceof PerlListTarget)
      {
        // Generate code to push each operand of target's temporaryArray:
        for each operand
          operand.compile(comp, target);
      }
    else
      {
        // Generate code to evaluate list in scalar context.
      }
  }
}

For print, you could do:

public class Print extends PerlCmd implements Inlineable
{
   public void apply(...) { }

  public void compile (ApplyExp exp, Compilation comp, Target target)
  {
    Declaration tempArray = ...;  // Perhaps a parameter? or allocate new?
    PerlListTarget subTarget = new PerlListTarget(tempArray);
    for each sub-expression
        subExp.compile(comp, subTarget);  // Leave on tempArray
    Generate code to call Print.apply at runtime, passing it the
    Vector corresponding to tempArray;
  }  
}

This is pretty dense, I admit.  I've left a bit vague the actual calling
convention to be used at run-time.  For that, I suggest taking a look
at the Consumer and ConsumeProc classes in gnu.kawa.util.  It seems
plausible to define a PerlConsumer class that would implement Consumer.
It would manage the temporary array,and the distinction between scalar
and list context.  Then Perl builtins and sub-rotines may be extensions
of ConsumeProc.
-- 
	--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]