Skip to content

Commit

Permalink
Showing 13 changed files with 129 additions and 27 deletions.
4 changes: 0 additions & 4 deletions spec/truffle/tags/core/exception/system_call_error_tags.txt

This file was deleted.

3 changes: 3 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/Layouts.java
Original file line number Diff line number Diff line change
@@ -26,6 +26,8 @@
import org.jruby.truffle.core.encoding.EncodingLayoutImpl;
import org.jruby.truffle.core.exception.ExceptionLayout;
import org.jruby.truffle.core.exception.ExceptionLayoutImpl;
import org.jruby.truffle.core.exception.SystemCallErrorLayout;
import org.jruby.truffle.core.exception.SystemCallErrorLayoutImpl;
import org.jruby.truffle.core.fiber.FiberLayout;
import org.jruby.truffle.core.fiber.FiberLayoutImpl;
import org.jruby.truffle.core.hash.HashLayout;
@@ -138,6 +140,7 @@ public abstract class Layouts {
public static final TracePointLayout TRACE_POINT = TracePointLayoutImpl.INSTANCE;
public static final DigestLayout DIGEST = DigestLayoutImpl.INSTANCE;
public static final StatLayout STAT = StatLayoutImpl.INSTANCE;
public static final SystemCallErrorLayout SYSTEM_CALL_ERROR = SystemCallErrorLayoutImpl.INSTANCE;

// Other standard identifiers

4 changes: 4 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/core/CoreLibrary.java
Original file line number Diff line number Diff line change
@@ -44,6 +44,7 @@
import org.jruby.truffle.core.encoding.EncodingConverterNodesFactory;
import org.jruby.truffle.core.encoding.EncodingNodesFactory;
import org.jruby.truffle.core.exception.ExceptionNodesFactory;
import org.jruby.truffle.core.exception.SystemCallErrorNodesFactory;
import org.jruby.truffle.core.fiber.FiberNodesFactory;
import org.jruby.truffle.core.hash.HashNodesFactory;
import org.jruby.truffle.core.kernel.KernelNodesFactory;
@@ -468,6 +469,7 @@ public CoreLibrary(RubyContext context) {

// StandardError > SystemCallError
systemCallErrorClass = defineClass(standardErrorClass, "SystemCallError");
Layouts.CLASS.setInstanceFactoryUnsafe(systemCallErrorClass, Layouts.SYSTEM_CALL_ERROR.createSystemCallErrorShape(systemCallErrorClass, systemCallErrorClass));

errnoModule = defineModule("Errno");

@@ -745,6 +747,7 @@ public void addPrimitives() {
primitiveManager.addPrimitiveNodes(IOPrimitiveNodesFactory.getFactories());
primitiveManager.addPrimitiveNodes(IOBufferPrimitiveNodesFactory.getFactories());
primitiveManager.addPrimitiveNodes(ExceptionNodesFactory.getFactories());
primitiveManager.addPrimitiveNodes(SystemCallErrorNodesFactory.getFactories());
return null;
}, () -> {
primitiveManager.addPrimitiveNodes(ThreadNodesFactory.getFactories());
@@ -773,6 +776,7 @@ public void addCoreMethods() {
coreMethodNodeManager.addCoreMethodNodes(ClassNodesFactory.getFactories());
coreMethodNodeManager.addCoreMethodNodes(ConditionVariableNodesFactory.getFactories());
coreMethodNodeManager.addCoreMethodNodes(ExceptionNodesFactory.getFactories());
coreMethodNodeManager.addCoreMethodNodes(SystemCallErrorNodesFactory.getFactories());
coreMethodNodeManager.addCoreMethodNodes(FalseClassNodesFactory.getFactories());
return null;
}, () -> {
Original file line number Diff line number Diff line change
@@ -91,7 +91,7 @@ private Object clock_gettime_clock_id(int clock_id, DynamicObject unit) {
TimeSpec timeSpec = new TimeSpec(jnr.ffi.Runtime.getRuntime(libCClockGetTime));
int r = libCClockGetTime.clock_gettime(clock_id, timeSpec);
if (r != 0) {
throw new RaiseException(coreExceptions().systemCallError("clock_gettime failed: " + r, this));
throw new RaiseException(coreExceptions().systemCallError("clock_gettime failed: " + r, r, this));
}
long nanos = timeSpec.getTVsec() * 1_000_000_000 + timeSpec.getTVnsec();
return timeToUnit(nanos, unit);
Original file line number Diff line number Diff line change
@@ -210,30 +210,30 @@ public DynamicObject mathDomainErrorLog(Node currentNode) {

@TruffleBoundary
public DynamicObject mathDomainError(String method, Node currentNode) {
return ExceptionOperations.createRubyException(
return ExceptionOperations.createSystemCallError(
context.getCoreLibrary().getErrnoClass(Errno.EDOM),
StringOperations.createString(context, StringOperations.encodeRope(String.format("Numerical argument is out of domain - \"%s\"", method), UTF8Encoding.INSTANCE)),
context.getCallStack().getBacktrace(currentNode));
context.getCallStack().getBacktrace(currentNode), Errno.EDOM.intValue());
}

@TruffleBoundary
public DynamicObject errnoError(int errno, Node currentNode) {
Errno errnoObj = Errno.valueOf(errno);
if (errnoObj == null) {
return systemCallError(String.format("Unknown Error (%s)", errno), currentNode);
return systemCallError(String.format("Unknown Error (%s)", errno), errno, currentNode);
}

return ExceptionOperations.createRubyException(
return ExceptionOperations.createSystemCallError(
context.getCoreLibrary().getErrnoClass(errnoObj),
StringOperations.createString(context, StringOperations.encodeRope(errnoObj.description(), UTF8Encoding.INSTANCE)),
context.getCallStack().getBacktrace(currentNode));
context.getCallStack().getBacktrace(currentNode), errno);
}

@TruffleBoundary
public DynamicObject errnoError(int errno, String message, Node currentNode) {
Errno errnoObj = Errno.valueOf(errno);
if (errnoObj == null) {
return systemCallError(String.format("Unknown Error (%s) - %s", errno, message), currentNode);
return systemCallError(String.format("Unknown Error (%s) - %s", errno, message), errno, currentNode);
}

DynamicObject errnoClass = context.getCoreLibrary().getErrnoClass(errnoObj);
@@ -242,12 +242,12 @@ public DynamicObject errnoError(int errno, String message, Node currentNode) {
message = "Unknown error: " + errno;
}

final DynamicObject errorMessage = StringOperations.createString(context, StringOperations.encodeRope(String.format("%s - %s", errnoObj.description(), message), UTF8Encoding.INSTANCE));
final DynamicObject errorMessage = StringOperations.createString(context, StringOperations.encodeRope(String.format("%s%s", errnoObj.description(), message), UTF8Encoding.INSTANCE));

return ExceptionOperations.createRubyException(
return ExceptionOperations.createSystemCallError(
errnoClass,
errorMessage,
context.getCallStack().getBacktrace(currentNode));
context.getCallStack().getBacktrace(currentNode), errno);
}

// IndexError
@@ -759,29 +759,29 @@ public DynamicObject securityError(String message, Node currentNode) {
// SystemCallError

@TruffleBoundary
public DynamicObject systemCallError(String message, Node currentNode) {
return ExceptionOperations.createRubyException(
public DynamicObject systemCallError(String message, int errno, Node currentNode) {
return ExceptionOperations.createSystemCallError(
context.getCoreLibrary().getSystemCallErrorClass(),
StringOperations.createString(context, StringOperations.encodeRope(message, UTF8Encoding.INSTANCE)),
context.getCallStack().getBacktrace(currentNode));
context.getCallStack().getBacktrace(currentNode), errno);
}

// IO::EAGAINWaitReadable, IO::EAGAINWaitWritable

@TruffleBoundary
public DynamicObject eAGAINWaitReadable(Node currentNode) {
return ExceptionOperations.createRubyException(
return ExceptionOperations.createSystemCallError(
context.getCoreLibrary().getEagainWaitReadable(),
coreStrings().RESOURCE_TEMP_UNAVAIL.createInstance(),
context.getCallStack().getBacktrace(currentNode));
context.getCallStack().getBacktrace(currentNode), Errno.EAGAIN.intValue());
}

@TruffleBoundary
public DynamicObject eAGAINWaitWritable(Node currentNode) {
return ExceptionOperations.createRubyException(
return ExceptionOperations.createSystemCallError(
context.getCoreLibrary().getEagainWaitWritable(),
coreStrings().RESOURCE_TEMP_UNAVAIL.createInstance(),
context.getCallStack().getBacktrace(currentNode));
context.getCallStack().getBacktrace(currentNode), Errno.EAGAIN.intValue());
}

// SystemExit
Original file line number Diff line number Diff line change
@@ -27,6 +27,7 @@
import org.jruby.truffle.builtins.PrimitiveArrayArgumentsNode;
import org.jruby.truffle.core.string.StringOperations;
import org.jruby.truffle.language.NotProvided;
import org.jruby.truffle.language.RubyGuards;
import org.jruby.truffle.language.backtrace.Backtrace;
import org.jruby.truffle.language.objects.AllocateObjectNode;
import org.jruby.truffle.language.objects.AllocateObjectNodeGen;
@@ -139,7 +140,7 @@ public AllocateNode(RubyContext context, SourceSection sourceSection) {

@Specialization
public DynamicObject allocate(DynamicObject rubyClass) {
return allocateObjectNode.allocate(rubyClass, null, null);
return allocateObjectNode.allocate(rubyClass, null, null, nil());
}

}
@@ -148,8 +149,14 @@ public DynamicObject allocate(DynamicObject rubyClass) {
public static abstract class ExceptionErrnoErrorPrimitiveNode extends PrimitiveArrayArgumentsNode {

@Specialization
public DynamicObject exceptionErrnoError(DynamicObject message, int errno) {
return coreExceptions().errnoError(errno, message.toString(), this);
public DynamicObject exceptionErrnoError(DynamicObject message, int errno, DynamicObject location) {
final String errorMessage;
if(RubyGuards.isRubyString(location)){
errorMessage = " @ " + location.toString() + " - " + message.toString();
} else {
errorMessage = " - " + message.toString();
}
return coreExceptions().errnoError(errno, errorMessage, this);
}

}
Original file line number Diff line number Diff line change
@@ -50,4 +50,8 @@ public static DynamicObject createRubyException(DynamicObject rubyClass, Object
return Layouts.EXCEPTION.createException(Layouts.CLASS.getInstanceFactory(rubyClass), message, backtrace);
}

public static DynamicObject createSystemCallError(DynamicObject rubyClass, Object message, Backtrace backtrace, int errno) {
return Layouts.SYSTEM_CALL_ERROR.createSystemCallError(Layouts.CLASS.getInstanceFactory(rubyClass), message, backtrace, errno);
}

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

import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.object.DynamicObjectFactory;
import com.oracle.truffle.api.object.dsl.Layout;
import com.oracle.truffle.api.object.dsl.Nullable;
import org.jruby.truffle.language.backtrace.Backtrace;

@Layout
public interface SystemCallErrorLayout extends ExceptionLayout {

DynamicObjectFactory createSystemCallErrorShape(
DynamicObject logicalClass,
DynamicObject metaClass);

DynamicObject createSystemCallError(
DynamicObjectFactory factory,
@Nullable Object message,
@Nullable Backtrace backtrace,
@Nullable Object errno);

Object getErrno(DynamicObject object);
void setErrno(DynamicObject object, Object value);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.jruby.truffle.core.exception;

import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.NodeChildren;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.object.DynamicObject;
import org.jruby.truffle.Layouts;
import org.jruby.truffle.builtins.CoreClass;
import org.jruby.truffle.builtins.CoreMethod;
import org.jruby.truffle.builtins.CoreMethodArrayArgumentsNode;
import org.jruby.truffle.builtins.NonStandard;
import org.jruby.truffle.language.RubyNode;

@CoreClass("SystemCallError")
public abstract class SystemCallErrorNodes {

@CoreMethod(names = "errno")
public abstract static class ErrnoNode extends CoreMethodArrayArgumentsNode {

@Specialization
public Object errno(DynamicObject self) {
return Layouts.SYSTEM_CALL_ERROR.getErrno(self);
}

}

@NonStandard
@NodeChildren({
@NodeChild(type = RubyNode.class, value = "self"),
@NodeChild(type = RubyNode.class, value = "errno")
})
public abstract static class InternalSetErrnoNode extends RubyNode {

@Specialization
public Object setErrno(DynamicObject error, int errno) {
Layouts.SYSTEM_CALL_ERROR.setErrno(error, errno);
return errno;
}

@Specialization(guards = "isNil(errno)")
public Object setErrno(DynamicObject error, DynamicObject errno) {
Layouts.SYSTEM_CALL_ERROR.setErrno(error, errno);
return errno;
}

}

}
Original file line number Diff line number Diff line change
@@ -167,7 +167,7 @@ private int performFill(int fd, byte[] readBuffer, int count) {
getContext().getSafepointManager().poll(this);
continue;
} else {
throw new RaiseException(ExceptionOperations.createRubyException(coreLibrary().getErrnoClass(Errno.valueOf(errno))));
throw new RaiseException(ExceptionOperations.createSystemCallError(coreLibrary().getErrnoClass(Errno.valueOf(errno)), null, null, errno));
}
} else {
break;
Original file line number Diff line number Diff line change
@@ -49,6 +49,7 @@
import org.jruby.truffle.core.cast.ToProcNodeGen;
import org.jruby.truffle.core.cast.ToSNode;
import org.jruby.truffle.core.cast.ToSNodeGen;
import org.jruby.truffle.core.exception.SystemCallErrorNodesFactory;
import org.jruby.truffle.core.hash.ConcatHashLiteralNode;
import org.jruby.truffle.core.hash.HashLiteralNode;
import org.jruby.truffle.core.hash.HashNodesFactory;
@@ -1827,6 +1828,12 @@ public RubyNode visitInstAsgnNode(org.jruby.ast.InstAsgnNode node) {
ret = new WriteInstanceVariableNode(context, sourceSection, name, self, IntegerCastNodeGen.create(context, sourceSection, rhs));
return addNewlineIfNeeded(node, ret);
}
} else if (path.equals(corePath + "exception.rb")) {
if (name.equals("@errno")) {
ret = SystemCallErrorNodesFactory.InternalSetErrnoNodeGen.create(self, rhs);
setSourceSection(ret, sourceSection);
return addNewlineIfNeeded(node, ret);
}
}

ret = new WriteInstanceVariableNode(context, sourceSection, name, self, rhs);
Original file line number Diff line number Diff line change
@@ -33,7 +33,7 @@ public TrufflePosixHandler(RubyContext context) {
public void error(Errno errno, String methodName) {
// TODO CS 17-Apr-15 - not specialised, no way to build a good stacktrace, missing content for error messages

throw new RaiseException(ExceptionOperations.createRubyException(context.getCoreLibrary().getErrnoClass(errno)));
throw new RaiseException(ExceptionOperations.createSystemCallError(context.getCoreLibrary().getErrnoClass(errno), null, null, errno.intValue()));
}

@Override
1 change: 0 additions & 1 deletion truffle/src/main/ruby/core/exception.rb
Original file line number Diff line number Diff line change
@@ -292,7 +292,6 @@ def success?

class SystemCallError < StandardError

attr_reader :errno

def self.errno_error(message, errno, location)
Truffle.primitive :exception_errno_error

0 comments on commit 0e2c04c

Please sign in to comment.