Skip to content

Commit

Permalink
[Truffle] Add POSIX and Pointer nodes for File.readlink
Browse files Browse the repository at this point in the history
  • Loading branch information
bjfish committed May 7, 2015
1 parent 440a90f commit 5b296eb
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 6 deletions.
6 changes: 0 additions & 6 deletions spec/truffle/tags/core/file/readlink_tags.txt

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.core.RubyClass;
import org.jruby.truffle.runtime.core.RubyString;
import org.jruby.util.unsafe.UnsafeHolder;
import sun.misc.Unsafe;

public abstract class PointerPrimitiveNodes {

Expand Down Expand Up @@ -172,6 +174,25 @@ protected boolean isSigned(boolean signed) {

}

@RubiniusPrimitive(name = "pointer_read_string")
public static abstract class PointerReadStringPrimitiveNode extends ReadAddressPrimitiveNode {

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

@Specialization
public RubyString readString(RubyBasicObject pointer, int length) {
final long address = getAddress(pointer);
final byte[] bytes = new byte[length];
for (int n = 0; n < bytes.length; n++) {
bytes[n] = UnsafeHolder.U.getByte(address + n * Unsafe.ARRAY_BYTE_INDEX_SCALE);
}
return getContext().makeString(bytes);
}

}

@RubiniusPrimitive(name = "pointer_set_autorelease")
public static abstract class PointerSetAutoreleasePrimitiveNode extends ReadAddressPrimitiveNode {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
*/
package org.jruby.truffle.nodes.rubinius;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.source.SourceSection;
import jnr.constants.platform.Fcntl;
Expand All @@ -18,6 +19,7 @@
import org.jruby.truffle.nodes.core.CoreMethod;
import org.jruby.truffle.nodes.core.CoreMethodArrayArgumentsNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.core.RubyNilClass;
import org.jruby.truffle.runtime.core.RubyString;
Expand Down Expand Up @@ -201,6 +203,31 @@ public RubyBasicObject memset(RubyBasicObject pointer, int c, long length) {

}

@CoreMethod(names = "readlink", isModuleFunction = true, required = 3)
public abstract static class ReadlinkNode extends PointerPrimitiveNodes.ReadAddressPrimitiveNode {

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

@Specialization
public int readlink(RubyString path, RubyBasicObject pointer, int bufsize) {
final String pathString = RubyEncoding.decodeUTF8(path.getByteList().getUnsafeBytes(), path.getByteList().getBegin(), path.getByteList().getRealSize());
final long address = getAddress(pointer);
final byte[] buffer = new byte[bufsize];
final int result = posix().readlink(pathString, buffer, bufsize);
if (result == -1) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().errnoError(posix().errno(), this));
}
for (int n = 0; n < buffer.length; n++) {
UnsafeHolder.U.putInt(address + n * Unsafe.ARRAY_BYTE_INDEX_SCALE, buffer[n]);

This comment has been minimized.

Copy link
@nirvdrum

nirvdrum May 7, 2015

Contributor

I think you want putByte here. It probably ends up being okay because you work your way forward, but putInt will end up writing over 4 byte slots allocated in the array, as far as I can tell.

This comment has been minimized.

Copy link
@bjfish

bjfish May 7, 2015

Author Contributor

Fixed at 8b700b6

This comment has been minimized.

Copy link
@nirvdrum

nirvdrum May 7, 2015

Contributor

Thanks. And I guess while you may not have seen a problem with the old approach, you'd end up writing 3 bytes after allocated memory which could lead to all sorts of unpredictable, non-deterministic problems.

}
return result;
}

}

@CoreMethod(names = "link", isModuleFunction = true, required = 2)
public abstract static class LinkNode extends PointerPrimitiveNodes.ReadAddressPrimitiveNode {

Expand Down

0 comments on commit 5b296eb

Please sign in to comment.