Skip to content

Commit

Permalink
Showing 5 changed files with 81 additions and 53 deletions.
9 changes: 9 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/core/CoreLibrary.java
Original file line number Diff line number Diff line change
@@ -206,6 +206,7 @@ public class CoreLibrary {
private final DynamicObjectFactory unboundMethodFactory;
private final DynamicObject byteArrayClass;
private final DynamicObjectFactory byteArrayFactory;
private final DynamicObjectFactory statFactory;
private final DynamicObject fiberErrorClass;
private final DynamicObject threadErrorClass;
private final DynamicObject internalBufferClass;
@@ -610,6 +611,10 @@ public CoreLibrary(RubyContext context) {
defineClass(rubiniusModule, objectClass, "Mirror");
defineModule(rubiniusModule, "Type");

DynamicObject statClass = defineClass(rubiniusModule, objectClass, "Stat");
statFactory = Layouts.STAT.createStatShape(statClass, statClass);
Layouts.CLASS.setInstanceFactoryUnsafe(statClass, statFactory);

byteArrayClass = defineClass(rubiniusModule, objectClass, "ByteArray");
byteArrayFactory = Layouts.BYTE_ARRAY.createByteArrayShape(byteArrayClass, byteArrayClass);
Layouts.CLASS.setInstanceFactoryUnsafe(byteArrayClass, byteArrayFactory);
@@ -1203,6 +1208,10 @@ public DynamicObjectFactory getByteArrayFactory() {
return byteArrayFactory;
}

public DynamicObjectFactory getStatFactory() {
return statFactory;
}

public DynamicObject getLookupTableClass() {
return lookupTableClass;
}
3 changes: 3 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/core/Layouts.java
Original file line number Diff line number Diff line change
@@ -68,6 +68,8 @@
import org.jruby.truffle.core.rubinius.PointerLayoutImpl;
import org.jruby.truffle.core.rubinius.RandomizerLayout;
import org.jruby.truffle.core.rubinius.RandomizerLayoutImpl;
import org.jruby.truffle.core.rubinius.StatLayout;
import org.jruby.truffle.core.rubinius.StatLayoutImpl;
import org.jruby.truffle.core.rubinius.WeakRefLayout;
import org.jruby.truffle.core.rubinius.WeakRefLayoutImpl;
import org.jruby.truffle.core.string.StringLayout;
@@ -130,6 +132,7 @@ public abstract class Layouts {
public static final HandleLayout HANDLE = HandleLayoutImpl.INSTANCE;
public static final TracePointLayout TRACE_POINT = TracePointLayoutImpl.INSTANCE;
public static final DigestLayout DIGEST = DigestLayoutImpl.INSTANCE;
public static final StatLayout STAT = StatLayoutImpl.INSTANCE;

// Other standard identifiers

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

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 jnr.posix.FileStat;
import org.jruby.truffle.core.basicobject.BasicObjectLayout;

@Layout
public interface StatLayout extends BasicObjectLayout {

DynamicObjectFactory createStatShape(DynamicObject logicalClass,
DynamicObject metaClass);

DynamicObject createStat(DynamicObjectFactory factory,
@Nullable FileStat stat);

FileStat getStat(DynamicObject object);
void setStat(DynamicObject object, FileStat stat);

}
Original file line number Diff line number Diff line change
@@ -14,66 +14,74 @@
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.object.HiddenKey;
import com.oracle.truffle.api.source.SourceSection;
import jnr.posix.FileStat;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.Layouts;
import org.jruby.truffle.core.string.StringOperations;
import org.jruby.truffle.language.SnippetNode;
import org.jruby.truffle.language.objects.ReadObjectFieldNode;
import org.jruby.truffle.language.objects.ReadObjectFieldNodeGen;
import org.jruby.truffle.language.objects.WriteObjectFieldNode;
import org.jruby.truffle.language.objects.WriteObjectFieldNodeGen;
import org.jruby.truffle.platform.UnsafeGroup;

public abstract class StatPrimitiveNodes {

public static final HiddenKey STAT_IDENTIFIER = new HiddenKey("stat");
static FileStat getStat(DynamicObject rubyStat) {
return Layouts.STAT.getStat(rubyStat);
}

@RubiniusPrimitive(name = "stat_allocate", unsafe = UnsafeGroup.IO)
public static abstract class StatAllocatePrimitiveNode extends RubiniusPrimitiveArrayArgumentsNode {

@Specialization
public DynamicObject allocate(DynamicObject classToAllocate) {
return Layouts.STAT.createStat(coreLibrary().getStatFactory(), null);
}

}

@RubiniusPrimitive(name = "stat_atime", unsafe = UnsafeGroup.IO)
public static abstract class StatAtimePrimitiveNode extends StatReadPrimitiveNode {
public static abstract class StatAtimePrimitiveNode extends RubiniusPrimitiveArrayArgumentsNode {

@Specialization
public Object atime(
VirtualFrame frame,
DynamicObject rubyStat,
@Cached("new()")SnippetNode snippetNode) {
@Cached("new()") SnippetNode snippetNode) {
final long time = getStat(rubyStat).atime();
return snippetNode.execute(frame, "Time.at(time)", "time", time);
}

}

@RubiniusPrimitive(name = "stat_ctime", unsafe = UnsafeGroup.IO)
public static abstract class StatCtimePrimitiveNode extends StatReadPrimitiveNode {
public static abstract class StatCtimePrimitiveNode extends RubiniusPrimitiveArrayArgumentsNode {

@Specialization
public Object ctime(
VirtualFrame frame,
DynamicObject rubyStat,
@Cached("new()")SnippetNode snippetNode) {
@Cached("new()") SnippetNode snippetNode) {
final long time = getStat(rubyStat).ctime();
return snippetNode.execute(frame, "Time.at(time)", "time", time);
}

}

@RubiniusPrimitive(name = "stat_mtime", unsafe = UnsafeGroup.IO)
public static abstract class StatMtimePrimitiveNode extends StatReadPrimitiveNode {
public static abstract class StatMtimePrimitiveNode extends RubiniusPrimitiveArrayArgumentsNode {

@Specialization
public Object mtime(
VirtualFrame frame,
DynamicObject rubyStat,
@Cached("new()")SnippetNode snippetNode) {
@Cached("new()") SnippetNode snippetNode) {
final long time = getStat(rubyStat).mtime();
return snippetNode.execute(frame, "Time.at(time)", "time", time);
}

}

@RubiniusPrimitive(name = "stat_nlink", unsafe = UnsafeGroup.IO)
public static abstract class NlinkPrimitiveNode extends StatReadPrimitiveNode {
public static abstract class NlinkPrimitiveNode extends RubiniusPrimitiveArrayArgumentsNode {

@Specialization
public int nlink(DynamicObject rubyStat) {
@@ -83,7 +91,7 @@ public int nlink(DynamicObject rubyStat) {
}

@RubiniusPrimitive(name = "stat_rdev", unsafe = UnsafeGroup.IO)
public static abstract class RdevPrimitiveNode extends StatReadPrimitiveNode {
public static abstract class RdevPrimitiveNode extends RubiniusPrimitiveArrayArgumentsNode {

@Specialization
public long rdev(DynamicObject rubyStat) {
@@ -93,7 +101,7 @@ public long rdev(DynamicObject rubyStat) {
}

@RubiniusPrimitive(name = "stat_blksize", unsafe = UnsafeGroup.IO)
public static abstract class StatBlksizePrimitiveNode extends StatReadPrimitiveNode {
public static abstract class StatBlksizePrimitiveNode extends RubiniusPrimitiveArrayArgumentsNode {

@Specialization
public long blksize(DynamicObject rubyStat) {
@@ -103,7 +111,7 @@ public long blksize(DynamicObject rubyStat) {
}

@RubiniusPrimitive(name = "stat_blocks", unsafe = UnsafeGroup.IO)
public static abstract class StatBlocksPrimitiveNode extends StatReadPrimitiveNode {
public static abstract class StatBlocksPrimitiveNode extends RubiniusPrimitiveArrayArgumentsNode {

@Specialization
public long blocks(DynamicObject rubyStat) {
@@ -113,7 +121,7 @@ public long blocks(DynamicObject rubyStat) {
}

@RubiniusPrimitive(name = "stat_dev", unsafe = UnsafeGroup.IO)
public static abstract class StatDevPrimitiveNode extends StatReadPrimitiveNode {
public static abstract class StatDevPrimitiveNode extends RubiniusPrimitiveArrayArgumentsNode {

@Specialization
public long dev(DynamicObject rubyStat) {
@@ -123,7 +131,7 @@ public long dev(DynamicObject rubyStat) {
}

@RubiniusPrimitive(name = "stat_ino", unsafe = UnsafeGroup.IO)
public static abstract class StatInoPrimitiveNode extends StatReadPrimitiveNode {
public static abstract class StatInoPrimitiveNode extends RubiniusPrimitiveArrayArgumentsNode {

@Specialization
public long ino(DynamicObject rubyStat) {
@@ -135,11 +143,8 @@ public long ino(DynamicObject rubyStat) {
@RubiniusPrimitive(name = "stat_stat", unsafe = UnsafeGroup.IO)
public static abstract class StatStatPrimitiveNode extends RubiniusPrimitiveArrayArgumentsNode {

@Child private WriteObjectFieldNode writeStatNode;

public StatStatPrimitiveNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
writeStatNode = WriteObjectFieldNodeGen.create(STAT_IDENTIFIER);
}

@TruffleBoundary
@@ -149,7 +154,7 @@ public int stat(DynamicObject rubyStat, DynamicObject path) {
final int code = posix().stat(StringOperations.decodeUTF8(path), stat);

if (code == 0) {
writeStatNode.execute(rubyStat, stat);
Layouts.STAT.setStat(rubyStat, stat);
}

return code;
@@ -165,11 +170,8 @@ public Object stat(DynamicObject rubyStat, Object path) {
@RubiniusPrimitive(name = "stat_fstat", unsafe = UnsafeGroup.IO)
public static abstract class StatFStatPrimitiveNode extends RubiniusPrimitiveArrayArgumentsNode {

@Child private WriteObjectFieldNode writeStatNode;

public StatFStatPrimitiveNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
writeStatNode = WriteObjectFieldNodeGen.create(STAT_IDENTIFIER);
}

@TruffleBoundary
@@ -179,7 +181,7 @@ public int fstat(DynamicObject rubyStat, int fd) {
final int code = posix().fstat(fd, stat);

if (code == 0) {
writeStatNode.execute(rubyStat, stat);
Layouts.STAT.setStat(rubyStat, stat);
}

return code;
@@ -190,11 +192,8 @@ public int fstat(DynamicObject rubyStat, int fd) {
@RubiniusPrimitive(name = "stat_lstat", unsafe = UnsafeGroup.IO)
public static abstract class StatLStatPrimitiveNode extends RubiniusPrimitiveArrayArgumentsNode {

@Child private WriteObjectFieldNode writeStatNode;

public StatLStatPrimitiveNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
writeStatNode = WriteObjectFieldNodeGen.create(STAT_IDENTIFIER);
}

@TruffleBoundary
@@ -204,7 +203,7 @@ public int lstat(DynamicObject rubyStat, DynamicObject path) {
final int code = posix().lstat(path.toString(), stat);

if (code == 0) {
writeStatNode.execute(rubyStat, stat);
Layouts.STAT.setStat(rubyStat, stat);
}

return code;
@@ -217,27 +216,8 @@ public Object stat(DynamicObject rubyStat, Object path) {

}

public static abstract class StatReadPrimitiveNode extends RubiniusPrimitiveArrayArgumentsNode {

@Child private ReadObjectFieldNode readStatNode;

public StatReadPrimitiveNode() {
this(null, null);
}

public StatReadPrimitiveNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
readStatNode = ReadObjectFieldNodeGen.create(STAT_IDENTIFIER, null);
}

public FileStat getStat(DynamicObject rubyStat) {
return (FileStat) readStatNode.execute(rubyStat);
}

}

@RubiniusPrimitive(name = "stat_size", unsafe = UnsafeGroup.IO)
public static abstract class StatSizePrimitiveNode extends StatReadPrimitiveNode {
public static abstract class StatSizePrimitiveNode extends RubiniusPrimitiveArrayArgumentsNode {

@Specialization
public long size(DynamicObject rubyStat) {
@@ -247,7 +227,7 @@ public long size(DynamicObject rubyStat) {
}

@RubiniusPrimitive(name = "stat_mode", unsafe = UnsafeGroup.IO)
public static abstract class StatModePrimitiveNode extends StatReadPrimitiveNode {
public static abstract class StatModePrimitiveNode extends RubiniusPrimitiveArrayArgumentsNode {

@Specialization
public int mode(DynamicObject rubyStat) {
@@ -257,7 +237,7 @@ public int mode(DynamicObject rubyStat) {
}

@RubiniusPrimitive(name = "stat_gid", unsafe = UnsafeGroup.IO)
public static abstract class StatGIDPrimitiveNode extends StatReadPrimitiveNode {
public static abstract class StatGIDPrimitiveNode extends RubiniusPrimitiveArrayArgumentsNode {

@Specialization
public int gid(DynamicObject rubyStat) {
@@ -267,7 +247,7 @@ public int gid(DynamicObject rubyStat) {
}

@RubiniusPrimitive(name = "stat_uid", unsafe = UnsafeGroup.IO)
public static abstract class StatUIDPrimitiveNode extends StatReadPrimitiveNode {
public static abstract class StatUIDPrimitiveNode extends RubiniusPrimitiveArrayArgumentsNode {

@Specialization
public int uid(DynamicObject rubyStat) {
5 changes: 5 additions & 0 deletions truffle/src/main/ruby/core/rubinius/bootstrap/stat.rb
Original file line number Diff line number Diff line change
@@ -27,6 +27,11 @@
module Rubinius
class Stat

def self.allocate
Rubinius.primitive :stat_allocate
raise PrimitiveFailure, "Rubinius::Stat.allocate primitive failed"
end

def setup(path)
Rubinius.primitive :stat_stat
path = Rubinius::Type.coerce_to_path(path)

0 comments on commit b5c186e

Please sign in to comment.