Skip to content

Commit

Permalink
Showing 22 changed files with 219 additions and 66 deletions.
13 changes: 7 additions & 6 deletions core/pom.rb
Original file line number Diff line number Diff line change
@@ -40,12 +40,13 @@
jar 'org.ow2.asm:asm-analysis:${asm.version}'
jar 'org.ow2.asm:asm-util:${asm.version}'

jar 'com.github.jnr:jnr-netdb:1.1.4'
jar 'com.github.jnr:jnr-enxio:0.9'
jar 'com.github.jnr:jnr-x86asm:1.0.2'
jar 'com.github.jnr:jnr-unixsocket:0.8'
jar 'com.github.jnr:jnr-posix:3.0.15'
jar 'com.github.jnr:jnr-constants:0.9.0-SNAPSHOT'
# exclude jnr-ffi to avoid problems with shading and relocation of the asm packages
jar 'com.github.jnr:jnr-netdb:1.1.4', :exclusions => ['com.github.jnr:jnr-ffi']
jar 'com.github.jnr:jnr-enxio:0.9', :exclusions => ['com.github.jnr:jnr-ffi']
jar 'com.github.jnr:jnr-x86asm:1.0.2', :exclusions => ['com.github.jnr:jnr-ffi']
jar 'com.github.jnr:jnr-unixsocket:0.8', :exclusions => ['com.github.jnr:jnr-ffi']
jar 'com.github.jnr:jnr-posix:3.0.15', :exclusions => ['com.github.jnr:jnr-ffi']
jar 'com.github.jnr:jnr-constants:0.9.0-SNAPSHOT', :exclusions => ['com.github.jnr:jnr-ffi']
jar 'com.github.jnr:jnr-ffi:2.0.3'
jar 'com.github.jnr:jffi:${jffi.version}'
jar 'com.github.jnr:jffi:${jffi.version}:native'
36 changes: 36 additions & 0 deletions core/pom.xml
Original file line number Diff line number Diff line change
@@ -93,31 +93,67 @@ DO NOT MODIFIY - GENERATED CODE
<groupId>com.github.jnr</groupId>
<artifactId>jnr-netdb</artifactId>
<version>1.1.4</version>
<exclusions>
<exclusion>
<artifactId>jnr-ffi</artifactId>
<groupId>com.github.jnr</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.github.jnr</groupId>
<artifactId>jnr-enxio</artifactId>
<version>0.9</version>
<exclusions>
<exclusion>
<artifactId>jnr-ffi</artifactId>
<groupId>com.github.jnr</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.github.jnr</groupId>
<artifactId>jnr-x86asm</artifactId>
<version>1.0.2</version>
<exclusions>
<exclusion>
<artifactId>jnr-ffi</artifactId>
<groupId>com.github.jnr</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.github.jnr</groupId>
<artifactId>jnr-unixsocket</artifactId>
<version>0.8</version>
<exclusions>
<exclusion>
<artifactId>jnr-ffi</artifactId>
<groupId>com.github.jnr</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.github.jnr</groupId>
<artifactId>jnr-posix</artifactId>
<version>3.0.15</version>
<exclusions>
<exclusion>
<artifactId>jnr-ffi</artifactId>
<groupId>com.github.jnr</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.github.jnr</groupId>
<artifactId>jnr-constants</artifactId>
<version>0.9.0-SNAPSHOT</version>
<exclusions>
<exclusion>
<artifactId>jnr-ffi</artifactId>
<groupId>com.github.jnr</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.github.jnr</groupId>
8 changes: 3 additions & 5 deletions core/src/main/java/org/jruby/PrependedModule.java
Original file line number Diff line number Diff line change
@@ -13,7 +13,7 @@
* rights and limitations under the License.
*
* Copyright (C) 2014 Timur Duehr <tduehr@gmail.com>
*
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
@@ -28,14 +28,10 @@
***** END LICENSE BLOCK *****/
package org.jruby;

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

import org.jruby.internal.runtime.methods.DynamicMethod;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.runtime.builtin.Variable;

/**
* This class is used as an intermediate superclass for Module#prepend
@@ -44,6 +40,7 @@
* @see org.jruby.RubyModule
*/
public class PrependedModule extends IncludedModule {

public PrependedModule(Ruby runtime, RubyClass superClass, RubyModule origin) {
super(runtime, superClass, origin);
methods = origin.methods;
@@ -59,4 +56,5 @@ public PrependedModule(Ruby runtime, RubyClass superClass, RubyModule origin) {
public boolean isPrepended() {
return true;
}

}
13 changes: 9 additions & 4 deletions core/src/main/java/org/jruby/RubyHash.java
Original file line number Diff line number Diff line change
@@ -499,7 +499,7 @@ private void checkResize() {
if (MRI_HASH_RESIZE) MRICheckResize(); else JavaSoftCheckResize();
}

private void checkIterating() {
protected final void checkIterating() {
if (iteratorCount > 0) {
throw getRuntime().newRuntimeError("can't add a new key into hash during iteration");
}
@@ -2020,10 +2020,15 @@ public Object remove(Object key) {

@Override
public void putAll(Map map) {
Ruby runtime = getRuntime();
for (Iterator<Map.Entry> iter = map.entrySet().iterator(); iter.hasNext();) {
final Ruby runtime = getRuntime();
@SuppressWarnings("unchecked")
final Iterator<Map.Entry> iter = map.entrySet().iterator();
while ( iter.hasNext() ) {
Map.Entry entry = iter.next();
internalPut(JavaUtil.convertJavaToUsableRubyObject(runtime, entry.getKey()), JavaUtil.convertJavaToUsableRubyObject(runtime, entry.getValue()));
internalPut(
JavaUtil.convertJavaToUsableRubyObject(runtime, entry.getKey()),
JavaUtil.convertJavaToUsableRubyObject(runtime, entry.getValue())
);
}
}

6 changes: 6 additions & 0 deletions core/src/main/java/org/jruby/ir/targets/JVMVisitor.java
Original file line number Diff line number Diff line change
@@ -28,6 +28,7 @@
import org.jruby.parser.StaticScope;
import org.jruby.runtime.*;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.runtime.callsite.RefinedCachingCallSite;
import org.jruby.util.ByteList;
import org.jruby.util.ClassDefiningClassLoader;
import org.jruby.util.JavaNameMangler;
@@ -777,6 +778,11 @@ public void BuildSplatInstr(BuildSplatInstr instr) {

@Override
public void CallInstr(CallInstr callInstr) {
// JIT does not support refinements yet
if (callInstr.getCallSite() instanceof RefinedCachingCallSite) {
throw new NotCompilableException("refinements are unsupported in JIT");
}

IRBytecodeAdapter m = jvmMethod();
String name = callInstr.getName();
Operand[] args = callInstr.getCallArgs();
62 changes: 37 additions & 25 deletions core/src/main/java/org/jruby/java/proxies/MapJavaProxy.java
Original file line number Diff line number Diff line change
@@ -103,64 +103,78 @@ private static class RubyHashMap extends RubyHash {
private final MapJavaProxy receiver;

public RubyHashMap(Ruby runtime, MapJavaProxy receiver) {
super(runtime);
super(runtime, 0);
this.receiver = receiver;
}

private void setSize(int size) {
this.size = size;
}
private void setSize(int size) { this.size = size; }

private Map getMap() { return receiver.getMapObject(); }
// the underlying Map object operations should be delegated to
private Map mapDelegate() { return receiver.getMapObject(); }

@Override
public void internalPut(final IRubyObject key, final IRubyObject value, final boolean checkForExisting) {
internalPutSmall(key, value, checkForExisting);
}

@Override
protected final void internalPutSmall(IRubyObject key, IRubyObject value, boolean checkForExisting) {
@SuppressWarnings("unchecked")
final Map<Object, Object> map = getMap();
final Map<Object, Object> map = mapDelegate();
map.put(key.toJava(Object.class), value.toJava(Object.class));
this.size = map.size();
}

@Override
protected final void op_asetForString(Ruby runtime, RubyString key, IRubyObject value) {
@SuppressWarnings("unchecked")
final Map<Object, Object> map = mapDelegate();
map.put(key.decodeString(), value.toJava(Object.class));
this.size = map.size();
}

@Override
protected final void op_asetSmallForString(Ruby runtime, RubyString key, IRubyObject value) {
op_asetForString(runtime, key, value);
}

@Override
public IRubyObject internalGet(IRubyObject key) {
Object result = getMap().get(key.toJava(Object.class));
Object result = mapDelegate().get(key.toJava(Object.class));
if (result == null) return null;
return JavaUtil.convertJavaToUsableRubyObject(getRuntime(), result);
}

@Override
@Override // NOTE: likely won't be called
public RubyHashEntry internalGetEntry(IRubyObject key) {
Map map = getMap();
Map map = mapDelegate();
Object convertedKey = key.toJava(Object.class);
Object value = map.get(convertedKey);

if (value != null) {
RubyHashEntry rubyEntry = new RubyHashEntry(key.hashCode(), key, JavaUtil.convertJavaToUsableRubyObject(getRuntime(), value), null, null);
return rubyEntry;
return new RubyHashEntry(key.hashCode(), key, JavaUtil.convertJavaToUsableRubyObject(getRuntime(), value), null, null);
}

return NO_ENTRY;
}

@Override
public RubyHashEntry internalDelete(final IRubyObject key) {
final Map map = getMap();
final Map map = mapDelegate();
Object convertedKey = key.toJava(Object.class);
Object value = map.get(convertedKey);

if (value != null) {
RubyHashEntry rubyEntry = new RubyHashEntry(key.hashCode(), key, JavaUtil.convertJavaToUsableRubyObject(getRuntime(), value), null, null);
map.remove(convertedKey);
this.size = map.size();
return rubyEntry;
return new RubyHashEntry(key.hashCode(), key, JavaUtil.convertJavaToUsableRubyObject(getRuntime(), value), null, null);
}

return NO_ENTRY;
}

@Override
@Override // NOTE: likely won't be called
public RubyHashEntry internalDeleteEntry(final RubyHashEntry entry) {
final Map map = getMap();
final Map map = mapDelegate();
Object convertedKey = ((IRubyObject) entry.getKey()).toJava(Object.class);

if (map.containsKey(convertedKey)) {
@@ -176,7 +190,7 @@ public RubyHashEntry internalDeleteEntry(final RubyHashEntry entry) {
public void visitAll(Visitor visitor) {
final Ruby runtime = getRuntime();
@SuppressWarnings("unchecked")
final Map<Object, Object> map = getMap();
final Map<Object, Object> map = mapDelegate();
final Map.Entry[] entries = map.entrySet().toArray( new Map.Entry[ map.size() ] );
for ( Map.Entry entry : entries ) {
IRubyObject key = JavaUtil.convertJavaToUsableRubyObject(runtime, entry.getKey());
@@ -186,11 +200,9 @@ public void visitAll(Visitor visitor) {
}

@Override
public void op_asetForString(Ruby runtime, RubyString key, IRubyObject value) {
@SuppressWarnings("unchecked")
final Map<Object, Object> map = getMap();
map.put(key.toJava(String.class), value.toJava(Object.class));
this.size = map.size();
public RubyBoolean has_key_p(IRubyObject key) {
final Object convertedKey = key.toJava(Object.class);
return getRuntime().newBoolean( mapDelegate().containsKey(convertedKey) );
}

@Override
@@ -201,7 +213,7 @@ public RubyHash rehash() {

@Override
public RubyHash rb_clear() {
getMap().clear();
mapDelegate().clear();
this.size = 0;
return this;
}
@@ -216,7 +228,7 @@ public RubyHash to_hash() {
final Ruby runtime = getRuntime();
final RubyHash hash = new RubyHash(runtime);
@SuppressWarnings("unchecked")
Set<Map.Entry> entries = getMap().entrySet();
Set<Map.Entry> entries = mapDelegate().entrySet();
for ( Map.Entry entry : entries ) {
IRubyObject key = JavaUtil.convertJavaToUsableRubyObject(runtime, entry.getKey());
IRubyObject value = JavaUtil.convertJavaToUsableRubyObject(runtime, entry.getValue());
Original file line number Diff line number Diff line change
@@ -143,7 +143,6 @@ public static Object newProxyInstance(Ruby runtime, Class superClass, Class[] in
constructorParameters == null ? EMPTY_CLASS_ARRAY : constructorParameters
);
return constructor.newInstance(constructorArgs, handler);

}

public Class getSuperclass() {
3 changes: 2 additions & 1 deletion truffle/pom.rb
Original file line number Diff line number Diff line change
@@ -34,7 +34,8 @@
:id => 'anno',
:phase => 'process-resources',
'includes' => [ 'org/jruby/truffle/om/dsl/processor/OMProcessor.java' ],
'compilerArgs' => [ '-J-ea' ] )
'compilerArgs' => [ '-XDignore.symbol.file=true',
'-J-ea' ] )
execute_goals( 'compile',
:id => 'default-compile',
:phase => 'compile',
1 change: 1 addition & 0 deletions truffle/pom.xml
Original file line number Diff line number Diff line change
@@ -82,6 +82,7 @@ DO NOT MODIFIY - GENERATED CODE
<include>org/jruby/truffle/om/dsl/processor/OMProcessor.java</include>
</includes>
<compilerArgs>
<compilerArg>-XDignore.symbol.file=true</compilerArg>
<compilerArg>-J-ea</compilerArg>
</compilerArgs>
</configuration>
Original file line number Diff line number Diff line change
@@ -58,7 +58,7 @@ protected RubyConstant lookupConstant(VirtualFrame frame, DynamicObject module,
@Cached("doLookup(cachedModule, cachedName)") RubyConstant constant,
@Cached("isVisible(cachedModule, constant)") boolean isVisible,
@Cached("createBinaryProfile()") ConditionProfile sameNameProfile) {
if (!isVisible && !ignoreVisibility) {
if (!isVisible) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().nameErrorPrivateConstant(module, name, this));
}
@@ -75,7 +75,7 @@ protected RubyConstant lookupConstantUncached(DynamicObject module, String name)
RubyConstant constant = doLookup(module, name);
boolean isVisible = isVisible(module, constant);

if (!isVisible && !ignoreVisibility) {
if (!isVisible) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().nameErrorPrivateConstant(module, name, this));
}
@@ -102,7 +102,7 @@ protected RubyConstant doLookup(DynamicObject module, String name) {
}

protected boolean isVisible(DynamicObject module, RubyConstant constant) {
return constant == null || constant.isVisibleTo(getContext(), LexicalScope.NONE, module);
return ignoreVisibility || constant == null || constant.isVisibleTo(getContext(), LexicalScope.NONE, module);
}

}
Original file line number Diff line number Diff line change
@@ -22,8 +22,8 @@
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.layouts.Layouts;
import org.jruby.truffle.runtime.signal.Signal;
import org.jruby.truffle.runtime.signal.SignalOperations;
import sun.misc.Signal;

@SuppressWarnings("restriction")
@CoreClass(name = "Process")
Original file line number Diff line number Diff line change
@@ -16,6 +16,8 @@
import com.oracle.truffle.api.nodes.IndirectCallNode;
import com.oracle.truffle.api.nodes.InvalidAssumptionException;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.object.Shape;

import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.runtime.RubyArguments;
import org.jruby.truffle.runtime.RubyContext;
@@ -24,7 +26,7 @@

public class CachedBoxedDispatchNode extends CachedDispatchNode {

private final DynamicObject expectedClass;
private final Shape expectedShape;
private final Assumption unmodifiedAssumption;

private final InternalMethod method;
@@ -35,6 +37,7 @@ public CachedBoxedDispatchNode(
RubyContext context,
Object cachedName,
DispatchNode next,
Shape expectedShape,
DynamicObject expectedClass,
InternalMethod method,
boolean indirect,
@@ -43,7 +46,7 @@ public CachedBoxedDispatchNode(

assert RubyGuards.isRubyClass(expectedClass);

this.expectedClass = expectedClass;
this.expectedShape = expectedShape;
this.unmodifiedAssumption = Layouts.MODULE.getFields(expectedClass).getUnmodifiedAssumption();
this.next = next;
this.method = method;
@@ -68,7 +71,7 @@ public CachedBoxedDispatchNode(
public boolean guard(Object methodName, Object receiver) {
return guardName(methodName) &&
(receiver instanceof DynamicObject) &&
Layouts.BASIC_OBJECT.getMetaClass(((DynamicObject) receiver)) == expectedClass;
((DynamicObject) receiver).getShape() == expectedShape;
}

@Override
@@ -137,7 +140,7 @@ public Object executeDispatch(
public String toString() {
return String.format("CachedBoxedDispatchNode(:%s, %s@%x, %s)",
getCachedNameAsSymbol().toString(),
Layouts.MODULE.getFields(expectedClass).getName(), expectedClass.hashCode(),
expectedShape, expectedShape.hashCode(),
method == null ? "null" : method.toString());
}

Original file line number Diff line number Diff line change
@@ -16,6 +16,8 @@
import com.oracle.truffle.api.nodes.IndirectCallNode;
import com.oracle.truffle.api.nodes.InvalidAssumptionException;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.object.Shape;

import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.runtime.RubyArguments;
import org.jruby.truffle.runtime.RubyContext;
@@ -29,7 +31,7 @@ public class CachedBoxedMethodMissingDispatchNode extends CachedDispatchNode {
private static final boolean DISPATCH_METHODMISSING_ALWAYS_CLONED = Options.TRUFFLE_DISPATCH_METHODMISSING_ALWAYS_CLONED.load();
private static final boolean DISPATCH_METHODMISSING_ALWAYS_INLINED = Options.TRUFFLE_DISPATCH_METHODMISSING_ALWAYS_INLINED.load();

private final DynamicObject expectedClass;
private final Shape expectedShape;
private final Assumption unmodifiedAssumption;
private final InternalMethod method;

@@ -40,14 +42,15 @@ public CachedBoxedMethodMissingDispatchNode(
RubyContext context,
Object cachedName,
DispatchNode next,
Shape expectedShape,
DynamicObject expectedClass,
InternalMethod method,
boolean indirect,
DispatchAction dispatchAction) {
super(context, cachedName, next, indirect, dispatchAction);

assert RubyGuards.isRubyClass(expectedClass);
this.expectedClass = expectedClass;
this.expectedShape = expectedShape;
unmodifiedAssumption = Layouts.MODULE.getFields(expectedClass).getUnmodifiedAssumption();
this.method = method;

@@ -79,7 +82,7 @@ public CachedBoxedMethodMissingDispatchNode(
protected boolean guard(Object methodName, Object receiver) {
return guardName(methodName) &&
(receiver instanceof DynamicObject) &&
Layouts.BASIC_OBJECT.getMetaClass(((DynamicObject) receiver)) == expectedClass;
((DynamicObject) receiver).getShape() == expectedShape;
}

@Override
Original file line number Diff line number Diff line change
@@ -13,25 +13,28 @@
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.InvalidAssumptionException;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.object.Shape;

import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.layouts.Layouts;

public class CachedBoxedReturnMissingDispatchNode extends CachedDispatchNode {

private final DynamicObject expectedClass;
private final Shape expectedShape;
private final Assumption unmodifiedAssumption;

public CachedBoxedReturnMissingDispatchNode(
RubyContext context,
Object cachedName,
DispatchNode next,
Shape expectedShape,
DynamicObject expectedClass,
boolean indirect,
DispatchAction dispatchAction) {
super(context, cachedName, next, indirect, dispatchAction);
assert RubyGuards.isRubyClass(expectedClass);
this.expectedClass = expectedClass;
this.expectedShape = expectedShape;
unmodifiedAssumption = Layouts.MODULE.getFields(expectedClass).getUnmodifiedAssumption();
this.next = next;
}
@@ -40,7 +43,7 @@ public CachedBoxedReturnMissingDispatchNode(
protected boolean guard(Object methodName, Object receiver) {
return guardName(methodName) &&
(receiver instanceof DynamicObject) &&
Layouts.BASIC_OBJECT.getMetaClass(((DynamicObject) receiver)) == expectedClass;
((DynamicObject) receiver).getShape() == expectedShape;
}

@Override
Original file line number Diff line number Diff line change
@@ -15,6 +15,7 @@
import com.oracle.truffle.api.frame.FrameInstance;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.object.Shape;
import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.nodes.objects.SingletonClassNode;
import org.jruby.truffle.runtime.RubyArguments;
@@ -186,7 +187,7 @@ private DispatchNode doDynamicObject(
if (RubyGuards.isRubySymbol(receiverObject)) {
return new CachedBoxedSymbolDispatchNode(getContext(), methodName, first, method, indirect, getDispatchAction());
} else {
return new CachedBoxedDispatchNode(getContext(), methodName, first,
return new CachedBoxedDispatchNode(getContext(), methodName, first, ((DynamicObject) receiverObject).getShape(),
getContext().getCoreLibrary().getMetaClass(receiverObject), method, indirect, getDispatchAction());
}
}
@@ -207,9 +208,12 @@ private DispatchNode createMethodMissingNode(
DispatchNode first,
Object methodName,
Object receiverObject) {
// TODO (eregon, 26 Aug. 2015): should handle primitive types as well
final Shape shape = (receiverObject instanceof DynamicObject) ? ((DynamicObject) receiverObject).getShape() : null;

switch (missingBehavior) {
case RETURN_MISSING: {
return new CachedBoxedReturnMissingDispatchNode(getContext(), methodName, first,
return new CachedBoxedReturnMissingDispatchNode(getContext(), methodName, first, shape,
getContext().getCoreLibrary().getMetaClass(receiverObject), indirect, getDispatchAction());
}

@@ -225,7 +229,7 @@ private DispatchNode createMethodMissingNode(
return new UncachedDispatchNode(getContext(), ignoreVisibility, getDispatchAction(), missingBehavior);
}

return new CachedBoxedMethodMissingDispatchNode(getContext(), methodName, first,
return new CachedBoxedMethodMissingDispatchNode(getContext(), methodName, first, shape,
getContext().getCoreLibrary().getMetaClass(receiverObject), method, DISPATCH_METAPROGRAMMING_ALWAYS_INDIRECT, getDispatchAction());
}

Original file line number Diff line number Diff line change
@@ -35,9 +35,12 @@ public static abstract class ExceptionErrnoErrorPrimitiveNode extends RubiniusPr
protected final static int ENOTDIR = Errno.ENOTDIR.intValue();
protected final static int EINVAL = Errno.EINVAL.intValue();
protected final static int EINPROGRESS = Errno.EINPROGRESS.intValue();
protected final static int ENOTCONN = Errno.ENOTCONN.intValue();

public static boolean isExceptionSupported(int errno) {
return errno == EPERM || errno == ENOENT || errno == EBADF || errno == EEXIST || errno == EACCES || errno == EFAULT || errno == ENOTDIR || errno == EINVAL || errno == EINPROGRESS;
return errno == EPERM || errno == ENOENT || errno == EBADF || errno == EEXIST || errno == EACCES
|| errno == EFAULT || errno == ENOTDIR || errno == EINVAL || errno == EINPROGRESS
|| errno == ENOTCONN;
}

public ExceptionErrnoErrorPrimitiveNode(RubyContext context, SourceSection sourceSection) {
@@ -114,6 +117,11 @@ public DynamicObject einprogress(DynamicObject message, int errno) {
return getContext().getCoreLibrary().errnoError(errno, this);
}

@Specialization(guards = {"isRubyString(message)", "errno == ENOTCONN"})
public DynamicObject enotconn(DynamicObject message, int errno) {
return getContext().getCoreLibrary().errnoError(errno, this);
}

@TruffleBoundary
@Specialization(guards = "!isExceptionSupported(errno)")
public DynamicObject unsupported(Object message, int errno) {
Original file line number Diff line number Diff line change
@@ -65,11 +65,11 @@
import org.jruby.truffle.runtime.control.ThrowException;
import org.jruby.truffle.runtime.layouts.Layouts;
import org.jruby.truffle.runtime.signal.ProcSignalHandler;
import org.jruby.truffle.runtime.signal.Signal;
import org.jruby.truffle.runtime.signal.SignalOperations;
import org.jruby.truffle.runtime.subsystems.ThreadManager;
import org.jruby.util.StringSupport;
import org.jruby.util.io.PosixShim;
import sun.misc.Signal;

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;
Original file line number Diff line number Diff line change
@@ -174,7 +174,7 @@
* indirection so you may want to cache the result (against the shape).
*
* You can also use the getter and setter against the {@code DynamicObjectFactory} that
* {@code createFooShape} returns, with the setter reutrning a new factory. This allows
* {@code createFooShape} returns, with the setter returning a new factory. This allows
* objects to be created with modified shape properties, and is much more efficient than
* using the instance setter after creating the object.
*
Original file line number Diff line number Diff line change
@@ -16,8 +16,6 @@
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.layouts.Layouts;
import org.jruby.truffle.runtime.subsystems.SafepointAction;
import sun.misc.Signal;
import sun.misc.SignalHandler;

@SuppressWarnings("restriction")
public class ProcSignalHandler implements SignalHandler {
61 changes: 61 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/runtime/signal/Signal.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* 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.runtime.signal;

import java.util.Map;
import java.util.WeakHashMap;

public class Signal {

private final sun.misc.Signal signal;

private final static Map<sun.misc.SignalHandler, SignalHandler> handlers = new WeakHashMap<>();

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

public static SignalHandler handle(final Signal signal, final SignalHandler newHandler) {
final sun.misc.SignalHandler wrappedNewHandler = new sun.misc.SignalHandler() {

@Override
public void handle(sun.misc.Signal wrappedSignal) {
newHandler.handle(signal);
}

};

synchronized (handlers) {
handlers.put(wrappedNewHandler, newHandler);

final sun.misc.SignalHandler oldWrappedHandler = sun.misc.Signal.handle(signal.signal, wrappedNewHandler);

SignalHandler oldHandler = handlers.getOrDefault(oldWrappedHandler, null);

if (oldHandler == null) {
oldHandler = new SignalHandler() {
@Override
public void handle(Signal signal) {
oldWrappedHandler.handle(signal.signal);
}
};

handlers.put(oldWrappedHandler, oldHandler);
}

return oldHandler;
}
}

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

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

public interface SignalHandler {

void handle(Signal signal);

}
Original file line number Diff line number Diff line change
@@ -10,8 +10,6 @@
package org.jruby.truffle.runtime.signal;

import org.jruby.RubySignal;
import sun.misc.Signal;
import sun.misc.SignalHandler;

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

0 comments on commit b20f3ff

Please sign in to comment.