Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 727f65bc0daf
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 1d955ff3432c
Choose a head ref
  • 3 commits
  • 31 files changed
  • 1 contributor

Commits on Jun 20, 2015

  1. Copy the full SHA
    df2ab1e View commit details
  2. 7
    Copy the full SHA
    9f47fbf View commit details
  3. Copy the full SHA
    1d955ff View commit details
Showing with 555 additions and 111 deletions.
  1. +0 −3 spec/truffle/tags/core/env/assoc_tags.txt
  2. +0 −1 spec/truffle/tags/core/env/clear_tags.txt
  3. +0 −5 spec/truffle/tags/core/env/delete_if_tags.txt
  4. +0 −1 spec/truffle/tags/core/env/delete_tags.txt
  5. +0 −3 spec/truffle/tags/core/env/each_key_tags.txt
  6. +0 −4 spec/truffle/tags/core/env/each_pair_tags.txt
  7. +0 −4 spec/truffle/tags/core/env/each_tags.txt
  8. +0 −3 spec/truffle/tags/core/env/each_value_tags.txt
  9. +0 −3 spec/truffle/tags/core/env/element_reference_tags.txt
  10. +0 −6 spec/truffle/tags/core/env/element_set_tags.txt
  11. +0 −2 spec/truffle/tags/core/env/empty_tags.txt
  12. +0 −3 spec/truffle/tags/core/env/fetch_tags.txt
  13. +0 −2 spec/truffle/tags/core/env/index_tags.txt
  14. +0 −5 spec/truffle/tags/core/env/keep_if_tags.txt
  15. +0 −2 spec/truffle/tags/core/env/key_tags.txt
  16. +0 −1 spec/truffle/tags/core/env/keys_tags.txt
  17. +0 −1 spec/truffle/tags/core/env/length_tags.txt
  18. +0 −3 spec/truffle/tags/core/env/rassoc_tags.txt
  19. +0 −10 spec/truffle/tags/core/env/reject_tags.txt
  20. +0 −1 spec/truffle/tags/core/env/replace_tags.txt
  21. +0 −7 spec/truffle/tags/core/env/select_tags.txt
  22. +0 −1 spec/truffle/tags/core/env/shift_tags.txt
  23. +34 −10 truffle/src/main/java/org/jruby/truffle/nodes/core/KernelNodes.java
  24. +83 −0 truffle/src/main/java/org/jruby/truffle/nodes/rubinius/PosixNodes.java
  25. +11 −21 truffle/src/main/java/org/jruby/truffle/runtime/core/CoreLibrary.java
  26. +6 −4 truffle/src/main/ruby/core.rb
  27. +9 −5 truffle/src/main/ruby/core/library.rb
  28. +5 −0 truffle/src/main/ruby/core/rubinius/bootstrap/kernel.rb
  29. +324 −0 truffle/src/main/ruby/core/rubinius/common/env.rb
  30. +46 −0 truffle/src/main/ruby/core/rubinius/delta/ffi.rb
  31. +37 −0 truffle/src/main/ruby/core/rubinius/platform/env.rb
3 changes: 0 additions & 3 deletions spec/truffle/tags/core/env/assoc_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/core/env/clear_tags.txt

This file was deleted.

5 changes: 0 additions & 5 deletions spec/truffle/tags/core/env/delete_if_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/core/env/delete_tags.txt

This file was deleted.

3 changes: 0 additions & 3 deletions spec/truffle/tags/core/env/each_key_tags.txt

This file was deleted.

4 changes: 0 additions & 4 deletions spec/truffle/tags/core/env/each_pair_tags.txt

This file was deleted.

4 changes: 0 additions & 4 deletions spec/truffle/tags/core/env/each_tags.txt

This file was deleted.

3 changes: 0 additions & 3 deletions spec/truffle/tags/core/env/each_value_tags.txt

This file was deleted.

3 changes: 0 additions & 3 deletions spec/truffle/tags/core/env/element_reference_tags.txt

This file was deleted.

6 changes: 0 additions & 6 deletions spec/truffle/tags/core/env/element_set_tags.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,2 @@
fails:ENV.[]= deletes the environment variable when the value is nil
fails:ENV.[]= coerces the key argument with #to_str
fails:ENV.[]= coerces the value argument with #to_str
fails:ENV.[]= raises TypeError when the key is not coercible to String
fails:ENV.[]= raises TypeError when the value is not coercible to String
fails:ENV.[]= raises Errno::EINVAL when the key contains the '=' character
fails:ENV.[]= raises Errno::EINVAL when the key is an empty string
fails:ENV.[]= does nothing when the key is not a valid environment variable key and the value is nil
2 changes: 0 additions & 2 deletions spec/truffle/tags/core/env/empty_tags.txt

This file was deleted.

3 changes: 0 additions & 3 deletions spec/truffle/tags/core/env/fetch_tags.txt

This file was deleted.

2 changes: 0 additions & 2 deletions spec/truffle/tags/core/env/index_tags.txt

This file was deleted.

5 changes: 0 additions & 5 deletions spec/truffle/tags/core/env/keep_if_tags.txt

This file was deleted.

2 changes: 0 additions & 2 deletions spec/truffle/tags/core/env/key_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/core/env/keys_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/core/env/length_tags.txt

This file was deleted.

3 changes: 0 additions & 3 deletions spec/truffle/tags/core/env/rassoc_tags.txt

This file was deleted.

10 changes: 0 additions & 10 deletions spec/truffle/tags/core/env/reject_tags.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1 @@
fails:ENV.reject! rejects entries based on key
fails:ENV.reject! rejects entries based on value
fails:ENV.reject! returns itself or nil
fails:ENV.reject! returns an Enumerator if called without a block
fails:ENV.reject! doesn't raise if empty
fails:ENV.reject rejects entries based on key
fails:ENV.reject rejects entries based on value
fails:ENV.reject returns a Hash
fails:ENV.reject doesn't raise if empty
fails:ENV.reject! when no block is given returned Enumerator size returns the enumerable size
fails:ENV.reject when no block is given returned Enumerator size returns the enumerable size
1 change: 0 additions & 1 deletion spec/truffle/tags/core/env/replace_tags.txt

This file was deleted.

7 changes: 0 additions & 7 deletions spec/truffle/tags/core/env/select_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/core/env/shift_tags.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
fails:ENV.shift returns a pair and deletes it
fails:ENV.shift returns nil if ENV.empty?
fails:ENV.shift uses the locale encoding if Encoding.default_internal is nil
fails:ENV.shift transcodes from the locale encoding to Encoding.default_internal if set
44 changes: 34 additions & 10 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/KernelNodes.java
Original file line number Diff line number Diff line change
@@ -76,24 +76,32 @@ public abstract class KernelNodes {
@CoreMethod(names = "`", isModuleFunction = true, needsSelf = false, required = 1)
public abstract static class BacktickNode extends CoreMethodArrayArgumentsNode {

@Child private CallDispatchHeadNode toHashNode;

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

@Specialization
public RubyBasicObject backtick(RubyString command) {
public RubyBasicObject backtick(VirtualFrame frame, RubyString command) {
// Command is lexically a string interoplation, so variables will already have been expanded

if (toHashNode == null) {
CompilerDirectives.transferToInterpreter();
toHashNode = insert(DispatchHeadNodeFactory.createMethodCall(getContext()));
}

CompilerDirectives.transferToInterpreter();

final RubyContext context = getContext();

final RubyBasicObject env = context.getCoreLibrary().getENV();
final RubyBasicObject envAsHash = (RubyBasicObject) toHashNode.call(frame, env, "to_hash", null);

final List<String> envp = new ArrayList<>();

// TODO(CS): cast
for (Map.Entry<Object, Object> keyValue : HashNodes.iterableKeyValues(env)) {
for (Map.Entry<Object, Object> keyValue : HashNodes.iterableKeyValues(envAsHash)) {
envp.add(keyValue.getKey().toString() + "=" + keyValue.getValue().toString());
}

@@ -528,12 +536,19 @@ public Object eval(RubyString source, RubyBasicObject badBinding, NotProvided fi
@CoreMethod(names = "exec", isModuleFunction = true, required = 1, argumentsAsArray = true)
public abstract static class ExecNode extends CoreMethodArrayArgumentsNode {

@Child private CallDispatchHeadNode toHashNode;

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

@Specialization
public Object require(Object[] args) {
public Object require(VirtualFrame frame, Object[] args) {
if (toHashNode == null) {
CompilerDirectives.transferToInterpreter();
toHashNode = insert(DispatchHeadNodeFactory.createMethodCall(getContext()));
}

CompilerDirectives.transferToInterpreter();

final String[] commandLine = new String[args.length];
@@ -542,19 +557,20 @@ public Object require(Object[] args) {
commandLine[n] = args[n].toString();
}

exec(getContext(), commandLine);
final RubyBasicObject env = getContext().getCoreLibrary().getENV();
final RubyBasicObject envAsHash = (RubyBasicObject) toHashNode.call(frame, env, "to_hash", null);

exec(getContext(), envAsHash, commandLine);

return null;
}

@TruffleBoundary
private static void exec(RubyContext context, String[] commandLine) {
private static void exec(RubyContext context, RubyBasicObject envAsHash, String[] commandLine) {
final ProcessBuilder builder = new ProcessBuilder(commandLine);
builder.inheritIO();

final RubyBasicObject env = context.getCoreLibrary().getENV();

for (Map.Entry<Object, Object> keyValue : HashNodes.iterableKeyValues(env)) {
for (Map.Entry<Object, Object> keyValue : HashNodes.iterableKeyValues(envAsHash)) {
builder.environment().put(keyValue.getKey().toString(), keyValue.getValue().toString());
}

@@ -1804,22 +1820,30 @@ protected RubyString asRubyString(Object arg) {
@CoreMethod(names = "system", isModuleFunction = true, needsSelf = false, required = 1)
public abstract static class SystemNode extends CoreMethodArrayArgumentsNode {

@Child private CallDispatchHeadNode toHashNode;

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

@Specialization
public boolean system(RubyString command) {
public boolean system(VirtualFrame frame, RubyString command) {
if (toHashNode == null) {
CompilerDirectives.transferToInterpreter();
toHashNode = insert(DispatchHeadNodeFactory.createMethodCall(getContext()));
}

CompilerDirectives.transferToInterpreter();

// TODO(CS 5-JAN-15): very simplistic implementation

final RubyBasicObject env = getContext().getCoreLibrary().getENV();
final RubyBasicObject envAsHash = (RubyBasicObject) toHashNode.call(frame, env, "to_hash", null);

final List<String> envp = new ArrayList<>();

// TODO(CS): cast
for (Map.Entry<Object, Object> keyValue : HashNodes.iterableKeyValues(env)) {
for (Map.Entry<Object, Object> keyValue : HashNodes.iterableKeyValues(envAsHash)) {
envp.add(keyValue.getKey().toString() + "=" + keyValue.getValue().toString());
}

Original file line number Diff line number Diff line change
@@ -20,12 +20,14 @@
import org.jruby.truffle.nodes.core.CoreMethod;
import org.jruby.truffle.nodes.core.CoreMethodArrayArgumentsNode;
import org.jruby.truffle.nodes.core.StringNodes;
import org.jruby.truffle.nodes.core.array.ArrayNodes;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.core.RubyString;

import java.nio.charset.StandardCharsets;
import java.util.Map;

@CoreClass(name = "Rubinius::FFI::Platform::POSIX")
public abstract class PosixNodes {
@@ -87,6 +89,19 @@ public int dup(int descriptor) {

}

@CoreMethod(names = "environ", isModuleFunction = true)
public abstract static class EnvironNode extends CoreMethodArrayArgumentsNode {

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

@Specialization
public RubyBasicObject environ() {
return PointerNodes.createPointer(getContext().getCoreLibrary().getRubiniusFFIPointerClass(), posix().environ());
}
}

@CoreMethod(names = "fchmod", isModuleFunction = true, required = 2)
public abstract static class FchmodNode extends CoreMethodArrayArgumentsNode {

@@ -145,6 +160,27 @@ public int getEGID() {

}

@CoreMethod(names = "getenv", isModuleFunction = true, required = 1)
public abstract static class GetenvNode extends CoreMethodArrayArgumentsNode {

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

@Specialization(guards = "isRubyString(name)")
public RubyBasicObject getenv(RubyBasicObject name) {
final String nameString = RubyEncoding.decodeUTF8(StringNodes.getByteList(name).getUnsafeBytes(), StringNodes.getByteList(name).getBegin(), StringNodes.getByteList(name).getRealSize());

Object result = posix().getenv(nameString);

if (result == null) {
return nil();
}

return StringNodes.createString(getContext().getCoreLibrary().getStringClass(), (String) result);
}
}

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

@@ -257,6 +293,20 @@ public RubyBasicObject memset(RubyBasicObject pointer, int c, long length) {

}

@CoreMethod(names = "putenv", isModuleFunction = true, required = 1)
public abstract static class PutenvNode extends CoreMethodArrayArgumentsNode {

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

@Specialization(guards = "isRubyString(nameValuePair)")
public int putenv(RubyBasicObject nameValuePair) {
throw new UnsupportedOperationException("Not yet implemented in jnr-posix");
}

}

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

@@ -279,6 +329,23 @@ public int readlink(RubyString path, RubyBasicObject pointer, int bufsize) {

}

@CoreMethod(names = "setenv", isModuleFunction = true, required = 3)
public abstract static class SetenvNode extends CoreMethodArrayArgumentsNode {

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

@Specialization(guards = { "isRubyString(name)", "isRubyString(value)" })
public int setenv(RubyBasicObject name, RubyBasicObject value, int overwrite) {
final String nameString = RubyEncoding.decodeUTF8(StringNodes.getByteList(name).getUnsafeBytes(), StringNodes.getByteList(name).getBegin(), StringNodes.getByteList(name).getRealSize());
final String valueString = RubyEncoding.decodeUTF8(StringNodes.getByteList(value).getUnsafeBytes(), StringNodes.getByteList(value).getBegin(), StringNodes.getByteList(value).getRealSize());

return posix().setenv(nameString, valueString, overwrite);
}

}

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

@@ -323,6 +390,22 @@ public int umask(int mask) {

}

@CoreMethod(names = "unsetenv", isModuleFunction = true, required = 1)
public abstract static class UnsetenvNode extends CoreMethodArrayArgumentsNode {

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

@Specialization(guards = "isRubyString(name)")
public int unsetenv(RubyBasicObject name) {
final String nameString = RubyEncoding.decodeUTF8(StringNodes.getByteList(name).getUnsafeBytes(), StringNodes.getByteList(name).getBegin(), StringNodes.getByteList(name).getRealSize());

return posix().unsetenv(nameString);
}

}

@CoreMethod(names = "utimes", isModuleFunction = true, required = 2)
public abstract static class UtimesNode extends CoreMethodArrayArgumentsNode {

Loading