Skip to content

Commit

Permalink
Moving interpreter logic into Interpreter (for now). IRScriptBody.int…
Browse files Browse the repository at this point in the history
…erpret moved into Intepreter.

New ScriptBodyInterpreterContext to store begin and end blocks (shared with scope currently).

Removed some dead code and parameters.
  • Loading branch information
enebo committed Oct 21, 2014
1 parent bc28e1c commit eafe2d7
Show file tree
Hide file tree
Showing 9 changed files with 91 additions and 82 deletions.
3 changes: 1 addition & 2 deletions core/src/main/java/org/jruby/Ruby.java
Expand Up @@ -1196,8 +1196,7 @@ private void init() {

// Create an IR manager and a top-level IR scope and bind it to the top-level static-scope object
irManager = new IRManager();
IRScriptBody topLevelScope = new IRScriptBody(irManager, "", "", tc.getCurrentScope().getStaticScope());


// Initialize the "dummy" class used as a marker
dummyClass = new RubyClass(this, classClass);
dummyClass.freeze(tc);
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/ir/Compiler.java
Expand Up @@ -35,7 +35,7 @@ public static Compiler getInstance() {
}

@Override
protected Script execute(final Ruby runtime, final IRScope scope, JRubyClassLoader classLoader) {
protected Script execute(final Ruby runtime, final IRScriptBody scope, JRubyClassLoader classLoader) {
final JVMVisitor visitor = new JVMVisitor();
final Class compiled = visitor.compile(scope, classLoader);
final StaticScope staticScope = scope.getStaticScope();
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/java/org/jruby/ir/IRBuilder.java
Expand Up @@ -3227,12 +3227,12 @@ public IREvalScript buildEvalRoot(StaticScope staticScope, IRScope containingSco
return script;
}

public IRScope buildRoot(RootNode rootNode) {
public IRScriptBody buildRoot(RootNode rootNode) {
String file = rootNode.getPosition().getFile();
StaticScope staticScope = rootNode.getStaticScope();

// Top-level script!
IRScriptBody script = new IRScriptBody(manager, "__file__", file, staticScope);
IRScriptBody script = new IRScriptBody(manager, file, staticScope);
addInstr(script, new ReceiveSelfInstr(script.getSelf()));
// Set %current_scope = <current-scope>
// Set %current_module = <current-module>
Expand Down
72 changes: 8 additions & 64 deletions core/src/main/java/org/jruby/ir/IRScriptBody.java
@@ -1,39 +1,30 @@
package org.jruby.ir;

import org.jruby.RubyModule;
import org.jruby.ir.interpreter.Interpreter;
import org.jruby.ir.instructions.Instr;
import org.jruby.ir.interpreter.InterpreterContext;
import org.jruby.ir.operands.IRException;
import org.jruby.ir.representations.CFG;
import org.jruby.ir.runtime.IRBreakJump;
import org.jruby.ir.runtime.IRRuntimeHelpers;
import org.jruby.ir.interpreter.ScriptBodyInterpreterContext;
import org.jruby.parser.StaticScope;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.Visibility;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.log.Logger;
import org.jruby.util.log.LoggerFactory;

import java.util.ArrayList;
import java.util.List;

// FIXME: I made this IRModule because any methods placed in top-level script goes
// into something which an IRScript is basically a module that is special in that
// it represents a lexical unit. Fix what now?
public class IRScriptBody extends IRScope {
private static final Logger LOG = LoggerFactory.getLogger("IRScriptBody");

private List<IRClosure> beginBlocks;
private List<IRClosure> endBlocks;

public IRScriptBody(IRManager manager, String className, String sourceName, StaticScope staticScope) {
public IRScriptBody(IRManager manager, String sourceName, StaticScope staticScope) {
super(manager, null, sourceName, sourceName, 0, staticScope);
if (!getManager().isDryRun() && staticScope != null) {
staticScope.setIRScope(this);
staticScope.setScopeType(this.getScopeType());
}
}

@Override
public InterpreterContext allocateInterpreterContext(Instr[] instructionList) {
return new ScriptBodyInterpreterContext(this, instructionList);
}

@Override
public int getNearestModuleReferencingScopeDepth() {
return 0;
Expand Down Expand Up @@ -79,51 +70,4 @@ public List<IRClosure> getEndBlocks() {
public boolean isScriptScope() {
return true;
}

public IRubyObject interpret(ThreadContext context, IRubyObject self) {
InterpreterContext ic = prepareForInterpretation();

String name = "(root)";
if (IRRuntimeHelpers.isDebug()) {
LOG.info("Executing '" + name + "'");
CFG cfg = getCFG();
LOG.info("Graph:\n" + cfg.toStringGraph());
LOG.info("CFG:\n" + cfg.toStringInstrs());
}

// We get the live object ball rolling here.
// This give a valid value for the top of this lexical tree.
// All new scopes can then retrieve and set based on lexical parent.
StaticScope scope = getStaticScope();
RubyModule currModule = scope.getModule();
if (currModule == null) {
// SSS FIXME: Looks like this has to do with Kernel#load
// and the wrap parameter. Figure it out and document it here.
currModule = context.getRuntime().getObject();
}

IRubyObject retVal;

scope.setModule(currModule);
if (!this.flags.contains(IRFlags.DYNSCOPE_ELIMINATED)) {
context.preMethodScopeOnly(scope);
}
context.setCurrentVisibility(Visibility.PRIVATE);

try {
Interpreter.runBeginEndBlocks(getBeginBlocks(), context, self, scope, null);
retVal = Interpreter.INTERPRET_ROOT(context, self, ic, currModule, name);
Interpreter.runBeginEndBlocks(getEndBlocks(), context, self, scope, null);

Interpreter.dumpStats();
} catch (IRBreakJump bj) {
throw IRException.BREAK_LocalJumpError.getException(context.runtime);
} finally {
if (!this.flags.contains(IRFlags.DYNSCOPE_ELIMINATED)) {
context.popScope();
}
}

return retVal;
}
}
13 changes: 4 additions & 9 deletions core/src/main/java/org/jruby/ir/IRTranslator.java
Expand Up @@ -10,9 +10,6 @@

import java.io.IOException;

//import org.jruby.ir.persistence.persist.string.IRToStringTranslator;
//import org.jruby.ir.persistence.util.FileIO;

/**
* Abstract class that contains general logic for both IR Compiler and IR Interpreter
*
Expand All @@ -21,18 +18,16 @@
*/
public abstract class IRTranslator<R, S> {
public R execute(Ruby runtime, ParseResult result, S specificObject) {
IRScope scope = null;
IRScriptBody scope = null;

if (result instanceof IRScope) { // Already have it (likely from read from persistent store).
scope = (IRScope) result;
if (result instanceof IRScriptBody) { // Already have it (likely from read from persistent store).
scope = (IRScriptBody) result;
} else if (result instanceof RootNode) { // Need to perform create IR from AST
scope = IRBuilder.createIRBuilder(runtime, runtime.getIRManager()).buildRoot((RootNode) result);

if (RubyInstanceConfig.IR_WRITING) {
try {
IRWriter.persist(new IRWriterFile(IRFileExpert.getIRPersistedFile(scope.getFileName())), scope);
// FileIO.writeToFile(IRFileExpert.getIRPersistedFile(scope.getFileName()),
// IRToStringTranslator.translate(scope));
} catch (IOException ex) {
ex.printStackTrace(); // FIXME: Handle errors better
return null;
Expand All @@ -43,5 +38,5 @@ public R execute(Ruby runtime, ParseResult result, S specificObject) {
return execute(runtime, scope, specificObject);
}

protected abstract R execute(Ruby runtime, IRScope producedIrScope, S specificObject);
protected abstract R execute(Ruby runtime, IRScriptBody producedIrScope, S specificObject);
}
40 changes: 38 additions & 2 deletions core/src/main/java/org/jruby/ir/interpreter/Interpreter.java
Expand Up @@ -13,6 +13,7 @@
import org.jruby.ir.instructions.specialized.*;
import org.jruby.ir.operands.*;
import org.jruby.ir.operands.Float;
import org.jruby.ir.runtime.IRBreakJump;
import org.jruby.ir.runtime.IRRuntimeHelpers;
import org.jruby.parser.StaticScope;
import org.jruby.runtime.*;
Expand Down Expand Up @@ -129,8 +130,43 @@ public static void runBeginEndBlocks(List<IRClosure> beBlocks, ThreadContext con
}

@Override
protected IRubyObject execute(Ruby runtime, IRScope scope, IRubyObject self) {
return ((IRScriptBody)scope).interpret(runtime.getCurrentContext(), self);
protected IRubyObject execute(Ruby runtime, IRScriptBody irScope, IRubyObject self) {
ScriptBodyInterpreterContext ic = (ScriptBodyInterpreterContext) irScope.prepareForInterpretation();
ThreadContext context = runtime.getCurrentContext();
String name = "(root)";

if (IRRuntimeHelpers.isDebug()) LOG.info("Executing " + ic);

// We get the live object ball rolling here.
// This give a valid value for the top of this lexical tree.
// All new scopes can then retrieve and set based on lexical parent.
StaticScope scope = ic.getStaticScope();
RubyModule currModule = scope.getModule();
if (currModule == null) {
// SSS FIXME: Looks like this has to do with Kernel#load
// and the wrap parameter. Figure it out and document it here.
currModule = context.getRuntime().getObject();
}

IRubyObject retVal;

scope.setModule(currModule);
if (!ic.isDynscopeEliminated()) context.preMethodScopeOnly(scope);
context.setCurrentVisibility(Visibility.PRIVATE);

try {
Interpreter.runBeginEndBlocks(ic.getBeginBlocks(), context, self, scope, null);
retVal = Interpreter.INTERPRET_ROOT(context, self, ic, currModule, name);
Interpreter.runBeginEndBlocks(ic.getEndBlocks(), context, self, scope, null);

Interpreter.dumpStats();
} catch (IRBreakJump bj) {
throw IRException.BREAK_LocalJumpError.getException(context.runtime);
} finally {
if (!ic.isDynscopeEliminated()) context.popScope();
}

return retVal;
}

private static void setResult(Object[] temp, DynamicScope currDynScope, Variable resultVar, Object result) {
Expand Down
Expand Up @@ -24,6 +24,7 @@ public class InterpreterContext {

// Cached computed fields
private final boolean hasExplicitCallProtocol;
private final boolean isDynscopeEliminated;
private final boolean pushNewDynScope;
private final boolean reuseParentDynScope;
private final boolean popDynScope;
Expand All @@ -50,7 +51,8 @@ public InterpreterContext(IRScope scope, Instr[] instructions) {
this.instructions = instructions;
this.hasExplicitCallProtocol = scope.getFlags().contains(IRFlags.HAS_EXPLICIT_CALL_PROTOCOL);
this.reuseParentDynScope = scope.getFlags().contains(IRFlags.REUSE_PARENT_DYNSCOPE);
this.pushNewDynScope = !scope.getFlags().contains(IRFlags.DYNSCOPE_ELIMINATED) && !this.reuseParentDynScope;
this.isDynscopeEliminated = scope.getFlags().contains(IRFlags.DYNSCOPE_ELIMINATED);
this.pushNewDynScope = !isDynscopeEliminated && !reuseParentDynScope;
this.popDynScope = this.pushNewDynScope || this.reuseParentDynScope;
this.receivesKeywordArguments = scope.getFlags().contains(IRFlags.RECEIVES_KEYWORD_ARGS);
}
Expand Down Expand Up @@ -83,6 +85,10 @@ public Instr[] getInstructions() {
return instructions;
}

public boolean isDynscopeEliminated() {
return isDynscopeEliminated;
}

/**
* Get a new dynamic scope. Note: This only works for method scopes (ClosureIC will throw).
*/
Expand Down
@@ -0,0 +1,29 @@
package org.jruby.ir.interpreter;

import java.util.List;
import org.jruby.ir.IRClosure;
import org.jruby.ir.IRScriptBody;
import org.jruby.ir.instructions.Instr;

/**
* Created by enebo on 10/21/14.
*/
public class ScriptBodyInterpreterContext extends InterpreterContext {
private List<IRClosure> beginBlocks;
private List<IRClosure> endBlocks;

public ScriptBodyInterpreterContext(IRScriptBody scope, Instr[] instrs) {
super(scope, instrs);

this.beginBlocks = scope.getBeginBlocks();
this.endBlocks = scope.getEndBlocks();
}

public List<IRClosure> getBeginBlocks() {
return beginBlocks;
}

public List<IRClosure> getEndBlocks() {
return endBlocks;
}
}
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/ir/persistence/IRReader.java
Expand Up @@ -125,7 +125,7 @@ public static IRScope createScope(IRManager manager, IRScopeType type, String na
case MODULE_BODY:
return new IRModuleBody(manager, lexicalParent, name, line, staticScope);
case SCRIPT_BODY:
return new IRScriptBody(manager, "__file__", name, staticScope);
return new IRScriptBody(manager, name, staticScope);
case FOR:
return new IRFor(manager, lexicalParent, line, staticScope, Arity.createArity(arity), argumentType);
case CLOSURE:
Expand Down

0 comments on commit eafe2d7

Please sign in to comment.