Skip to content

Commit

Permalink
Showing 5 changed files with 52 additions and 10 deletions.
2 changes: 0 additions & 2 deletions spec/truffle/tags/core/dir/each_tags.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
fails:Dir#each yields each directory entry in succession
fails:Dir#each returns the directory which remains open
fails:Dir#each returns an Enumerator if no block given
fails:Dir#each raises an IOError when called on a closed Dir instance
5 changes: 0 additions & 5 deletions spec/truffle/tags/core/dir/foreach_tags.txt

This file was deleted.

3 changes: 0 additions & 3 deletions spec/truffle/tags/core/dir/home_tags.txt

This file was deleted.

Original file line number Diff line number Diff line change
@@ -21,6 +21,7 @@
import com.oracle.truffle.api.source.Source;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.ConditionProfile;
import jnr.posix.Passwd;
import org.jcodings.Encoding;
import org.jruby.runtime.Visibility;
import org.jruby.truffle.nodes.RubyNode;
@@ -1800,6 +1801,27 @@ private RubyModule undefMethod(RubyModule module, String name) {

}

@CoreMethod(names = "get_user_home", needsSelf = false, required = 1)
public abstract static class GetUserHomeNode extends CoreMethodArrayArgumentsNode {

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

@Specialization
public RubyString userHome(RubyString uname) {
notDesignedForCompilation();

This comment has been minimized.

Copy link
@chrisseaton

chrisseaton May 1, 2015

Contributor

Please don't use notDesignedForCompilation() in any new code.

  • Method uses code which won't compile (StringBuilder etc) but it has a VirtualFrametransferToInterpreter()
  • Method uses code which won't compile but doesn't have a VirtualFrame@TruffleBoundary
  • Method doesn't really implement Ruby semantics ⇒ try not to write code like this, but if you have to make it CompilerDirectives.bailout(msg)
  • Method is probably fine but you haven't checked ⇒ give it the benefit of the doubt and see what happens

This way we should have a system which will compile what it can, transfer when it can't do that, but will still not accidentally compile something that is not really Ruby semantics so we don't benchmark that by mistake.

For this method it's the last case above. You already have a transfer on the exception branch, and toString and makeString are both boundary.

@eregon @nirvdrum

// TODO BJF 30-APR-2015 Review the more robust getHomeDirectoryPath implementation
final Passwd passwd = getContext().getPosix().getpwnam(uname.toString());
if (passwd == null) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().argumentError("user " + uname.toString() + " does not exist", this));
}
return getContext().makeString(passwd.getHome());
}

}

@NodeChildren({ @NodeChild(value = "module"), @NodeChild(value = "names") })
public abstract static class SetVisibilityNode extends CoreMethodNode {

30 changes: 30 additions & 0 deletions truffle/src/main/ruby/core/rubinius/common/dir.rb
Original file line number Diff line number Diff line change
@@ -121,6 +121,22 @@ def self.mkdir(path, mode = 0777)
error
end

def self.foreach(path)
return to_enum(:foreach, path) unless block_given?

open(path) do |dir|
while s = dir.read
yield s
end
end

nil
end

def self.join_path(p1, p2, dirsep)
"#{p1}#{dirsep ? '/' : ''}#{p2}"
end

def self.chdir(path = ENV['HOME'])
path = Rubinius::Type.coerce_to_path path

@@ -157,6 +173,16 @@ def self.getwd
Rubinius::Type.external_string wd
end

def each
return to_enum unless block_given?

while s = read
yield s
end

self
end

class << self
alias_method :pwd, :getwd
alias_method :delete, :rmdir
@@ -171,4 +197,8 @@ class << self
alias_method :exists?, :exist?
end

def self.home(user=nil)
PrivateFile.expand_path("~#{user}")
end

end

0 comments on commit 9de830f

Please sign in to comment.