Skip to content

Commit

Permalink
Showing 8 changed files with 1,506 additions and 2 deletions.
1 change: 1 addition & 0 deletions core/src/main/java/org/jruby/util/cli/Options.java
Original file line number Diff line number Diff line change
@@ -224,6 +224,7 @@ public class Options {
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.");
public static final Option<Boolean> TRUFFLE_POSIX_USE_JAVA = bool(TRUFFLE, "truffle.posix.use_java", false, "Use a Java emulation of POSIX.");

public static final Option<Integer> TRUFFLE_ARRAY_UNINITIALIZED_SIZE = integer(TRUFFLE, "truffle.array.uninitialized_size", 32, "How large an Array to allocate when we have no other information to go on.");
public static final Option<Integer> TRUFFLE_ARRAY_SMALL = integer(TRUFFLE, "truffle.array.small", 3, "Maximum size of an Array to consider small for optimisations.");
540 changes: 540 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/runtime/BaseLibC.java

Large diffs are not rendered by default.

25 changes: 25 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/runtime/JavaLibC.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.runtime;

import jnr.posix.LibC;

public class JavaLibC extends BaseLibC implements LibC {

public static final JavaLibC INSTANCE = new JavaLibC();

private JavaLibC() {
}

@Override
public int isatty(int fd) {
return System.console() != null ? 1 : 0;
}
}
Original file line number Diff line number Diff line change
@@ -19,6 +19,7 @@ public class Options {
// Resources

public final String CORE_LOAD_PATH = org.jruby.util.cli.Options.TRUFFLE_CORE_LOAD_PATH.load();
public final boolean POSIX_USE_JAVA = org.jruby.util.cli.Options.TRUFFLE_POSIX_USE_JAVA.load();

// Data structures

636 changes: 636 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/runtime/POSIXDelegator.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -171,8 +171,11 @@ public RubyContext(Ruby runtime, TruffleLanguage.Env env) {

this.runtime = runtime;

// JRuby+Truffle uses POSIX for all IO - we need the native version
posix = POSIXFactory.getNativePOSIX(new TrufflePOSIXHandler(this));
if (options.POSIX_USE_JAVA) {
posix = new TruffleJavaPOSIX(this, POSIXFactory.getJavaPOSIX(new TrufflePOSIXHandler(this)));
} else {
posix = POSIXFactory.getNativePOSIX(new TrufflePOSIXHandler(this));
}

nativeSockets = LibraryLoader.create(NativeSockets.class).library("c").load();

Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.runtime;

import jnr.posix.FileStat;
import jnr.posix.JavaFileStat;
import jnr.posix.POSIX;
import jnr.posix.POSIXHandler;

import java.io.File;

public class TruffleJavaFileStat extends JavaFileStat {

private boolean executable = false;

public TruffleJavaFileStat(POSIX posix, POSIXHandler handler) {
super(posix, handler);
}

@Override
public void setup(String path) {
super.setup(path);

executable = new File(path).canExecute();
}

@Override
public int gid() {
return 1;
}

@Override
public int mode() {
int mode = super.mode();

if (executable) {
mode |= FileStat.S_IXOTH;
}

return mode;
}

}
248 changes: 248 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/runtime/TruffleJavaPOSIX.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
/*
* Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.runtime;

import jnr.constants.platform.Errno;
import jnr.constants.platform.Fcntl;
import jnr.constants.platform.OpenFlags;
import jnr.posix.FileStat;
import jnr.posix.LibC;
import jnr.posix.POSIX;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintStream;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

public class TruffleJavaPOSIX extends POSIXDelegator implements POSIX {

private static class OpenFile {

private final RandomAccessFile randomAccessFile;
private final int flags;

private OpenFile(RandomAccessFile randomAccessFile, int flags) {
this.randomAccessFile = randomAccessFile;
this.flags = flags;
}

public RandomAccessFile getRandomAccessFile() {
return randomAccessFile;
}

public int getFlags() {
return flags;
}
}

private static final int STDIN = 0;
private static final int STDOUT = 1;
private static final int STDERR = 2;

private final RubyContext context;

private final AtomicInteger nextFileHandle = new AtomicInteger(3);
private final Map<Integer, OpenFile> fileHandles = new ConcurrentHashMap<>();

public TruffleJavaPOSIX(RubyContext context, POSIX delegateTo) {
super(delegateTo);
this.context = context;
}

@Override
public int fcntlInt(int fd, Fcntl fcntlConst, int arg) {
if (fcntlConst.longValue() == Fcntl.F_GETFL.longValue()) {
switch (fd) {
case STDIN:
return OpenFlags.O_RDONLY.intValue();
case STDOUT:
case STDERR:
return OpenFlags.O_WRONLY.intValue();
}

final OpenFile openFile = fileHandles.get(fd);

if (openFile != null) {
return openFile.getFlags();
}
}

return super.fcntlInt(fd, fcntlConst, arg);
}

@Override
public int getpid() {
return context.hashCode();
}

@Override
public LibC libc() {
return JavaLibC.INSTANCE;
}

@Override
public int open(CharSequence path, int flags, int perm) {
if (perm != 0666) {
return super.open(path, flags, perm);
}

final int fileHandle = nextFileHandle.getAndIncrement();

if (fileHandle < 0) {
throw new UnsupportedOperationException();
}

final int basicMode = flags & 3;
final String mode;

if (basicMode == OpenFlags.O_RDONLY.intValue()) {
mode = "r";
} else if (basicMode == OpenFlags.O_WRONLY.intValue()) {
mode = "w";
} else if (basicMode == OpenFlags.O_RDWR.intValue()) {
mode = "rw";
} else {
return super.open(path, flags, perm);
}

final RandomAccessFile randomAccessFile;

try {
randomAccessFile = new RandomAccessFile(path.toString(), mode);
} catch (FileNotFoundException e) {
return -1;
}

fileHandles.put(fileHandle, new OpenFile(randomAccessFile, flags));

return fileHandle;
}

@Override
public int read(int fd, ByteBuffer buf, int n) {
return pread(fd, buf.array(), n, buf.arrayOffset());
}

@Override
public int read(int fd, byte[] buf, int n) {
return pread(fd, buf, n, 0);
}

@Override
public int pread(int fd, byte[] buf, int n, int offset) {
if (fd == STDIN) {
try {
System.in.read(buf, offset, n);
} catch (IOException e) {
return -1;
}

return n;
}

final OpenFile openFile = fileHandles.get(fd);

if (openFile != null) {
final int read;

try {
read = openFile.getRandomAccessFile().read(buf, offset, n);
} catch (IOException e) {
return -1;
}

if (read == -1) {
errno(Errno.ETIMEDOUT.intValue());
}

return read;
}

return super.pwrite(fd, buf, n, offset);
}

@Override
public int write(int fd, ByteBuffer buf, int n) {
return pwrite(fd, buf.array(), n, buf.arrayOffset());
}

@Override
public int write(int fd, byte[] buf, int n) {
return pwrite(fd, buf, n, 0);
}

@Override
public int pwrite(int fd, byte[] buf, int n, int offset) {
if (fd == STDOUT || fd == STDERR) {
final PrintStream stream;

switch (fd) {
case STDOUT:
stream = System.out;
break;
case STDERR:
stream = System.err;
break;
default:
throw new UnsupportedOperationException();
}

stream.write(buf, offset, n);

return n;
}

return super.pwrite(fd, buf, n, offset);
}

@Override
public int close(int fd) {
final OpenFile openFile = fileHandles.get(fd);

if (openFile != null) {
fileHandles.remove(fd);

try {
openFile.getRandomAccessFile().close();
} catch (IOException e) {
return -1;
}

return 0;
}

return super.close(fd);
}

@Override
public int getgid() {
return 0;
}

@Override
public FileStat allocateStat() {
return new TruffleJavaFileStat(this, null);
}

@Override
public String getenv(String envName) {
final String javaValue = System.getenv(envName);

if (javaValue != null) {
return javaValue;
}

return super.getenv(envName);
}
}

0 comments on commit 95956f0

Please sign in to comment.