Skip to content

Commit

Permalink
Merge pull request #3290 from bbelleville/minimal-lazy
Browse files Browse the repository at this point in the history
[Truffle] Allow for lazy parsing
  • Loading branch information
eregon committed Aug 28, 2015
2 parents 39eaddc + 4d40c03 commit 677c3f6
Showing 1 changed file with 44 additions and 2 deletions.
Expand Up @@ -9,6 +9,9 @@
*/
package org.jruby.truffle.translator;

import java.util.ArrayDeque;
import java.util.Deque;

import com.oracle.truffle.api.CallTarget;
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.frame.FrameSlot;
Expand All @@ -34,11 +37,12 @@
import org.jruby.truffle.nodes.supercall.GeneralSuperCallNode;
import org.jruby.truffle.nodes.supercall.GeneralSuperReCallNode;
import org.jruby.truffle.nodes.supercall.ZSuperOutsideMethodNode;
import org.jruby.truffle.runtime.LexicalScope;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.methods.Arity;
import org.jruby.truffle.runtime.methods.SharedMethodInfo;

class MethodTranslator extends BodyTranslator {
public class MethodTranslator extends BodyTranslator {

private final org.jruby.ast.ArgsNode argsNode;
private boolean isBlock;
Expand Down Expand Up @@ -156,7 +160,16 @@ private RubyNode wrapBody(RubyNode prelude, RubyNode body) {
return body;
}

public MethodDefinitionNode compileMethodNode(SourceSection sourceSection, String methodName, org.jruby.ast.Node bodyNode, SharedMethodInfo sharedMethodInfo) {
/*
* This method exists solely to be substituted to support lazy
* method parsing. The substitution returns a node which performs
* the parsing lazily and then calls doCompileMethodBody.
*/
public RubyNode compileMethodBody(SourceSection sourceSection, String methodName, org.jruby.ast.Node bodyNode, SharedMethodInfo sharedMethodInfo) {
return doCompileMethodBody(sourceSection, methodName, bodyNode, sharedMethodInfo);
}

public RubyNode doCompileMethodBody(SourceSection sourceSection, String methodName, org.jruby.ast.Node bodyNode, SharedMethodInfo sharedMethodInfo) {
final ParameterCollector parameterCollector = declareArguments(sourceSection, methodName, sharedMethodInfo);
final Arity arity = getArity(argsNode);

Expand Down Expand Up @@ -194,7 +207,11 @@ public MethodDefinitionNode compileMethodNode(SourceSection sourceSection, Strin

// TODO(CS, 10-Jan-15) why do we only translate exceptions in methods and not blocks?
body = new ExceptionTranslatingNode(context, sourceSection, body);
return body;
}

public MethodDefinitionNode compileMethodNode(SourceSection sourceSection, String methodName, org.jruby.ast.Node bodyNode, SharedMethodInfo sharedMethodInfo) {
final RubyNode body = compileMethodBody(sourceSection, methodName, bodyNode, sharedMethodInfo);
final RubyRootNode rootNode = new RubyRootNode(
context, sourceSection, environment.getFrameDescriptor(), environment.getSharedMethodInfo(), body, environment.needsDeclarationFrame());

Expand Down Expand Up @@ -322,4 +339,29 @@ protected FlipFlopStateNode createFlipFlopState(SourceSection sourceSection, int
}
}

/*
* The following methods allow us to save and restore enough of
* the current state of the Translator to allow lazy parsing. When
* the lazy parsing is actually performed, the state is restored
* to what it would have been if the method had been parsed
* eagerly.
*/
public TranslatorState getCurrentState() {
return new TranslatorState(getEnvironment().getLexicalScope(), new ArrayDeque<SourceSection>(parentSourceSection));
}

public void restoreState(TranslatorState state) {
this.getEnvironment().getParseEnvironment().resetLexicalScope(state.scope);
this.parentSourceSection = state.parentSourceSection;
}

public static class TranslatorState {
private final LexicalScope scope;
private final Deque<SourceSection> parentSourceSection;

private TranslatorState(LexicalScope scope, Deque<SourceSection> parentSourceSection) {
this.scope = scope;
this.parentSourceSection = parentSourceSection;
}
}
}

0 comments on commit 677c3f6

Please sign in to comment.