Skip to content

Commit

Permalink
[Truffle] Call #to_path on autoload paths.
Browse files Browse the repository at this point in the history
  • Loading branch information
eregon committed Jul 11, 2015
1 parent 83e437d commit 43561c1
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 22 deletions.
1 change: 0 additions & 1 deletion spec/truffle/tags/core/kernel/autoload_tags.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
fails:Kernel.autoload calls #to_path on non-String filenames
slow:Kernel#autoload when Object is frozen raises a RuntimeError before defining the constant
2 changes: 0 additions & 2 deletions spec/truffle/tags/core/module/autoload_tags.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
fails:Module#autoload calls #to_path on non-string filenames
fails:Module#autoload calls #to_path on non-String filename arguments
fails:Module#autoload (concurrently) blocks a second thread while a first is doing the autoload
fails:Module#autoload (concurrently) blocks others threads while doing an autoload
fails:Module#autoload shares the autoload request across dup'ed copies of modules
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* 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.coerce;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory;
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;

@NodeChild(value = "child", type = RubyNode.class)
public abstract class ToPathNode extends RubyNode {

@Child private CallDispatchHeadNode toPathNode;

public ToPathNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
toPathNode = DispatchHeadNodeFactory.createMethodCall(context);
}

public abstract RubyString executeRubyString(VirtualFrame frame, Object object);

@Specialization
public RubyBasicObject coerceRubyString(RubyString path) {
return path;
}

@Specialization(guards = "!isRubyString(object)")
public RubyBasicObject coerceObject(VirtualFrame frame, Object object) {
final Object coerced;

try {
coerced = toPathNode.call(frame, object, "to_path", null);
} catch (RaiseException e) {
if (e.getRubyException().getLogicalClass() == getContext().getCoreLibrary().getNoMethodErrorClass()) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().typeErrorNoImplicitConversion(object, "String", this));
} else {
throw e;
}
}

if (coerced instanceof RubyString) {
return (RubyString) coerced;
} else {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().typeErrorBadCoercion(object, "String", "to_path", coerced, this));
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,7 @@ public RubyBasicObject coerceObject(VirtualFrame frame, Object object) {
} catch (RaiseException e) {
if (e.getRubyException().getLogicalClass() == getContext().getCoreLibrary().getNoMethodErrorClass()) {
CompilerDirectives.transferToInterpreter();

throw new RaiseException(
getContext().getCoreLibrary().typeErrorNoImplicitConversion(object, "String", this));
throw new RaiseException(getContext().getCoreLibrary().typeErrorNoImplicitConversion(object, "String", this));
} else {
throw e;
}
Expand All @@ -61,9 +59,7 @@ public RubyBasicObject coerceObject(VirtualFrame frame, Object object) {
return (RubyBasicObject) coerced;
} else {
CompilerDirectives.transferToInterpreter();

throw new RaiseException(
getContext().getCoreLibrary().typeErrorBadCoercion(object, "String", "to_str", coerced, this));
throw new RaiseException(getContext().getCoreLibrary().typeErrorBadCoercion(object, "String", "to_str", coerced, this));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -528,23 +528,16 @@ public AutoloadNode(RubyContext context, SourceSection sourceSection) {
emptyNode = StringNodesFactory.EmptyNodeFactory.create(context, sourceSection, new RubyNode[]{});
}

@CreateCast("filename") public RubyNode coerceFilenameToString(RubyNode filename) {
return ToStrNodeGen.create(getContext(), getSourceSection(), filename);
}

@Specialization(guards = {"isRubySymbol(name)", "isRubyString(filename)"})
public RubyBasicObject autoloadSymbol(RubyModule module, RubyBasicObject name, RubyBasicObject filename) {
return autoload(module, SymbolNodes.getString(name), filename);
@CreateCast("name") public RubyNode coerceNameToString(RubyNode name) {
return NameToJavaStringNodeGen.create(getContext(), getSourceSection(), name);
}

@Specialization(guards = {"isRubyString(name)", "isRubyString(filename)"})
public RubyBasicObject autoloadString(RubyModule module, RubyBasicObject name, RubyBasicObject filename) {
return autoload(module, name.toString(), filename);
@CreateCast("filename") public RubyNode coerceFilenameToPath(RubyNode filename) {
return ToPathNodeGen.create(getContext(), getSourceSection(), filename);
}

private RubyBasicObject autoload(RubyModule module, String name, RubyBasicObject filename) {
assert RubyGuards.isRubyString(filename);

@Specialization(guards = "isRubyString(filename)")
public RubyBasicObject autoload(RubyModule module, String name, RubyBasicObject filename) {
if (invalidConstantName.profile(!IdUtil.isValidConstantName19(name))) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().nameError(String.format("autoload must be constant name: %s", name), name, this));
Expand Down

0 comments on commit 43561c1

Please sign in to comment.