Skip to content

Commit

Permalink
Showing 13 changed files with 156 additions and 173 deletions.
4 changes: 2 additions & 2 deletions ci.hocon
Original file line number Diff line number Diff line change
@@ -47,7 +47,7 @@ graal-core: {
]

environment: {
GRAAL_BIN: graal-workspace/jvmci/jdk1.8.0_60/product/bin/java,
GRAALVM_BIN: graal-workspace/jvmci/jdk1.8.0_60/product/bin/java, // temporarily looks like GraalVM - will use GRAAL_HOME later
HOST_VM: server,
HOST_VM_CONFIG: graal-core
}
@@ -63,7 +63,7 @@ graalvm: {
}

environment: {
GRAAL_BIN: "$GRAALVM_DIR/bin/java"
GRAALVM_BIN: "$GRAALVM_DIR/bin/java"
HOST_VM: server,
HOST_VM_CONFIG: graal-enterprise
}
4 changes: 1 addition & 3 deletions core/src/main/java/org/jruby/Ruby.java
Original file line number Diff line number Diff line change
@@ -4782,15 +4782,13 @@ public ProfiledMethods getProfiledMethods() {
*
* @param name the name of the method
* @param method
* @deprecated This should be an implementation detail of the ProfilingService and should remove from the Ruby class.
*/
@Deprecated
@SuppressWarnings("deprecation")
void addProfiledMethod(final String name, final DynamicMethod method) {
if (!config.isProfiling()) return;
if (method.isUndefined()) return;

getProfiledMethods().addProfiledMethod( name, method );

}

/**
6 changes: 3 additions & 3 deletions core/src/main/java/org/jruby/RubyArray.java
Original file line number Diff line number Diff line change
@@ -4058,10 +4058,10 @@ public IRubyObject rotate(ThreadContext context, IRubyObject cnt) {
return internalRotate(context, RubyNumeric.fix2int(cnt));
}


// Enumerable direct implementations (non-"each" versions)
// NOTE: not a @JRubyMethod(name = "all?") as there's no Array#all? on MRI
public IRubyObject all_p(ThreadContext context, Block block) {
if (!isBuiltin("each")) return RubyEnumerable.all_pCommon(context, this, block, Arity.OPTIONAL);
if (!isBuiltin("each")) return RubyEnumerable.all_pCommon(context, this, block);
if (!block.isGiven()) return all_pBlockless(context);

for (int i = 0; i < realLength; i++) {
@@ -4082,7 +4082,7 @@ private IRubyObject all_pBlockless(ThreadContext context) {
@JRubyMethod(name = "any?")
public IRubyObject any_p(ThreadContext context, Block block) {
if (isEmpty()) return context.runtime.getFalse();
if (!isBuiltin("each")) return RubyEnumerable.any_pCommon(context, this, block, Arity.OPTIONAL);
if (!isBuiltin("each")) return RubyEnumerable.any_pCommon(context, this, block);
if (!block.isGiven()) return any_pBlockless(context);

for (int i = 0; i < realLength; i++) {
78 changes: 26 additions & 52 deletions core/src/main/java/org/jruby/RubyEnumerable.java
Original file line number Diff line number Diff line change
@@ -174,6 +174,7 @@ public IRubyObject yield(ThreadContext context, IRubyObject[] unusedValue) {
return RubyFixnum.newFixnum(runtime, result[0]);
}

@Deprecated
public static IRubyObject count18(ThreadContext context, IRubyObject self, final IRubyObject methodArg, final Block block) {
return count(context, self, methodArg, block);
}
@@ -190,7 +191,7 @@ public IRubyObject yield(ThreadContext context, IRubyObject[] args) {
IRubyObject packedArg = packEnumValues(context.runtime, args);
if (packedArg.equals(methodArg)) result[0]++;

return runtime.getNil();
return context.nil;
}
});

@@ -432,15 +433,16 @@ public IRubyObject yield(ThreadContext context, IRubyObject[] args) {
return result;
}

@JRubyMethod(name = {"to_a", "entries"})
public static IRubyObject to_a(ThreadContext context, IRubyObject self) {
return to_a19(context, self);
}

@JRubyMethod(name = {"to_a", "entries"}, rest = true)
public static IRubyObject to_a(ThreadContext context, IRubyObject self, IRubyObject[] args) {
return to_a19(context, self, args);
}

@JRubyMethod(name = {"to_a", "entries"})
public static IRubyObject to_a19(ThreadContext context, IRubyObject self) {
Ruby runtime = context.runtime;
RubyArray result = runtime.newArray();
@@ -449,7 +451,6 @@ public static IRubyObject to_a19(ThreadContext context, IRubyObject self) {
return result;
}

@JRubyMethod(name = {"to_a", "entries"}, rest = true)
public static IRubyObject to_a19(ThreadContext context, IRubyObject self, IRubyObject[] args) {
final Ruby runtime = context.runtime;
final RubyArray result = runtime.newArray();
@@ -1365,6 +1366,7 @@ public IRubyObject call(ThreadContext ctx, IRubyObject[] largs, Block blk) {
return runtime.newArrayNoCopy(result);
}

@JRubyMethod(name = "none?")
public static IRubyObject none_p(ThreadContext context, IRubyObject self, final Block block) {
final Ruby runtime = context.runtime;
final ThreadContext localContext = context;
@@ -1396,7 +1398,6 @@ public IRubyObject call(ThreadContext ctx, IRubyObject[] largs, Block blk) {
return runtime.getTrue();
}

@JRubyMethod(name = "none?")
public static IRubyObject none_p19(ThreadContext context, IRubyObject self, final Block block) {
return none_p(context, self, block);
}
@@ -1431,6 +1432,7 @@ public IRubyObject call(ThreadContext ctx, IRubyObject[] largs, Block blk) {
return runtime.getTrue();
}

@JRubyMethod(name = "one?")
public static IRubyObject one_p(ThreadContext context, IRubyObject self, final Block block) {
final Ruby runtime = context.runtime;
final ThreadContext localContext = context;
@@ -1474,7 +1476,6 @@ public IRubyObject call(ThreadContext ctx, IRubyObject[] largs, Block blk) {
return result[0] ? runtime.getTrue() : runtime.getFalse();
}

@JRubyMethod(name = "one?")
public static IRubyObject one_p19(ThreadContext context, IRubyObject self, final Block block) {
return one_p(context, self, block);
}
@@ -1522,73 +1523,46 @@ public IRubyObject call(ThreadContext ctx, IRubyObject[] largs, Block blk) {
return result[0] ? runtime.getTrue() : runtime.getFalse();
}

@JRubyMethod(name = "all?")
public static IRubyObject all_p(ThreadContext context, IRubyObject self, final Block block) {
final Ruby runtime = context.runtime;
final ThreadContext localContext = context;

try {
if (block.isGiven()) {
callEach(runtime, context, self, block.getSignature(), new BlockCallback() {
public IRubyObject call(ThreadContext ctx, IRubyObject[] largs, Block blk) {
checkContext(localContext, ctx, "all?");
IRubyObject larg = packEnumValues(runtime, largs);
if (!block.yield(ctx, larg).isTrue()) {
throw JumpException.SPECIAL_JUMP;
}
return runtime.getNil();
}
});
} else {
callEach(runtime, context, self, Signature.ONE_REQUIRED, new BlockCallback() {
public IRubyObject call(ThreadContext ctx, IRubyObject[] largs, Block blk) {
checkContext(localContext, ctx, "all?");
IRubyObject larg = packEnumValues(runtime, largs);
if (!larg.isTrue()) {
throw JumpException.SPECIAL_JUMP;
}
return runtime.getNil();
}
});
}
} catch (JumpException.SpecialJump sj) {
return runtime.getFalse();
}

return runtime.getTrue();
if (self instanceof RubyArray) return ((RubyArray) self).all_p(context, block);
return all_pCommon(context, self, block);
}

@JRubyMethod(name = "all?")
public static IRubyObject all_p19(ThreadContext context, IRubyObject self, final Block block) {
if (self instanceof RubyArray) return ((RubyArray) self).all_p(context, block);

return all_p(context, self, block);
}

@Deprecated
public static IRubyObject all_pCommon(final ThreadContext context, IRubyObject self, final Block block, Arity callbackArity) {
return all_pCommon(context, self, block);
}

public static IRubyObject all_pCommon(ThreadContext context, IRubyObject self, final Block block) {
final Ruby runtime = context.runtime;
final ThreadContext localContext = context;

try {
if (block.isGiven()) {
callEach(runtime, context, self, callbackArity, new BlockCallback() {
public IRubyObject call(ThreadContext ctx, IRubyObject[] largs, Block blk) {
checkContext(context, ctx, "all?");
IRubyObject larg = packEnumValues(ctx, largs);
if (!block.yield(ctx, larg).isTrue()) {
callEach(runtime, context, self, block.getSignature(), new BlockCallback() {
public IRubyObject call(ThreadContext context, IRubyObject[] largs, Block blk) {
checkContext(localContext, context, "all?");
IRubyObject larg = packEnumValues(runtime, largs);
if (!block.yield(context, larg).isTrue()) {
throw JumpException.SPECIAL_JUMP;
}
return ctx.nil;
return context.nil;
}
});
} else {
callEach(runtime, context, self, Signature.ONE_REQUIRED, new BlockCallback() {
public IRubyObject call(ThreadContext ctx, IRubyObject[] largs, Block blk) {
checkContext(context, ctx, "all?");
IRubyObject larg = packEnumValues(ctx, largs);
public IRubyObject call(ThreadContext context, IRubyObject[] largs, Block blk) {
checkContext(localContext, context, "all?");
IRubyObject larg = packEnumValues(runtime, largs);
if (!larg.isTrue()) {
throw JumpException.SPECIAL_JUMP;
}
return ctx.nil;
return context.nil;
}
});
}
@@ -1618,15 +1592,15 @@ public static IRubyObject any_pCommon(ThreadContext context, IRubyObject self, f
public IRubyObject yield(ThreadContext context, IRubyObject[] args) {
IRubyObject packedArg = packEnumValues(context, args);
if (block.yield(context, packedArg).isTrue()) throw JumpException.SPECIAL_JUMP;
return runtime.getNil();
return context.nil;
}
});
} else {
each(context, self, new JavaInternalBlockBody(runtime, context, "Enumerable#any?", Signature.ONE_REQUIRED) {
public IRubyObject yield(ThreadContext context, IRubyObject[] args) {
IRubyObject packedArg = packEnumValues(context.runtime, args);
if (packedArg.isTrue()) throw JumpException.SPECIAL_JUMP;
return runtime.getNil();
return context.nil;
}
});
}
6 changes: 2 additions & 4 deletions core/src/main/java/org/jruby/runtime/ThreadContext.java
Original file line number Diff line number Diff line change
@@ -1080,10 +1080,8 @@ public int profileEnter(int nextMethod) {
}

public int profileEnter(String name, DynamicMethod nextMethod) {
if (isProfiling()) {
// TODO This can be removed, because the profiled method will be added in the MethodEnhancer if necessary
getRuntime().getProfiledMethods().addProfiledMethod( name, nextMethod );
}
// profiled method is added in the MethodEnhancer (if necessary)
// @see BuiltinProfilingService.DefaultMethodEnhancer
return profileEnter((int) nextMethod.getSerialNumber());
}

Original file line number Diff line number Diff line change
@@ -15,15 +15,15 @@

public abstract class CachingCallSite extends CallSite {
protected CacheEntry cache = CacheEntry.NULL_CACHE;
public static volatile int totalCallSites;
// private AtomicBoolean isPolymorphic = new AtomicBoolean(false);
//public static volatile int totalCallSites;
//private AtomicBoolean isPolymorphic = new AtomicBoolean(false);

public CachingCallSite(String methodName, CallType callType) {
super(methodName, callType);
totalCallSites++;
//totalCallSites++;
}

public CacheEntry getCache() {
public final CacheEntry getCache() {
return cache;
}

@@ -39,7 +39,7 @@ public int getCachedClassIndex() {
return ClassIndex.NO_INDEX.ordinal();
}

public String getMethodName() {
public final String getMethodName() {
return methodName;
}

Original file line number Diff line number Diff line change
@@ -74,6 +74,7 @@ private Ruby getRuntime() {
}

@Override
@SuppressWarnings("deprecation")
public DynamicMethod enhance( String name, DynamicMethod delegate ) {
getRuntime().getProfiledMethods().addProfiledMethod( name, delegate );
return new ProfilingDynamicMethod(delegate);
@@ -95,12 +96,8 @@ public DefaultProfileReporter(ThreadContext context) {
this.context = context;
}

private ThreadContext getThreadContext() {
return context;
}

private Ruby getRuntime() {
return getThreadContext().getRuntime();
return context.runtime;
}

private RubyInstanceConfig getConfig() {
4 changes: 0 additions & 4 deletions spec/truffle/tags/core/process/spawn_tags.txt
Original file line number Diff line number Diff line change
@@ -25,11 +25,7 @@ fails:Process.spawn raises a TypeError if given a symbol as :pgroup option
fails:Process.spawn uses the current working directory as its working directory
fails:Process.spawn uses the current umask by default
fails:Process.spawn sets the umask if given the :umask option
fails:Process.spawn redirects STDOUT to the given file descriptior if out: Fixnum
fails:Process.spawn redirects STDOUT to the given file if out: IO
fails:Process.spawn redirects STDOUT to the given file if out: String
fails:Process.spawn redirects STDERR to the given file descriptior if err: Fixnum
fails:Process.spawn redirects STDERR to the given file descriptor if err: IO
fails:Process.spawn redirects STDERR to the given file if err: String
fails:Process.spawn redirects both STDERR and STDOUT to the given file descriptior
fails:Process.spawn redirects both STDERR and STDOUT to the given IO
2 changes: 1 addition & 1 deletion spec/truffle/truffle.mspec
Original file line number Diff line number Diff line change
@@ -13,7 +13,7 @@ class MSpecScript
set :target, File.expand_path("../../../bin/jruby#{windows? ? '.bat' : ''}", __FILE__)

if ARGV[-2..-1] != %w[-t ruby] # No flags for MRI
set :flags, %w[-X+T -J-ea -J-esa -J-Xmx2G]
set :flags, %w[-X+T -J-ea -J-esa -J-Xmx2G -Xtruffle.graal.warn_unless=false]
end

set :capi, [
130 changes: 46 additions & 84 deletions tool/jt.rb
Original file line number Diff line number Diff line change
@@ -40,33 +40,31 @@ def self.truffle_version
end
end
end

def self.graal_locations
from_env = ENV['GRAAL_BIN']
yield File.expand_path(from_env) if from_env

from_branch = ENV["GRAAL_BIN_#{mangle_for_env(git_branch)}"]
yield File.expand_path(from_branch) if from_branch

rel_java_bin = "bin/java" # "jre/bin/javao"
['', '../', '../../'].each do |prefix|
%w[dk re].each do |kind|
path = "#{prefix}graalvm-#{GRAALVM_VERSION}-#{kind}/#{rel_java_bin}"
yield File.expand_path(path, JRUBY_DIR)

def self.find_graal_javacmd_and_options
graalvm_bin_var = ENV['GRAALVM_BIN'] || ENV["GRAALVM_BIN_#{mangle_for_env(git_branch)}"]
graal_home_var = ENV['GRAAL_HOME'] || ENV["GRAAL_HOME_#{mangle_for_env(git_branch)}"]

if graalvm_bin_var
javacmd = File.expand_path(graalvm_bin_var)
options = []
elsif graal_home_var
graal_home = File.expand_path(graal_home_var)
if ENV['JVMCI_JAVA_HOME']
mx_options = "--java-home #{ENV['JVMCI_JAVA_HOME']}"
else
mx_options = ''
end
p "mx -v #{mx_options} -p #{graal_home} vm -version 2>/dev/null"
command_line = `mx -v #{mx_options} -p #{graal_home} vm -version 2>/dev/null`.lines.last
vm_args = command_line.split
vm_args.pop # Drop "-version"
javacmd = vm_args.shift
options = vm_args.map { |arg| "-J#{arg}" }
else
raise 'set one of GRAALVM_BIN or GRAAL_HOME in order to use Graal'
end

['', '../', '../../'].each do |prefix|
path = Dir["#{prefix}graal/jvmci/jdk1.8.*/product/#{rel_java_bin}"].sort.last
yield File.expand_path(path, JRUBY_DIR) if path
end
end

def self.find_graal
graal_locations do |location|
return location if File.executable?(location)
end
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"
[javacmd, options]
end

def self.find_sulong_graal(dir)
@@ -174,50 +172,12 @@ def self.mangle_for_env(name)
name.upcase.tr('-', '_')
end

def self.find_jvmci
jvmci_locations = [
ENV['JVMCI_DIR'],
ENV["JVMCI_DIR#{mangle_for_env(git_branch)}"]
].compact.map { |path| File.expand_path(path, JRUBY_DIR) }

not_found = -> {
raise "couldn't find JVMCI"
}

jvmci_locations.find(not_found) do |location|
Dir.exist?(location)
end
end

def self.igv_running?
`ps ax`.include?('idealgraphvisualizer')
end

def self.ensure_igv_running
unless igv_running?
Dir.chdir(find_jvmci) do
spawn 'mx --vm server igv', pgroup: true
end

puts
puts
puts "-------------"
puts "Waiting for IGV start"
puts "The first time you run IGV it may take several minutes to download dependencies and compile"
puts "-------------"
puts
puts

sleep 3

until igv_running?
puts 'still waiting for IGV to appear in ps ax...'
sleep 3
end

puts 'just a few more seconds...'
sleep 6
end
abort "I can't see IGV running - go to your checkout of Graal and run 'mx igv' in a separate shell, then run this command again" unless igv_running?
end

def self.jruby_version
@@ -375,7 +335,7 @@ def help
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 ' --graal use Graal (set either GRAALVM_BIN or GRAAL_HOME and maybe JVMCI_JAVA_HOME)'
puts ' --js add Graal.js to the classpath (set GRAAL_JS_JAR)'
puts ' --sulong add Sulong to the classpath (set SULONG_DIR, implies --graal but finds it from the SULONG_DIR)'
puts ' --asm show assembly (implies --graal)'
@@ -423,11 +383,13 @@ def help
puts 'recognised environment variables:'
puts
puts ' RUBY_BIN The JRuby+Truffle executable to use (normally just bin/jruby)'
puts ' GRAAL_BIN GraalVM executable (java command) to use'
puts ' GRAAL_BIN_...git_branch_name... GraalVM executable to use for a given branch'
puts ' branch names are mangled - eg truffle-head becomes GRAAL_BIN_TRUFFLE_HEAD'
puts ' JVMCI_DIR JMVCI repository checkout to use when running IGV (mx must already be on the $PATH)'
puts ' JVMCI_DIR_...git_branch_name... JMVCI repository to use for a given branch'
puts ' GRAALVM_BIN GraalVM executable (java command) to use'
puts ' GRAALVM_BIN_...git_branch_name... GraalVM executable to use for a given branch'
puts ' branch names are mangled - eg truffle-head becomes GRAALVM_BIN_TRUFFLE_HEAD'
puts ' GRAAL_HOME Directory where there is a built checkout of the Graal compiler (make sure mx is on your path and maybe set JVMCI_JAVA_HOME)'
puts ' GRAAL_HOME_...git_branch_name...'
puts ' JVMCI_JAVA The Java with JVMCI to use with GRAAL_HOME'
puts ' JVMCI_JAVA_...git_branch_name...'
puts ' GRAAL_JS_JAR The location of trufflejs.jar'
puts ' SL_JAR The location of truffle-sl.jar'
puts ' SULONG_DIR The location of a built checkout of the Sulong repository'
@@ -492,18 +454,9 @@ def run(*args)
end

if args.delete('--graal')
if graal_home = ENV["GRAAL_HOME"]
graal_home = File.expand_path(graal_home)
command_line = `mx -v -p #{graal_home} vm -version 2>/dev/null`.lines.last
vm_args = command_line.split
vm_args.pop # Drop "-version"
graal_bin = vm_args.shift
jruby_args = vm_args.map { |arg| "-J#{arg}" } + jruby_args
else
graal_bin = Utilities.find_graal
end

env_vars["JAVACMD"] = graal_bin
javacmd, javacmd_options = Utilities.find_graal_javacmd_and_options
env_vars["JAVACMD"] = javacmd
jruby_args.push *javacmd_options
jruby_args.delete('-Xtruffle.graal.warn_unless=false')
end

@@ -628,8 +581,15 @@ def test_compiler(*args)

jruby_opts << '-Xtruffle.exceptions.print_java=true'

no_java_cmd = args.delete('--no-java-cmd')

unless no_java_cmd
javacmd, javacmd_options = Utilities.find_graal_javacmd_and_options
jruby_opts.push *javacmd_options
end

env_vars = {}
env_vars["JAVACMD"] = Utilities.find_graal unless args.delete('--no-java-cmd')
env_vars["JAVACMD"] = javacmd unless no_java_cmd
env_vars["JRUBY_OPTS"] = jruby_opts.join(' ')
env_vars["PATH"] = "#{Utilities.find_jruby_bin_dir}:#{ENV["PATH"]}"

@@ -758,7 +718,9 @@ def test_specs(command, *args)
end

if args.delete('--graal')
env_vars["JAVACMD"] = Utilities.find_graal
javacmd, javacmd_options = Utilities.find_graal_javacmd_and_options
env_vars["JAVACMD"] = javacmd
options.push *javacmd_options
options << '-T-J-server'
end

Original file line number Diff line number Diff line change
@@ -18,31 +18,39 @@
import org.jruby.truffle.builtins.CoreMethod;
import org.jruby.truffle.builtins.CoreMethodArrayArgumentsNode;
import org.jruby.truffle.core.array.ArrayOperations;
import org.jruby.truffle.core.hash.HashOperations;
import org.jruby.truffle.core.string.StringOperations;
import org.jruby.truffle.language.control.RaiseException;
import org.jruby.truffle.platform.UnsafeGroup;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Map.Entry;

@CoreClass("Truffle::Process")
public abstract class TruffleProcessNodes {

@CoreMethod(names = "spawn", onSingleton = true, required = 3, unsafe = UnsafeGroup.PROCESSES)
@CoreMethod(names = "spawn", onSingleton = true, required = 4, unsafe = UnsafeGroup.PROCESSES)
public abstract static class SpawnNode extends CoreMethodArrayArgumentsNode {

@Specialization(guards = {
"isRubyString(command)",
"isRubyArray(arguments)",
"isRubyArray(environmentVariables)" })
"isRubyArray(environmentVariables)",
"isRubyHash(options)" })
public int spawn(DynamicObject command,
DynamicObject arguments,
DynamicObject environmentVariables) {
DynamicObject environmentVariables,
DynamicObject options) {

Collection<SpawnFileAction> fileActions = parseOptions(options);

final long longPid = call(
StringOperations.getString(getContext(), command),
toStringArray(arguments),
toStringArray(environmentVariables));
toStringArray(environmentVariables),
fileActions);
assert longPid <= Integer.MAX_VALUE;
// VMWaitPidPrimitiveNode accepts only int
final int pid = (int) longPid;
@@ -69,11 +77,44 @@ private String[] toStringArray(DynamicObject rubyStrings) {
}

@TruffleBoundary
private long call(String command, String[] arguments, String[] environmentVariables) {
private Collection<SpawnFileAction> parseOptions(DynamicObject options) {
if (Layouts.HASH.getSize(options) == 0) {
return Collections.emptyList();
}

Collection<SpawnFileAction> actions = new ArrayList<>();
for (Entry<Object, Object> keyValue : HashOperations.iterableKeyValues(options)) {
final Object key = keyValue.getKey();
final Object value = keyValue.getValue();

if (Layouts.SYMBOL.isSymbol(key)) {
if (key == getSymbol("redirect_fd")) {
assert Layouts.ARRAY.isArray(value);
final DynamicObject array = (DynamicObject) value;
final int size = Layouts.ARRAY.getSize(array);
assert size % 2 == 0;
final Object[] store = ArrayOperations.toObjectArray(array);
for (int i = 0; i < size; i += 2) {
int from = (int) store[i];
int to = (int) store[i + 1];
actions.add(SpawnFileAction.dup(to, from));
actions.add(SpawnFileAction.close(to));
}
continue;
}
}
throw new UnsupportedOperationException("Unsupported spawn option: " + key + " => " + value);
}

return actions;
}

@TruffleBoundary
private long call(String command, String[] arguments, String[] environmentVariables, Collection<SpawnFileAction> fileActions) {
// TODO (pitr 04-Sep-2015): only simple implementation, does not support file actions or other options
return getContext().getNativePlatform().getPosix().posix_spawnp(
command,
Collections.<SpawnFileAction>emptyList(),
fileActions,
Arrays.asList(arguments),
Arrays.asList(environmentVariables));

2 changes: 2 additions & 0 deletions truffle/src/main/ruby/core/io.rb
Original file line number Diff line number Diff line change
@@ -1914,6 +1914,8 @@ def pid
@pid
end

attr_writer :pid

def pipe=(v)
@pipe = !!v
end
21 changes: 18 additions & 3 deletions truffle/src/main/ruby/core/process_mirror.rb
Original file line number Diff line number Diff line change
@@ -230,6 +230,19 @@ def default_mode(target)
end
end

def convert_file_mode(obj)
case obj
when ::Fixnum
obj
when ::String
OFLAGS[obj]
when nil
OFLAGS["r"]
else
Rubinius::Type.coerce_to obj, Integer, :to_int
end
end

# Mapping of string open modes to integer oflag versions.
OFLAGS = {
"r" => ::File::RDONLY,
@@ -242,16 +255,18 @@ def default_mode(target)

def spawn(options, command, arguments)
options ||= {}
env = options[:unsetenv_others] ? {} : ENV.to_hash
env.merge! Hash[options[:env]] if options[:env]
env = options.delete(:unsetenv_others) ? {} : ENV.to_hash
if add_to_env = options.delete(:env)
env.merge! Hash[add_to_env]
end

env_array = env.map { |k, v| "#{k}=#{v}" }

if arguments.empty?
command, arguments = 'bash', ['bash', '-c', command]
end

Truffle::Process.spawn command, arguments, env_array
Truffle::Process.spawn command, arguments, env_array, options
end

def exec(command, args)

0 comments on commit 21f6f94

Please sign in to comment.