Skip to content

Commit

Permalink
Showing 316 changed files with 3,812 additions and 1,965 deletions.
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -78,6 +78,8 @@ matrix:
jdk: oraclejdk8
- env: COMMAND=test/truffle/integration-tests.sh
jdk: oraclejdk8
allow_failures:
- env: PHASE='-Prake -Dtask=test:mri:fullint'
# NOTE: build seems to never start (waited for any to finish for more than a day) - probably a travis-ci bug
#- env: PHASE='-Pmain'
# sudo: required
15 changes: 15 additions & 0 deletions bin/jruby.bash
Original file line number Diff line number Diff line change
@@ -229,6 +229,21 @@ do
CP="$CP$CP_DELIMITER$2"
CLASSPATH=""
shift
elif [ "${val:0:3}" = "-G:" ]; then # Graal options
opt=${val:3}
case $opt in
+*)
opt="${opt:1}=true" ;;
-*)
opt="${opt:1}=false" ;;
esac
java_args=("${java_args[@]}" "-Djvmci.option.$opt")
elif [ "${val:0:15}" = "-Djvmci.option." ]; then # Graal options
opt=${val:15}
java_args=("${java_args[@]}" "-Djvmci.option.$opt")
elif [ "${val:0:15}" = "-Dgraal.option." ]; then # Graal options
opt=${val:15}
java_args=("${java_args[@]}" "-Djvmci.option.$opt")
else
if [ "${val:0:3}" = "-ea" ]; then
VERIFY_JRUBY="yes"
Original file line number Diff line number Diff line change
@@ -9,18 +9,12 @@
*/
package org.jruby;

public interface TruffleContextInterface {
public interface JRubyTruffleInterface {

enum BacktraceFormatter {
MRI,
DEBUG,
IMPL_DEBUG
}

void initialize();
String RUNTIME_SYMBOL = "org.jruby.truffle.runtime";

Object execute(org.jruby.ast.RootNode rootNode);

void shutdown();
void dispose();

}
30 changes: 16 additions & 14 deletions core/src/main/java/org/jruby/Ruby.java
Original file line number Diff line number Diff line change
@@ -367,10 +367,6 @@ public static boolean isGlobalRuntimeReady() {
return globalRuntime != null;
}

public static boolean isSubstrateVM() {
return false;
}

/**
* Set the global runtime to the given runtime only if it has no been set.
*
@@ -843,7 +839,7 @@ public IRubyObject runInterpreter(ThreadContext context, Node rootNode, IRubyObj
if (getInstanceConfig().getCompileMode() == CompileMode.TRUFFLE) {
assert rootNode instanceof RootNode;
assert self == getTopSelf();
final TruffleContextInterface truffleContext = getTruffleContext();
final JRubyTruffleInterface truffleContext = getTruffleContext();
Main.printTruffleTimeMetric("before-run");
truffleContext.execute((RootNode) rootNode);
Main.printTruffleTimeMetric("after-run");
@@ -884,42 +880,48 @@ public JITCompiler getJITCompiler() {
return jitCompiler;
}

public TruffleContextInterface getTruffleContext() {
public JRubyTruffleInterface getTruffleContext() {
synchronized (truffleContextMonitor) {
if (truffleContext == null) {
truffleContext = loadTruffleContext();
truffleContext = loadTruffle();
}
return truffleContext;
}
}

private TruffleContextInterface loadTruffleContext() {
private JRubyTruffleInterface loadTruffle() {
Main.printTruffleTimeMetric("before-load-truffle-context");

final Class<?> clazz;

try {
clazz = getJRubyClassLoader().loadClass("org.jruby.truffle.runtime.RubyContext");
clazz = getJRubyClassLoader().loadClass("org.jruby.truffle.JRubyTruffleImpl");
} catch (Exception e) {
throw new RuntimeException("Truffle backend not available", e);
}

final TruffleContextInterface truffleContext;
final JRubyTruffleInterface truffleContext;

try {
Constructor<?> con = clazz.getConstructor(Ruby.class);
truffleContext = (TruffleContextInterface) con.newInstance(this);
truffleContext = (JRubyTruffleInterface) con.newInstance(this);
} catch (Exception e) {
throw new RuntimeException("Error while calling the constructor of Truffle's RubyContext", e);
}

truffleContext.initialize();

Main.printTruffleTimeMetric("after-load-truffle-context");

return truffleContext;
}

public void shutdownTruffleContextIfRunning() {
synchronized (truffleContextMonitor) {
if (truffleContext != null) {
truffleContext.dispose();
}
}
}

/**
* @deprecated use #newInstance()
*/
@@ -4959,7 +4961,7 @@ public FilenoUtil getFilenoUtil() {
// Compilation
private final JITCompiler jitCompiler;

private TruffleContextInterface truffleContext;
private JRubyTruffleInterface truffleContext;
private final Object truffleContextMonitor = new Object();

// Note: this field and the following static initializer
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/RubyInstanceConfig.java
Original file line number Diff line number Diff line change
@@ -1861,7 +1861,7 @@ private static int initGlobalJavaVersion() {
return Opcodes.V1_5;
} else if (specVersion.equals("1.6")) {
return Opcodes.V1_6;
} else if (specVersion.equals("1.7") || specVersion.equals("1.8") || specVersion.equals("1.9")) {
} else if (specVersion.equals("1.7") || specVersion.equals("1.8") || specVersion.equals("1.9") || specVersion.equals("9")) {
return Opcodes.V1_7;
} else {
System.err.println("unsupported Java version \"" + specVersion + "\", defaulting to 1.5");
136 changes: 128 additions & 8 deletions core/src/main/java/org/jruby/ext/socket/RubyUNIXSocket.java
Original file line number Diff line number Diff line change
@@ -36,10 +36,15 @@
import jnr.unixsocket.UnixServerSocketChannel;
import jnr.unixsocket.UnixSocketAddress;
import jnr.unixsocket.UnixSocketChannel;
import jnr.posix.CmsgHdr;
import jnr.posix.MsgHdr;
import jnr.posix.POSIX;
import org.jruby.Ruby;
import org.jruby.RubyClass;
import org.jruby.RubyNumeric;
import org.jruby.RubyString;
import org.jruby.RubyIO;
import org.jruby.RubyFixnum;
import org.jruby.anno.JRubyClass;
import org.jruby.anno.JRubyMethod;
import org.jruby.runtime.Helpers;
@@ -49,10 +54,14 @@
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.ByteList;
import org.jruby.util.io.ModeFlags;
import org.jruby.util.io.OpenFile;
import org.jruby.util.io.FilenoUtil;

import java.io.File;
import java.io.IOException;
import java.nio.channels.Channel;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;


@JRubyClass(name="UNIXSocket", parent="BasicSocket")
@@ -74,6 +83,18 @@ public RubyUNIXSocket(Ruby runtime, RubyClass type) {
super(runtime, type);
}

@JRubyMethod(meta = true)
public static IRubyObject for_fd(ThreadContext context, IRubyObject recv, IRubyObject _fileno) {
Ruby runtime = context.runtime;
int fileno = (int)_fileno.convertToInteger().getLongValue();

RubyClass klass = (RubyClass)recv;
RubyUNIXSocket unixSocket = (RubyUNIXSocket)(Helpers.invoke(context, klass, "allocate"));
UnixSocketChannel channel = UnixSocketChannel.fromFD(fileno);
unixSocket.init_sock(runtime, channel);
return unixSocket;
}

@JRubyMethod(visibility = Visibility.PRIVATE)
public IRubyObject initialize(ThreadContext context, IRubyObject path) {
init_unixsock(context.runtime, path, false);
@@ -133,16 +154,115 @@ public IRubyObject recvfrom(ThreadContext context, IRubyObject[] args) {
peeraddr(context));
}

@JRubyMethod(notImplemented = true)
public IRubyObject send_io(IRubyObject path) {
//TODO: implement, won't do this now
return getRuntime().getNil();
@JRubyMethod
public IRubyObject send_io(ThreadContext context, IRubyObject arg) {
final Ruby runtime = context.runtime;
final POSIX posix = runtime.getPosix();
OpenFile fptr = getOpenFileChecked();
int fd;

if (arg.callMethod(context, "kind_of?", runtime.getIO()).isTrue()) {
fd = ((RubyIO) arg).getOpenFileChecked().getFileno();
} else if (arg.callMethod(context, "kind_of?", runtime.getFixnum()).isTrue()) {
fd = ((RubyFixnum) arg).getIntValue();
} else {
throw runtime.newTypeError("neither IO nor file descriptor");
}

if (FilenoUtil.isFake(fd)) {
throw runtime.newTypeError("file descriptor is not native");
}

byte[] dataBytes = new byte[1];
dataBytes[0] = 0;

MsgHdr outMessage = posix.allocateMsgHdr();

ByteBuffer[] outIov = new ByteBuffer[1];
outIov[0] = ByteBuffer.allocateDirect(dataBytes.length);
outIov[0].put(dataBytes);
outIov[0].flip();

outMessage.setIov(outIov);

CmsgHdr outControl = outMessage.allocateControl(4);
outControl.setLevel(SocketLevel.SOL_SOCKET.intValue());
outControl.setType(0x01);

ByteBuffer fdBuf = ByteBuffer.allocateDirect(4);
fdBuf.order(ByteOrder.nativeOrder());
fdBuf.putInt(0, fd);
outControl.setData(fdBuf);

boolean locked = fptr.lock();
try {
while (posix.sendmsg(fptr.getFileno(), outMessage, 0) == -1) {
if (!fptr.waitWritable(context)) {
throw runtime.newErrnoFromInt(posix.errno(), "sendmsg(2)");
}
}
} finally {
if (locked) fptr.unlock();
}

return runtime.getNil();
}

@JRubyMethod(rest = true, notImplemented = true)
public IRubyObject recv_io(IRubyObject[] args) {
//TODO: implement, won't do this now
return getRuntime().getNil();
@JRubyMethod(optional = 2)
public IRubyObject recv_io(ThreadContext context, IRubyObject[] args) {
final Ruby runtime = context.runtime;
final POSIX posix = runtime.getPosix();
OpenFile fptr = getOpenFileChecked();

IRubyObject klass = runtime.getIO();
IRubyObject mode = runtime.getNil();
if (args.length > 0) {
klass = args[0];
}
if (args.length > 1) {
mode = args[1];
}

MsgHdr inMessage = posix.allocateMsgHdr();
ByteBuffer[] inIov = new ByteBuffer[1];
inIov[0] = ByteBuffer.allocateDirect(1);
inMessage.setIov(inIov);

CmsgHdr inControl = inMessage.allocateControl(4);
inControl.setLevel(SocketLevel.SOL_SOCKET.intValue());
inControl.setType(0x01);

ByteBuffer fdBuf = ByteBuffer.allocateDirect(4);
fdBuf.order(ByteOrder.nativeOrder());
fdBuf.putInt(0, -1);
inControl.setData(fdBuf);

boolean locked = fptr.lock();
try {
while (posix.recvmsg(fptr.getFileno(), inMessage, 0) == -1) {
if (!fptr.waitReadable(context)) {
throw runtime.newErrnoFromInt(posix.errno(), "recvmsg(2)");
}
}
} finally {
if (locked) fptr.unlock();
}


ByteBuffer inFdBuf = inMessage.getControls()[0].getData();
inFdBuf.order(ByteOrder.nativeOrder());

IRubyObject fd = runtime.newFixnum(inFdBuf.getInt());

if (klass.isNil()) {
return fd;
} else {
if (mode.isNil()) {
return Helpers.invoke(context, klass, "for_fd", fd);
} else {
return Helpers.invoke(context, klass, "for_fd", fd, mode);
}
}
}

@JRubyMethod(name = {"socketpair", "pair"}, optional = 2, meta = true)
Original file line number Diff line number Diff line change
@@ -20,18 +20,39 @@
// Represents a dynamic regexp in Ruby
// Ex: /#{a}#{b}/
public class BuildDynRegExpInstr extends NOperandResultBaseInstr {
final private RegexpOptions options;
// Create a cache object so that this can be shared
// through the lifetime of the original instruction independent
// of it being cloned (because of inlining, JIT-ting, whatever).
private static class RECache {
// Cached regexp
private volatile RubyRegexp rubyRegexp;
private static final AtomicReferenceFieldUpdater<RECache, RubyRegexp> UPDATER =
AtomicReferenceFieldUpdater.newUpdater(RECache.class, RubyRegexp.class, "rubyRegexp");
public void updateCache(boolean isOnce, RubyRegexp re) {
if (isOnce) {
// Atomically update this, so we only see one instance cached ever.
// See MRI's ruby/test_regexp.rb, test_once_multithread
UPDATER.compareAndSet(this, null, re);
} else {
rubyRegexp = re;
}
}
};

// Cached regexp
private volatile RubyRegexp rubyRegexp;
final private RegexpOptions options;
final private RECache reCache;

private static final AtomicReferenceFieldUpdater<BuildDynRegExpInstr, RubyRegexp> UPDATER =
AtomicReferenceFieldUpdater.newUpdater(BuildDynRegExpInstr.class, RubyRegexp.class, "rubyRegexp");
// Only used by cloning
private BuildDynRegExpInstr(Variable result, Operand[] pieces, RegexpOptions options, RECache reCache) {
super(Operation.BUILD_DREGEXP, result, pieces);
this.options = options;
this.reCache = reCache;
}

public BuildDynRegExpInstr(Variable result, Operand[] pieces, RegexpOptions options) {
super(Operation.BUILD_DREGEXP, result, pieces);

this.options = options;
this.reCache = new RECache();
}

public Operand[] getPieces() {
@@ -43,7 +64,7 @@ public RegexpOptions getOptions() {
}

public RubyRegexp getRegexp() {
return rubyRegexp;
return reCache.rubyRegexp;
}

@Override
@@ -53,7 +74,8 @@ public String[] toStringNonOperandArgs() {

@Override
public Instr clone(CloneInfo ii) {
return new BuildDynRegExpInstr(ii.getRenamedVariable(result), cloneOperands(ii), options);
// Share the cache!
return new BuildDynRegExpInstr(ii.getRenamedVariable(result), cloneOperands(ii), options, this.reCache);
}

private RubyString[] retrievePieces(ThreadContext context, IRubyObject self, StaticScope currScope, DynamicScope currDynScope, Object[] temp) {
@@ -82,21 +104,15 @@ public static BuildDynRegExpInstr decode(IRReaderDecoder d) {
public Object interpret(ThreadContext context, StaticScope currScope, DynamicScope currDynScope, IRubyObject self, Object[] temp) {
// FIXME (from RegexpNode.java): 1.9 should care about internal or external encoding and not kcode.
// If we have a constant regexp string or if the regexp patterns asks for caching, cache the regexp
if (rubyRegexp == null || !options.isOnce() || context.runtime.getKCode() != rubyRegexp.getKCode()) {
if (reCache.rubyRegexp == null || !options.isOnce() || context.runtime.getKCode() != reCache.rubyRegexp.getKCode()) {
RubyString[] pieces = retrievePieces(context, self, currScope, currDynScope, temp);
RubyString pattern = RubyRegexp.preprocessDRegexp(context.runtime, pieces, options);
RubyRegexp re = RubyRegexp.newDRegexp(context.runtime, pattern, options);
re.setLiteral();
if (options.isOnce()) {
// Atomically update this, so we only see one instance cached ever.
// See MRI's ruby/test_regexp.rb, test_once_multithread
UPDATER.compareAndSet(this, null, re);
} else {
rubyRegexp = re;
}
reCache.updateCache(options.isOnce(), re);
}

return rubyRegexp;
return reCache.rubyRegexp;
}

@Override
11 changes: 6 additions & 5 deletions core/src/main/java/org/jruby/util/cli/Options.java
Original file line number Diff line number Diff line change
@@ -36,7 +36,6 @@
import java.util.HashSet;

import com.headius.options.Option;
import org.jruby.TruffleContextInterface;
import org.jruby.runtime.Constants;
import org.jruby.util.KCode;
import org.jruby.util.SafePropertyAccessor;
@@ -142,15 +141,15 @@ public class Options {
public static final Option<Boolean> OBJECTSPACE_ENABLED = bool(MISCELLANEOUS, "objectspace.enabled", false, "Enable or disable ObjectSpace.each_object.");
public static final Option<Boolean> SIPHASH_ENABLED = bool(MISCELLANEOUS, "siphash.enabled", false, "Enable or disable SipHash for String hash function.");
public static final Option<Boolean> LAUNCH_INPROC = bool(MISCELLANEOUS, "launch.inproc", false, "Set in-process launching of e.g. system('ruby ...').");
public static final Option<String> BYTECODE_VERSION = string(MISCELLANEOUS, "bytecode.version", new String[]{"1.5","1.6","1.7"}, SafePropertyAccessor.getProperty("java.specification.version", "1.5"), "Specify the major Java bytecode version.");
public static final Option<String> BYTECODE_VERSION = string(MISCELLANEOUS, "bytecode.version", new String[]{"1.5", "1.6", "1.7"}, SafePropertyAccessor.getProperty("java.specification.version", "1.5"), "Specify the major Java bytecode version.");
public static final Option<Boolean> MANAGEMENT_ENABLED = bool(MISCELLANEOUS, "management.enabled", false, "Set whether JMX management is enabled.");
public static final Option<Boolean> JUMP_BACKTRACE = bool(MISCELLANEOUS, "jump.backtrace", false, "Make non-local flow jumps generate backtraces.");
public static final Option<Boolean> PROCESS_NOUNWRAP = bool(MISCELLANEOUS, "process.noUnwrap", false, "Do not unwrap process streams (issue on some recent JVMs).");
public static final Option<Boolean> REIFY_CLASSES = bool(MISCELLANEOUS, "reify.classes", false, "Before instantiation, stand up a real Java class for every Ruby class.");
public static final Option<Boolean> REIFY_LOGERRORS = bool(MISCELLANEOUS, "reify.logErrors", false, "Log errors during reification (reify.classes=true).");
public static final Option<Boolean> REFLECTED_HANDLES = bool(MISCELLANEOUS, "reflected.handles", false, "Use reflection for binding methods, not generated bytecode.");
public static final Option<Boolean> BACKTRACE_COLOR = bool(MISCELLANEOUS, "backtrace.color", false, "Enable colorized backtraces.");
public static final Option<String> BACKTRACE_STYLE = string(MISCELLANEOUS, "backtrace.style", new String[]{"normal","raw","full","mri"}, "normal", "Set the style of exception backtraces.");
public static final Option<String> BACKTRACE_STYLE = string(MISCELLANEOUS, "backtrace.style", new String[]{"normal", "raw", "full", "mri"}, "normal", "Set the style of exception backtraces.");
public static final Option<Boolean> BACKTRACE_MASK = bool(MISCELLANEOUS, "backtrace.mask", false, "Mask .java lines in Ruby backtraces.");
public static final Option<String> THREAD_DUMP_SIGNAL = string(MISCELLANEOUS, "thread.dump.signal", new String[]{"USR1", "USR2", "etc"}, "USR2", "Set the signal used for dumping thread stacks.");
public static final Option<Boolean> NATIVE_NET_PROTOCOL = bool(MISCELLANEOUS, "native.net.protocol", false, "Use native impls for parts of net/protocol.");
@@ -175,7 +174,7 @@ public class Options {
public static final Option<Boolean> LOG_BACKTRACES = bool(DEBUG, "log.backtraces", false, "Log every time an exception backtrace is generated.");
public static final Option<Boolean> LOG_CALLERS = bool(DEBUG, "log.callers", false, "Log every time a Kernel#caller backtrace is generated.");
public static final Option<Boolean> LOG_WARNINGS = bool(DEBUG, "log.warnings", false, "Log every time a built-in warning backtrace is generated.");
public static final Option<String> LOGGER_CLASS = string(DEBUG, "logger.class", new String[] {"class name"}, "org.jruby.util.log.StandardErrorLogger", "Use specified class for logging.");
public static final Option<String> LOGGER_CLASS = string(DEBUG, "logger.class", new String[]{"class name"}, "org.jruby.util.log.StandardErrorLogger", "Use specified class for logging.");
public static final Option<Boolean> DUMP_INSTANCE_VARS = bool(DEBUG, "dump.variables", false, "Dump class + instance var names on first new of Object subclasses.");
public static final Option<Boolean> REWRITE_JAVA_TRACE = bool(DEBUG, "rewrite.java.trace", true, "Rewrite stack traces from exceptions raised in Java calls.");

@@ -218,7 +217,8 @@ public class Options {
public static final Option<Boolean> CLI_STRIP_HEADER = bool(CLI, "cli.strip.header", false, "Strip text before shebang in script. Same as -x.");
public static final Option<Boolean> CLI_LOAD_GEMFILE = bool(CLI, "cli.load.gemfile", false, "Load a bundler Gemfile in cwd before running. Same as -G.");

public static final Option<Boolean> TRUFFLE_COVERAGE = bool(TRUFFLE, "truffle.coverage", false, "Enable coverage (will be enabled by default in the future - currently has some bugs");
public static final Option<Boolean> TRUFFLE_COVERAGE = bool(TRUFFLE, "truffle.coverage", false, "Enable coverage (will be enabled by default in the future - currently has some bugs).");
public static final Option<Boolean> TRUFFLE_COVERAGE_GLOBAL = bool(TRUFFLE, "truffle.coverage.global", false, "Run coverage for all code and print results on exit.");

public static final Option<String> TRUFFLE_CORE_LOAD_PATH = string(TRUFFLE, "truffle.core.load_path", "truffle:/jruby-truffle", "Location to load the Truffle core library from.");

@@ -258,6 +258,7 @@ public class Options {
public static final Option<Boolean> TRUFFLE_EXCEPTIONS_PRINT_JAVA = bool(TRUFFLE, "truffle.exceptions.print_java", false, "Print Java exceptions at the point of translating them to Ruby exceptions.");
public static final Option<Boolean> TRUFFLE_EXCEPTIONS_PRINT_UNCAUGHT_JAVA = bool(TRUFFLE, "truffle.exceptions.print_uncaught_java", false, "Print uncaught Java exceptions at the point of translating them to Ruby exceptions.");
public static final Option<Boolean> TRUFFLE_BACKTRACES_HIDE_CORE_FILES = bool(TRUFFLE, "truffle.backtraces.hide_core_files", true, "Hide core source files in backtraces, like MRI does.");
public static final Option<Boolean> TRUFFLE_INCLUDE_CORE_FILE_CALLERS_IN_SET_TRACE_FUNC = bool(TRUFFLE, "truffle.set_trace_func.include_core_file_callers", false, "Include internal core library calls in set_trace_func output.");

public static final Option<Boolean> TRUFFLE_METRICS_TIME = bool(TRUFFLE, "truffle.metrics.time", false, "Print the time at various stages of VM operation.");
public static final Option<Boolean> TRUFFLE_METRICS_MEMORY_USED_ON_EXIT = bool(TRUFFLE, "truffle.metrics.memory_used_on_exit", false, "Print the size of heap memory in use on exit.");
Original file line number Diff line number Diff line change
@@ -56,8 +56,7 @@ module SecureRandom
def self.random_bytes(n=nil)
n ||= 16

# TODO (pitr 04-Oct-2015): pending PR https://github.com/rubysl/rubysl-securerandom/pull/1
if defined?(OpenSSL::Random) && OpenSSL::Random != Random
if defined? OpenSSL::Random
@pid = 0 if !defined?(@pid)
pid = $$
if @pid != pid
2 changes: 1 addition & 1 deletion pom.rb
Original file line number Diff line number Diff line change
@@ -125,7 +125,7 @@

rules = { :requireMavenVersion => { :version => '[3.3.0,)' } }
unless model.version =~ /-SNAPSHOT/
rules[:requireReleaseDeps] = { :message => 'No Snapshots Allowed!' }
#rules[:requireReleaseDeps] = { :message => 'No Snapshots Allowed!' }
end
plugin :enforcer, '1.4' do
execute_goal :enforce, :rules => rules
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# 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

require 'mkmf'
$CFLAGS << ' -Wall'
create_makefile('foo/foo')
65 changes: 65 additions & 0 deletions spec/truffle/specs/truffle/objspace/reachable_objects_from_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# 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

require_relative '../../../../ruby/spec_helper'
require 'objspace'

# Truffle-specific behavior
describe "ObjectSpace.reachable_objects_from" do
it "enumerates objects directly reachable from a given object" do
ObjectSpace.reachable_objects_from(nil).should == [NilClass]
ObjectSpace.reachable_objects_from(['a', 'b', 'c']).should include(Array, 'a', 'b', 'c')
ObjectSpace.reachable_objects_from(Object.new).should == [Object]
end

it "finds the superclass and included/prepended modules of a class" do
superclass = Class.new
klass = Class.new(superclass)
included = Module.new
klass.include included
prepended = Module.new
klass.prepend prepended
ObjectSpace.reachable_objects_from(klass).should include(prepended, included, superclass)
end

it "finds a variable captured by a block captured by #define_method" do
captured = Object.new
obj = Object.new
block = lambda {
captured
}
obj.singleton_class.send(:define_method, :capturing_method, block)

meth = obj.method(:capturing_method)
reachable = ObjectSpace.reachable_objects_from(meth)
reachable.should include(Method, obj)

reachable = reachable + reachable.flat_map { |r| ObjectSpace.reachable_objects_from(r) }
reachable.should include(captured)
end

it "finds an object stored in a Queue" do
require 'thread'
o = Object.new
q = Queue.new
q << o

reachable = ObjectSpace.reachable_objects_from(q)
reachable.should include(o)
end

it "finds an object stored in a SizedQueue" do
require 'thread'
o = Object.new
q = SizedQueue.new(3)
q << o

reachable = ObjectSpace.reachable_objects_from(q)
reachable.should include(o)
end
end
1 change: 1 addition & 0 deletions spec/truffle/tags/core/dir/entries_tags.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
fails:Dir.entries returns entries encoded with the specified encoding
graalvm:Dir.entries returns entries encoded with the filesystem encoding by default
1 change: 1 addition & 0 deletions spec/truffle/tags/core/env/element_reference_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
graalvm:ENV.[] uses the locale encoding if Encoding.default_internal is nil
1 change: 1 addition & 0 deletions spec/truffle/tags/core/exception/backtrace_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:Exception#backtrace contains lines of the same format for each prior position in the stack
3 changes: 3 additions & 0 deletions spec/truffle/tags/core/file/stat/grpowned_tags.txt
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
fails(windows):File::Stat#grpowned? returns false if the file exist
graalvm:File::Stat#grpowned? returns true if the file exist
graalvm:File::Stat#grpowned? accepts an object that has a #to_path method
graalvm:File::Stat#grpowned? takes non primary groups into account
3 changes: 3 additions & 0 deletions spec/truffle/tags/core/filetest/grpowned_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
graalvm:FileTest.grpowned? accepts an object that has a #to_path method
graalvm:FileTest.grpowned? takes non primary groups into account
graalvm:FileTest.grpowned? returns true if the file exist
1 change: 1 addition & 0 deletions spec/truffle/tags/core/objectspace/each_object_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:ObjectSpace.each_object doesn't find an object stored in a WeakRef that should have been cleared
1 change: 1 addition & 0 deletions spec/truffle/tags/library/stringio/readpartial_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
graalvm:StringIO#readpartial reads after ungetc without data in the buffer
1 change: 1 addition & 0 deletions spec/truffle/tags/library/stringio/tell_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
graalvm:StringIO#tell returns the current byte offset
2 changes: 2 additions & 0 deletions spec/truffle/tags/library/stringscanner/pre_match_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
graalvm:StringScanner#pre_match returns an instance of String when passed a String subclass
graalvm:StringScanner#pre_match taints the returned String if the input was tainted
1 change: 1 addition & 0 deletions spec/truffle/tags/library/stringscanner/reset_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
graalvm:StringScanner#reset reset the scan pointer and clear matching data
2 changes: 2 additions & 0 deletions spec/truffle/tags/library/stringscanner/rest_size_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
graalvm:StringScanner#rest_size Returns the length of the rest of the string
graalvm:StringScanner#rest_size is equivalent to rest.size
4 changes: 4 additions & 0 deletions spec/truffle/tags/library/stringscanner/rest_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
graalvm:StringScanner#rest returns the rest of the string
graalvm:StringScanner#rest returns an instance of String when passed a String subclass
graalvm:StringScanner#rest taints the returned String if the input was tainted
graalvm:StringScanner#rest? returns true if there is more data in the string
2 changes: 2 additions & 0 deletions spec/truffle/tags/library/stringscanner/restsize_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
graalvm:StringScanner#restsize Returns the length of the rest of the string
graalvm:StringScanner#restsize is equivalent to rest.size
4 changes: 4 additions & 0 deletions spec/truffle/tags/library/stringscanner/scan_full_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
graalvm:StringScanner#scan_full returns the number of bytes advanced
graalvm:StringScanner#scan_full returns the number of bytes advanced and advances the scan pointer if the second argument is true
graalvm:StringScanner#scan_full returns the matched string if the third argument is true
graalvm:StringScanner#scan_full returns the matched string if the third argument is true and advances the scan pointer if the second argument is true
4 changes: 4 additions & 0 deletions spec/truffle/tags/library/stringscanner/scan_tags.txt
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
fails:StringScanner#scan treats ^ as matching from the beginning of the current position
graalvm:StringScanner#scan returns the matched string
graalvm:StringScanner#scan returns nil if there's no match
graalvm:StringScanner#scan returns nil when there is no more to scan
graalvm:StringScanner#scan returns an empty string when the pattern matches empty
2 changes: 2 additions & 0 deletions spec/truffle/tags/library/stringscanner/scan_until_tags.txt
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
fails:StringScanner#scan_until can match anchors properly
graalvm:StringScanner#scan_until returns the substring up to and including the end of the match
graalvm:StringScanner#scan_until returns nil if there's no match
4 changes: 4 additions & 0 deletions spec/truffle/tags/library/stringscanner/search_full_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
graalvm:StringScanner#search_full returns the number of bytes advanced
graalvm:StringScanner#search_full returns the number of bytes advanced and advances the scan pointer if the second argument is true
graalvm:StringScanner#search_full returns the matched string if the third argument is true
graalvm:StringScanner#search_full returns the matched string if the third argument is true and advances the scan pointer if the second argument is true
2 changes: 2 additions & 0 deletions spec/truffle/tags/library/stringscanner/skip_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
graalvm:StringScanner#skip returns length of the match
graalvm:StringScanner#skip returns nil if there's no match
2 changes: 2 additions & 0 deletions spec/truffle/tags/library/stringscanner/skip_until_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
graalvm:StringScanner#skip_until returns the number of bytes advanced and advances the scan pointer until pattern is matched and consumed
graalvm:StringScanner#skip_until returns nil if no match was found
1 change: 1 addition & 0 deletions spec/truffle/tags/truffle/runtime/java_class_of_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
graalvm:Truffle::Runtime.java_class_of returns 'DynamicObject*' for a String
8 changes: 8 additions & 0 deletions spec/truffle/truffle_formatter.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# 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

require 'mspec/expectations/expectations'
require 'mspec/utils/ruby_name'
require 'mspec/runner/formatters/dotted'
8 changes: 4 additions & 4 deletions test/mri/excludes/TestSocket_UNIXSocket.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
exclude :test_addr, "needs investigation"
exclude :test_dgram_pair, "needs investigation"
exclude :test_epipe, "needs investigation"
exclude :test_fd_passing, "close_on_exec? not implemented"
exclude :test_fd_passing_race_condition, "needs investigation"
exclude :test_getpeereid, "needs investigation"
exclude :test_initialize, "needs investigation"
exclude :test_noname_recv_nonblock, "needs investigation"
exclude :test_noname_unpack_sockaddr_un, "needs investigation"
exclude :test_nul, "needs investigation"
exclude :test_socket_pair_with_block, "needs investigation"
exclude :test_too_long_path, "needs investigation"
exclude :test_unix_server_socket, "needs investigation"
exclude :test_unix_socket_pair_with_block, "needs investigation"
exclude :test_unix_socket_pair_with_block, "needs investigation"
exclude :test_cloexec, "needs investigation"
exclude :test_dgram_pair_sendrecvmsg_errno_set, "needs investigation"
2 changes: 1 addition & 1 deletion test/mri_truffle.index
Original file line number Diff line number Diff line change
@@ -45,7 +45,7 @@ ruby/test_integer.rb
ruby/test_integer_comb.rb
# ruby/test_io.rb # cannot load such file -- io/nonblock
ruby/test_io_m17n.rb
ruby/test_iterator.rb
# ruby/test_iterator.rb /Users/chrisseaton/Documents/ruby/jruby/test/mri/lib/minitest/unit.rb:1417:in `sort': internal implementation error - NullPointerException null org.jruby.truffle.runtime.subsystems.TraceManager$4.probeTaggedAs(TraceManager.java:117) (RubyTruffleError)
ruby/test_lambda.rb
ruby/test_literal.rb
# ruby/test_m17n.rb # NPE in Body Translator
21 changes: 2 additions & 19 deletions test/pom.rb
Original file line number Diff line number Diff line change
@@ -301,27 +301,10 @@ def truffle_spec_config(spec_type, generate_report)

end

profile 'truffle-test-pe' do

plugin :antrun do
execute_goals( 'run',
:id => 'rake',
:phase => 'test',
:configuration => [ xml(
'<target>' +
'<exec dir="${jruby.home}" executable="${jruby.home}/bin/jruby" failonerror="true">' +
'<arg value="-J-server" />' +
'<arg value="-X+T" />' +
'<arg value="test/truffle/pe/pe.rb" />' +
'</exec>' +
'</target>' ) ] )
end

end


profile 'truffle-mri-tests' do

plugin :surefire, '2.15', :skipTests => true

plugin :antrun do
execute_goals('run',
:id => 'rake',
40 changes: 40 additions & 0 deletions test/truffle/attachments-optimise.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# 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

# -J-G:+TruffleCompilationExceptionsAreFatal

def foo
foo = 14
foo * 2
end

Truffle::Attachments.attach __FILE__, 5 do |binding|
binding.local_variable_set(:foo, 100)
end

begin
loop do
x = foo
raise "value not correct" unless x == 200
Truffle::Primitive.assert_constant x
Truffle::Primitive.assert_not_compiled
end
rescue RubyTruffleError => e
if e.message.include? 'Truffle::Primitive.assert_not_compiled'
puts "attachments optimising"
exit 0
elsif e.message.include? 'Truffle::Primitive.assert_constant'
puts "attachments not optimising"
exit 1
else
puts "some other error"
exit 1
end
end

exit 1
2 changes: 2 additions & 0 deletions test/truffle/can-we-fold-yet.rb
Original file line number Diff line number Diff line change
@@ -6,6 +6,8 @@
# GNU General Public License version 2
# GNU Lesser General Public License version 2.1

# Use -J-G:+TruffleIterativePartialEscape

unless Truffle.graal?
puts 'You need Graal to run this'
exit
8 changes: 8 additions & 0 deletions test/truffle/cext/foo/ext/foo/extconf.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# 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

require 'mkmf'
$CFLAGS << ' -Wall'
create_makefile('foo/foo')
8 changes: 8 additions & 0 deletions test/truffle/cext/inline.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# 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

p Truffle::CExt.supported?

Truffle::CExt.inline %{
8 changes: 8 additions & 0 deletions test/truffle/cext/inline_capi.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# 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

p Truffle::CExt.supported?

Truffle::CExt.inline %{
8 changes: 8 additions & 0 deletions test/truffle/cext/inline_flags.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# 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

p Truffle::CExt.supported?

Truffle::CExt.inline %{
8 changes: 8 additions & 0 deletions test/truffle/cext/require.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# 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

p Truffle::CExt.supported?

require 'foo/foo'
2 changes: 2 additions & 0 deletions test/truffle/compiler-tests.sh
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
#!/bin/bash

bin/jruby -X+T test/truffle/attachments-optimise.rb || exit 1
8 changes: 8 additions & 0 deletions test/truffle/coverage/subject.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# 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

a = 1
b = 2

17 changes: 11 additions & 6 deletions test/truffle/coverage/test.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
# 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

require 'coverage'

Coverage.start

require_relative 'subject.rb'

data = Coverage.result.values.first
expected = [1, 1, nil, 1, 0, nil, nil, 1, nil, 1, 1, nil, nil, 1, 2, nil, nil, 1, 1, nil, 1]
#[1, 1, nil, 1, 10, nil, nil, 1, nil, 1, 1, nil, nil, 1, 2, nil, nil, 1, 1, nil, 1]

p data
data = Coverage.result[File.join(File.dirname(__FILE__), 'subject.rb')]
expected = [nil, nil, nil, nil, nil, nil, nil, nil, 1, 1, nil, 1, 10, nil, nil, 1, nil, 1, 1, nil, nil, 1, 2, nil, nil, 1, 1, nil, 1]

raise 'failed' unless data == expected
raise 'coverage data not as expected' unless data == expected
9 changes: 5 additions & 4 deletions test/truffle/integration-tests.sh
Original file line number Diff line number Diff line change
@@ -40,10 +40,11 @@ bin/jruby -X-T bin/gem install rack
bin/jruby -X+T -Ilib/ruby/gems/shared/gems/rack-1.6.4/lib test/truffle/simple-webrick-server.rb &
test_server

echo "Simple Sinatra web server..."
bin/jruby -X-T bin/gem install sinatra
bin/jruby -X+T -Ilib/ruby/gems/shared/gems/rack-1.6.4/lib -Ilib/ruby/gems/shared/gems/tilt-2.0.1/lib -Ilib/ruby/gems/shared/gems/rack-protection-1.5.3/lib -Ilib/ruby/gems/shared/gems/sinatra-1.4.6/lib test/truffle/simple-sinatra-server.rb &
test_server
# TODO CS 11-Nov-15 doesn't work on GraalVm as where do the gems get installed?
#echo "Simple Sinatra web server..."
#bin/jruby -X-T bin/gem install sinatra
#bin/jruby -X+T -Ilib/ruby/gems/shared/gems/rack-1.6.4/lib -Ilib/ruby/gems/shared/gems/tilt-2.0.1/lib -Ilib/ruby/gems/shared/gems/rack-protection-1.5.3/lib -Ilib/ruby/gems/shared/gems/sinatra-1.4.6/lib test/truffle/simple-sinatra-server.rb &
#test_server

echo "Coverage..."
bin/jruby -X+T -Xtruffle.coverage=true test/truffle/coverage/test.rb
5 changes: 1 addition & 4 deletions test/truffle/pe/core/array_pe.rb
Original file line number Diff line number Diff line change
@@ -10,7 +10,4 @@

example "[3, 1, 2].sort[1]", 2

# why does this fail but the next one work?
tagged_example "[14].pack('C').getbyte(0)", 14

example "[14].pack('C').getbyte(0) * 2", 28
example "[14].pack('C').getbyte(0)", 14
8 changes: 1 addition & 7 deletions test/truffle/pe/core/binding_pe.rb
Original file line number Diff line number Diff line change
@@ -6,28 +6,22 @@
# GNU General Public License version 2
# GNU Lesser General Public License version 2.1

# why do the tagged_example fail? identity of boxing?
# TODO CS 8-Nov-15 fail due to a boundary and control flow diverge

# Kernel#binding
tagged_example "x = 14; binding.local_variable_get(:x)", 14
example "x = 14; binding.local_variable_get(:x) * 2", 28

# Proc#binding
tagged_example "x = 14; p = Proc.new { }; p.binding.local_variable_get(:x)", 14
example "x = 14; p = Proc.new { }; p.binding.local_variable_get(:x) * 2", 28

# set + get
tagged_example "b = binding; b.local_variable_set(:x, 14); b.local_variable_get(:x)", 14
example "b = binding; b.local_variable_set(:x, 14); b.local_variable_get(:x) * 2", 28

# get (2 levels)
tagged_example "x = 14; y = nil; 1.times { y = binding.local_variable_get(:x) }; y", 14
example "x = 14; y = nil; 1.times { y = binding.local_variable_get(:x) }; y * 2", 28

# set (2 levels)
tagged_example "x = 14; 1.times { binding.local_variable_set(:x, 15) }; x", 15
example "x = 14; 1.times { binding.local_variable_set(:x, 15) }; x * 2", 30

# get + set (2 levels)
tagged_example "x = 14; y = nil; 1.times { binding.local_variable_set(:x, 15); y = binding.local_variable_get(:x) }; y", 15
example "x = 14; y = nil; 1.times { binding.local_variable_set(:x, 15); y = binding.local_variable_get(:x) }; y * 2", 30
8 changes: 6 additions & 2 deletions test/truffle/pe/core/string_pe.rb
Original file line number Diff line number Diff line change
@@ -6,6 +6,10 @@
# GNU General Public License version 2
# GNU Lesser General Public License version 2.1

example "'abc'.length", 3
simple_string = 'test'

example "Truffle::Primitive.create_simple_string.length", simple_string.length
example "Truffle::Primitive.create_simple_string.getbyte(0)", simple_string.getbyte(0)

example "'abc' == 'abc'", true
example "'abc'.length", 3
tagged_example "'abc' == 'abc'", true # seems to fail sometimes
7 changes: 3 additions & 4 deletions test/truffle/pe/language/constant_pe.rb
Original file line number Diff line number Diff line change
@@ -17,7 +17,7 @@ def self.get
A
end

def self.get_const_get(name)
def self.const_get_in_scope(name)
ConstantFixtures.const_get(name)
end

@@ -50,10 +50,9 @@ def self.const_missing(const)

example "ConstantFixtures.get_existing", Proc
example "ConstantFixtures.get", 1
example "ConstantFixtures.get_const_get(:A)", 1
example "ConstantFixtures.const_get_in_scope(:A)", 1

# Internal Graal compiler error
tagged_example "ConstantFixtures.get_const_get('A')", 1
example "ConstantFixtures.const_get_in_scope('A')", 1

example "ConstantFixtures::Nested.get_nested", 1
example "ConstantFixtures::Child.get_inherited", 2
2 changes: 1 addition & 1 deletion test/truffle/pe/pe.rb
Original file line number Diff line number Diff line change
@@ -24,7 +24,7 @@
#
# Run with:
#
# jt run --graal -J-G:+TraceTruffleCompilation -J-G:+TruffleCompilationExceptionsAreFatal test.rb
# jt run --graal -J-G:+TraceTruffleCompilation -J-G:+TruffleCompilationExceptionsAreFatal -J-G:+TruffleIterativePartialEscape test.rb

TIMEOUT = 10

8 changes: 8 additions & 0 deletions test/truffle/simple-rack-server.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# 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

require 'rack'

# bin/jruby bin/gem install rack
8 changes: 8 additions & 0 deletions test/truffle/simple-sinatra-server.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# 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

require 'sinatra'

# bin/jruby bin/gem install sinatra
8 changes: 8 additions & 0 deletions test/truffle/simple-webrick-server.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# 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

require 'webrick'

server = WEBrick::HTTPServer.new(:Port => 8080)
67 changes: 48 additions & 19 deletions tool/jt.rb
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@

JDEBUG_PORT = 51819
JDEBUG = "-J-agentlib:jdwp=transport=dt_socket,server=y,address=#{JDEBUG_PORT},suspend=y"
JDEBUG_TEST = "-Dmaven.surefire.debug=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=#{JDEBUG_PORT} -Xnoagent -Djava.compiler=NONE"
JEXCEPTION = "-Xtruffle.exceptions.print_java=true"

# wait for sub-processes to handle the interrupt
@@ -37,13 +38,13 @@ def self.find_graal
graal_locations = [
ENV['GRAAL_BIN'],
ENV["GRAAL_BIN_#{mangle_for_env(git_branch)}"],
"graalvm-jdk1.8.0/bin/java",
"../graalvm-jdk1.8.0/bin/java",
"../../graalvm-jdk1.8.0/bin/java",
"GraalVM-0.9/jre/bin/javao",
"../GraalVM-0.9/jre/bin/javao",
"../../GraalVM-0.9/jre/bin/javao",
].compact.map { |path| File.expand_path(path, JRUBY_DIR) }

not_found = -> {
raise "couldn't find graal - download it from http://lafo.ssw.uni-linz.ac.at/graalvm/ and extract it into the JRuby repository or parent directory"
raise "couldn't find graal - download it as described in https://github.com/jruby/jruby/wiki/Downloading-GraalVM and extract it into the JRuby repository or parent directory"
}

graal_locations.find(not_found) do |location|
@@ -59,19 +60,28 @@ def self.mangle_for_env(name)
name.upcase.tr('-', '_')
end

def self.find_graal_parent
graal = File.expand_path('../../../../../graal-compiler', find_graal)
raise "couldn't find graal - set GRAAL_BIN, and you need to use a checkout of Graal, not a build" unless Dir.exist?(graal)
graal
end

def self.find_graal_mx
mx = File.expand_path('../../../../mx.sh', find_graal)
raise "couldn't find mx.sh - set GRAAL_BIN, and you need to use a checkout of Graal, not a build" unless File.executable?(mx)
mx = File.expand_path('../../../../../../mx/mx', find_graal)
raise "couldn't find mx - set GRAAL_BIN, and you need to use a checkout of Graal, not a build" unless File.executable?(mx)
mx
end

def self.igv_running?
`ps a`.lines.any? { |p| p.include? 'mxtool/mx.py igv' }
`ps a`.include? 'IdealGraphVisualizer'
end

def self.ensure_igv_running
unless igv_running?
spawn "#{find_graal_mx} igv", pgroup: true
Dir.chdir(find_graal_parent + "/../jvmci") do
spawn "#{find_graal_mx} --vm server igv", pgroup: true
end

sleep 5
puts
puts
@@ -179,6 +189,7 @@ def help
puts ' --no-tests don\'t run JUnit unit tests'
puts 'jt clean clean'
puts 'jt irb irb'
puts 'jt rebuild clean and build'
puts 'jt run [options] args... run JRuby with -X+T and args'
puts ' --graal use Graal (set GRAAL_BIN or it will try to automagically find it)'
puts ' --asm show assembly (implies --graal)'
@@ -190,6 +201,7 @@ def help
puts 'jt e 14 + 2 evaluate an expression'
puts 'jt puts 14 + 2 evaluate and print an expression'
puts 'jt test run all mri tests and specs'
puts 'jt test tck [--jdebug] run the Truffle Compatibility Kit tests'
puts 'jt test mri run mri tests'
puts 'jt test specs run all specs'
puts 'jt test specs fast run all specs except sub-processes, GC, sleep, ...'
@@ -223,7 +235,7 @@ def checkout(branch)
sh 'git', 'checkout', branch
rebuild
end

def build(project = nil)
opts = %w[-DskipTests]
case project
@@ -244,9 +256,10 @@ def irb(*args)
run(*%w[-S irb], *args)
end

def rebuild(*args)
def rebuild
FileUtils.cp('bin/jruby.bash', 'bin/jruby')
clean
build *args
build
end

def run(*args)
@@ -330,10 +343,17 @@ def test(*args)

case path
when nil
test_tck
test_specs('run')
test_mri
when 'pe' then test_pe(*rest)
when 'specs' then test_specs('run', *rest)
when 'tck' then
args = []
if rest.include? '--jdebug'
args << JDEBUG_TEST
end
test_tck *args
when 'mri' then test_mri(*rest)
else
if File.expand_path(path).start_with?("#{JRUBY_DIR}/test")
@@ -346,6 +366,8 @@ def test(*args)

def test_pe(*args)
file = args.pop if args.last and File.exist?(args.last)
args.push('-J-G:+TruffleIterativePartialEscape')
args.push('-J-G:+TruffleCompilationExceptionsAreThrown')
run('--graal', *args, 'test/truffle/pe/pe.rb', *file)
end
private :test_pe
@@ -391,6 +413,11 @@ def test_specs(command, *args)
end
private :test_specs

def test_tck(*args)
mvn *args + ['test']
end
private :test_tck

def tag(path, *args)
return tag_all(*args) if path == 'all'
test_specs('tag', path, *args)
@@ -521,14 +548,13 @@ def main(args)
exit
end

if ['build', 'rebuild'].include? args.first
build_args = [args.shift]

while ['truffle', '--no-tests'].include? args.first
build_args << args.shift
end

send(*build_args)
case args.first
when "rebuild"
send(args.shift)
when "build"
command = [args.shift]
command << args.shift if args.first == "truffle"
send(*command)
end

return if args.empty?
@@ -549,4 +575,7 @@ def main(args)
end
end

# tool/jruby_eclipse only works on release currently
ENV.delete("JRUBY_ECLIPSE") unless Utilities.graal_version

JT.new.main(ARGV)
55 changes: 45 additions & 10 deletions tool/update_truffle_copyright.rb
Original file line number Diff line number Diff line change
@@ -1,28 +1,61 @@
# Copyright (c) 2014, 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

require 'rugged'

RB_COPYRIGHT = <<-EOS
# Copyright (c) #{Time.now.year} 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
EOS

JAVA_COPYRIGHT = <<-EOS
/*
* Copyright (c) #{Time.now.year} 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
*/
EOS

NEW_COPYRIGHT = {
'.rb' => RB_COPYRIGHT,
'.java' => JAVA_COPYRIGHT
}

EXTENSIONS = %w[.java .rb]

COPYRIGHT = /Copyright \(c\) (?<year1>\d{4})(?:, (?<year2>\d{4}))? Oracle\b/

OTHER_COPYRIGHTS = [
/Copyright \(c\) \d{4} Software Architecture Group, Hasso Plattner Institute/,
/Copyright \(c\) \d{4}(?:-\d{4})?,? Evan Phoenix/
/Copyright \(c\) \d{4}(?:-\d{4})?,? Evan Phoenix/,
/Copyright \(c\) \d{4} Engine Yard/
]

EXTENSIONS = %w[.java .rb]

truffle_paths = %w[
truffle/src/main/java/org/jruby/truffle
truffle/src/main/ruby
test/truffle/pe/pe.rb
truffle/src
test/truffle
spec/truffle
] + [__FILE__]

excludes = %w[
test/truffle/pack-real-usage.rb
]

truffle_paths.each do |path|
puts "WARNING: incorrect path #{path}" unless File.exist? path
end
@@ -53,7 +86,9 @@
paths = diff.each_delta.to_a.map { |delta|
delta.new_file[:path]
}.select { |path|
EXTENSIONS.include?(File.extname(path)) and truffle_paths.any? { |prefix| path.start_with? prefix }
EXTENSIONS.include?(File.extname(path)) &&
truffle_paths.any? { |prefix| path.start_with? prefix } &&
excludes.none? { |prefix| path.start_with? prefix }
}

paths.each do |file|
@@ -63,8 +98,8 @@

unless COPYRIGHT =~ header
if OTHER_COPYRIGHTS.none? { |copyright| copyright =~ header }
puts "WARNING: No copyright in #{file}"
puts header
puts "Adding copyright in #{file}"
File.write(file, NEW_COPYRIGHT[File.extname(file)]+File.read(file))
end
next
end
4 changes: 2 additions & 2 deletions truffle/.factorypath
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<factorypath>
<factorypathentry kind="VARJAR" id="M2_REPO/com/oracle/truffle/0.7/truffle-0.7.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/com/oracle/truffle-dsl-processor/0.7/truffle-dsl-processor-0.7.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/com/oracle/truffle/truffle-api/0.10/truffle-api-0.10.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/com/oracle/truffle/truffle-dsl-processor/0.10/truffle-dsl-processor-0.10.jar" enabled="true" runInBatchMode="false"/>
</factorypath>
1 change: 1 addition & 0 deletions truffle/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/bin/
/target/
/.apt_generated/
/src_gen/
11 changes: 8 additions & 3 deletions truffle/pom.rb
Original file line number Diff line number Diff line change
@@ -15,8 +15,12 @@

jar 'org.jruby:jruby-core', '${project.version}', :scope => 'provided'

jar 'com.oracle:truffle:0.7'
jar 'com.oracle:truffle-dsl-processor:0.7', :scope => 'provided'
truffle_version = '0.10'
jar 'com.oracle.truffle:truffle-api:' + truffle_version
jar 'com.oracle.truffle:truffle-debug:' + truffle_version
jar 'com.oracle.truffle:truffle-dsl-processor:' + truffle_version, :scope => 'provided'
jar 'com.oracle.truffle:truffle-tck:' + truffle_version, :scope => 'test'
jar 'junit:junit', :scope => 'test'

plugin 'org.antlr:antlr4-maven-plugin', '4.5.1-1' do
execute_goal :antlr4
@@ -42,7 +46,8 @@
:phase => 'compile',
'annotationProcessors' => [ 'org.jruby.truffle.om.dsl.processor.OMProcessor',
'com.oracle.truffle.dsl.processor.TruffleProcessor',
'com.oracle.truffle.dsl.processor.verify.VerifyTruffleProcessor' ],
'com.oracle.truffle.dsl.processor.verify.VerifyTruffleProcessor',
'com.oracle.truffle.dsl.processor.LanguageRegistrationProcessor' ],
'generatedSourcesDirectory' => 'target/generated-sources',
'compilerArgs' => [ '-XDignore.symbol.file=true',
'-J-Duser.language=en',
27 changes: 22 additions & 5 deletions truffle/pom.xml
Original file line number Diff line number Diff line change
@@ -39,16 +39,32 @@ DO NOT MODIFIY - GENERATED CODE
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>truffle</artifactId>
<version>0.7</version>
<groupId>com.oracle.truffle</groupId>
<artifactId>truffle-api</artifactId>
<version>0.10</version>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<groupId>com.oracle.truffle</groupId>
<artifactId>truffle-debug</artifactId>
<version>0.10</version>
</dependency>
<dependency>
<groupId>com.oracle.truffle</groupId>
<artifactId>truffle-dsl-processor</artifactId>
<version>0.7</version>
<version>0.10</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.oracle.truffle</groupId>
<artifactId>truffle-tck</artifactId>
<version>0.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<defaultGoal>package</defaultGoal>
@@ -104,6 +120,7 @@ DO NOT MODIFIY - GENERATED CODE
<annotationProcessor>org.jruby.truffle.om.dsl.processor.OMProcessor</annotationProcessor>
<annotationProcessor>com.oracle.truffle.dsl.processor.TruffleProcessor</annotationProcessor>
<annotationProcessor>com.oracle.truffle.dsl.processor.verify.VerifyTruffleProcessor</annotationProcessor>
<annotationProcessor>com.oracle.truffle.dsl.processor.LanguageRegistrationProcessor</annotationProcessor>
</annotationProcessors>
<generatedSourcesDirectory>target/generated-sources</generatedSourcesDirectory>
<compilerArgs>
56 changes: 56 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/JRubyTruffleImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2014, 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;

import com.oracle.truffle.api.source.Source;
import com.oracle.truffle.api.vm.PolyglotEngine;
import org.jruby.JRubyTruffleInterface;
import org.jruby.Ruby;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.RubyLanguage;

import java.io.IOException;

public class JRubyTruffleImpl implements JRubyTruffleInterface {

private final PolyglotEngine engine;
private final RubyContext context;

// Run by reflection from Ruby#loadTruffle
public JRubyTruffleImpl(Ruby runtime) {
engine = PolyglotEngine.newBuilder().globalSymbol(JRubyTruffleInterface.RUNTIME_SYMBOL, new RubyLanguage.JRubyContextWrapper(runtime)).build();

try {
context = (RubyContext) engine.eval(Source.fromText("Truffle::Primitive.context", "context").withMimeType(RubyLanguage.MIME_TYPE)).get();
} catch (IOException e) {
throw new RuntimeException(e);
}
}

@Override
public Object execute(org.jruby.ast.RootNode rootNode) {
context.setInitialJRubyRootNode(rootNode);

try {
return engine.eval(Source.fromText("Truffle::Primitive.run_jruby_root", "run_jruby_root").withMimeType(RubyLanguage.MIME_TYPE)).get();
} catch (IOException e) {
if (e.getCause() instanceof RuntimeException) {
throw (RuntimeException) e.getCause();
}

throw new RuntimeException(e);
}
}

@Override
public void dispose() {
engine.dispose();
}
}
36 changes: 36 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/PolyglotEngineMain.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* 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
*/
package org.jruby.truffle;

import com.oracle.truffle.api.source.Source;
import com.oracle.truffle.api.vm.PolyglotEngine;
import org.jruby.truffle.runtime.RubyLanguage;

import java.io.*;
import java.nio.charset.StandardCharsets;

public class PolyglotEngineMain {

public static void main(String[] args) {
final PolyglotEngine engine = PolyglotEngine.newBuilder().build();

for (String arg : args) {
try (InputStream inputStream = new FileInputStream(arg)) {
final Reader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
final Source source = Source.fromReader(reader, arg).withMimeType(RubyLanguage.MIME_TYPE);
engine.eval(source);
} catch (IOException e) {
e.printStackTrace();
}
}

}

}
Original file line number Diff line number Diff line change
@@ -19,6 +19,7 @@
import org.jruby.truffle.format.runtime.PackFrameDescriptor;
import org.jruby.truffle.format.runtime.exceptions.TooFewArgumentsException;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.array.ArrayUtils;
import org.jruby.util.ByteList;

import java.util.Arrays;
@@ -187,7 +188,7 @@ private byte[] ensureCapacity(VirtualFrame frame, int length) {
// If we ran out of output byte[], deoptimize and next time we'll allocate more

CompilerDirectives.transferToInterpreterAndInvalidate();
output = Arrays.copyOf(output, (output.length + length) * 2);
output = Arrays.copyOf(output, ArrayUtils.capacity(output.length, outputPosition + length));
setOutput(frame, output);
}

Original file line number Diff line number Diff line change
@@ -14,11 +14,11 @@
import com.oracle.truffle.api.frame.FrameSlotTypeException;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.RootNode;
import com.oracle.truffle.api.source.NullSourceSection;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.format.runtime.PackEncoding;
import org.jruby.truffle.format.runtime.PackFrameDescriptor;
import org.jruby.truffle.format.runtime.PackResult;
import org.jruby.truffle.runtime.array.ArrayUtils;
import org.jruby.truffle.runtime.RubyLanguage;

/**
* The node at the root of a pack expression.
@@ -30,10 +30,10 @@ public class PackRootNode extends RootNode {

@Child private PackNode child;

@CompilationFinal private int expectedLength = ArrayUtils.capacity(0, 0);
@CompilationFinal private int expectedLength = 0;

public PackRootNode(String description, PackEncoding encoding, PackNode child) {
super(new NullSourceSection("pack", description), PackFrameDescriptor.FRAME_DESCRIPTOR);
super(RubyLanguage.class, SourceSection.createUnavailable("pack", description), PackFrameDescriptor.FRAME_DESCRIPTOR);
this.description = description;
this.encoding = encoding;
this.child = child;
@@ -60,7 +60,7 @@ public Object execute(VirtualFrame frame) {

if (outputLength > expectedLength) {
CompilerDirectives.transferToInterpreterAndInvalidate();
expectedLength = ArrayUtils.capacity(expectedLength, outputLength);
expectedLength = outputLength;
}

final byte[] output;
Original file line number Diff line number Diff line change
@@ -14,7 +14,6 @@
import com.oracle.truffle.api.dsl.NodeChildren;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.object.DynamicObject;

import org.jruby.truffle.format.nodes.PackNode;
import org.jruby.truffle.format.parser.PrintfTreeBuilder;
import org.jruby.truffle.runtime.RubyContext;
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
/*
* 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
*/
package org.jruby.truffle.format.nodes.read;

import com.oracle.truffle.api.frame.VirtualFrame;
import org.jruby.truffle.format.nodes.PackNode;
import org.jruby.truffle.runtime.RubyContext;

import com.oracle.truffle.api.frame.VirtualFrame;

public class LiteralIntegerNode extends PackNode {

private final int value;
Original file line number Diff line number Diff line change
@@ -13,14 +13,9 @@
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.NodeChildren;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
import org.jruby.truffle.format.nodes.PackNode;
import org.jruby.truffle.format.nodes.SourceNode;
import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.core.hash.HashNodes;
import org.jruby.truffle.nodes.core.hash.HashNodesFactory;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;

Original file line number Diff line number Diff line change
@@ -9,17 +9,16 @@
*/
package org.jruby.truffle.format.nodes.read;

import org.jruby.truffle.format.nodes.PackNode;
import org.jruby.truffle.format.nodes.SourceNode;
import org.jruby.truffle.format.nodes.type.ToIntegerNode;
import org.jruby.truffle.format.nodes.type.ToIntegerNodeGen;
import org.jruby.truffle.runtime.RubyContext;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.NodeChildren;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import org.jruby.truffle.format.nodes.PackNode;
import org.jruby.truffle.format.nodes.SourceNode;
import org.jruby.truffle.format.nodes.type.ToIntegerNode;
import org.jruby.truffle.format.nodes.type.ToIntegerNodeGen;
import org.jruby.truffle.runtime.RubyContext;

/**
* Read a {@code int} value from the source.
Original file line number Diff line number Diff line change
@@ -15,9 +15,9 @@
import com.oracle.truffle.api.dsl.NodeChildren;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import org.jruby.truffle.format.nodes.PackNode;
import org.jruby.truffle.nodes.coerce.ToFNode;
import org.jruby.truffle.nodes.coerce.ToFNodeGen;
import org.jruby.truffle.format.nodes.PackNode;
import org.jruby.truffle.runtime.RubyContext;

/**
Original file line number Diff line number Diff line change
@@ -15,9 +15,9 @@
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
import org.jruby.truffle.format.nodes.PackNode;
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory;
import org.jruby.truffle.format.nodes.PackNode;
import org.jruby.truffle.runtime.RubyContext;

@NodeChildren({
Original file line number Diff line number Diff line change
@@ -16,14 +16,14 @@
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory;
import org.jruby.truffle.nodes.dispatch.DispatchNode;
import org.jruby.truffle.nodes.dispatch.MissingBehavior;
import org.jruby.truffle.format.nodes.PackGuards;
import org.jruby.truffle.format.nodes.PackNode;
import org.jruby.truffle.format.runtime.exceptions.CantConvertException;
import org.jruby.truffle.format.runtime.exceptions.NoImplicitConversionException;
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory;
import org.jruby.truffle.nodes.dispatch.DispatchNode;
import org.jruby.truffle.nodes.dispatch.MissingBehavior;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.layouts.Layouts;

Original file line number Diff line number Diff line change
@@ -17,6 +17,8 @@
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.utilities.ConditionProfile;
import org.jruby.truffle.format.nodes.PackNode;
import org.jruby.truffle.format.runtime.exceptions.NoImplicitConversionException;
import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.core.KernelNodes;
@@ -27,8 +29,6 @@
import org.jruby.truffle.nodes.dispatch.MissingBehavior;
import org.jruby.truffle.nodes.objects.IsTaintedNode;
import org.jruby.truffle.nodes.objects.IsTaintedNodeGen;
import org.jruby.truffle.format.nodes.PackNode;
import org.jruby.truffle.format.runtime.exceptions.NoImplicitConversionException;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.StringOperations;
import org.jruby.util.ByteList;
Original file line number Diff line number Diff line change
@@ -17,9 +17,6 @@
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyContext;

import org.jruby.truffle.format.parser.PackLexer;
import org.jruby.truffle.format.parser.PackParser;

public class PackCompiler {

private final RubyContext context;
Original file line number Diff line number Diff line change
@@ -23,17 +23,14 @@
import org.jruby.truffle.format.nodes.write.*;
import org.jruby.truffle.format.runtime.PackEncoding;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;

import java.nio.ByteOrder;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;

import org.jruby.truffle.format.parser.PackBaseListener;
import org.jruby.truffle.format.parser.PackParser;
import org.jruby.truffle.runtime.control.RaiseException;

public class PackTreeBuilder extends PackBaseListener {

private final RubyContext context;
Original file line number Diff line number Diff line change
@@ -17,9 +17,6 @@
import org.jruby.truffle.format.runtime.PackEncoding;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyContext;

import org.jruby.truffle.format.parser.PrintfLexer;
import org.jruby.truffle.format.parser.PrintfParser;
import org.jruby.util.ByteList;

public class PrintfCompiler {
Original file line number Diff line number Diff line change
@@ -11,7 +11,6 @@

import com.oracle.truffle.api.object.DynamicObject;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.misc.Interval;
import org.jruby.truffle.format.nodes.PackNode;
import org.jruby.truffle.format.nodes.SourceNode;
import org.jruby.truffle.format.nodes.control.SequenceNode;
@@ -25,9 +24,7 @@
import org.jruby.truffle.format.nodes.write.WriteBytesNodeGen;
import org.jruby.truffle.format.nodes.write.WritePaddedBytesNodeGen;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.layouts.Layouts;
import org.jruby.util.ByteList;
import org.jruby.util.StringSupport;

import java.util.ArrayList;
import java.util.List;
113 changes: 113 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/nodes/LazyRubyRootNode.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/*
* 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
*/
package org.jruby.truffle.nodes;

import com.oracle.truffle.api.CallTarget;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.frame.FrameDescriptor;
import com.oracle.truffle.api.frame.FrameInstance;
import com.oracle.truffle.api.frame.MaterializedFrame;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.DirectCallNode;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.RootNode;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.Source;
import com.oracle.truffle.api.source.SourceSection;
import org.jcodings.specific.UTF8Encoding;
import org.jruby.runtime.Visibility;
import org.jruby.truffle.nodes.methods.DeclarationContext;
import org.jruby.truffle.runtime.RubyArguments;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.RubyLanguage;
import org.jruby.truffle.runtime.methods.InternalMethod;
import org.jruby.truffle.runtime.subsystems.AttachmentsManager;
import org.jruby.truffle.translator.TranslatorDriver;
import org.jruby.truffle.translator.TranslatorDriver.ParserContext;

public class LazyRubyRootNode extends RootNode {

private final Source source;
private final String[] argumentNames;

@CompilationFinal private RubyContext cachedContext;
@CompilationFinal private DynamicObject mainObject;
@CompilationFinal private InternalMethod method;

@Child private Node findContextNode;
@Child private DirectCallNode callNode;

public LazyRubyRootNode(SourceSection sourceSection, FrameDescriptor frameDescriptor, Source source, String[] argumentNames) {
super(RubyLanguage.class, sourceSection, frameDescriptor);
this.source = source;
this.argumentNames = argumentNames;
}

@Override
public Object execute(VirtualFrame frame) {
if (findContextNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
findContextNode = insert(RubyLanguage.INSTANCE.unprotectedCreateFindContextNode());
}

final RubyContext context = RubyLanguage.INSTANCE.unprotectedFindContext(findContextNode);

if (cachedContext == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
cachedContext = context;
}

if (callNode == null || context != cachedContext) {
CompilerDirectives.transferToInterpreter();

if (AttachmentsManager.ATTACHMENT_SOURCE == source) {
final SourceSection sourceSection = (SourceSection) frame.getArguments()[getIndex("section")];
final DynamicObject block = (DynamicObject) frame.getArguments()[getIndex("block")];

final RootNode rootNode = new AttachmentsManager.AttachmentRootNode(RubyLanguage.class, cachedContext, sourceSection, null, block);
final CallTarget callTarget = Truffle.getRuntime().createCallTarget(rootNode);

callNode = insert(Truffle.getRuntime().createDirectCallNode(callTarget));
callNode.forceInlining();
} else {
final TranslatorDriver translator = new TranslatorDriver(context);
final RubyRootNode rootNode = translator.parse(context, source, UTF8Encoding.INSTANCE, ParserContext.TOP_LEVEL, argumentNames, null, true, null);
final CallTarget callTarget = Truffle.getRuntime().createCallTarget(rootNode);

callNode = insert(Truffle.getRuntime().createDirectCallNode(callTarget));
callNode.forceInlining();

mainObject = context.getCoreLibrary().getMainObject();
method = new InternalMethod(rootNode.getSharedMethodInfo(), rootNode.getSharedMethodInfo().getName(),
context.getCoreLibrary().getObjectClass(), Visibility.PUBLIC, callTarget);
}
}

if (method == null) {
final MaterializedFrame callerFrame = Truffle.getRuntime().getCallerFrame().getFrame(FrameInstance.FrameAccess.MATERIALIZE, false).materialize();
return callNode.call(frame, new Object[] { callerFrame });
}

return callNode.call(frame,
RubyArguments.pack(method, null, null, mainObject, null, DeclarationContext.TOP_LEVEL, frame.getArguments()));
}

private int getIndex(String name) {
for (int i = 0; i < argumentNames.length; i++) {
if (name.equals(argumentNames[i])) {
return i;
}
}
return -1;
}

}
12 changes: 11 additions & 1 deletion truffle/src/main/java/org/jruby/truffle/nodes/RubyGuards.java
Original file line number Diff line number Diff line change
@@ -228,7 +228,17 @@ public static boolean isThreadLocal(Object value) {
}

public static boolean isForeignObject(Object object) {
return (object instanceof TruffleObject) && !(object instanceof DynamicObject);
return object instanceof TruffleObject && !isRubyBasicObject(object);
}

public static boolean isBoxedPrimitive(Object object) {
return object instanceof Boolean
|| object instanceof Byte
|| object instanceof Short
|| object instanceof Integer
|| object instanceof Long
|| object instanceof Float
|| object instanceof Double;
}

// Sentinels
35 changes: 2 additions & 33 deletions truffle/src/main/java/org/jruby/truffle/nodes/RubyNode.java
Original file line number Diff line number Diff line change
@@ -9,42 +9,23 @@
*/
package org.jruby.truffle.nodes;

import com.oracle.truffle.api.CompilerAsserts;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.dsl.ImportStatic;
import com.oracle.truffle.api.dsl.TypeSystemReference;
import com.oracle.truffle.api.frame.*;
import com.oracle.truffle.api.instrument.ProbeNode;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.object.DynamicObjectFactory;
import com.oracle.truffle.api.source.SourceSection;
import jnr.ffi.provider.MemoryManager;
import jnr.posix.POSIX;

import org.jcodings.specific.UTF8Encoding;
import org.jruby.truffle.nodes.instrument.RubyWrapperNode;
import org.jruby.truffle.runtime.NotProvided;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.StringOperations;
import org.jruby.truffle.runtime.layouts.Layouts;
import org.jruby.truffle.runtime.sockets.NativeSockets;
import org.jruby.truffle.translator.TranslatorDriver;
import org.jruby.util.ByteList;
import org.jruby.util.StringSupport;

import com.oracle.truffle.api.dsl.ImportStatic;
import com.oracle.truffle.api.dsl.TypeSystemReference;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.instrument.ProbeNode;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.object.DynamicObjectFactory;
import com.oracle.truffle.api.source.SourceSection;
import org.jcodings.specific.USASCIIEncoding;

@TypeSystemReference(RubyTypes.class)
@ImportStatic(RubyGuards.class)
@@ -144,7 +125,7 @@ public DynamicObject executeDynamicObject(VirtualFrame frame) throws UnexpectedR
public Object[] executeObjectArray(VirtualFrame frame) throws UnexpectedResultException {
final Object value = execute(frame);

if (value instanceof Object[]) {
if (value.getClass() == Object[].class) {
return (Object[]) value;
} else {
throw new UnexpectedResultException(value);
@@ -199,18 +180,6 @@ protected DynamicObjectFactory getInstanceFactory(DynamicObject rubyClass) {
return Layouts.CLASS.getInstanceFactory(rubyClass);
}

// Instrumentation

@Override
public boolean isInstrumentable() {
return true;
}

@Override
public ProbeNode.WrapperNode createWrapperNode() {
return new RubyWrapperNode(this);
}

public void setAtNewline() {
atNewline = true;
}
14 changes: 2 additions & 12 deletions truffle/src/main/java/org/jruby/truffle/nodes/RubyRootNode.java
Original file line number Diff line number Diff line change
@@ -13,10 +13,10 @@
import com.oracle.truffle.api.ExecutionContext;
import com.oracle.truffle.api.frame.FrameDescriptor;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.instrument.Probe;
import com.oracle.truffle.api.nodes.RootNode;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.RubyLanguage;
import org.jruby.truffle.runtime.methods.SharedMethodInfo;

/**
@@ -30,14 +30,12 @@ public class RubyRootNode extends RootNode {
@Child private RubyNode body;
private final boolean needsDeclarationFrame;

private boolean instrumentationApplied = false;

public RubyRootNode(RubyContext context, SourceSection sourceSection, FrameDescriptor frameDescriptor, SharedMethodInfo sharedMethodInfo, RubyNode body) {
this(context, sourceSection, frameDescriptor, sharedMethodInfo, body, false);
}

public RubyRootNode(RubyContext context, SourceSection sourceSection, FrameDescriptor frameDescriptor, SharedMethodInfo sharedMethodInfo, RubyNode body, boolean needsDeclarationFrame) {
super(sourceSection, frameDescriptor);
super(RubyLanguage.class, sourceSection, frameDescriptor);
assert body != null;
this.context = context;
this.body = body;
@@ -78,14 +76,6 @@ public ExecutionContext getExecutionContext() {
return context;
}

@Override
public void applyInstrumentation() {
if (!instrumentationApplied) {
Probe.applyASTProbers(body);
instrumentationApplied = true;
}
}

public boolean needsDeclarationFrame() {
return needsDeclarationFrame;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* 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
*/

package org.jruby.truffle.nodes;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.object.DynamicObject;

public abstract class ShapeCachingGuards {

public static boolean updateShape(DynamicObject object) {
CompilerDirectives.transferToInterpreter();
return object.updateShape();
}

}
Original file line number Diff line number Diff line change
@@ -12,7 +12,6 @@

import com.oracle.truffle.api.object.DynamicObject;
import org.jruby.truffle.runtime.core.StringOperations;
import org.jruby.truffle.runtime.layouts.Layouts;
import org.jruby.util.ByteList;

public abstract class StringCachingGuards {
@@ -27,10 +26,15 @@ public static ByteList privatizeByteList(DynamicObject string) {

public static boolean byteListsEqual(DynamicObject string, ByteList byteList) {
if (RubyGuards.isRubyString(string)) {
// TODO CS 8-Nov-15 this code goes off into the woods - need to break it apart and branch profile it
return StringOperations.getByteList(string).equal(byteList);
} else {
return false;
}
}

public static int byteListLength(ByteList byteList) {
return byteList.length();
}

}
Original file line number Diff line number Diff line change
@@ -13,7 +13,6 @@
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;

import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyArguments;
import org.jruby.truffle.runtime.RubyContext;
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@

import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.utilities.ConditionProfile;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyArguments;
@@ -21,21 +22,22 @@
*/
public class ReadBlockNode extends RubyNode {

private final Object valueIfNotPresent;
private final ConditionProfile hasBlockProfile = ConditionProfile.createBinaryProfile();
private final Object valueIfAbsent;

public ReadBlockNode(RubyContext context, SourceSection sourceSection, Object valueIfNotPresent) {
public ReadBlockNode(RubyContext context, SourceSection sourceSection, Object valueIfAbsent) {
super(context, sourceSection);
this.valueIfNotPresent = valueIfNotPresent;
this.valueIfAbsent = valueIfAbsent;
}

@Override
public Object execute(VirtualFrame frame) {
final DynamicObject block = RubyArguments.getBlock(frame.getArguments());

if (block == null) {
return valueIfNotPresent;
} else {
if (hasBlockProfile.profile(block != null)) {
return block;
} else {
return valueIfAbsent;
}
}

Original file line number Diff line number Diff line change
@@ -10,9 +10,8 @@
package org.jruby.truffle.nodes.arguments;

import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.ConditionProfile;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.NotProvided;
import org.jruby.truffle.runtime.RubyArguments;
Original file line number Diff line number Diff line change
@@ -12,9 +12,9 @@
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.ConditionProfile;
import com.oracle.truffle.api.utilities.ValueProfile;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyArguments;
Original file line number Diff line number Diff line change
@@ -10,8 +10,8 @@
package org.jruby.truffle.nodes.arguments;

import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.BranchProfile;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyArguments;
import org.jruby.truffle.runtime.RubyContext;
Original file line number Diff line number Diff line change
@@ -10,9 +10,9 @@
package org.jruby.truffle.nodes.arguments;

import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.BranchProfile;
import com.oracle.truffle.api.utilities.ValueProfile;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.NotProvided;
import org.jruby.truffle.runtime.RubyArguments;
Original file line number Diff line number Diff line change
@@ -10,8 +10,8 @@
package org.jruby.truffle.nodes.arguments;

import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.ConditionProfile;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyArguments;
import org.jruby.truffle.runtime.RubyContext;
Original file line number Diff line number Diff line change
@@ -10,8 +10,8 @@
package org.jruby.truffle.nodes.arguments;

import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.BranchProfile;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyArguments;
Original file line number Diff line number Diff line change
@@ -10,9 +10,8 @@
package org.jruby.truffle.nodes.arguments;

import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.BranchProfile;

import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.dispatch.RespondToNode;
Original file line number Diff line number Diff line change
@@ -97,7 +97,7 @@ public Object cast(Object nil) {

@Specialization(guards = {"!isNil(object)", "!isRubyBignum(object)", "!isRubyArray(object)"})
public Object cast(VirtualFrame frame, DynamicObject object) {
final Object result = toArrayNode.call(frame, object, "to_ary", null, new Object[]{});
final Object result = toArrayNode.call(frame, object, "to_ary", null);

if (result == DispatchNode.MISSING) {
return nil();
Original file line number Diff line number Diff line change
@@ -75,7 +75,7 @@ public DynamicObject castHash(DynamicObject hash) {

@Specialization(guards = {"!isNil(object)", "!isRubyBignum(object)", "!isRubyHash(object)"})
public Object cast(VirtualFrame frame, DynamicObject object) {
final Object result = toHashNode.call(frame, object, "to_hash", null, new Object[]{});
final Object result = toHashNode.call(frame, object, "to_hash", null);

if (result == DispatchNode.MISSING) {
return nil();
Original file line number Diff line number Diff line change
@@ -17,11 +17,11 @@
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.core.KernelNodes;
import org.jruby.truffle.nodes.core.KernelNodesFactory;
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory;
import org.jruby.truffle.nodes.dispatch.MissingBehavior;
import org.jruby.truffle.nodes.objects.IsANode;
import org.jruby.truffle.nodes.objects.IsANodeGen;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;

@@ -31,14 +31,14 @@
@NodeChild(value = "value", type = RubyNode.class)
public abstract class NumericToFloatNode extends RubyNode {

@Child private KernelNodes.IsANode isANode;
@Child private IsANode isANode;
@Child CallDispatchHeadNode toFloatCallNode;

private final String method;

public NumericToFloatNode(RubyContext context, SourceSection sourceSection, String method) {
super(context, sourceSection);
isANode = KernelNodesFactory.IsANodeFactory.create(context, sourceSection, new RubyNode[] { null, null });
isANode = IsANodeGen.create(context, sourceSection, null, null);
this.method = method;
}

@@ -71,7 +71,7 @@ protected double fallback(Object value) {
}

protected boolean isNumeric(VirtualFrame frame, Object value) {
return isANode.executeIsA(frame, value, getContext().getCoreLibrary().getNumericClass());
return isANode.executeIsA(value, getContext().getCoreLibrary().getNumericClass());
}

}
Original file line number Diff line number Diff line change
@@ -15,7 +15,6 @@
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;

import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.core.array.ArrayDupNode;
Original file line number Diff line number Diff line change
@@ -15,8 +15,8 @@
import com.oracle.truffle.api.nodes.ControlFlowException;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.ConditionProfile;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.objects.IsTaintedNode;
import org.jruby.truffle.nodes.objects.IsTaintedNodeGen;
Original file line number Diff line number Diff line change
@@ -16,8 +16,8 @@
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.ConditionProfile;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.core.FloatNodes;
Original file line number Diff line number Diff line change
@@ -10,12 +10,12 @@
package org.jruby.truffle.nodes.coerce;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;

import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
@@ -30,11 +30,8 @@
@NodeChild("child")
public abstract class ToProcNode extends RubyNode {

@Child private CallDispatchHeadNode toProc;

public ToProcNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
toProc = DispatchHeadNodeFactory.createMethodCall(context);
}

@Specialization(guards = "isNil(nil)")
@@ -48,7 +45,8 @@ public DynamicObject doRubyProc(DynamicObject proc) {
}

@Specialization(guards = "!isRubyProc(object)")
public DynamicObject doObject(VirtualFrame frame, Object object) {
public DynamicObject doObject(VirtualFrame frame, Object object,
@Cached("createCallNode()") CallDispatchHeadNode toProc) {
final Object coerced;
try {
coerced = toProc.call(frame, object, "to_proc", null);
@@ -69,4 +67,8 @@ public DynamicObject doObject(VirtualFrame frame, Object object) {
}
}

protected CallDispatchHeadNode createCallNode() {
return DispatchHeadNodeFactory.createMethodCall(getContext());
}

}
Original file line number Diff line number Diff line change
@@ -16,8 +16,8 @@
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.ConditionProfile;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.core.KernelNodes.RequireNode;
import org.jruby.truffle.nodes.core.KernelNodesFactory;
Original file line number Diff line number Diff line change
@@ -18,8 +18,8 @@
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.ConditionProfile;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.LexicalScope;
import org.jruby.truffle.runtime.ModuleOperations;
Original file line number Diff line number Diff line change
@@ -11,7 +11,6 @@

import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;

import org.jcodings.specific.UTF8Encoding;
import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.nodes.RubyNode;
Original file line number Diff line number Diff line change
@@ -10,8 +10,8 @@
package org.jruby.truffle.nodes.control;

import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.ConditionProfile;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.cast.BooleanCastNode;
import org.jruby.truffle.nodes.cast.BooleanCastNodeGen;
Original file line number Diff line number Diff line change
@@ -10,9 +10,8 @@
package org.jruby.truffle.nodes.control;

import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.ConditionProfile;

import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.cast.BooleanCastNode;
import org.jruby.truffle.nodes.cast.BooleanCastNodeGen;
Original file line number Diff line number Diff line change
@@ -10,8 +10,8 @@
package org.jruby.truffle.nodes.control;

import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.ConditionProfile;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.cast.BooleanCastNode;
import org.jruby.truffle.nodes.cast.BooleanCastNodeGen;
100 changes: 0 additions & 100 deletions truffle/src/main/java/org/jruby/truffle/nodes/control/TraceNode.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -14,8 +14,8 @@
import com.oracle.truffle.api.nodes.LoopNode;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.RepeatingNode;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.BranchProfile;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.cast.BooleanCastNode;
import org.jruby.truffle.nodes.cast.BooleanCastNodeGen;
Original file line number Diff line number Diff line change
@@ -17,7 +17,6 @@
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.StringOperations;
import org.jruby.truffle.runtime.layouts.Layouts;

@NodeChild(value="child", type=RubyNode.class)
public abstract class ToSymbolNode extends RubyNode {
Original file line number Diff line number Diff line change
@@ -10,23 +10,19 @@
package org.jruby.truffle.nodes.core;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.dsl.CreateCast;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.NodeUtil;
import com.oracle.truffle.api.nodes.Node.Child;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;

import org.jruby.runtime.Visibility;
import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.cast.BooleanCastNodeGen;
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory;
import org.jruby.truffle.nodes.dispatch.DispatchNode;
import org.jruby.truffle.nodes.dispatch.MissingBehavior;
import org.jruby.truffle.nodes.dispatch.RubyCallNode;
import org.jruby.truffle.nodes.methods.DeclarationContext;
@@ -39,7 +35,6 @@
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.StringOperations;
import org.jruby.truffle.runtime.layouts.Layouts;
import org.jruby.truffle.runtime.methods.InternalMethod;

@CoreClass(name = "BasicObject")
Original file line number Diff line number Diff line change
@@ -14,9 +14,8 @@
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.BranchProfile;

import com.oracle.truffle.api.source.SourceSection;
import org.jcodings.specific.USASCIIEncoding;
import org.jruby.truffle.nodes.cast.BooleanCastNode;
import org.jruby.truffle.nodes.cast.BooleanCastNodeGen;
@@ -27,7 +26,6 @@
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.StringOperations;
import org.jruby.truffle.runtime.layouts.Layouts;
import org.jruby.util.StringSupport;

import java.math.BigInteger;

@@ -40,10 +38,13 @@ public static abstract class BignumCoreMethodNode extends CoreMethodArrayArgumen

public BignumCoreMethodNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
fixnumOrBignum = new FixnumOrBignumNode(context, sourceSection);
}

public Object fixnumOrBignum(BigInteger value) {
if (fixnumOrBignum == null) {
CompilerDirectives.transferToInterpreter();
fixnumOrBignum = insert(new FixnumOrBignumNode(getContext(), getSourceSection()));
}
return fixnumOrBignum.fixnumOrBignum(value);
}

Original file line number Diff line number Diff line change
@@ -20,7 +20,6 @@
import com.oracle.truffle.api.frame.MaterializedFrame;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;

import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.nodes.locals.ReadFrameSlotNode;
import org.jruby.truffle.nodes.locals.ReadFrameSlotNodeGen;
@@ -50,11 +49,16 @@ public static DynamicObject createBinding(RubyContext context, MaterializedFrame
RubyArguments.getBlock(arguments),
RubyArguments.getDeclarationContext(arguments),
RubyArguments.extractUserArguments(arguments)),
new FrameDescriptor(context.getCoreLibrary().getNilObject()));
newFrameDescriptor(context));

return Layouts.BINDING.createBinding(context.getCoreLibrary().getBindingFactory(), bindingFrame);
}

@TruffleBoundary
private static FrameDescriptor newFrameDescriptor(RubyContext context) {
return new FrameDescriptor(context.getCoreLibrary().getNilObject());
}

public static FrameDescriptor getFrameDescriptor(DynamicObject binding) {
assert RubyGuards.isRubyBinding(binding);
return Layouts.BINDING.getFrame(binding).getFrameDescriptor();
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@

import com.oracle.truffle.api.CompilerAsserts;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
@@ -33,6 +34,7 @@ public abstract class ClassNodes {
private final static com.oracle.truffle.api.object.Layout LAYOUT = com.oracle.truffle.api.object.Layout.createLayout();

/** Special constructor for class Class */
@TruffleBoundary
public static DynamicObject createClassClass(RubyContext context) {
final ModuleFields model = new ModuleFields(context, null, "Class");

@@ -61,6 +63,7 @@ public static DynamicObject createClassClass(RubyContext context) {
* This constructor supports initialization and solves boot-order problems and should not
* normally be used from outside this class.
*/
@TruffleBoundary
public static DynamicObject createBootClass(RubyContext context, DynamicObject classClass, DynamicObject superclass, String name) {
assert RubyGuards.isRubyClass(classClass);
assert superclass == null || RubyGuards.isRubyClass(superclass);
@@ -91,6 +94,7 @@ public static DynamicObject createBootClass(RubyContext context, DynamicObject c
return rubyClass;
}

@TruffleBoundary
public static DynamicObject createSingletonClassOfObject(RubyContext context, DynamicObject superclass, DynamicObject attached, String name) {
// We also need to create the singleton class of a singleton class for proper lookup and consistency.
// See rb_singleton_class() documentation in MRI.
@@ -100,12 +104,14 @@ public static DynamicObject createSingletonClassOfObject(RubyContext context, Dy
return ensureSingletonConsistency(context, createRubyClass(context, Layouts.BASIC_OBJECT.getLogicalClass(superclass), null, superclass, name, true, attached));
}

@TruffleBoundary
public static DynamicObject createRubyClass(RubyContext context, DynamicObject lexicalParent, DynamicObject superclass, String name) {
final DynamicObject rubyClass = createRubyClass(context, Layouts.BASIC_OBJECT.getLogicalClass(superclass), lexicalParent, superclass, name, false, null);
ensureSingletonConsistency(context, rubyClass);
return rubyClass;
}

@TruffleBoundary
public static DynamicObject createRubyClass(RubyContext context, DynamicObject classClass, DynamicObject lexicalParent, DynamicObject superclass, String name, boolean isSingleton, DynamicObject attached) {
final ModuleFields model = new ModuleFields(context, lexicalParent, name);

@@ -138,7 +144,7 @@ public static DynamicObject createRubyClass(RubyContext context, DynamicObject c
return rubyClass;
}


@TruffleBoundary
public static void initialize(RubyContext context, DynamicObject rubyClass, DynamicObject superclass) {
assert RubyGuards.isRubyClass(superclass);

Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.nodes.NodeUtil;
import com.oracle.truffle.api.object.DynamicObject;

import com.oracle.truffle.api.source.SourceSection;
import org.jruby.runtime.Visibility;
import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.nodes.RubyNode;
@@ -146,7 +146,7 @@ private static void addMethod(RubyContext context, DynamicObject module, RubyRoo
private static RubyRootNode makeGenericMethod(RubyContext context, MethodDetails methodDetails) {
final CoreMethod method = methodDetails.getMethodAnnotation();

final CoreSourceSection sourceSection = new CoreSourceSection(methodDetails.getClassAnnotation().name(), method.names()[0]);
final SourceSection sourceSection = CoreSourceSection.createCoreSourceSection(methodDetails.getClassAnnotation().name(), method.names()[0]);

final int required = method.required();
final int optional = method.optional();
Original file line number Diff line number Diff line change
@@ -29,7 +29,6 @@
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.layouts.Layouts;
import org.jruby.util.ByteList;
import org.jruby.util.StringSupport;
import org.jruby.util.io.EncodingUtils;

@CoreClass(name = "Encoding::Converter")
Original file line number Diff line number Diff line change
@@ -16,8 +16,6 @@
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;

import com.oracle.truffle.api.utilities.ConditionProfile;
import org.jcodings.Encoding;
import org.jcodings.EncodingDB;
import org.jcodings.specific.ASCIIEncoding;
@@ -35,7 +33,6 @@
import org.jruby.truffle.runtime.core.StringOperations;
import org.jruby.truffle.runtime.layouts.Layouts;
import org.jruby.util.ByteList;
import org.jruby.util.StringSupport;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
Original file line number Diff line number Diff line change
@@ -23,6 +23,7 @@
import org.jruby.truffle.runtime.backtrace.BacktraceFormatter;
import org.jruby.truffle.runtime.core.StringOperations;
import org.jruby.truffle.runtime.layouts.Layouts;

import java.util.EnumSet;
import java.util.List;

Original file line number Diff line number Diff line change
@@ -17,7 +17,6 @@
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;

import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.cast.SingleValueCastNode;
Original file line number Diff line number Diff line change
@@ -11,9 +11,8 @@

import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.ConditionProfile;

import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.CoreLibrary;
Original file line number Diff line number Diff line change
@@ -15,9 +15,8 @@
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.ConditionProfile;

import com.oracle.truffle.api.source.SourceSection;
import org.jcodings.specific.USASCIIEncoding;
import org.jruby.runtime.Visibility;
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
Original file line number Diff line number Diff line change
@@ -12,8 +12,8 @@
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.BranchProfile;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
Original file line number Diff line number Diff line change
@@ -9,12 +9,10 @@
*/
package org.jruby.truffle.nodes.core;

import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.ExplodeLoop;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.ConditionProfile;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.cast.ToSNode;
@@ -25,8 +23,6 @@
import org.jruby.truffle.nodes.objects.TaintNode;
import org.jruby.truffle.nodes.objects.TaintNodeGen;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.layouts.Layouts;

/**
* A list of expressions to build up into a string.
Loading

0 comments on commit 8701a48

Please sign in to comment.