Skip to content

Commit

Permalink
Showing 32 changed files with 684 additions and 190 deletions.
Original file line number Diff line number Diff line change
@@ -209,7 +209,7 @@ public void encode(StaticScope.Type value) {

@Override
public void encode(Operation value) {
encode((byte) value.ordinal());
encode(value.ordinal());
}

@Override
4 changes: 2 additions & 2 deletions tool/jt.rb
Original file line number Diff line number Diff line change
@@ -627,10 +627,10 @@ def metrics_minheap(score_name, *args)
heap = 10
log '>', "Trying #{heap} MB"
until can_run_in_heap(heap, *args)
log '>', "Trying #{heap} MB"
heap += 10
log '>', "Trying #{heap} MB"
end
heap -= 10
heap -= 9
heap = 1 if heap == 0
successful = 0
loop do
65 changes: 24 additions & 41 deletions truffle/src/main/java/org/jruby/truffle/RubyContext.java
Original file line number Diff line number Diff line change
@@ -21,7 +21,6 @@
import com.oracle.truffle.tools.CoverageTracker;
import jnr.ffi.LibraryLoader;
import jnr.posix.POSIX;
import jnr.posix.POSIXFactory;
import org.jcodings.Encoding;
import org.jcodings.specific.UTF8Encoding;
import org.jruby.Ruby;
@@ -35,7 +34,7 @@
import org.jruby.truffle.core.SetTopLevelBindingNode;
import org.jruby.truffle.core.array.ArrayOperations;
import org.jruby.truffle.core.binding.BindingNodes;
import org.jruby.truffle.core.ffi.LibCClockGetTime;
import org.jruby.truffle.platform.ClockGetTime;
import org.jruby.truffle.core.kernel.AtExitManager;
import org.jruby.truffle.core.kernel.TraceManager;
import org.jruby.truffle.core.objectspace.ObjectSpaceManager;
@@ -61,11 +60,9 @@
import org.jruby.truffle.language.objects.ObjectIDOperations;
import org.jruby.truffle.language.translator.TranslatorDriver;
import org.jruby.truffle.language.translator.TranslatorDriver.ParserContext;
import org.jruby.truffle.platform.RubiniusConfiguration;
import org.jruby.truffle.platform.TrufflePOSIXHandler;
import org.jruby.truffle.platform.darwin.CrtExterns;
import org.jruby.truffle.platform.posix.TruffleJavaPOSIX;
import org.jruby.truffle.stdlib.sockets.NativeSockets;
import org.jruby.truffle.platform.*;
import org.jruby.truffle.platform.signal.SignalManager;
import org.jruby.truffle.platform.Sockets;
import org.jruby.truffle.tools.InstrumentationServerManager;
import org.jruby.truffle.tools.callgraph.CallGraph;
import org.jruby.truffle.tools.callgraph.SimpleWriter;
@@ -93,10 +90,7 @@ public class RubyContext extends ExecutionContext {

private final Options options;

private final POSIX posix;
private final NativeSockets nativeSockets;
private final LibCClockGetTime libCClockGetTime;
private CrtExterns crtExterns;
private final NativePlatform nativePlatform;

private final CoreLibrary coreLibrary;
private final FeatureLoader featureLoader;
@@ -115,7 +109,6 @@ public class RubyContext extends ExecutionContext {
private final InstrumentationServerManager instrumentationServerManager;
private final AttachmentsManager attachmentsManager;
private final SourceCache sourceCache;
private final RubiniusConfiguration rubiniusConfiguration;
private final CallGraph callGraph;

private final AtomicLong nextObjectID = new AtomicLong(ObjectIDOperations.FIRST_OBJECT_ID);
@@ -176,32 +169,14 @@ public RubyContext(Ruby runtime, TruffleLanguage.Env env) {

this.runtime = runtime;

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();

try {
crtExterns = LibraryLoader.create(CrtExterns.class).failImmediately().library("libSystem.B.dylib").load();
} catch (UnsatisfiedLinkError e) {
crtExterns = null;
}

if (Platform.getPlatform().getOS() == OS_TYPE.LINUX) {
libCClockGetTime = LibraryLoader.create(LibCClockGetTime.class).library("c").load();
} else {
libCClockGetTime = null;
}

warnings = new Warnings(this);

// Object space manager needs to come early before we create any objects
objectSpaceManager = new ObjectSpaceManager(this);

coreLibrary = new CoreLibrary(this);

nativePlatform = NativePlatformFactory.createPlatform(this);
rootLexicalScope = new LexicalScope(null, coreLibrary.getObjectClass());

org.jruby.Main.printTruffleTimeMetric("before-load-nodes");
@@ -228,7 +203,6 @@ public RubyContext(Ruby runtime, TruffleLanguage.Env env) {

attachmentsManager = new AttachmentsManager(this);
sourceCache = new SourceCache(new SourceLoader(this));
rubiniusConfiguration = RubiniusConfiguration.create(this);

final PrintStream configStandardOut = runtime.getInstanceConfig().getOutput();
debugStandardOut = (configStandardOut == System.out) ? null : configStandardOut;
@@ -603,19 +577,19 @@ public SourceCache getSourceCache() {
}

public RubiniusConfiguration getRubiniusConfiguration() {
return rubiniusConfiguration;
return getNativePlatform().getRubiniusConfiguration();
}

public POSIX getPosix() {
return posix;
return getNativePlatform().getPosix();
}

public NativeSockets getNativeSockets() {
return nativeSockets;
public Sockets getNativeSockets() {
return getNativePlatform().getSockets();
}

public LibCClockGetTime getLibCClockGetTime() {
return libCClockGetTime;
public ClockGetTime getLibCClockGetTime() {
return getNativePlatform().getClockGetTime();
}

public Object execute(final org.jruby.ast.RootNode rootNode) {
@@ -722,8 +696,12 @@ public DynamicObject createHandle(Object object) {
return Layouts.HANDLE.createHandle(coreLibrary.getHandleFactory(), object);
}

public CrtExterns getCrtExterns() {
return crtExterns;
public NativePlatform getNativePlatform() {
return nativePlatform;
}

public ProcessName getProcessName() {
return getNativePlatform().getProcessName();
}

public static void appendToFile(String fileName, String message) {
@@ -737,4 +715,9 @@ public static void appendToFile(String fileName, String message) {
public CallGraph getCallGraph() {
return callGraph;
}

public SignalManager getSignalManager() {
return getNativePlatform().getSignalManager();
}

}
6 changes: 3 additions & 3 deletions truffle/src/main/java/org/jruby/truffle/core/CoreLibrary.java
Original file line number Diff line number Diff line change
@@ -89,7 +89,7 @@
import org.jruby.truffle.language.objects.SingletonClassNode;
import org.jruby.truffle.language.objects.SingletonClassNodeGen;
import org.jruby.truffle.platform.RubiniusTypes;
import org.jruby.truffle.platform.signal.SignalOperations;
import org.jruby.truffle.platform.signal.SignalManager;
import org.jruby.truffle.stdlib.*;
import org.jruby.truffle.stdlib.psych.PsychEmitterNodesFactory;
import org.jruby.truffle.stdlib.psych.PsychParserNodes;
@@ -712,10 +712,10 @@ private void initializeConstants() {
}

private void initializeSignalConstants() {
Object[] signals = new Object[SignalOperations.SIGNALS_LIST.size()];
Object[] signals = new Object[SignalManager.SIGNALS_LIST.size()];

int i = 0;
for (Map.Entry<String, Integer> signal : SignalOperations.SIGNALS_LIST.entrySet()) {
for (Map.Entry<String, Integer> signal : SignalManager.SIGNALS_LIST.entrySet()) {
DynamicObject signalName = StringOperations.createString(context, StringOperations.encodeRope(signal.getKey(), UTF8Encoding.INSTANCE));
Object[] objects = new Object[]{signalName, signal.getValue()};
signals[i++] = Layouts.ARRAY.createArray(Layouts.CLASS.getInstanceFactory(arrayClass), objects, objects.length);
Original file line number Diff line number Diff line change
@@ -19,13 +19,12 @@
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.cast.DefaultValueNodeGen;
import org.jruby.truffle.core.ffi.LibCClockGetTime;
import org.jruby.truffle.platform.ClockGetTime;
import org.jruby.truffle.core.ffi.TimeSpec;
import org.jruby.truffle.language.RubyGuards;
import org.jruby.truffle.language.RubyNode;
import org.jruby.truffle.language.control.RaiseException;
import org.jruby.truffle.platform.signal.Signal;
import org.jruby.truffle.platform.signal.SignalOperations;

@CoreClass(name = "Process")
public abstract class ProcessNodes {
@@ -82,7 +81,7 @@ protected Object clock_gettime_monotonic_raw(int clock_id, DynamicObject unit) {

@TruffleBoundary
private Object clock_gettime_clock_id(int clock_id, DynamicObject unit) {
final LibCClockGetTime libCClockGetTime = getContext().getLibCClockGetTime();
final ClockGetTime libCClockGetTime = getContext().getLibCClockGetTime();
TimeSpec timeSpec = new TimeSpec(jnr.ffi.Runtime.getRuntime(libCClockGetTime));
int r = libCClockGetTime.clock_gettime(clock_id, timeSpec);
if (r != 0) {
@@ -143,9 +142,9 @@ public int kill(DynamicObject signalName, int pid) {

@TruffleBoundary
private int raise(String signalName) {
Signal signal = new Signal(signalName);
Signal signal = getContext().getSignalManager().createSignal(signalName);
try {
SignalOperations.raise(signal);
getContext().getSignalManager().raise(signal);
} catch (IllegalArgumentException e) {
throw new RaiseException(getContext().getCoreLibrary().argumentError(e.getMessage(), this));
}
Original file line number Diff line number Diff line change
@@ -7,14 +7,15 @@
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.platform.signal;
package org.jruby.truffle.core.proc;

import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.object.DynamicObject;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.Layouts;
import org.jruby.truffle.core.proc.ProcNodes;
import org.jruby.truffle.language.RubyGuards;
import org.jruby.truffle.platform.signal.Signal;
import org.jruby.truffle.platform.signal.SignalHandler;
import org.jruby.util.func.Function2;

public class ProcSignalHandler implements SignalHandler {
Original file line number Diff line number Diff line change
@@ -70,10 +70,10 @@
import org.jruby.truffle.language.objects.IsANode;
import org.jruby.truffle.language.objects.IsANodeGen;
import org.jruby.truffle.language.yield.YieldDispatchHeadNode;
import org.jruby.truffle.platform.signal.ProcSignalHandler;
import org.jruby.truffle.core.proc.ProcSignalHandler;
import org.jruby.truffle.platform.signal.Signal;
import org.jruby.truffle.platform.signal.SignalHandler;
import org.jruby.truffle.platform.signal.SignalOperations;
import org.jruby.truffle.platform.signal.SignalManager;
import org.jruby.util.io.PosixShim;

import java.lang.management.ManagementFactory;
@@ -451,7 +451,7 @@ public boolean watchSignal(DynamicObject signalName, DynamicObject action) {

@Specialization(guards = { "isRubyString(signalName)", "isNil(nil)" })
public boolean watchSignal(DynamicObject signalName, Object nil) {
return handle(signalName, SignalOperations.IGNORE_HANDLER);
return handle(signalName, SignalManager.IGNORE_HANDLER);
}

@Specialization(guards = { "isRubyString(signalName)", "isRubyProc(proc)" })
@@ -461,9 +461,9 @@ public boolean watchSignalProc(DynamicObject signalName, DynamicObject proc) {

@TruffleBoundary
private boolean handleDefault(DynamicObject signalName) {
Signal signal = new Signal(signalName.toString());
Signal signal = getContext().getSignalManager().createSignal(signalName.toString());
try {
SignalOperations.watchDefaultForSignal(signal);
getContext().getSignalManager().watchDefaultForSignal(signal);
} catch (IllegalArgumentException e) {
throw new RaiseException(getContext().getCoreLibrary().argumentError(e.getMessage(), this));
}
@@ -472,9 +472,9 @@ private boolean handleDefault(DynamicObject signalName) {

@TruffleBoundary
private boolean handle(DynamicObject signalName, SignalHandler newHandler) {
final Signal signal = new Signal(signalName.toString());
Signal signal = getContext().getSignalManager().createSignal(signalName.toString());
try {
SignalOperations.watchSignal(signal, newHandler);
getContext().getSignalManager().watchSignal(signal, newHandler);
} catch (IllegalArgumentException e) {
throw new RaiseException(getContext().getCoreLibrary().argumentError(e.getMessage(), this));
}
Original file line number Diff line number Diff line change
@@ -26,7 +26,7 @@
import org.jruby.truffle.core.rope.CodeRange;
import org.jruby.truffle.core.rope.Rope;
import org.jruby.truffle.core.string.StringOperations;
import org.jruby.truffle.stdlib.sockets.NativeSockets;
import org.jruby.truffle.platform.Sockets;
import org.jruby.util.ByteList;

@TypeSystemReference(RubyTypes.class)
@@ -179,7 +179,7 @@ protected POSIX posix() {
return getContext().getPosix();
}

protected NativeSockets nativeSockets() {
protected Sockets nativeSockets() {
return getContext().getNativeSockets();
}

Original file line number Diff line number Diff line change
@@ -23,29 +23,18 @@
@NodeChild(value = "value", type = RubyNode.class)
public abstract class WriteProgramNameNode extends RubyNode {

/*
* When we call _NSGetArgv we seem to always get a string that looks like what we'd expect from running ps, but
* with a null character inserted early. I don't know where this comes from, but it means I don't know how to get
* the length of space available for writing in the new program name. We therefore about 40 characters, which is
* a number without any foundation, but it at leaast allows the specs to pass, the functionality to be useful,
* and probably avoid crashing anyone's programs. I can't pretend this is great engineering.
*/
private static final int MAX_PROGRAM_NAME_LENGTH = 40;

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

@TruffleBoundary
@Specialization(guards = "isRubyString(value)")
protected Object writeProgramName(DynamicObject value) {
if (getContext().getCrtExterns() != null) {
final String valueString = value.toString();
final Pointer programNameAddress = getContext().getCrtExterns()._NSGetArgv().getPointer(0).getPointer(0);
programNameAddress.putString(0, valueString, MAX_PROGRAM_NAME_LENGTH, StandardCharsets.UTF_8);
@Specialization(guards = "isRubyString(name)")
protected Object writeProgramName(DynamicObject name) {
if (getContext().getProcessName().canSet()) {
getContext().getProcessName().set(name.toString());
}

return value;
return name;
}

}
Original file line number Diff line number Diff line change
@@ -7,8 +7,10 @@
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.core.ffi;
package org.jruby.truffle.platform;

public interface LibCClockGetTime {
import org.jruby.truffle.core.ffi.TimeSpec;

public interface ClockGetTime {
int clock_gettime(int clock_id, TimeSpec timeSpec);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* 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.platform;

import jnr.posix.POSIX;
import org.jruby.truffle.platform.signal.SignalManager;

public interface NativePlatform {

POSIX getPosix();

SignalManager getSignalManager();

ProcessName getProcessName();

Sockets getSockets();

ClockGetTime getClockGetTime();

RubiniusConfiguration getRubiniusConfiguration();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* 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.platform;

import org.jruby.ext.ffi.Platform;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.platform.darwin.DarwinPlatform;
import org.jruby.truffle.platform.java.JavaPlatform;
import org.jruby.truffle.platform.linux.LinuxPlatform;

public abstract class NativePlatformFactory {

public static NativePlatform createPlatform(RubyContext context) {
if (context.getOptions().POSIX_USE_JAVA) {
return new JavaPlatform(context);
}

if (Platform.getPlatform().getOS() == Platform.OS_TYPE.LINUX) {
return new LinuxPlatform(context);
}

if (Platform.getPlatform().getOS() == Platform.OS_TYPE.DARWIN) {
return new DarwinPlatform(context);
}

throw new UnsupportedOperationException();
}

}
18 changes: 18 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/platform/ProcessName.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* 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.platform;

public interface ProcessName {

boolean canSet();

void set(String name);

}
Original file line number Diff line number Diff line change
@@ -49,30 +49,9 @@

public class RubiniusConfiguration {

public static RubiniusConfiguration create(RubyContext context) {
final RubiniusConfiguration configuration = new RubiniusConfiguration();

DefaultRubiniusConfiguration.load(configuration, context);

switch (Platform.getPlatform().getOS()) {
case DARWIN:
DarwinRubiniusConfiguration.load(configuration, context);
break;

case LINUX:
LinuxRubiniusConfiguration.load(configuration, context);
break;

default:
throw new UnsupportedOperationException();
}

return configuration;
}

private final Map<String, Object> configuration = new HashMap<>(); // Only written to by create() once per RubyContext.

private RubiniusConfiguration() {
public RubiniusConfiguration() {
}

public void config(String key, Object value) {
Original file line number Diff line number Diff line change
@@ -7,12 +7,12 @@
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.stdlib.sockets;
package org.jruby.truffle.platform;

import jnr.ffi.Pointer;
import jnr.posix.Timeval;

public interface NativeSockets {
public interface Sockets {

/*
* int
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* 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.platform.darwin;

import jnr.ffi.LibraryLoader;
import jnr.posix.POSIX;
import jnr.posix.POSIXFactory;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.platform.*;
import org.jruby.truffle.platform.java.JavaClockGetTime;
import org.jruby.truffle.platform.signal.SignalManager;
import org.jruby.truffle.platform.sunmisc.SunMiscSignalManager;

public class DarwinPlatform implements NativePlatform {

private final POSIX posix;
private final SignalManager signalManager;
private final ProcessName processName;
private final Sockets sockets;
private final ClockGetTime clockGetTime;
private final RubiniusConfiguration rubiniusConfiguration;

public DarwinPlatform(RubyContext context) {
posix = POSIXFactory.getNativePOSIX(new TrufflePOSIXHandler(context));
signalManager = new SunMiscSignalManager();
processName = new DarwinProcessName();
sockets = LibraryLoader.create(Sockets.class).library("c").load();
clockGetTime = new JavaClockGetTime();
rubiniusConfiguration = new RubiniusConfiguration();
DefaultRubiniusConfiguration.load(rubiniusConfiguration, context);
DarwinRubiniusConfiguration.load(rubiniusConfiguration, context);
}

@Override
public POSIX getPosix() {
return posix;
}

@Override
public SignalManager getSignalManager() {
return signalManager;
}

@Override
public ProcessName getProcessName() {
return processName;
}

@Override
public Sockets getSockets() {
return sockets;
}

@Override
public ClockGetTime getClockGetTime() {
return clockGetTime;
}

@Override
public RubiniusConfiguration getRubiniusConfiguration() {
return rubiniusConfiguration;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package org.jruby.truffle.platform.darwin;

import jnr.ffi.LibraryLoader;
import jnr.ffi.Pointer;
import org.jruby.truffle.platform.ProcessName;

import java.nio.charset.StandardCharsets;

public class DarwinProcessName implements ProcessName {

/*
* When we call _NSGetArgv we seem to always get a string that looks like what we'd expect from running ps, but
* with a null character inserted early. I don't know where this comes from, but it means I don't know how to get
* the length of space available for writing in the new program name. We therefore about 40 characters, which is
* a number without any foundation, but it at leaast allows the specs to pass, the functionality to be useful,
* and probably avoid crashing anyone's programs. I can't pretend this is great engineering.
*/
private static final int MAX_PROGRAM_NAME_LENGTH = 40;

private final CrtExterns crtExterns;

public DarwinProcessName() {
crtExterns = LibraryLoader.create(CrtExterns.class).failImmediately().library("libSystem.B.dylib").load();
}

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

@Override
public void set(String name) {
final Pointer programNameAddress = crtExterns._NSGetArgv().getPointer(0).getPointer(0);
programNameAddress.putString(0, name, MAX_PROGRAM_NAME_LENGTH, StandardCharsets.UTF_8);
}

}
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.platform.posix;
package org.jruby.truffle.platform.java;

import jnr.constants.platform.Sysconf;
import jnr.ffi.Pointer;
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* 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.platform.java;

import org.jruby.truffle.core.ffi.TimeSpec;
import org.jruby.truffle.platform.ClockGetTime;

public class JavaClockGetTime implements ClockGetTime {

@Override
public int clock_gettime(int clock_id, TimeSpec timeSpec) {
throw new UnsupportedOperationException();
}

}
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.platform.posix;
package org.jruby.truffle.platform.java;

import jnr.posix.LibC;

Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* 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.platform.java;

import jnr.posix.POSIX;
import jnr.posix.POSIXFactory;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.platform.*;
import org.jruby.truffle.platform.darwin.DarwinRubiniusConfiguration;
import org.jruby.truffle.platform.linux.LinuxRubiniusConfiguration;
import org.jruby.truffle.platform.signal.SignalManager;
import org.jruby.truffle.platform.sunmisc.SunMiscSignalManager;

public class JavaPlatform implements NativePlatform {

private final POSIX posix;
private final SignalManager signalManager;
private final ProcessName processName;
private final Sockets sockets;
private final ClockGetTime clockGetTime;
private final RubiniusConfiguration rubiniusConfiguration;

public JavaPlatform(RubyContext context) {
posix = new TruffleJavaPOSIX(context, POSIXFactory.getJavaPOSIX(new TrufflePOSIXHandler(context)));
signalManager = new SunMiscSignalManager();
processName = new JavaProcessName();
sockets = new JavaSockets();
clockGetTime = new JavaClockGetTime();
rubiniusConfiguration = new RubiniusConfiguration();
DefaultRubiniusConfiguration.load(rubiniusConfiguration, context);
LinuxRubiniusConfiguration.load(rubiniusConfiguration, context); // Just load the Linux one - let errors happen later
}

@Override
public POSIX getPosix() {
return posix;
}

@Override
public SignalManager getSignalManager() {
return signalManager;
}

@Override
public ProcessName getProcessName() {
return processName;
}

@Override
public Sockets getSockets() {
return sockets;
}

@Override
public ClockGetTime getClockGetTime() {
return clockGetTime;
}

@Override
public RubiniusConfiguration getRubiniusConfiguration() {
return rubiniusConfiguration;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* 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.platform.java;

import org.jruby.truffle.platform.ProcessName;

public class JavaProcessName implements ProcessName {

@Override
public boolean canSet() {
return false;
}

@Override
public void set(String name) {
throw new UnsupportedOperationException();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* 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.platform.java;

import jnr.ffi.Pointer;
import jnr.posix.Timeval;
import org.jruby.truffle.platform.Sockets;

public class JavaSockets implements Sockets {

@Override
public int getaddrinfo(CharSequence hostname, CharSequence servname, Pointer hints, Pointer res) {
throw new UnsupportedOperationException();
}

@Override
public void freeaddrinfo(Pointer ai) {
throw new UnsupportedOperationException();
}

@Override
public int getnameinfo(Pointer sa, int salen, Pointer host, int hostlen, Pointer serv, int servlen, int flags) {
throw new UnsupportedOperationException();
}

@Override
public int socket(int domain, int type, int protocol) {
throw new UnsupportedOperationException();
}

@Override
public int setsockopt(int socket, int level, int option_name, Pointer option_value, int option_len) {
throw new UnsupportedOperationException();
}

@Override
public int bind(int socket, Pointer address, int address_len) {
throw new UnsupportedOperationException();
}

@Override
public int listen(int socket, int backlog) {
throw new UnsupportedOperationException();
}

@Override
public int accept(int socket, Pointer address, int[] addressLength) {
throw new UnsupportedOperationException();
}

@Override
public int gethostname(Pointer name, int namelen) {
throw new UnsupportedOperationException();
}

@Override
public int select(int nfds, Pointer readfds, Pointer writefds, Pointer errorfds, Timeval timeout) {
throw new UnsupportedOperationException();
}

@Override
public int getpeername(int socket, Pointer address, Pointer address_len) {
throw new UnsupportedOperationException();
}

@Override
public int getsockname(int socket, Pointer address, Pointer address_len) {
throw new UnsupportedOperationException();
}

@Override
public int getsockopt(int sockfd, int level, int optname, Pointer optval, Pointer optlen) {
throw new UnsupportedOperationException();
}

@Override
public int connect(int socket, Pointer address, int address_len) {
throw new UnsupportedOperationException();
}

@Override
public int shutdown(int socket, int how) {
throw new UnsupportedOperationException();
}

}
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.platform.posix;
package org.jruby.truffle.platform.java;

import jnr.constants.platform.Fcntl;
import jnr.constants.platform.Signal;
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.platform.posix;
package org.jruby.truffle.platform.java;

import jnr.posix.FileStat;
import jnr.posix.JavaFileStat;
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.platform.posix;
package org.jruby.truffle.platform.java;

import jnr.constants.platform.Errno;
import jnr.constants.platform.Fcntl;
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* 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.platform.linux;

import jnr.ffi.LibraryLoader;
import jnr.posix.POSIX;
import jnr.posix.POSIXFactory;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.platform.*;
import org.jruby.truffle.platform.java.JavaProcessName;
import org.jruby.truffle.platform.signal.SignalManager;
import org.jruby.truffle.platform.sunmisc.SunMiscSignalManager;

public class LinuxPlatform implements NativePlatform {

private final POSIX posix;
private final SignalManager signalManager;
private final ProcessName processName;
private final Sockets sockets;
private final ClockGetTime clockGetTime;
private final RubiniusConfiguration rubiniusConfiguration;

public LinuxPlatform(RubyContext context) {
posix = POSIXFactory.getNativePOSIX(new TrufflePOSIXHandler(context));
signalManager = new SunMiscSignalManager();
processName = new JavaProcessName();
sockets = LibraryLoader.create(Sockets.class).library("c").load();
clockGetTime = LibraryLoader.create(ClockGetTime.class).library("c").load();
rubiniusConfiguration = new RubiniusConfiguration();
DefaultRubiniusConfiguration.load(rubiniusConfiguration, context);
LinuxRubiniusConfiguration.load(rubiniusConfiguration, context);
}

@Override
public POSIX getPosix() {
return posix;
}

@Override
public SignalManager getSignalManager() {
return signalManager;
}

@Override
public ProcessName getProcessName() {
return processName;
}

@Override
public Sockets getSockets() {
return sockets;
}

@Override
public ClockGetTime getClockGetTime() {
return clockGetTime;
}

@Override
public RubiniusConfiguration getRubiniusConfiguration() {
return rubiniusConfiguration;
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2016 Oracle and/or its affiliates. All rights reserved. This
* 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:
*
@@ -9,43 +9,5 @@
*/
package org.jruby.truffle.platform.signal;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

@SuppressWarnings("restriction")
public class Signal {

private final sun.misc.Signal sunSignal;

private static final ConcurrentMap<sun.misc.Signal, sun.misc.SignalHandler> DEFAULT_HANDLERS = new ConcurrentHashMap<sun.misc.Signal, sun.misc.SignalHandler>();

public Signal(String name) {
sunSignal = new sun.misc.Signal(name);
}

public static void handle(final Signal signal, final SignalHandler newHandler) throws IllegalArgumentException {
final sun.misc.SignalHandler oldSunHandler = sun.misc.Signal.handle(signal.sunSignal, wrapHandler(signal, newHandler));
DEFAULT_HANDLERS.putIfAbsent(signal.sunSignal, oldSunHandler);
}

public static void handleDefault(final Signal signal) throws IllegalArgumentException {
final sun.misc.SignalHandler defaultHandler = DEFAULT_HANDLERS.get(signal.sunSignal);
if (defaultHandler != null) { // otherwise it is already the default signal
sun.misc.Signal.handle(signal.sunSignal, defaultHandler);
}
}

private static sun.misc.SignalHandler wrapHandler(final Signal signal, final SignalHandler newHandler) {
return new sun.misc.SignalHandler() {
@Override
public void handle(sun.misc.Signal wrappedSignal) {
newHandler.handle(signal);
}
};
}

public static void raise(Signal signal) throws IllegalArgumentException {
sun.misc.Signal.raise(signal.sunSignal);
}

public interface Signal {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2015, 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.platform.signal;

import org.jruby.RubySignal;

import java.util.Collections;
import java.util.Map;

public interface SignalManager {

Map<String, Integer> SIGNALS_LIST = Collections.unmodifiableMap(RubySignal.list());

SignalHandler IGNORE_HANDLER = new SignalHandler() {
@Override
public void handle(Signal arg0) {
// Just ignore the signal.
}
};

Signal createSignal(String name);

void watchSignal(Signal signal, SignalHandler newHandler) throws IllegalArgumentException;

void watchDefaultForSignal(Signal signal) throws IllegalArgumentException;

void handle(final Signal signal, final SignalHandler newHandler) throws IllegalArgumentException;

void handleDefault(final Signal signal) throws IllegalArgumentException;

void raise(Signal signal) throws IllegalArgumentException;

}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright (c) 2015, 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.platform.sunmisc;

import org.jruby.truffle.platform.signal.Signal;

public class SunMiscSignal implements Signal {

private final sun.misc.Signal sunMiscSignal;

public SunMiscSignal(String name) {
sunMiscSignal = new sun.misc.Signal(name);
}

public sun.misc.Signal getSunMiscSignal() {
return sunMiscSignal;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Copyright (c) 2015, 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.platform.sunmisc;

import org.jruby.RubySignal;
import org.jruby.truffle.platform.signal.Signal;
import org.jruby.truffle.platform.signal.SignalHandler;
import org.jruby.truffle.platform.signal.SignalManager;

import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

public class SunMiscSignalManager implements SignalManager {

public final Map<String, Integer> SIGNALS_LIST = Collections.unmodifiableMap(RubySignal.list());

public final SignalHandler IGNORE_HANDLER = new SignalHandler() {
@Override
public void handle(Signal arg0) {
// Just ignore the signal.
}
};
private final ConcurrentMap<sun.misc.Signal, sun.misc.SignalHandler> DEFAULT_HANDLERS = new ConcurrentHashMap<sun.misc.Signal, sun.misc.SignalHandler>();

@Override
public Signal createSignal(String name) {
return new SunMiscSignal(name);
}

@Override
public void watchSignal(Signal signal, SignalHandler newHandler) throws IllegalArgumentException {
handle((SunMiscSignal) signal, newHandler);
}

@Override
public void watchDefaultForSignal(Signal signal) throws IllegalArgumentException {
handleDefault((SunMiscSignal) signal);
}

@Override
public void handle(final Signal signal, final SignalHandler newHandler) throws IllegalArgumentException {
final SunMiscSignal smSignal = (SunMiscSignal) signal;
final sun.misc.SignalHandler oldSunHandler = sun.misc.Signal.handle(smSignal.getSunMiscSignal(), wrapHandler(signal, newHandler));
DEFAULT_HANDLERS.putIfAbsent(smSignal.getSunMiscSignal(), oldSunHandler);
}

@Override
public void handleDefault(final Signal signal) throws IllegalArgumentException {
final SunMiscSignal smSignal = (SunMiscSignal) signal;
final sun.misc.SignalHandler defaultHandler = DEFAULT_HANDLERS.get(smSignal.getSunMiscSignal());
if (defaultHandler != null) { // otherwise it is already the default signal
sun.misc.Signal.handle(smSignal.getSunMiscSignal(), defaultHandler);
}
}

private sun.misc.SignalHandler wrapHandler(final Signal signal, final SignalHandler newHandler) {
final SunMiscSignal smSignal = (SunMiscSignal) signal;
return new sun.misc.SignalHandler() {
@Override
public void handle(sun.misc.Signal wrappedSignal) {
newHandler.handle(smSignal);
}
};
}

@Override
public void raise(Signal signal) throws IllegalArgumentException {
sun.misc.Signal.raise(((SunMiscSignal) signal).getSunMiscSignal());
}
}

0 comments on commit 5faaebf

Please sign in to comment.