FAQ

From PolyglotWiki

Jump to: navigation, search

Contents

Polyglot FAQ

General questions

Does Polyglot support Java 5?

Polyglot supports Java version 1.4, but a Polyglot Java 5 extension has been developed by Milan Stanojevic at UCLA, based on an earlier version by Jennifer Lhotak at McGill.

We are considering the best way to integrate this extension into the Polyglot framework.

Extending the base compiler

How do I add a pass?

Stub. See Overview.

How do I add a new AST node?

Stub. See Overview.

What are extension objects and delegate objects for?

Extension and delegate objects are intended to avoid code duplication when "mixing in" functionality into the middle of the AST class hierarchy; that is, when adding functionality that should be inherited by other existing classes in the hierarchy.

The rule of thumb is:

  • Use an extension object to mix in new methods and fields to an existing AST class.
  • Use a delegate object to override a method in an existing class if that class has existing subclasses that you want to inherit the change.
  • Otherwise, subclass the AST node class.

For more details, see our CC'03 paper.

Rewriting

Why do I get NullPointerExceptions when Translator visits a new AST?

The Translator assumes the AST has been type-checked. It's likely the new AST nodes aren't annotated with type information. Unfortunately, there's not really an easy way to create a type-checked AST. One option is to manually add the types. For example to create a typed IntLit:

IntLit x = nf.IntLit(position(), IntLit.INT, 1);
x = (IntLit) x.type(ts.Int());
  • Exprs require Types.
  • LocalDecls, Locals, and Formals require LocalInstances.
  • FieldDecls and Fields require FieldInstances.
  • MethodDecls and Calls require MethodInstances.
  • ConstructorDecls, ConstructorCalls, and News require ConstructorInstances.
  • ClassDecls require ParsedClassTypes.

Another option is to run the TypeChecker visitor over the new AST. In this case a context, containing the appropriate type information must be available.

IntLit x = nf.IntLit(position(), IntLit.INT, 1);
x = (IntLit) x.visit(new TypeChecker(job, ts, nf).context(c));

It may be necessary to run TypeBuilder and AmbiguityRemover as well. online dating relationships

How do I ... ?

How do I get a list of children for an AST node

There is no explicit list of children in each node. Instead, each node contains fields for its children. The method visitChildren visits each child of a node. If you really need a list of the immediate children, you can do something like:

final List children = new ArrayList();
n.visitChildren(new NodeVisitor() {
    public Node override(Node n) {
        children.add(n);
        return n;
    }
});

Debugging

The 2.0 compiler died claiming there was an infinite loop detected. What do I do now?

There is some cycle of dependencies between passes. These are difficult to debug. Run with:

-report deps=1 -report dump-dep-graph=1 -report frontend=3

Doing this will print out a stack trace when a dependency is added and will dump a dot? file containing the dependency graph.

How do I figure out what pass an error occurred in?

Run with -report frontend=1

The compiler is taking a lot of time. Is there any profiling support?

You can get the time taken in each pass by running with:

-report time=1

You can insert your own calls to the statistics collector by adding:

extInfo.getStats().accumPassTimes(<key>, <inclusive time>, <exclusive time>);

You can also run polyglot in a JVM with profiling enabled. Try java -Xrunhprof:cpu=samples.

Migration from the 1.x to 2.x

Passes and goals

In Polyglot 1.x, compiler passes are scheduled in the passes method of the ExtensionInfo class. The method returns a list of passes in the order of execution. In Polyglot 2.x, more general scheduling is supported by specifying a DAG of goals for each job: a goal wraps around a pass and defines its (direct) prerequisites. More concretely, for a visitor V, you need to do the following:

  • Write a subclass of polyglot.frontend.goals.VisitorGoal, with its prerequisiteGoals method overridden to include goals that will run before it.
  • A method in the scheduler to return an instance of that goal. Remember to use the method internGoal to ensure that there is only one instance of a goal per job. A lot of these methods can be overridden from JLScheduler.

A concise way of writing it is to create a local class for that subclass of VisitorGoal inside the "goal creation" method in the scheduler, and call these goal creation methods for adding prerequisite goals.

The scheduler of a new language extension might look like this:

public class NewScheduler extends JLScheduler {
   public Goal TypeInitialized(final Job job) {                         // overriding from JLScheduler
      NewTypeSystem ts = (NewTypeSystem) extInfo.typeSystem();
      NewNodeFactory nf = (NewNodeFactory) extInfo.nodeFactory();
      Goal g = internGoal(                                              // don't forget to "intern" the goal
          new VisitorGoal(job, new NewTypeBuilder(job, ts, nf)) {       // a local class, which is a subclass of VisitorGoal
             public Collection prerequisiteGoals(Scheduler scheduler) {
                List l = new ArrayList();
                l.addAll(super.prerequisiteGoals(scheduler));
                l.add(PreProcessing(job));                              // call another goal creation method in the scheduler.
                return l;
             }
          }
       );
       return g;
   }
   public Goal PreProcessing(final Job job) {                           // a new kind of pass that is not in the base compiler
       // Similar as above for NewPreProcessor.
   }
   ...
}

Finally, in ExtensionInfo, the method getCompileGoal specifies the last goal for compiling a job. In the base compiler of Polyglot, it returns an (interned) instance of CodeGenerated, which corresponds to OutputPass. This method can also be overridden to fit the new language extension.

Personal tools