Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: f26dda1d577e
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 01deae8d94b1
Choose a head ref
  • 2 commits
  • 5 files changed
  • 1 contributor

Commits on Mar 12, 2015

  1. 4
    Copy the full SHA
    6754792 View commit details
  2. Copy the full SHA
    01deae8 View commit details
Original file line number Diff line number Diff line change
@@ -22,6 +22,7 @@
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.control.RetryException;
import org.jruby.truffle.runtime.core.RubyBasicObject;

/**
* Represents a block of code run with exception handlers. There's no {@code try} keyword in Ruby -
@@ -44,7 +45,7 @@ public TryNode(RubyContext context, SourceSection sourceSection, ExceptionTransl
this.rescueParts = rescueParts;
this.elsePart = elsePart;
clearExceptionVariableNode = new WriteInstanceVariableNode(context, sourceSection, "$!",
new ObjectLiteralNode(context, sourceSection, context.getCoreLibrary().getGlobalVariablesObject()),
new ObjectLiteralNode(context, sourceSection, context.getThreadManager().getCurrentThread().getThreadLocals()),
new ObjectLiteralNode(context, sourceSection, context.getCoreLibrary().getNilObject()),
true);
}
@@ -84,7 +85,9 @@ private Object handleException(VirtualFrame frame, RaiseException exception) {
CompilerAsserts.neverPartOfCompilation();

notDesignedForCompilation();
getContext().getCoreLibrary().getGlobalVariablesObject().getOperations().setInstanceVariable(getContext().getCoreLibrary().getGlobalVariablesObject(), "$!", exception.getRubyException());

final RubyBasicObject threadLocals = getContext().getThreadManager().getCurrentThread().getThreadLocals();
threadLocals.getOperations().setInstanceVariable(threadLocals, "$!", exception.getRubyException());

for (RescueNode rescue : rescueParts) {
if (rescue.canHandle(frame, exception.getRubyException())) {
Original file line number Diff line number Diff line change
@@ -14,34 +14,38 @@
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.ThreadLocalObjectNode;
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory;
import org.jruby.truffle.nodes.objects.ReadInstanceVariableNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.RubyBasicObject;

public class ReadLastBacktraceNode extends RubyNode {

@Child private ReadInstanceVariableNode getLastExceptionNode;
@Child private CallDispatchHeadNode getBacktraceNode;

public ReadLastBacktraceNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
getLastExceptionNode = new ReadInstanceVariableNode(getContext(), getSourceSection(), "$!",
new ThreadLocalObjectNode(getContext(), getSourceSection()),
true);
getBacktraceNode = DispatchHeadNodeFactory.createMethodCall(getContext());
}

@Override
public Object isDefined(VirtualFrame frame) {
return getContext().makeString("global-variable");
}

@Override
public Object execute(VirtualFrame frame) {
// TODO (nirvdrum 12-Mar-15) $! should be thread-local.
final RubyBasicObject globals = getContext().getCoreLibrary().getGlobalVariablesObject();
final Object lastException = globals.getOperations().getInstanceVariable(globals, "$!");
final Object lastException = getLastExceptionNode.execute(frame);

if (lastException == getContext().getCoreLibrary().getNilObject()) {
return getContext().getCoreLibrary().getNilObject();
}

if (getBacktraceNode == null) {
CompilerDirectives.transferToInterpreter();
getBacktraceNode = insert(DispatchHeadNodeFactory.createMethodCall(getContext()));
}

return getBacktraceNode.call(frame, lastException, "backtrace", null);
}
}
Original file line number Diff line number Diff line change
@@ -14,38 +14,37 @@
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.ThreadLocalObjectNode;
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory;
import org.jruby.truffle.nodes.objects.ReadInstanceVariableNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.RubyBasicObject;

public class UpdateLastBacktraceNode extends RubyNode {

@Child private RubyNode child;
@Child private ReadInstanceVariableNode getLastExceptionNode;
@Child private CallDispatchHeadNode setBacktraceNode;

public UpdateLastBacktraceNode(RubyContext context, SourceSection sourceSection, RubyNode child) {
super(context, sourceSection);
this.child = child;
getLastExceptionNode = new ReadInstanceVariableNode(getContext(), getSourceSection(), "$!",
new ThreadLocalObjectNode(getContext(), getSourceSection()),
true);
setBacktraceNode = DispatchHeadNodeFactory.createMethodCall(getContext());
}

@Override
public Object execute(VirtualFrame frame) {
// TODO (nirvdrum 12-Mar-15) $! should be thread-local.
final RubyBasicObject globals = getContext().getCoreLibrary().getGlobalVariablesObject();
final Object lastException = globals.getOperations().getInstanceVariable(globals, "$!");
final Object lastException = getLastExceptionNode.execute(frame);

if (lastException == getContext().getCoreLibrary().getNilObject()) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().argumentError("$! is not set", this));
}

if (setBacktraceNode == null) {
CompilerDirectives.transferToInterpreter();
setBacktraceNode = insert(DispatchHeadNodeFactory.createMethodCall(getContext()));
}

final Object newBacktrace = child.execute(frame);
setBacktraceNode.call(frame, lastException, "set_backtrace", null, newBacktrace);

Original file line number Diff line number Diff line change
@@ -14,8 +14,10 @@
import org.jruby.truffle.nodes.core.BasicObjectNodesFactory;
import org.jruby.truffle.nodes.core.KernelNodes;
import org.jruby.truffle.nodes.core.KernelNodesFactory;
import org.jruby.truffle.nodes.literal.ObjectLiteralNode;
import org.jruby.truffle.nodes.objects.ClassNode;
import org.jruby.truffle.nodes.objects.ClassNodeFactory;
import org.jruby.truffle.nodes.objects.WriteInstanceVariableNode;
import org.jruby.truffle.nodes.yield.YieldDispatchHeadNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.ThrowException;
@@ -46,6 +48,7 @@ public abstract static class CatchNode extends RubiniusPrimitiveNode {

@Child private YieldDispatchHeadNode dispatchNode;
@Child private BasicObjectNodes.ReferenceEqualNode referenceEqualNode;
@Child private WriteInstanceVariableNode clearExceptionVariableNode;

public CatchNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
@@ -74,8 +77,18 @@ public Object doCatch(VirtualFrame frame, Object tag, RubyProc block) {
} catch (ThrowException e) {
if (areSame(frame, e.getTag(), tag)) {
notDesignedForCompilation();
RubyBasicObject globals = getContext().getCoreLibrary().getGlobalVariablesObject();
globals.getOperations().setInstanceVariable(globals, "$!", getContext().getCoreLibrary().getNilObject());

if (clearExceptionVariableNode == null) {
CompilerDirectives.transferToInterpreter();
clearExceptionVariableNode = insert(
new WriteInstanceVariableNode(getContext(), getSourceSection(), "$!",
new ObjectLiteralNode(getContext(), getSourceSection(), getContext().getThreadManager().getCurrentThread().getThreadLocals()),
new ObjectLiteralNode(getContext(), getSourceSection(), getContext().getCoreLibrary().getNilObject()),
true)
);
}

clearExceptionVariableNode.execute(frame);
return e.getValue();
} else {
throw e;
Original file line number Diff line number Diff line change
@@ -102,7 +102,7 @@ public class BodyTranslator extends Translator {
}

public static final Set<String> FRAME_LOCAL_GLOBAL_VARIABLES = new HashSet<>(Arrays.asList("$_", "$+", "$&", "$`", "$'"));
public static final Set<String> THREAD_LOCAL_GLOBAL_VARIABLES = new HashSet<>(Arrays.asList("$~", "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9")); // "$_"
public static final Set<String> THREAD_LOCAL_GLOBAL_VARIABLES = new HashSet<>(Arrays.asList("$~", "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9", "$!")); // "$_"

public BodyTranslator(com.oracle.truffle.api.nodes.Node currentNode, RubyContext context, BodyTranslator parent, TranslatorEnvironment environment, Source source, boolean topLevel) {
super(currentNode, context, source);