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: f2359d159310
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 8a9ea3eb1ab5
Choose a head ref
  • 3 commits
  • 9 files changed
  • 1 contributor

Commits on Feb 27, 2015

  1. Copy the full SHA
    efe3973 View commit details
  2. [Truffle] Move all Truffle-specific nodes into Truffle::Primitive to …

    …clear the way for new functionality.
    chrisseaton committed Feb 27, 2015
    Copy the full SHA
    2e97631 View commit details
  3. Copy the full SHA
    8a9ea3e View commit details
Original file line number Diff line number Diff line change
@@ -92,14 +92,12 @@ public void init() {
CoreMethodNodeManager.addCoreMethodNodes(rubyObjectClass, SymbolNodesFactory.getFactories());
CoreMethodNodeManager.addCoreMethodNodes(rubyObjectClass, ThreadNodesFactory.getFactories());
CoreMethodNodeManager.addCoreMethodNodes(rubyObjectClass, TrueClassNodesFactory.getFactories());
CoreMethodNodeManager.addCoreMethodNodes(rubyObjectClass, TruffleDebugNodesFactory.getFactories());
CoreMethodNodeManager.addCoreMethodNodes(rubyObjectClass, TrufflePrimitiveNodesFactory.getFactories());
CoreMethodNodeManager.addCoreMethodNodes(rubyObjectClass, PrimitiveNodesFactory.getFactories());
CoreMethodNodeManager.addCoreMethodNodes(rubyObjectClass, EncodingNodesFactory.getFactories());
CoreMethodNodeManager.addCoreMethodNodes(rubyObjectClass, EncodingConverterNodesFactory.getFactories());
CoreMethodNodeManager.addCoreMethodNodes(rubyObjectClass, MethodNodesFactory.getFactories());
CoreMethodNodeManager.addCoreMethodNodes(rubyObjectClass, UnboundMethodNodesFactory.getFactories());
CoreMethodNodeManager.addCoreMethodNodes(rubyObjectClass, ByteArrayNodesFactory.getFactories());
CoreMethodNodeManager.addCoreMethodNodes(rubyObjectClass, TruffleNodesFactory.getFactories());
CoreMethodNodeManager.addCoreMethodNodes(rubyObjectClass, TimeNodesFactory.getFactories());

// Give the core library manager a chance to tweak some of those methods
Original file line number Diff line number Diff line change
@@ -641,7 +641,7 @@ public Object classEval(VirtualFrame frame, RubyModule module, RubyString code,
private Object classEvalSource(VirtualFrame frame, RubyModule module, Source source, Encoding encoding) {
RubyBinding binding = getCallerBinding(frame);

return getContext().execute(getContext(), source, encoding, TranslatorDriver.ParserContext.MODULE, module, binding.getFrame(), this, new NodeWrapper() {
return getContext().execute(source, encoding, TranslatorDriver.ParserContext.MODULE, module, binding.getFrame(), this, new NodeWrapper() {
@Override
public RubyNode wrap(RubyNode node) {
return new SetMethodDeclarationContext(node.getContext(), node.getSourceSection(), Visibility.PUBLIC, "class_eval", node);
Original file line number Diff line number Diff line change
@@ -9,23 +9,109 @@
*/
package org.jruby.truffle.nodes.core;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.FrameInstance;
import com.oracle.truffle.api.frame.FrameInstanceVisitor;
import com.oracle.truffle.api.frame.MaterializedFrame;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.NodeUtil;
import com.oracle.truffle.api.source.SourceSection;

import org.jruby.RubyGC;
import org.jruby.truffle.runtime.DebugOperations;
import org.jruby.truffle.runtime.RubyArguments;
import org.jruby.truffle.runtime.RubyCallStack;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.backtrace.Backtrace;
import org.jruby.truffle.runtime.core.RubyArray;
import org.jruby.truffle.runtime.core.RubyHash;
import org.jruby.truffle.runtime.core.RubyNilClass;
import org.jruby.truffle.runtime.core.RubyString;
import org.jruby.truffle.runtime.core.*;
import org.jruby.truffle.runtime.subsystems.SimpleShell;
import org.jruby.util.Memo;

import java.util.Locale;

@CoreClass(name = "Truffle::Primitive")
public abstract class PrimitiveNodes {

@CoreMethod(names = "binding_of_caller", onSingleton = true)
public abstract static class BindingOfCallerNode extends CoreMethodNode {

public BindingOfCallerNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

public BindingOfCallerNode(BindingOfCallerNode prev) {
super(prev);
}

@Specialization
public RubyBinding bindingOfCaller() {
/*
* When you use this method you're asking for the binding of the caller at the call site. When we get into
* this method, that is then the binding of the caller of the caller.
*/

@CoreClass(name = "Truffle::Debug")
public abstract class TruffleDebugNodes {
notDesignedForCompilation();

final Memo<Integer> frameCount = new Memo<>(0);

final MaterializedFrame frame = Truffle.getRuntime().iterateFrames(new FrameInstanceVisitor<MaterializedFrame>() {

@Override
public MaterializedFrame visitFrame(FrameInstance frameInstance) {
if (frameCount.get() == 1) {
return frameInstance.getFrame(FrameInstance.FrameAccess.READ_WRITE, false).materialize();
} else {
frameCount.set(frameCount.get() + 1);
return null;
}
}

});

return new RubyBinding(
getContext().getCoreLibrary().getBindingClass(),
RubyArguments.getSelf(frame.getArguments()),
frame);
}

}

@CoreMethod(names = "gc_count", onSingleton = true)
public abstract static class GCCountNode extends CoreMethodNode {

public GCCountNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

public GCCountNode(GCCountNode prev) {
super(prev);
}

@Specialization
public int gcCount() {
return RubyGC.getCollectionCount();
}

}

@CoreMethod(names = "gc_time", onSingleton = true)
public abstract static class GCTimeNode extends CoreMethodNode {

public GCTimeNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

public GCTimeNode(GCTimeNode prev) {
super(prev);
}

@Specialization
public long gcTime() {
return RubyGC.getCollectionTime();
}

}

@CoreMethod(names = "dump_call_stack", onSingleton = true)
public abstract static class DumpCallStackNode extends CoreMethodNode {
@@ -259,4 +345,78 @@ public RubyString tree() {

}

@CoreMethod(names = "graal?", onSingleton = true)
public abstract static class GraalNode extends CoreMethodNode {

public GraalNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

public GraalNode(GraalNode prev) {
super(prev);
}

@Specialization
public boolean graal() {
return Truffle.getRuntime().getName().toLowerCase(Locale.ENGLISH).contains("graal");
}

}

@CoreMethod(names = "substrate?", onSingleton = true)
public abstract static class SubstrateNode extends CoreMethodNode {

public SubstrateNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

public SubstrateNode(SubstrateNode prev) {
super(prev);
}

@Specialization
public boolean substrate() {
return getContext().getRuntime().isSubstrateVM();
}

}

@CoreMethod(names = "version", onSingleton = true)
public abstract static class VersionNode extends CoreMethodNode {

public VersionNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

public VersionNode(VersionNode prev) {
super(prev);
}

@Specialization
public RubyString version() {
return getContext().makeString(System.getProperty("graal.version", "unknown"));
}

}

@CoreMethod(names = "simple_shell", onSingleton = true)
public abstract static class SimpleShellNode extends CoreMethodNode {

public SimpleShellNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

public SimpleShellNode(SimpleShellNode prev) {
super(prev);
}

@CompilerDirectives.TruffleBoundary
@Specialization
public RubyNilClass simpleShell() {
new SimpleShell(getContext()).run(Truffle.getRuntime().getCallerFrame().getFrame(FrameInstance.FrameAccess.MATERIALIZE, true).materialize(), this);
return getContext().getCoreLibrary().getNilObject();
}

}

}

This file was deleted.

This file was deleted.

21 changes: 7 additions & 14 deletions truffle/src/main/java/org/jruby/truffle/runtime/RubyContext.java
Original file line number Diff line number Diff line change
@@ -31,7 +31,6 @@
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.*;
import org.jruby.truffle.runtime.methods.InternalMethod;
import org.jruby.truffle.runtime.methods.SharedMethodInfo;
import org.jruby.truffle.runtime.subsystems.*;
import org.jruby.truffle.runtime.util.FileUtils;
import org.jruby.truffle.translator.NodeWrapper;
@@ -40,13 +39,7 @@
import org.jruby.util.cli.Options;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Locale;
import java.util.Queue;
import java.util.Random;
import java.util.concurrent.atomic.AtomicLong;

@@ -187,7 +180,7 @@ public RubyNode wrap(RubyNode node) {
}
};

execute(this, source, UTF8Encoding.INSTANCE, TranslatorDriver.ParserContext.TOP_LEVEL, coreLibrary.getMainObject(), null, currentNode, composed);
execute(source, UTF8Encoding.INSTANCE, TranslatorDriver.ParserContext.TOP_LEVEL, coreLibrary.getMainObject(), null, currentNode, composed);
}

public RubySymbol.SymbolTable getSymbolTable() {
@@ -213,7 +206,7 @@ public RubySymbol newSymbol(ByteList name) {
@TruffleBoundary
public Object instanceEval(ByteList code, Object self, String filename, RubyNode currentNode) {
final Source source = Source.fromText(code, filename);
return execute(this, source, code.getEncoding(), TranslatorDriver.ParserContext.EVAL, self, null, currentNode, new NodeWrapper() {
return execute(source, code.getEncoding(), TranslatorDriver.ParserContext.EVAL, self, null, currentNode, new NodeWrapper() {
@Override
public RubyNode wrap(RubyNode node) {
return new SetMethodDeclarationContext(node.getContext(), node.getSourceSection(), Visibility.PUBLIC, "instance_eval", node);
@@ -228,20 +221,20 @@ public Object instanceEval(ByteList code, Object self, RubyNode currentNode) {
@TruffleBoundary
public Object eval(ByteList code, RubyBinding binding, boolean ownScopeForAssignments, String filename, RubyNode currentNode) {
final Source source = Source.fromText(code, filename);
return execute(this, source, code.getEncoding(), TranslatorDriver.ParserContext.EVAL, binding.getSelf(), binding.getFrame(), ownScopeForAssignments, currentNode, NodeWrapper.IDENTITY);
return execute(source, code.getEncoding(), TranslatorDriver.ParserContext.EVAL, binding.getSelf(), binding.getFrame(), ownScopeForAssignments, currentNode, NodeWrapper.IDENTITY);
}

public Object eval(ByteList code, RubyBinding binding, boolean ownScopeForAssignments, RubyNode currentNode) {
return eval(code, binding, ownScopeForAssignments, "(eval)", currentNode);
}

public Object execute(RubyContext context, Source source, Encoding defaultEncoding, TranslatorDriver.ParserContext parserContext, Object self, MaterializedFrame parentFrame, RubyNode currentNode, NodeWrapper wrapper) {
return execute(context, source, defaultEncoding, parserContext, self, parentFrame, true, currentNode, wrapper);
public Object execute(Source source, Encoding defaultEncoding, TranslatorDriver.ParserContext parserContext, Object self, MaterializedFrame parentFrame, RubyNode currentNode, NodeWrapper wrapper) {
return execute(source, defaultEncoding, parserContext, self, parentFrame, true, currentNode, wrapper);
}

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

final InternalMethod method = new InternalMethod(rootNode.getSharedMethodInfo(), rootNode.getSharedMethodInfo().getName(),
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright (c) 2013, 2015 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.runtime.subsystems;

import com.oracle.truffle.api.frame.MaterializedFrame;
import com.oracle.truffle.api.source.Source;
import org.jcodings.specific.UTF8Encoding;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyArguments;
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.core.RubyException;
import org.jruby.truffle.translator.NodeWrapper;
import org.jruby.truffle.translator.TranslatorDriver;

import java.util.StringTokenizer;

public class SimpleShell {

private final RubyContext context;

public SimpleShell(RubyContext context) {
this.context = context;
}

public void run(MaterializedFrame frame, RubyNode currentNode) {
while (true) {
final String shellLine = System.console().readLine("> ");

final StringTokenizer tokenizer = new StringTokenizer(shellLine);

if (!tokenizer.hasMoreElements()) {
continue;
}

switch (tokenizer.nextToken()) {
case "exit":
return;

default:
try {
final Object result = context.execute(
Source.fromText(shellLine, "shell"), UTF8Encoding.INSTANCE,
TranslatorDriver.ParserContext.EVAL,
RubyArguments.getSelf(frame.getArguments()), frame,
false, currentNode, NodeWrapper.IDENTITY);

System.console().writer().println(result);
} catch (RaiseException e) {
final RubyException rubyException = e.getRubyException();

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

}
3 changes: 3 additions & 0 deletions truffle/src/main/ruby/core.rb
Original file line number Diff line number Diff line change
@@ -85,6 +85,9 @@

require_relative 'core/shims'

# Load JRuby+Truffle specific classes
require_relative 'core/truffle/debug'

# Start running Ruby code outside classes
require_relative 'core/config'
require_relative 'core/main'
19 changes: 19 additions & 0 deletions truffle/src/main/ruby/core/truffle/debug.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Copyright (c) 2015 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

module Truffle

module Debug

def self.break
Truffle::Primitive.simple_shell
end

end

end