-
-
Notifications
You must be signed in to change notification settings - Fork 925
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2811 from jruby/truffle-io
[Truffle] Start to support the Rubinius FFI and POSIX calls
- 9.4.12.0
- 9.4.11.0
- 9.4.10.0
- 9.4.9.0
- 9.4.8.0
- 9.4.7.0
- 9.4.6.0
- 9.4.5.0
- 9.4.4.0
- 9.4.3.0
- 9.4.2.0
- 9.4.1.0
- 9.4.0.0
- 9.3.15.0
- 9.3.14.0
- 9.3.13.0
- 9.3.12.0
- 9.3.11.0
- 9.3.10.0
- 9.3.9.0
- 9.3.8.0
- 9.3.7.0
- 9.3.6.0
- 9.3.5.0
- 9.3.4.0
- 9.3.3.0
- 9.3.2.0
- 9.3.1.0
- 9.3.0.0
- 9.2.21.0
- 9.2.20.1
- 9.2.20.0
- 9.2.19.0
- 9.2.18.0
- 9.2.17.0
- 9.2.16.0
- 9.2.15.0
- 9.2.14.0
- 9.2.13.0
- 9.2.12.0
- 9.2.11.1
- 9.2.11.0
- 9.2.10.0
- 9.2.9.0
- 9.2.8.0
- 9.2.7.0
- 9.2.6.0
- 9.2.5.0
- 9.2.4.1
- 9.2.4.0
- 9.2.3.0
- 9.2.2.0
- 9.2.1.0
- 9.2.0.0
- 9.1.17.0
- 9.1.16.0
- 9.1.15.0
- 9.1.14.0
- 9.1.13.0
- 9.1.12.0
- 9.1.11.0
- 9.1.10.0
- 9.1.9.0
- 9.1.8.0
- 9.1.7.0
- 9.1.6.0
- 9.1.5.0
- 9.1.4.0
- 9.1.3.0
- 9.1.2.0
- 9.1.1.0
- 9.1.0.0
- 9.0.5.0
- 9.0.4.0
- 9.0.3.0
- 9.0.1.0
- 9.0.0.0
- 9.0.0.0.rc2
- 9.0.0.0.rc1
- 9.0.0.0.pre2
Showing
26 changed files
with
2,942 additions
and
225 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
99 changes: 99 additions & 0 deletions
99
truffle/src/main/java/org/jruby/truffle/nodes/rubinius/NativeFunctionPrimitiveNodes.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
} | ||
} | ||
|
||
} | ||
|
||
} |
210 changes: 210 additions & 0 deletions
210
truffle/src/main/java/org/jruby/truffle/nodes/rubinius/PointerPrimitiveNodes.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
113
truffle/src/main/java/org/jruby/truffle/nodes/rubinius/PosixNodes.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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()); | ||
} | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
152 changes: 152 additions & 0 deletions
152
truffle/src/main/java/org/jruby/truffle/nodes/rubinius/StatPrimitiveNodes.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
} | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
471
truffle/src/main/ruby/core/rubinius/platform/pointer.rb
Large diffs are not rendered by default.
Oops, something went wrong.
864 changes: 864 additions & 0 deletions
864
truffle/src/main/ruby/core/rubinius/platform/pointer_accessors.rb
Large diffs are not rendered by default.
Oops, something went wrong.