Skip to content

Commit

Permalink
[Truffle] Make a node for the top-level handler.
Browse files Browse the repository at this point in the history
  • Loading branch information
eregon committed Dec 6, 2014
1 parent b790936 commit 8551198
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 58 deletions.
56 changes: 25 additions & 31 deletions core/src/main/java/org/jruby/truffle/TruffleBridgeImpl.java
Expand Up @@ -9,23 +9,19 @@
*/
package org.jruby.truffle;

import com.oracle.truffle.api.CallTarget;
import com.oracle.truffle.api.source.BytesDecoder;
import com.oracle.truffle.api.source.Source;
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.frame.MaterializedFrame;
import org.jruby.TruffleBridge;
import org.jruby.internal.runtime.methods.DynamicMethod;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.truffle.nodes.RubyRootNode;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.TopLevelRaiseHandler;
import org.jruby.truffle.nodes.core.*;
import org.jruby.truffle.nodes.methods.MethodDefinitionNode;
import org.jruby.truffle.runtime.DebugOperations;
import org.jruby.truffle.runtime.core.*;
import org.jruby.truffle.runtime.RubyArguments;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.RubyArray;
import org.jruby.truffle.runtime.util.Supplier;
import org.jruby.truffle.translator.NodeWrapper;
import org.jruby.truffle.translator.TranslatorDriver;
import org.jruby.util.cli.Options;

Expand Down Expand Up @@ -125,33 +121,31 @@ public void init() {

@Override
public Object execute(final TranslatorDriver.ParserContext parserContext, final Object self, final MaterializedFrame parentFrame, final org.jruby.ast.RootNode rootNode) {
return truffleContext.handlingTopLevelRaise(new Supplier<Object>() {
final String inputFile = rootNode.getPosition().getFile();
final Source source;

if (inputFile.equals("-e")) {
// Assume UTF-8 for the moment
source = Source.fromBytes(runtime.getInstanceConfig().inlineScript(), "-e", new BytesDecoder.UTF8BytesDecoder());
} else {
final byte[] bytes;

try {
bytes = Files.readAllBytes(Paths.get(inputFile));
} catch (IOException e) {
throw new RuntimeException(e);
}

// Assume UTF-8 for the moment
source = Source.fromBytes(bytes, inputFile, new BytesDecoder.UTF8BytesDecoder());
}

return truffleContext.execute(truffleContext, source, parserContext, self, parentFrame, null, new NodeWrapper() {
@Override
public Object get() {
final String inputFile = rootNode.getPosition().getFile();
final Source source;

if (inputFile.equals("-e")) {
// Assume UTF-8 for the moment
source = Source.fromBytes(runtime.getInstanceConfig().inlineScript(), "-e", new BytesDecoder.UTF8BytesDecoder());
} else {
final byte[] bytes;

try {
bytes = Files.readAllBytes(Paths.get(inputFile));
} catch (IOException e) {
throw new RuntimeException(e);
}

// Assume UTF-8 for the moment
source = Source.fromBytes(bytes, inputFile, new BytesDecoder.UTF8BytesDecoder());
}

return truffleContext.execute(truffleContext, source, parserContext, self, parentFrame, null);
public RubyNode wrap(RubyNode node) {
return new TopLevelRaiseHandler(node.getContext(), node.getSourceSection(), node);
}

}, truffleContext.getCoreLibrary().getNilObject());
});
}

@Override
Expand Down
@@ -0,0 +1,47 @@
/*
* Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.nodes;

import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.backtrace.Backtrace;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.control.ThreadExitException;
import org.jruby.truffle.runtime.core.RubyException;

public class TopLevelRaiseHandler extends RubyNode {

@Child protected RubyNode body;

public TopLevelRaiseHandler(RubyContext context, SourceSection sourceSection, RubyNode body) {
super(context, sourceSection);
this.body = body;
}

@Override
public Object execute(VirtualFrame frame) {
try {
return body.execute(frame);
} catch (RaiseException e) {
// TODO(CS): what's this cast about?
final RubyException rubyException = (RubyException) e.getRubyException();

for (String line : Backtrace.DISPLAY_FORMATTER.format(getContext(), rubyException, rubyException.getBacktrace())) {
System.err.println(line);
}
} catch (ThreadExitException e) {
// Ignore
}

return getContext().getCoreLibrary().getNilObject();
}

}
27 changes: 6 additions & 21 deletions core/src/main/java/org/jruby/truffle/runtime/RubyContext.java
Expand Up @@ -28,16 +28,14 @@
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.RubyRootNode;
import org.jruby.truffle.nodes.debug.RubyASTProber;
import org.jruby.truffle.runtime.backtrace.Backtrace;
import org.jruby.truffle.runtime.control.*;
import org.jruby.truffle.runtime.core.*;
import org.jruby.truffle.runtime.core.RubyArray;
import org.jruby.truffle.runtime.core.RubyBinding;
import org.jruby.truffle.runtime.core.RubyException;
import org.jruby.truffle.runtime.core.RubyString;
import org.jruby.truffle.runtime.core.RubySymbol;
import org.jruby.truffle.runtime.subsystems.*;
import org.jruby.truffle.runtime.util.Supplier;
import org.jruby.truffle.translator.NodeWrapper;
import org.jruby.truffle.translator.TranslatorDriver;
import org.jruby.util.ByteList;

Expand Down Expand Up @@ -184,7 +182,11 @@ public Object eval(String code, RubyBinding binding, RubyNode currentNode) {
}

public Object execute(RubyContext context, Source source, TranslatorDriver.ParserContext parserContext, Object self, MaterializedFrame parentFrame, RubyNode currentNode) {
final RubyRootNode rootNode = translator.parse(context, source, parserContext, parentFrame, currentNode);
return execute(context, source, parserContext, self, parentFrame, currentNode, NodeWrapper.IDENTITY);
}

public Object execute(RubyContext context, Source source, TranslatorDriver.ParserContext parserContext, Object self, MaterializedFrame parentFrame, RubyNode currentNode, NodeWrapper wrapper) {
final RubyRootNode rootNode = translator.parse(context, source, parserContext, parentFrame, currentNode, wrapper);
final CallTarget callTarget = Truffle.getRuntime().createCallTarget(rootNode);

// TODO(CS): we really need a method here - it's causing problems elsewhere
Expand Down Expand Up @@ -375,23 +377,6 @@ public Warnings getWarnings() {
return warnings;
}

public <T> T handlingTopLevelRaise(Supplier<T> run, T defaultValue) {
try {
return run.get();
} catch (RaiseException e) {
// TODO(CS): what's this cast about?
final RubyException rubyException = (RubyException) e.getRubyException();

for (String line : Backtrace.DISPLAY_FORMATTER.format(this, rubyException, rubyException.getBacktrace())) {
System.err.println(line);
}
} catch (ThreadExitException e) {
// Ignore
}

return defaultValue;
}

public Queue<Object> getThrowTags() {
return throwTags.get();
}
Expand Down
Expand Up @@ -7,10 +7,19 @@
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.runtime.util;
package org.jruby.truffle.translator;

public interface Supplier<T> {
import org.jruby.truffle.nodes.RubyNode;

T get();
public interface NodeWrapper {

public static NodeWrapper IDENTITY = new NodeWrapper() {
@Override
public RubyNode wrap(RubyNode node) {
return node;
}
};

RubyNode wrap(RubyNode node);

}
Expand Up @@ -67,7 +67,7 @@ public MethodDefinitionNode parse(RubyContext context, org.jruby.ast.Node parseT
return translator.compileFunctionNode(sourceSection, "(unknown)", argsNode, bodyNode, false);
}

public RubyRootNode parse(RubyContext context, Source source, ParserContext parserContext, MaterializedFrame parentFrame, RubyNode currentNode) {
public RubyRootNode parse(RubyContext context, Source source, ParserContext parserContext, MaterializedFrame parentFrame, RubyNode currentNode, NodeWrapper wrapper) {
// Set up the JRuby parser

final org.jruby.parser.Parser parser = new org.jruby.parser.Parser(context.getRuntime());
Expand Down Expand Up @@ -113,10 +113,10 @@ public RubyRootNode parse(RubyContext context, Source source, ParserContext pars
throw new RaiseException(new RubyException(context.getCoreLibrary().getSyntaxErrorClass(), context.makeString(message), RubyCallStack.getBacktrace(currentNode)));
}

return parse(currentNode, context, source, parserContext, parentFrame, node);
return parse(currentNode, context, source, parserContext, parentFrame, node, wrapper);
}

public RubyRootNode parse(RubyNode currentNode, RubyContext context, Source source, ParserContext parserContext, MaterializedFrame parentFrame, org.jruby.ast.RootNode rootNode) {
public RubyRootNode parse(RubyNode currentNode, RubyContext context, Source source, ParserContext parserContext, MaterializedFrame parentFrame, org.jruby.ast.RootNode rootNode, NodeWrapper wrapper) {
final SourceSection sourceSection = source.createSection("<main>", 0, source.getCode().length());
final SharedMethodInfo sharedMethodInfo = new SharedMethodInfo(sourceSection, context.getRootLexicalScope(), "<main>", false, rootNode, false);

Expand Down Expand Up @@ -181,6 +181,10 @@ public RubyRootNode parse(RubyNode currentNode, RubyContext context, Source sour

truffleNode = new CatchRetryAsErrorNode(context, truffleNode.getSourceSection(), truffleNode);

// Custom node wrapper

truffleNode = wrapper.wrap(truffleNode);

// Shell result

return new RubyRootNode(context, truffleNode.getSourceSection(), environment.getFrameDescriptor(), sharedMethodInfo, truffleNode);
Expand Down

0 comments on commit 8551198

Please sign in to comment.