Skip to content

Commit

Permalink
Showing 9 changed files with 91 additions and 82 deletions.
3 changes: 1 addition & 2 deletions core/src/main/java/org/jruby/Ruby.java
Original file line number Diff line number Diff line change
@@ -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);
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/ir/Compiler.java
Original file line number Diff line number Diff line change
@@ -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();
4 changes: 2 additions & 2 deletions core/src/main/java/org/jruby/ir/IRBuilder.java
Original file line number Diff line number Diff line change
@@ -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>
72 changes: 8 additions & 64 deletions core/src/main/java/org/jruby/ir/IRScriptBody.java
Original file line number Diff line number Diff line change
@@ -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;
@@ -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
Original file line number Diff line number Diff line change
@@ -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
*
@@ -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;
@@ -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
Original file line number Diff line number Diff line change
@@ -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.*;
@@ -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) {
Original file line number Diff line number Diff line change
@@ -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;
@@ -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);
}
@@ -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).
*/
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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:

0 comments on commit eafe2d7

Please sign in to comment.