Skip to content

Commit

Permalink
Showing 26 changed files with 2,942 additions and 225 deletions.
9 changes: 0 additions & 9 deletions spec/truffle/tags/core/file/constants_tags.txt
Original file line number Diff line number Diff line change
@@ -1,14 +1,5 @@
fails:File::Constants matches mode constants
fails:File::Constants the open mode constants
fails:File::Constants lock mode constants
fails:File::Constants File::RDONLY
fails:File::Constants File::WRONLY
fails:File::Constants File::CREAT
fails:File::Constants File::RDWR
fails:File::Constants File::APPEND
fails:File::Constants File::TRUNC
fails:File::Constants File::NOCTTY
fails:File::Constants File::NONBLOCK
fails:File::Constants File::LOCK_EX
fails:File::Constants File::LOCK_NB
fails:File::Constants File::LOCK_SH
4 changes: 0 additions & 4 deletions spec/truffle/tags/core/file/delete_tags.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1 @@
fails:File.delete returns 0 when called without arguments
fails:File.delete deletes multiple files
fails:File.delete raises an Errno::ENOENT when the given file doesn't exist
fails:File.delete coerces a given parameter into a string if possible
fails:File.delete accepts an object that has a #to_path method
1 change: 0 additions & 1 deletion spec/truffle/tags/core/file/exist_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/core/file/exists_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/core/file/file_tags.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
fails:File includes File::Constants
fails:File.file? accepts an object that has a #to_path method
windows:File.file? returns true if the named file exists and is a regular file.
windows:File.file? raises an ArgumentError if not passed one argument
windows:File.file? raises a TypeError if not passed a String type
4 changes: 0 additions & 4 deletions spec/truffle/tags/core/file/open_tags.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
fails:File.open opens the file (basic case)
fails:File.open opens a file when called with a block
fails:File.open opens with mode string
fails:File.open opens a file with mode string and block
fails:File.open opens a file with mode num
fails:File.open opens a file with mode num and block
fails:File.open opens a file with mode and permission as nil
fails:File.open opens the file when passed mode, num and permissions
fails:File.open opens the file when passed mode, num, permissions and block
@@ -28,7 +26,6 @@ fails:File.open raises an IO exception when write in a block opened with 'r' mod
fails:File.open can't write in a block when call open with File::WRONLY||File::RDONLY mode
fails:File.open can't read in a block when call open with File::WRONLY||File::RDONLY mode
fails:File.open can write in a block when call open with WRONLY mode
fails:File.open can write in a block when call open with 'w' mode
fails:File.open raises an IOError when read in a block opened with WRONLY mode
fails:File.open raises an IOError when read in a block opened with 'w' mode
fails:File.open raises an IOError when read in a block opened with 'a' mode
@@ -56,7 +53,6 @@ fails:File.open opens a file for binary read-write starting at the beginning of
fails:File.open opens a file for binary read-write and truncate the file
fails:File.open raises a TypeError if passed a filename that is not a String or Integer type
fails:File.open raises a SystemCallError if passed an invalid Integer type
fails:File.open raises an ArgumentError if passed the wrong number of arguments
fails:File.open raises an ArgumentError if passed an invalid string for mode
fails:File.open defaults external_encoding to ASCII-8BIT for binary modes
fails:File.open uses the second argument as an options Hash
2 changes: 0 additions & 2 deletions spec/truffle/tags/core/file/stat/sticky_tags.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
fails:File::Stat#sticky? returns true if the named file has the sticky bit, otherwise false
fails:File::Stat#sticky? accepts an object that has a #to_path method
fails:File::Stat#sticky? needs to be reviewed for spec completeness
Original file line number Diff line number Diff line change
@@ -22,6 +22,7 @@
import org.jruby.truffle.nodes.control.SequenceNode;
import org.jruby.truffle.nodes.core.*;
import org.jruby.truffle.nodes.rubinius.ByteArrayNodesFactory;
import org.jruby.truffle.nodes.rubinius.PosixNodesFactory;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.backtrace.Backtrace;
import org.jruby.truffle.runtime.control.RaiseException;
@@ -100,6 +101,7 @@ public void init() {
CoreMethodNodeManager.addCoreMethodNodes(rubyObjectClass, UnboundMethodNodesFactory.getFactories());
CoreMethodNodeManager.addCoreMethodNodes(rubyObjectClass, ByteArrayNodesFactory.getFactories());
CoreMethodNodeManager.addCoreMethodNodes(rubyObjectClass, TimeNodesFactory.getFactories());
CoreMethodNodeManager.addCoreMethodNodes(rubyObjectClass, PosixNodesFactory.getFactories());

// Give the core library manager a chance to tweak some of those methods

182 changes: 0 additions & 182 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/FileNodes.java
Original file line number Diff line number Diff line change
@@ -121,51 +121,6 @@ public RubyNilClass close(RubyFile file) {

}

@CoreMethod(names = { "delete", "unlink" }, onSingleton = true, required = 1)
public abstract static class DeleteNode extends CoreMethodNode {

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

public DeleteNode(DeleteNode prev) {
super(prev);
}

@Specialization
public int delete(RubyString file) {
notDesignedForCompilation();

if (!new File(file.toString()).delete()) {
// TODO(CS, 12-Jan-15) handle failure
throw new UnsupportedOperationException();
}

return 1;
}

}

@CoreMethod(names = "directory?", onSingleton = true, required = 1)
public abstract static class DirectoryNode extends CoreMethodNode {

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

public DirectoryNode(DirectoryNode prev) {
super(prev);
}

@Specialization
public boolean directory(RubyString path) {
notDesignedForCompilation();

return new File(path.toString()).isDirectory();
}

}

@CoreMethod(names = "dirname", onSingleton = true, required = 1)
public abstract static class DirnameNode extends CoreMethodNode {

@@ -234,51 +189,6 @@ public RubyNilClass eachLine(VirtualFrame frame, RubyFile file, RubyProc block)

}

@CoreMethod(names = "executable?", onSingleton = true, required = 1)
public abstract static class ExecutableNode extends CoreMethodNode {

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

public ExecutableNode(ExecutableNode prev) {
super(prev);
}

@Specialization
public boolean executable(RubyString path) {
notDesignedForCompilation();

return new File(path.toString()).canExecute();
}

}

@CoreMethod(names = {"exist?", "exists?"}, onSingleton = true, required = 1)
@NodeChild(value = "path")
public abstract static class ExistsNode extends RubyNode {

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

public ExistsNode(ExistsNode prev) {
super(prev);
}

@CreateCast("path") public RubyNode coercePathToString(RubyNode path) {
return ToStrNodeFactory.create(getContext(), getSourceSection(), path);
}

@Specialization
public boolean exists(RubyString path) {
notDesignedForCompilation();

return new File(path.toString()).exists();
}

}

@CoreMethod(names = "expand_path", onSingleton = true, required = 1, optional = 1)
public abstract static class ExpandPathNode extends CoreMethodNode {

@@ -304,26 +214,6 @@ public RubyString expandPath(RubyString path, RubyString dir) {

}

@CoreMethod(names = "file?", onSingleton = true, required = 1)
public abstract static class FileNode extends CoreMethodNode {

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

public FileNode(FileNode prev) {
super(prev);
}

@Specialization
public boolean file(RubyString path) {
notDesignedForCompilation();

return new File(path.toString()).isFile();
}

}

@CoreMethod(names = "join", onSingleton = true, argumentsAsArray = true)
public abstract static class JoinNode extends CoreMethodNode {

@@ -399,26 +289,6 @@ public Object open(VirtualFrame frame, RubyString fileName, RubyString mode, Rub

}

@CoreMethod(names = "path", onSingleton = true, required = 1)
public abstract static class PathNode extends CoreMethodNode {

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

public PathNode(PathNode prev) {
super(prev);
}

@Specialization
public RubyString path(RubyString path) {
notDesignedForCompilation();

return getContext().makeString(path.toString());
}

}

@CoreMethod(names = "puts", required = 1)
public abstract static class PutsNode extends CoreMethodNode {

@@ -507,26 +377,6 @@ public RubyString read(RubyFile file) {

}

@CoreMethod(names = "readable?", onSingleton = true, needsSelf = false, required = 1)
public abstract static class ReadableQueryNode extends CoreMethodNode {

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

public ReadableQueryNode(ReadableQueryNode prev) {
super(prev);
}

@Specialization
public boolean isReadable(RubyString file) {
notDesignedForCompilation();

return new File(file.toString()).canRead();
}

}

@CoreMethod(names = "realpath", onSingleton = true, required = 1, optional = 1)
public abstract static class RealpathNode extends CoreMethodNode {

@@ -562,38 +412,6 @@ private String realpath(String path, String dir) {

}

@CoreMethod(names = "size?", onSingleton = true, required = 1)
public abstract static class SizeNode extends CoreMethodNode {

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

public SizeNode(SizeNode prev) {
super(prev);
}

@Specialization
public Object read(RubyString file) {
notDesignedForCompilation();

final File f = new File(file.toString());

if (!f.exists()) {
return nil();
}

final long size = f.length();

if (size == 0) {
return nil();
}

return size;
}

}

@CoreMethod(names = "symlink?", onSingleton = true, required = 1)
public abstract static class SymlinkQueryNode extends CoreMethodNode {

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

import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import com.oracle.truffle.api.object.HiddenKey;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.objectstorage.ReadHeadObjectFieldNode;
import org.jruby.truffle.nodes.objectstorage.WriteHeadObjectFieldNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.RubyBasicObject;

public abstract class NativeFunctionPrimitiveNodes {

public static final int TYPE_CHAR = 0;
public static final int TYPE_UCHAR = 1;
public static final int TYPE_BOOL = 2;
public static final int TYPE_SHORT = 3;
public static final int TYPE_USHORT = 4;
public static final int TYPE_INT = 5;
public static final int TYPE_UINT = 6;
public static final int TYPE_LONG = 7;
public static final int TYPE_ULONG = 8;
public static final int TYPE_LL = 9;
public static final int TYPE_ULL = 10;
public static final int TYPE_FLOAT = 11;
public static final int TYPE_DOUBLE = 12;
public static final int TYPE_PTR = 13;
public static final int TYPE_VOID = 14;
public static final int TYPE_STRING = 15;
public static final int TYPE_STRPTR = 16;
public static final int TYPE_CHARARR = 17;
public static final int TYPE_ENUM = 18;
public static final int TYPE_VARARGS = 19;

@RubiniusPrimitive(name = "nativefunction_type_size", needsSelf = false)
public static abstract class NativeFunctionTypeSizePrimitiveNode extends RubiniusPrimitiveNode {

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

public NativeFunctionTypeSizePrimitiveNode(NativeFunctionTypeSizePrimitiveNode prev) {
super(prev);
}

@Specialization
public long typeSize(int type) {
switch (type) {
case TYPE_CHAR:
case TYPE_UCHAR:
return 1;

case TYPE_SHORT:
case TYPE_USHORT:
return 2;

case TYPE_INT:
case TYPE_UINT:
return 4;

case TYPE_LONG:
case TYPE_ULONG:
return 8;

case TYPE_FLOAT:
return 4;

case TYPE_DOUBLE:
return 8;

case TYPE_PTR:
case TYPE_STRPTR:
return 8;

case TYPE_BOOL:
case TYPE_LL:
case TYPE_ULL:
case TYPE_VOID:
case TYPE_STRING:
case TYPE_CHARARR:
case TYPE_ENUM:
case TYPE_VARARGS:
default:
throw new UnsupportedOperationException();
}
}

}

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

import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import com.oracle.truffle.api.object.HiddenKey;
import com.oracle.truffle.api.source.SourceSection;
import jnr.posix.FileStat;
import org.jruby.truffle.nodes.objectstorage.ReadHeadObjectFieldNode;
import org.jruby.truffle.nodes.objectstorage.WriteHeadObjectFieldNode;
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 {

public static final HiddenKey ADDRESS_IDENTIFIER = new HiddenKey("address");

public static abstract class WriteAddressPrimitiveNode extends RubiniusPrimitiveNode {

@Child private WriteHeadObjectFieldNode writeAddressNode;

public WriteAddressPrimitiveNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
writeAddressNode = new WriteHeadObjectFieldNode(PointerPrimitiveNodes.ADDRESS_IDENTIFIER);
}

public WriteAddressPrimitiveNode(WriteAddressPrimitiveNode prev) {
super(prev);
writeAddressNode = prev.writeAddressNode;
}

public long writeAddress(RubyBasicObject pointer, long address) {
writeAddressNode.execute(pointer, address);
return address;
}

}

public static abstract class ReadAddressPrimitiveNode extends RubiniusPrimitiveNode {

@Child private ReadHeadObjectFieldNode readAddressNode;

public ReadAddressPrimitiveNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
readAddressNode = new ReadHeadObjectFieldNode(PointerPrimitiveNodes.ADDRESS_IDENTIFIER);
}

public ReadAddressPrimitiveNode(ReadAddressPrimitiveNode prev) {
super(prev);
readAddressNode = prev.readAddressNode;
}

public long getAddress(RubyBasicObject pointer) {
try {
return readAddressNode.executeLong(pointer);
} catch (UnexpectedResultException e) {
throw new UnsupportedOperationException();
}
}

}

@RubiniusPrimitive(name = "pointer_malloc")
public static abstract class PointerMallocPrimitiveNode extends WriteAddressPrimitiveNode {

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

public PointerMallocPrimitiveNode(PointerMallocPrimitiveNode prev) {
super(prev);
}

@Specialization
public RubyBasicObject malloc(RubyClass pointerClass, int size) {
return malloc(pointerClass, (long) size);
}

@Specialization
public RubyBasicObject malloc(RubyClass pointerClass, long size) {
final RubyBasicObject pointer = new RubyBasicObject(pointerClass);
writeAddress(pointer, UnsafeHolder.U.allocateMemory(size));
return pointer;
}

}

@RubiniusPrimitive(name = "pointer_free")
public static abstract class PointerFreePrimitiveNode extends ReadAddressPrimitiveNode {

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

public PointerFreePrimitiveNode(PointerFreePrimitiveNode prev) {
super(prev);
}

@Specialization
public long free(RubyBasicObject pointer) {
final long address = getAddress(pointer);
UnsafeHolder.U.freeMemory(address);
return address;
}

}

@RubiniusPrimitive(name = "pointer_set_address")
public static abstract class PointerSetAddressPrimitiveNode extends WriteAddressPrimitiveNode {

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

public PointerSetAddressPrimitiveNode(PointerSetAddressPrimitiveNode prev) {
super(prev);
}

@Specialization
public long setAddress(RubyBasicObject pointer, int address) {
return setAddress(pointer, (long) address);
}

@Specialization
public long setAddress(RubyBasicObject pointer, long address) {
return writeAddress(pointer, address);
}

}

@RubiniusPrimitive(name = "pointer_add")
public static abstract class PointerAddPrimitiveNode extends WriteAddressPrimitiveNode {

@Child private WriteHeadObjectFieldNode writeAddressNode;
@Child private ReadHeadObjectFieldNode readAddressNode;

public PointerAddPrimitiveNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
writeAddressNode = new WriteHeadObjectFieldNode(ADDRESS_IDENTIFIER);
readAddressNode = new ReadHeadObjectFieldNode(PointerPrimitiveNodes.ADDRESS_IDENTIFIER);
}

public PointerAddPrimitiveNode(PointerAddPrimitiveNode prev) {
super(prev);
writeAddressNode = prev.writeAddressNode;
readAddressNode = prev.readAddressNode;
}

@Specialization
public RubyBasicObject add(RubyBasicObject a, int b) {
return add(a, (long) b);
}

@Specialization
public RubyBasicObject add(RubyBasicObject a, long b) {
final RubyBasicObject result = new RubyBasicObject(a.getLogicalClass());
writeAddress(result, getAddress(a) + b);
return result;
}

public long writeAddress(RubyBasicObject pointer, long address) {
writeAddressNode.execute(pointer, address);
return address;
}

public long getAddress(RubyBasicObject pointer) {
try {
return readAddressNode.executeLong(pointer);
} catch (UnexpectedResultException e) {
throw new UnsupportedOperationException();
}
}

}

@RubiniusPrimitive(name = "pointer_read_int")
public static abstract class PointerReadIntPrimitiveNode extends ReadAddressPrimitiveNode {

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

public PointerReadIntPrimitiveNode(PointerReadIntPrimitiveNode prev) {
super(prev);
}

@Specialization(guards = "isSigned(arguments[1])")
public long readInt(RubyBasicObject pointer, boolean signed) {
return UnsafeHolder.U.getInt(getAddress(pointer));
}

protected boolean isSigned(boolean signed) {
return signed;
}

}

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

import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import com.oracle.truffle.api.object.HiddenKey;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.platform.Platform;
import org.jruby.truffle.nodes.core.CoreClass;
import org.jruby.truffle.nodes.core.CoreMethod;
import org.jruby.truffle.nodes.core.CoreMethodNode;
import org.jruby.truffle.nodes.objectstorage.ReadHeadObjectFieldNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.core.RubyString;
import org.jruby.truffle.runtime.rubinius.RubiniusByteArray;
import org.jruby.util.unsafe.UnsafeHolder;
import sun.misc.Unsafe;

@CoreClass(name = "Rubinius::FFI::Platform::POSIX")
public abstract class PosixNodes {

@CoreMethod(names = "geteuid", isModuleFunction = true, needsSelf = false)
public abstract static class GetEUIDNode extends CoreMethodNode {

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

public GetEUIDNode(GetEUIDNode prev) {
super(prev);
}

@Specialization
public int getEUID() {
return getContext().getRuntime().getPosix().geteuid();
}

}

@CoreMethod(names = "getgroups", isModuleFunction = true, needsSelf = false, required = 2)
public abstract static class GetGroupsNode extends PointerPrimitiveNodes.ReadAddressPrimitiveNode {

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

public GetGroupsNode(GetGroupsNode prev) {
super(prev);
}

@Specialization
public int getGroups(int max, RubyBasicObject pointer) {
final long[] groups = Platform.getPlatform().getGroups(null);

final long address = getAddress(pointer);

for (int n = 0; n < groups.length && n < max; n++) {
UnsafeHolder.U.putInt(address + n * Unsafe.ARRAY_LONG_INDEX_SCALE, (int) groups[n]);
}

return groups.length;
}

}

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

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

public MemsetNode(MemsetNode prev) {
super(prev);
}

@Specialization
public RubyBasicObject memset(RubyBasicObject pointer, int c, int length) {
final long address = getAddress(pointer);
UnsafeHolder.U.setMemory(address, length, (byte) c);
return pointer;
}

}

@CoreMethod(names = "unlink", isModuleFunction = true, required = 1)
public abstract static class UnlinkNode extends PointerPrimitiveNodes.ReadAddressPrimitiveNode {

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

public UnlinkNode(UnlinkNode prev) {
super(prev);
}

@Specialization
public int unlink(RubyString path) {
return getContext().getRuntime().getPosix().unlink(path.toString());
}

}

}
Original file line number Diff line number Diff line change
@@ -56,6 +56,9 @@ public static RubiniusPrimitiveManager create() {
nodeFactories.addAll(ModulePrimitiveNodesFactory.getFactories());
nodeFactories.addAll(RandomPrimitiveNodesFactory.getFactories());
nodeFactories.addAll(ArrayPrimitiveNodesFactory.getFactories());
nodeFactories.addAll(StatPrimitiveNodesFactory.getFactories());
nodeFactories.addAll(PointerPrimitiveNodesFactory.getFactories());
nodeFactories.addAll(NativeFunctionPrimitiveNodesFactory.getFactories());
nodeFactories.addAll(UndefinedPrimitiveNodesFactory.getFactories());

final Map<String, RubiniusPrimitiveConstructor> primitives = new HashMap<>();
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
/*
* 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.nodes.rubinius;

import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.object.HiddenKey;
import com.oracle.truffle.api.source.SourceSection;
import jnr.posix.FileStat;
import org.jruby.truffle.nodes.objectstorage.ReadHeadObjectFieldNode;
import org.jruby.truffle.nodes.objectstorage.WriteHeadObjectFieldNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.core.RubyString;

public abstract class StatPrimitiveNodes {

public static final HiddenKey STAT_IDENTIFIER = new HiddenKey("stat");

@RubiniusPrimitive(name = "stat_stat")
public static abstract class StatStatPrimitiveNode extends RubiniusPrimitiveNode {

@Child private WriteHeadObjectFieldNode writeStatNode;

public StatStatPrimitiveNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
writeStatNode = new WriteHeadObjectFieldNode(STAT_IDENTIFIER);
}

public StatStatPrimitiveNode(StatStatPrimitiveNode prev) {
super(prev);
writeStatNode = prev.writeStatNode;
}

@Specialization
public int stat(RubyBasicObject rubyStat, RubyString path) {
final FileStat stat = getContext().getRuntime().getPosix().allocateStat();
final int code = getContext().getRuntime().getPosix().stat(path.toString(), stat);

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

return code;
}

@Specialization(guards = "!isRubyString(arguments[1])")
public Object stat(RubyBasicObject rubyStat, Object path) {
return null;
}

}

public static abstract class StatReadPrimitiveNode extends RubiniusPrimitiveNode {

@Child private ReadHeadObjectFieldNode readStatNode;

public StatReadPrimitiveNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
readStatNode = new ReadHeadObjectFieldNode(STAT_IDENTIFIER);
}

public StatReadPrimitiveNode(StatReadPrimitiveNode prev) {
super(prev);
readStatNode = prev.readStatNode;
}

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

}

@RubiniusPrimitive(name = "stat_size")
public static abstract class StatSizePrimitiveNode extends StatReadPrimitiveNode {

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

public StatSizePrimitiveNode(StatSizePrimitiveNode prev) {
super(prev);
}

@Specialization
public long size(RubyBasicObject rubyStat) {
return getStat(rubyStat).st_size();
}

}

@RubiniusPrimitive(name = "stat_mode")
public static abstract class StatModePrimitiveNode extends StatReadPrimitiveNode {

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

public StatModePrimitiveNode(StatModePrimitiveNode prev) {
super(prev);
}

@Specialization
public int mode(RubyBasicObject rubyStat) {
return getStat(rubyStat).mode();
}

}

@RubiniusPrimitive(name = "stat_gid")
public static abstract class StatGIDPrimitiveNode extends StatReadPrimitiveNode {

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

public StatGIDPrimitiveNode(StatGIDPrimitiveNode prev) {
super(prev);
}

@Specialization
public int gid(RubyBasicObject rubyStat) {
return getStat(rubyStat).gid();
}

}

@RubiniusPrimitive(name = "stat_uid")
public static abstract class StatUIDPrimitiveNode extends StatReadPrimitiveNode {

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

public StatUIDPrimitiveNode(StatUIDPrimitiveNode prev) {
super(prev);
}

@Specialization
public int uid(RubyBasicObject rubyStat) {
return getStat(rubyStat).uid();
}

}

}
Original file line number Diff line number Diff line change
@@ -15,6 +15,7 @@
import com.oracle.truffle.api.source.Source;

import jnr.constants.platform.Errno;
import jnr.posix.FileStat;
import org.jcodings.Encoding;
import org.jcodings.EncodingDB;
import org.jcodings.transcode.EConvFlags;
@@ -27,6 +28,7 @@
import org.jruby.truffle.nodes.core.ProcessNodes;
import org.jruby.truffle.nodes.methods.SetMethodDeclarationContext;
import org.jruby.truffle.nodes.objects.Allocator;
import org.jruby.truffle.nodes.rubinius.NativeFunctionPrimitiveNodes;
import org.jruby.truffle.runtime.RubyCallStack;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.backtrace.Backtrace;
@@ -121,6 +123,7 @@ public class CoreLibrary {
private final RubyModule mathModule;
private final RubyModule objectSpaceModule;
private final RubyModule rubiniusModule;
private final RubyModule rubiniusFFIModule;
private final RubyModule signalModule;
private final RubyModule truffleModule;
private final RubyModule truffleDebugModule;
@@ -308,6 +311,9 @@ public CoreLibrary(RubyContext context) {
defineModule(truffleModule, "Primitive");

rubiniusModule = defineModule("Rubinius");
rubiniusFFIModule = defineModule(rubiniusModule, "FFI");
defineModule(defineModule(rubiniusFFIModule, "Platform"), "POSIX");

byteArrayClass = defineClass(rubiniusModule, objectClass, "ByteArray");
lookupTableClass = defineClass(rubiniusModule, hashClass, "LookupTable");
stringDataClass = defineClass(rubiniusModule, objectClass, "StringData");
@@ -485,6 +491,9 @@ private RubyModule defineModule(RubyModule lexicalParent, String name) {
}

public void initializeAfterMethodsAdded() {
initializeRubiniusFFI();
initializeRubiniusConfig();

// ENV is supposed to be an object that actually updates the environment, and sees any updates

envHash = getSystemEnv();
@@ -510,6 +519,65 @@ public void initializeAfterMethodsAdded() {
}
}

private void initializeRubiniusFFI() {
rubiniusFFIModule.setConstant(null, "TYPE_CHAR", NativeFunctionPrimitiveNodes.TYPE_CHAR);
rubiniusFFIModule.setConstant(null, "TYPE_UCHAR", NativeFunctionPrimitiveNodes.TYPE_UCHAR);
rubiniusFFIModule.setConstant(null, "TYPE_BOOL", NativeFunctionPrimitiveNodes.TYPE_BOOL);
rubiniusFFIModule.setConstant(null, "TYPE_SHORT", NativeFunctionPrimitiveNodes.TYPE_SHORT);
rubiniusFFIModule.setConstant(null, "TYPE_USHORT", NativeFunctionPrimitiveNodes.TYPE_USHORT);
rubiniusFFIModule.setConstant(null, "TYPE_INT", NativeFunctionPrimitiveNodes.TYPE_INT);
rubiniusFFIModule.setConstant(null, "TYPE_UINT", NativeFunctionPrimitiveNodes.TYPE_UINT);
rubiniusFFIModule.setConstant(null, "TYPE_LONG", NativeFunctionPrimitiveNodes.TYPE_LONG);
rubiniusFFIModule.setConstant(null, "TYPE_ULONG", NativeFunctionPrimitiveNodes.TYPE_ULONG);
rubiniusFFIModule.setConstant(null, "TYPE_LL", NativeFunctionPrimitiveNodes.TYPE_LL);
rubiniusFFIModule.setConstant(null, "TYPE_ULL", NativeFunctionPrimitiveNodes.TYPE_ULL);
rubiniusFFIModule.setConstant(null, "TYPE_FLOAT", NativeFunctionPrimitiveNodes.TYPE_FLOAT);
rubiniusFFIModule.setConstant(null, "TYPE_DOUBLE", NativeFunctionPrimitiveNodes.TYPE_DOUBLE);
rubiniusFFIModule.setConstant(null, "TYPE_PTR", NativeFunctionPrimitiveNodes.TYPE_PTR);
rubiniusFFIModule.setConstant(null, "TYPE_VOID", NativeFunctionPrimitiveNodes.TYPE_VOID);
rubiniusFFIModule.setConstant(null, "TYPE_STRING", NativeFunctionPrimitiveNodes.TYPE_STRING);
rubiniusFFIModule.setConstant(null, "TYPE_STRPTR", NativeFunctionPrimitiveNodes.TYPE_STRPTR);
rubiniusFFIModule.setConstant(null, "TYPE_CHARARR", NativeFunctionPrimitiveNodes.TYPE_CHARARR);
rubiniusFFIModule.setConstant(null, "TYPE_ENUM", NativeFunctionPrimitiveNodes.TYPE_ENUM);
rubiniusFFIModule.setConstant(null, "TYPE_VARARGS", NativeFunctionPrimitiveNodes.TYPE_VARARGS);
}

private void initializeRubiniusConfig() {
final List<KeyValue> config = new ArrayList<>();

config.add(new KeyValue(context.makeString("hash.hamt"), false));

config.add(new KeyValue(context.makeString("rbx.platform.file.S_IRUSR"), FileStat.S_IRUSR));
config.add(new KeyValue(context.makeString("rbx.platform.file.S_IWUSR"), FileStat.S_IWUSR));
config.add(new KeyValue(context.makeString("rbx.platform.file.S_IXUSR"), FileStat.S_IXUSR));
config.add(new KeyValue(context.makeString("rbx.platform.file.S_IRGRP"), FileStat.S_IRGRP));
config.add(new KeyValue(context.makeString("rbx.platform.file.S_IWGRP"), FileStat.S_IWGRP));
config.add(new KeyValue(context.makeString("rbx.platform.file.S_IXGRP"), FileStat.S_IXGRP));
config.add(new KeyValue(context.makeString("rbx.platform.file.S_IROTH"), FileStat.S_IROTH));
config.add(new KeyValue(context.makeString("rbx.platform.file.S_IWOTH"), FileStat.S_IWOTH));
config.add(new KeyValue(context.makeString("rbx.platform.file.S_IXOTH"), FileStat.S_IXOTH));
config.add(new KeyValue(context.makeString("rbx.platform.file.S_IFMT"), FileStat.S_IFMT));
config.add(new KeyValue(context.makeString("rbx.platform.file.S_IFIFO"), FileStat.S_IFIFO));
config.add(new KeyValue(context.makeString("rbx.platform.file.S_IFCHR"), FileStat.S_IFCHR));
config.add(new KeyValue(context.makeString("rbx.platform.file.S_IFDIR"), FileStat.S_IFDIR));
config.add(new KeyValue(context.makeString("rbx.platform.file.S_IFBLK"), FileStat.S_IFBLK));
config.add(new KeyValue(context.makeString("rbx.platform.file.S_IFREG"), FileStat.S_IFREG));
config.add(new KeyValue(context.makeString("rbx.platform.file.S_IFLNK"), FileStat.S_IFLNK));
config.add(new KeyValue(context.makeString("rbx.platform.file.S_IFSOCK"), FileStat.S_IFSOCK));
config.add(new KeyValue(context.makeString("rbx.platform.file.S_ISUID"), FileStat.S_ISUID));
config.add(new KeyValue(context.makeString("rbx.platform.file.S_ISGID"), FileStat.S_ISGID));
config.add(new KeyValue(context.makeString("rbx.platform.file.S_ISVTX"), FileStat.S_ISVTX));

/*
* There is also rbx.platform.file.S_IFWHT, which I think is from FreeBSD. We don't support
* this as it isn't part of jnr-posix.
*/

final RubyHash configHash = HashOperations.verySlowFromEntries(getHashClass(), config, false);

rubiniusModule.setConstant(null, "Config", configHash);
}

public void loadRubyCore(String fileName) {
loadRubyCore(fileName, "core:/");
}
135 changes: 130 additions & 5 deletions truffle/src/main/ruby/core.rb
Original file line number Diff line number Diff line change
@@ -7,90 +7,213 @@
# GNU Lesser General Public License version 2.1

# Load Rubinius API

require_relative 'core/rubinius/api/compat/type'
require_relative 'core/rubinius/api/kernel/common/thread'
require_relative 'core/rubinius/api/kernel/common/type'

# Patch rubinius-core-api to make it work for us

require_relative 'core/rubinius/api/shims/lookuptable'
require_relative 'core/rubinius/api/shims/array'
require_relative 'core/rubinius/api/shims/rubinius'
require_relative 'core/rubinius/api/shims/thread'
require_relative 'core/rubinius/api/shims/tuple'
require_relative 'core/rubinius/api/shims/undefined'
require_relative 'core/rubinius/api/shims/metrics'
require_relative 'core/rubinius/api/shims/config'
require_relative 'core/rubinius/api/shims/module'

# Load bootstrap (ordered according to Rubinius' load_order.txt)

require_relative 'core/rubinius/bootstrap/basic_object'
#require_relative 'core/rubinius/bootstrap/logger'
#require_relative 'core/rubinius/bootstrap/alias'
require_relative 'core/rubinius/bootstrap/mirror'
#require_relative 'core/rubinius/bootstrap/array_mirror'
#require_relative 'core/rubinius/bootstrap/array'
#require_relative 'core/rubinius/bootstrap/atomic'
#require_relative 'core/rubinius/bootstrap/bignum'
#require_relative 'core/rubinius/bootstrap/block_environment'
#require_relative 'core/rubinius/bootstrap/byte_array'
#require_relative 'core/rubinius/bootstrap/call_site'
#require_relative 'core/rubinius/bootstrap/call_custom_cache'
#require_relative 'core/rubinius/bootstrap/channel'
require_relative 'core/rubinius/bootstrap/character'
#require_relative 'core/rubinius/bootstrap/class'
#require_relative 'core/rubinius/bootstrap/compact_lookup_table'
#require_relative 'core/rubinius/bootstrap/compiled_code'
#require_relative 'core/rubinius/bootstrap/configuration'
#require_relative 'core/rubinius/bootstrap/constant_cache'
#require_relative 'core/rubinius/bootstrap/constant_scope'
#require_relative 'core/rubinius/bootstrap/constant_table'
#require_relative 'core/rubinius/bootstrap/dir'
#require_relative 'core/rubinius/bootstrap/encoding'
#require_relative 'core/rubinius/bootstrap/exception'
#require_relative 'core/rubinius/bootstrap/executable'
require_relative 'core/rubinius/bootstrap/false'
#require_relative 'core/rubinius/bootstrap/fixnum'
require_relative 'core/rubinius/bootstrap/gc'
#require_relative 'core/rubinius/bootstrap/io'
#require_relative 'core/rubinius/bootstrap/iseq'
#require_relative 'core/rubinius/bootstrap/jit'
require_relative 'core/rubinius/bootstrap/kernel'
#require_relative 'core/rubinius/bootstrap/lookup_table'
#require_relative 'core/rubinius/bootstrap/method_table'
#require_relative 'core/rubinius/bootstrap/mono_inline_cache'
require_relative 'core/rubinius/bootstrap/nil'
#require_relative 'core/rubinius/bootstrap/proc'
require_relative 'core/rubinius/bootstrap/process'
#require_relative 'core/rubinius/bootstrap/poly_inline_cache'
require_relative 'core/rubinius/bootstrap/regexp'
#require_relative 'core/rubinius/bootstrap/respond_to_cache'
require_relative 'core/rubinius/bootstrap/rubinius'
require_relative 'core/rubinius/bootstrap/stat'
require_relative 'core/rubinius/bootstrap/string'
require_relative 'core/rubinius/bootstrap/symbol'
#require_relative 'core/rubinius/bootstrap/thread'
#require_relative 'core/rubinius/bootstrap/thunk'
require_relative 'core/rubinius/bootstrap/time'
require_relative 'core/rubinius/bootstrap/true'
#require_relative 'core/rubinius/bootstrap/tuple'
require_relative 'core/rubinius/bootstrap/type'
#require_relative 'core/rubinius/bootstrap/variable_scope'
#require_relative 'core/rubinius/bootstrap/vm'
#require_relative 'core/rubinius/bootstrap/weakref'

# Load common (ordered according to Rubinius' load_order.txt)

#require_relative 'core/rubinius/common/basic_object'
require_relative 'core/rubinius/common/string_mirror'
require_relative 'core/rubinius/common/enumerator'
#require_relative 'core/rubinius/common/class'
#require_relative 'core/rubinius/common/autoload'
#require_relative 'core/rubinius/common/module'
#require_relative 'core/rubinius/common/binding'
require_relative 'core/rubinius/common/proc'
require_relative 'core/rubinius/common/enumerable'
require_relative 'core/rubinius/common/enumerator'
#require_relative 'core/rubinius/common/argf'
#require_relative 'core/rubinius/common/tuple'
require_relative 'core/rubinius/common/exception'
require_relative 'core/rubinius/common/undefined'
require_relative 'core/rubinius/common/type'
require_relative 'core/rubinius/common/hash'
#require_relative 'core/rubinius/common/hash_hamt'
require_relative 'core/rubinius/common/array'
require_relative 'core/rubinius/common/kernel'
require_relative 'core/rubinius/common/identity_map'
#require_relative 'core/rubinius/common/loaded_features'
#require_relative 'core/rubinius/common/global'
#require_relative 'core/rubinius/common/backtrace'
require_relative 'core/rubinius/common/comparable'
require_relative 'core/rubinius/common/numeric'
require_relative 'core/rubinius/common/ctype'
require_relative 'core/rubinius/common/integer'
require_relative 'core/rubinius/common/bignum'
#require_relative 'core/rubinius/common/block_environment'
#require_relative 'core/rubinius/common/byte_array'
#require_relative 'core/rubinius/common/channel'
#require_relative 'core/rubinius/common/executable'
#require_relative 'core/rubinius/common/constant_scope'
#require_relative 'core/rubinius/common/hook'
#require_relative 'core/rubinius/common/code_loader'
#require_relative 'core/rubinius/common/compiled_code'
#require_relative 'core/rubinius/common/continuation'
#require_relative 'core/rubinius/common/delegated_method'
require_relative 'core/rubinius/common/fixnum'
#require_relative 'core/rubinius/common/lru_cache'
require_relative 'core/rubinius/api/shims/encoding'
require_relative 'core/rubinius/common/encoding'
#require_relative 'core/rubinius/common/env'
#require_relative 'core/rubinius/common/errno'
#require_relative 'core/rubinius/common/eval'
require_relative 'core/rubinius/common/false'
#require_relative 'core/rubinius/common/fiber'
#require_relative 'core/rubinius/common/io'
require_relative 'core/rubinius/common/file'
#require_relative 'core/rubinius/common/dir'
#require_relative 'core/rubinius/common/dir_glob'
#require_relative 'core/rubinius/common/file_test'
require_relative 'core/rubinius/common/stat'
require_relative 'core/rubinius/common/float'
require_relative 'core/rubinius/common/immediate'
#require_relative 'core/rubinius/common/location'
#require_relative 'core/rubinius/common/lookup_table'
require_relative 'core/rubinius/common/main'
require_relative 'core/rubinius/common/marshal'
#require_relative 'core/rubinius/common/math'
#require_relative 'core/rubinius/common/method'
#require_relative 'core/rubinius/common/method_equality'
#require_relative 'core/rubinius/common/method_table'
#require_relative 'core/rubinius/common/missing_method'
#require_relative 'core/rubinius/common/native_method'
require_relative 'core/rubinius/common/nil'
require_relative 'core/rubinius/common/object_space'
require_relative 'core/rubinius/common/proc'
require_relative 'core/rubinius/common/string'
require_relative 'core/rubinius/common/range'
require_relative 'core/rubinius/common/struct'
require_relative 'core/rubinius/common/process'
require_relative 'core/rubinius/common/symbol'
#require_relative 'core/rubinius/common/process_mirror'
require_relative 'core/rubinius/common/random'
require_relative 'core/rubinius/common/regexp'
require_relative 'core/rubinius/common/signal'
require_relative 'core/rubinius/common/splitter'
#require_relative 'core/rubinius/common/sprinter'
require_relative 'core/rubinius/common/symbol'
require_relative 'core/rubinius/common/mutex'
require_relative 'core/rubinius/common/thread'
#require_relative 'core/rubinius/common/thread_group'
require_relative 'core/rubinius/common/throw_catch'
require_relative 'core/rubinius/common/time'
require_relative 'core/rubinius/common/true'
require_relative 'core/rubinius/common/random'
#require_relative 'core/rubinius/common/variable_scope'
#require_relative 'core/rubinius/common/capi'
require_relative 'core/rubinius/common/rational'
require_relative 'core/rubinius/common/rationalizer'
require_relative 'core/rubinius/common/complex'
require_relative 'core/rubinius/common/complexifier'
require_relative 'core/rubinius/common/gc'

# Load delta (ordered according to Rubinius' load_order.txt)

#require_relative 'core/rubinius/delta/ctype'
#require_relative 'core/rubinius/delta/exception'
#require_relative 'core/rubinius/delta/file'
#require_relative 'core/rubinius/delta/rubinius'
#require_relative 'core/rubinius/delta/runtime'
#require_relative 'core/rubinius/delta/module'
require_relative 'core/rubinius/delta/class'
#require_relative 'core/rubinius/delta/file_test'
#require_relative 'core/rubinius/delta/kernel'
#require_relative 'core/rubinius/delta/math'
#require_relative 'core/rubinius/delta/options'
#require_relative 'core/rubinius/delta/stats'
#require_relative 'core/rubinius/delta/signal'
require_relative 'core/rubinius/delta/struct'
#require_relative 'core/rubinius/delta/thread'
#require_relative 'core/rubinius/delta/code_loader'
#require_relative 'core/rubinius/delta/fsevent'
#require_relative 'core/rubinius/delta/console'
#require_relative 'core/rubinius/delta/ffi'
#require_relative 'core/rubinius/delta/ruby_constants'
#require_relative 'core/rubinius/delta/pack'
#require_relative 'core/rubinius/delta/metrics'

# Load platform (ordered according to Rubinius' load_order.txt)

require_relative 'core/rubinius/platform/ffi'
#require_relative 'core/rubinius/platform/enum'
#require_relative 'core/rubinius/platform/library'
require_relative 'core/rubinius/platform/pointer_accessors'
require_relative 'core/rubinius/platform/pointer'
#require_relative 'core/rubinius/platform/env'
#require_relative 'core/rubinius/platform/file'
#require_relative 'core/rubinius/platform/math'
#require_relative 'core/rubinius/platform/posix'
#require_relative 'core/rubinius/platform/struct'
#require_relative 'core/rubinius/platform/union'

# Load JRuby+Truffle classes

require_relative 'core/array'
require_relative 'core/fixnum'
require_relative 'core/float'
@@ -106,9 +229,11 @@
require_relative 'core/shims'

# Load JRuby+Truffle specific classes

require_relative 'core/truffle/truffle'
require_relative 'core/truffle/debug'

# Start running Ruby code outside classes

require_relative 'core/config'
require_relative 'core/main'
7 changes: 4 additions & 3 deletions truffle/src/main/ruby/core/rubinius/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
`bootstrap` and `common` contains the Ruby component of the Rubinius kernel (core library)
implementation, in some cases modified. We have taken files from version 2.4.1
of Rubinius. This code was written by Evan Phoenix, Brian Shirai, et al.
`bootstrap`, `common`, `delta` and `platform` contains the Ruby component of the
Rubinius kernel (core library) implementation, in some cases modified. We have
taken files from version 2.4.1 of Rubinius. This code was written by Evan
Phoenix, Brian Shirai, et al.

https://github.com/rubinius/rubinius

13 changes: 0 additions & 13 deletions truffle/src/main/ruby/core/rubinius/api/shims/config.rb

This file was deleted.

20 changes: 20 additions & 0 deletions truffle/src/main/ruby/core/rubinius/api/shims/rubinius.rb
Original file line number Diff line number Diff line change
@@ -8,6 +8,21 @@

module Rubinius

L64 = true
CPU = "jvm"
SIZEOF_LONG = 8
WORDSIZE = 8

# Pretend to be Linux for the purposes of the FFI - doesn't make a difference anyway at this stage

def self.windows?
false
end

def self.darwin?
false
end

def self.mathn_loaded?
false
end
@@ -22,6 +37,11 @@ def initialize(size, &block)

end

module FFI
class DynamicLibrary
end
end

end

class PrimitiveFailure < StandardError
124 changes: 124 additions & 0 deletions truffle/src/main/ruby/core/rubinius/bootstrap/stat.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
# Copyright (c) 2007-2014, Evan Phoenix and contributors
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of Rubinius nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

module Rubinius
class Stat

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

def fsetup(fd)
Rubinius.primitive :stat_fstat
fd = Rubinius::Type.coerce_to fd, Integer, :to_int
fsetup(fd)
end
private :fsetup

def lsetup(path)
Rubinius.primitive :stat_lstat
path = Rubinius::Type.coerce_to_path(path)
lsetup(path)
end
private :lsetup

def dev
Rubinius.primitive :stat_dev
raise PrimitiveFailure, "Rubinius::Stat#dev primitive failed"
end

def ino
Rubinius.primitive :stat_ino
raise PrimitiveFailure, "Rubinius::Stat#ino primitive failed"
end

def mode
Rubinius.primitive :stat_mode
raise PrimitiveFailure, "Rubinius::Stat#mode primitive failed"
end

def nlink
Rubinius.primitive :stat_nlink
raise PrimitiveFailure, "Rubinius::Stat#nlink primitive failed"
end

def uid
Rubinius.primitive :stat_uid
raise PrimitiveFailure, "Rubinius::Stat#uid primitive failed"
end

def gid
Rubinius.primitive :stat_gid
raise PrimitiveFailure, "Rubinius::Stat#gid primitive failed"
end

def rdev
Rubinius.primitive :stat_rdev
raise PrimitiveFailure, "Rubinius::Stat#rdev primitive failed"
end

def size
Rubinius.primitive :stat_size
raise PrimitiveFailure, "Rubinius::Stat#size primitive failed"
end

def blksize
Rubinius.primitive :stat_blksize
raise PrimitiveFailure, "Rubinius::Stat#blksize primitive failed"
end

def blocks
Rubinius.primitive :stat_blocks
raise PrimitiveFailure, "Rubinius::Stat#blocks primitive failed"
end

def atime
Rubinius.primitive :stat_atime
raise PrimitiveFailure, "Rubinius::Stat#atime primitive failed"
end

def mtime
Rubinius.primitive :stat_mtime
raise PrimitiveFailure, "Rubinius::Stat#mtime primitive failed"
end

def ctime
Rubinius.primitive :stat_ctime
raise PrimitiveFailure, "Rubinius::Stat#ctime primitive failed"
end

def inspect
"#<#{self.class.name} dev=0x#{self.dev.to_s(16)}, ino=#{self.ino}, " \
"mode=#{sprintf("%07d", self.mode.to_s(8).to_i)}, nlink=#{self.nlink}, " \
"uid=#{self.uid}, gid=#{self.gid}, rdev=0x#{self.rdev.to_s(16)}, " \
"size=#{self.size}, blksize=#{self.blksize}, blocks=#{self.blocks}, " \
"atime=#{self.atime}, mtime=#{self.mtime}, ctime=#{self.ctime}>"
end
end
end
126 changes: 126 additions & 0 deletions truffle/src/main/ruby/core/rubinius/common/file.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# Copyright (c) 2007-2014, Evan Phoenix and contributors
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of Rubinius nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# Only part of Rubinius' file.rb

class File < IO
include Enumerable

FFI = Rubinius::FFI

POSIX = FFI::Platform::POSIX

##
# Return true if the named file exists.
def self.exist?(path)
st = Stat.stat(path)
st ? true : false
end

##
# Returns nil if file_name doesn‘t exist or has zero size,
# the size of the file otherwise.
def self.size?(io_or_path)
s = 0

io = Rubinius::Type.try_convert io_or_path, IO, :to_io

if io.is_a? IO
s = Stat.fstat(io.fileno).size
else
st = Stat.stat io_or_path
s = st.size if st
end

s > 0 ? s : nil
end

##
# Returns true if the named file is a directory, false otherwise.
#
# File.directory?(".")
def self.directory?(io_or_path)
io = Rubinius::Type.try_convert io_or_path, IO, :to_io

if io.is_a? IO
Stat.fstat(io.fileno).directory?
else
st = Stat.stat io_or_path
st ? st.directory? : false
end
end

##
# Returns true if the named file exists and is a regular file.
def self.file?(path)
st = Stat.stat path
st ? st.file? : false
end

##
# Returns true if the named file is executable by the
# effective user id of this process.
def self.executable?(path)
st = Stat.stat path
st ? st.executable? : false
end

##
# Returns true if the named file is readable by the effective
# user id of this process.
def self.readable?(path)
st = Stat.stat path
st ? st.readable? : false
end

##
# Deletes the named files, returning the number of names
# passed as arguments. Raises an exception on any error.
#
# See also Dir::rmdir.
def self.unlink(*paths)
paths.each do |path|
n = POSIX.unlink Rubinius::Type.coerce_to_path(path)
Errno.handle if n == -1
end

paths.size
end

class << self
alias_method :delete, :unlink
alias_method :exists?, :exist?
end

def self.path(obj)
return obj.to_path if obj.respond_to? :to_path

StringValue(obj)
end

end

File::Stat = Rubinius::Stat
20 changes: 20 additions & 0 deletions truffle/src/main/ruby/core/rubinius/common/process.rb
Original file line number Diff line number Diff line change
@@ -28,8 +28,28 @@

class Process

FFI = Rubinius::FFI

def self.times
Struct::Tms.new(*cpu_times)
end

@maxgroups = 32
class << self
attr_reader :maxgroups
def maxgroups=(m)
@maxgroups = m
end
end

def self.groups
g = []
FFI::MemoryPointer.new(:int, @maxgroups) { |p|
num_groups = FFI::Platform::POSIX.getgroups(@maxgroups, p)
Errno.handle if num_groups == -1
g = p.read_array_of_int(num_groups)
}
g
end

end
249 changes: 249 additions & 0 deletions truffle/src/main/ruby/core/rubinius/common/stat.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
# Copyright (c) 2007-2014, Evan Phoenix and contributors
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of Rubinius nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

class Rubinius::Stat

include Comparable

S_IRUSR = Rubinius::Config['rbx.platform.file.S_IRUSR']
S_IWUSR = Rubinius::Config['rbx.platform.file.S_IWUSR']
S_IXUSR = Rubinius::Config['rbx.platform.file.S_IXUSR']
S_IRGRP = Rubinius::Config['rbx.platform.file.S_IRGRP']
S_IWGRP = Rubinius::Config['rbx.platform.file.S_IWGRP']
S_IXGRP = Rubinius::Config['rbx.platform.file.S_IXGRP']
S_IROTH = Rubinius::Config['rbx.platform.file.S_IROTH']
S_IWOTH = Rubinius::Config['rbx.platform.file.S_IWOTH']
S_IXOTH = Rubinius::Config['rbx.platform.file.S_IXOTH']

S_IRUGO = S_IRUSR | S_IRGRP | S_IROTH
S_IWUGO = S_IWUSR | S_IWGRP | S_IWOTH
S_IXUGO = S_IXUSR | S_IXGRP | S_IXOTH

S_IFMT = Rubinius::Config['rbx.platform.file.S_IFMT']
S_IFIFO = Rubinius::Config['rbx.platform.file.S_IFIFO']
S_IFCHR = Rubinius::Config['rbx.platform.file.S_IFCHR']
S_IFDIR = Rubinius::Config['rbx.platform.file.S_IFDIR']
S_IFBLK = Rubinius::Config['rbx.platform.file.S_IFBLK']
S_IFREG = Rubinius::Config['rbx.platform.file.S_IFREG']
S_IFLNK = Rubinius::Config['rbx.platform.file.S_IFLNK']
S_IFSOCK = Rubinius::Config['rbx.platform.file.S_IFSOCK']
S_IFWHT = Rubinius::Config['rbx.platform.file.S_IFWHT']
S_ISUID = Rubinius::Config['rbx.platform.file.S_ISUID']
S_ISGID = Rubinius::Config['rbx.platform.file.S_ISGID']
S_ISVTX = Rubinius::Config['rbx.platform.file.S_ISVTX']

attr_reader :path

def initialize(path)
Errno.handle path unless setup(path) == 0
end

def self.stat(path)
stat = allocate
if Rubinius.privately { stat.setup path } == 0
stat
else
nil
end
end

def self.fstat(fd)
stat = allocate
result = Rubinius.privately { stat.fsetup fd }
Errno.handle "file descriptor #{descriptor}" unless result == 0
stat
end

def self.lstat(path)
stat = allocate
result = Rubinius.privately { stat.lsetup path }
Errno.handle path unless result == 0
stat
end

def blockdev?
mode & S_IFMT == S_IFBLK
end

def chardev?
mode & S_IFMT == S_IFCHR
end

def dev_major
major = Rubinius::FFI::Platform::POSIX.major dev
major < 0 ? nil : major
end

def dev_minor
minor = Rubinius::FFI::Platform::POSIX.major dev
minor < 0 ? nil : minor
end

def directory?
mode & S_IFMT == S_IFDIR
end

def executable?
return true if superuser?
return mode & S_IXUSR != 0 if owned?
return mode & S_IXGRP != 0 if grpowned?
return mode & S_IXOTH != 0
end

def executable_real?
return true if rsuperuser?
return mode & S_IXUSR != 0 if rowned?
return mode & S_IXGRP != 0 if rgrpowned?
return mode & S_IXOTH != 0
end

def file?
mode & S_IFMT == S_IFREG
end

def ftype
if file?
"file"
elsif directory?
"directory"
elsif chardev?
"characterSpecial"
elsif blockdev?
"blockSpecial"
elsif pipe?
"fifo"
elsif socket?
"socket"
elsif symlink?
"link"
else
"unknown"
end
end

def grpowned?
Process.groups.include?(gid)
end

def owned?
uid == Rubinius::FFI::Platform::POSIX.geteuid
end

def pipe?
mode & S_IFMT == S_IFIFO
end

def rdev_major
major = Rubinius::FFI::Platform::POSIX.major rdev
major < 0 ? nil : major
end

def rdev_minor
minor = Rubinius::FFI::Platform::POSIX.minor rdev
minor < 0 ? nil : minor
end

def readable?
return true if superuser?
return mode & S_IRUSR != 0 if owned?
return mode & S_IRGRP != 0 if grpowned?
return mode & S_IROTH != 0
end

def readable_real?
return true if rsuperuser?
return mode & S_IRUSR != 0 if rowned?
return mode & S_IRGRP != 0 if rgrpowned?
return mode & S_IROTH != 0
end

def setgid?
mode & S_ISGID != 0
end

def setuid?
mode & S_ISUID != 0
end

def sticky?
mode & S_ISVTX != 0
end

def size?
size == 0 ? nil : size
end

def socket?
mode & S_IFMT == S_IFSOCK
end

def symlink?
mode & S_IFMT == S_IFLNK
end

def writable?
return true if superuser?
return mode & S_IWUSR != 0 if owned?
return mode & S_IWGRP != 0 if grpowned?
return mode & S_IWOTH != 0
end

def writable_real?
return true if rsuperuser?
return mode & S_IWUSR != 0 if rowned?
return mode & S_IWGRP != 0 if rgrpowned?
return mode & S_IWOTH != 0
end

def zero?
size == 0
end

def <=>(other)
return nil unless other.is_a?(File::Stat)
self.mtime <=> other.mtime
end

def rgrpowned?
gid == Rubinius::FFI::Platform::POSIX.getgid
end
private :rgrpowned?

def rowned?
uid == Rubinius::FFI::Platform::POSIX.getuid
end
private :rowned?

def rsuperuser?
Rubinius::FFI::Platform::POSIX.getuid == 0
end
private :rsuperuser?

def superuser?
Rubinius::FFI::Platform::POSIX.geteuid == 0
end
private :superuser?
end
287 changes: 287 additions & 0 deletions truffle/src/main/ruby/core/rubinius/platform/ffi.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,287 @@
# Copyright (c) 2007-2014, Evan Phoenix and contributors
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of Rubinius nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

##
# A Foreign Function Interface used to bind C libraries to ruby.

module Rubinius
module FFI

# Specialised error classes
class TypeError < RuntimeError; end

class NotFoundError < RuntimeError; end

# Shorthand for the current process, i.e. all code that
# the process image itself contains. In addition to the
# Rubinius codebase, this also includes libc etc.
#
# Use this constant instead of nil directly.
#
CURRENT_PROCESS = nil

TypeDefs = Rubinius::LookupTable.new

class << self
def add_typedef(current, add)
if current.kind_of? Fixnum
code = current
else
code = FFI::TypeDefs[current]
raise TypeError, "Unable to resolve type '#{current}'" unless code
end

FFI::TypeDefs[add] = code
end

def find_type(name)
code = FFI::TypeDefs[name]
raise TypeError, "Unable to resolve type '#{name}'" unless code
return code
end

##
# Given a +type+ as a number, indicate how many bytes that type
# takes up on this platform.

def type_size(type)
Rubinius.primitive :nativefunction_type_size

case type
when Symbol
return type_size(find_type(type))
when Rubinius::NativeFunction
return type_size(TYPE_PTR)
when FFI::Enum
return type_size(TYPE_ENUM)
end

raise PrimitiveFailure, "FFI.type_size primitive failed: #{type}"
end

def size_to_type(size)
if sz = TypeSizes[size]
return sz
end

# Be like C, use int as the default type size.
return :int
end

def config(name)
Rubinius::Config["rbx.platform.#{name}"]
end

def config_hash(name)
vals = {}
section = "rbx.platform.#{name}."
Rubinius::Config.section section do |key, value|
vals[key.substring(section.size, key.length)] = value
end
vals
end

def errno
FFI::Platform::POSIX.errno
end

end

# Converts a char
add_typedef TYPE_CHAR, :char

# Converts an unsigned char
add_typedef TYPE_UCHAR, :uchar

# The C++ boolean type
add_typedef TYPE_BOOL, :bool

# Converts a short
add_typedef TYPE_SHORT, :short

# Converts an unsigned short
add_typedef TYPE_USHORT, :ushort

# Converts an int
add_typedef TYPE_INT, :int

# Converts an unsigned int
add_typedef TYPE_UINT, :uint

# Converts a long
add_typedef TYPE_LONG, :long

# Converts an unsigned long
add_typedef TYPE_ULONG, :ulong

# Converts a size_t
add_typedef TYPE_ULONG, :size_t

# Converts a long long
add_typedef TYPE_LL, :long_long

# Converts an unsigned long long
add_typedef TYPE_ULL, :ulong_long

# Converts a float
add_typedef TYPE_FLOAT, :float

# Converts a double
add_typedef TYPE_DOUBLE, :double

# Converts a pointer to opaque data
add_typedef TYPE_PTR, :pointer

# For when a function has no return value
add_typedef TYPE_VOID, :void

# Converts NULL-terminated C strings
add_typedef TYPE_STRING, :string

# Use strptr when you need to free the result of some operation.
add_typedef TYPE_STRPTR, :strptr
add_typedef TYPE_STRPTR, :string_and_pointer

# Use for a C struct with a char [] embedded inside.
add_typedef TYPE_CHARARR, :char_array

# A set of unambigious integer types
add_typedef TYPE_CHAR, :int8
add_typedef TYPE_UCHAR, :uint8
add_typedef TYPE_SHORT, :int16
add_typedef TYPE_USHORT, :uint16
add_typedef TYPE_INT, :int32
add_typedef TYPE_UINT, :uint32

# Converts a varargs argument
add_typedef TYPE_VARARGS, :varargs

if Rubinius::L64
add_typedef TYPE_LONG, :int64
add_typedef TYPE_ULONG, :uint64
else
add_typedef TYPE_LL, :int64
add_typedef TYPE_ULL, :uint64
end

TypeSizes = Rubinius::LookupTable.new
TypeSizes[1] = :char
TypeSizes[2] = :short
TypeSizes[4] = :int
TypeSizes[8] = Rubinius::L64 ? :long : :long_long

# Load all the platform dependent types

# MODIFIED
#Rubinius::Config.section("rbx.platform.typedef.") do |key, value|
# add_typedef(find_type(value.to_sym), key.substring(21, key.length).to_sym)
#end

# It's a class to be compat with the ffi gem.
class Type
class Array
def initialize(element_type, size, impl_class=nil)
@element_type = element_type
@size = size
@implementation = impl_class
end

attr_reader :element_type
attr_reader :size
attr_reader :implementation
end

class StructByValue
def initialize(struct)
@implementation = struct
end

attr_reader :implementation
end

Struct = StructByValue

CHAR = TYPE_CHAR
UCHAR = TYPE_UCHAR
BOOL = TYPE_BOOL
SHORT = TYPE_SHORT
USHORT = TYPE_USHORT
INT = TYPE_INT
UINT = TYPE_UINT
LONG = TYPE_LONG
ULONG = TYPE_ULONG
LL = TYPE_LL
ULL = TYPE_ULL
FLOAT = TYPE_FLOAT
DOUBLE = TYPE_DOUBLE
PTR = TYPE_PTR
VOID = TYPE_VOID
STRING = TYPE_STRING
STRPTR = TYPE_STRPTR
CHARARR = TYPE_CHARARR
ENUM = TYPE_ENUM
VARARGS = TYPE_VARARGS
end
end

##
# Namespace for holding platform-specific C constants.

module FFI::Platform
case
when Rubinius.windows?
LIBSUFFIX = "dll"
IS_WINDOWS = true
OS = 'windows'
when Rubinius.darwin?
LIBSUFFIX = "dylib"
IS_WINDOWS = false
OS = 'darwin'
else
LIBSUFFIX = "so"
IS_WINDOWS = false
OS = 'linux'
end

ARCH = Rubinius::CPU

# ruby-ffi compatible
LONG_SIZE = Rubinius::SIZEOF_LONG * 8
ADDRESS_SIZE = Rubinius::WORDSIZE

def self.windows?
Rubinius.windows?
end

def self.mac?
Rubinius.darwin?
end

def self.unix?
! windows?
end
end
end
471 changes: 471 additions & 0 deletions truffle/src/main/ruby/core/rubinius/platform/pointer.rb

Large diffs are not rendered by default.

864 changes: 864 additions & 0 deletions truffle/src/main/ruby/core/rubinius/platform/pointer_accessors.rb

Large diffs are not rendered by default.

0 comments on commit 2e27cfc

Please sign in to comment.