Skip to content

Commit

Permalink
Showing 31 changed files with 355 additions and 265 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -79,6 +79,7 @@ matrix:
fast_finish: true
allow_failures:
- env: COMMAND=test/truffle/run.sh
- env: PHASE='-Ptruffle-mri-tests'


branches:
4 changes: 3 additions & 1 deletion core/src/main/java/org/jruby/parser/ParserSupport.java
Original file line number Diff line number Diff line change
@@ -1378,7 +1378,9 @@ public String internalId() {
return "";
}

private static final String TRUFFLE_CORE_LOAD_PATH = Options.TRUFFLE_CORE_LOAD_PATH.load();

public static boolean skipTruffleRubiniusWarnings(RubyLexer lexer) {
return lexer.getFile().startsWith("core:/");
return lexer.getFile().startsWith(TRUFFLE_CORE_LOAD_PATH);
}
}
2 changes: 2 additions & 0 deletions core/src/main/java/org/jruby/util/cli/Options.java
Original file line number Diff line number Diff line change
@@ -125,6 +125,8 @@ public class Options {
public static final Option<Boolean> IR_WRITING_DEBUG = bool(IR, "ir.writing.debug", false, "Debug writing JRuby IR file.");
public static final Option<String> IR_INLINE_COMPILER_PASSES = string(IR, "ir.inline_passes", "Specify comma delimeted list of passes to run after inlining a method.");

public static final Option<String> TRUFFLE_CORE_LOAD_PATH = string(TRUFFLE, "truffle.core.load_path", "truffle:/", "Directory to load the Truffle core library from.");

public static final Option<Integer> TRUFFLE_DISPATCH_POLYMORPHIC_MAX = integer(TRUFFLE, "truffle.dispatch.polymorphic.max", 8, "Maximum size of a polymorphic call site cache.");
public static final Option<Integer> TRUFFLE_ARRAYS_UNINITIALIZED_SIZE = integer(TRUFFLE, "truffle.arrays.uninitialized_size", 32, "How large an array to allocate when we have no other information to go on.");
public static final Option<Integer> TRUFFLE_ARRAYS_SMALL = integer(TRUFFLE, "truffle.arrays.small", 3, "Maximum size of an Array to consider small for optimisations.");
1 change: 1 addition & 0 deletions spec/truffle/tags/core/argf/gets_tags.txt
Original file line number Diff line number Diff line change
@@ -2,3 +2,4 @@ fails:ARGF.gets sets $_ global variable with each line read
fails:ARGF.gets modifies the files when in place edit mode is on
fails:ARGF.gets modifies and backups two files when in place edit mode is on
slow:ARGF.gets reads all lines of stdin
fails:ARGF.gets reads all lines of stdin
3 changes: 3 additions & 0 deletions spec/truffle/tags/core/argf/read_tags.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
slow:ARGF.read reads the contents of stdin
slow:ARGF.read reads a number of bytes from stdin
slow:ARGF.read reads the contents of one file and stdin
fails:ARGF.read reads the contents of stdin
fails:ARGF.read reads a number of bytes from stdin
fails:ARGF.read reads the contents of one file and stdin
1 change: 1 addition & 0 deletions spec/truffle/tags/core/argf/readline_tags.txt
Original file line number Diff line number Diff line change
@@ -2,3 +2,4 @@ fails:ARGF.readline sets $_ global variable with each line read
fails:ARGF.readline modifies the files when in place edit mode is on
fails:ARGF.readline modifies and backups two files when in place edit mode is on
slow:ARGF.readline reads all lines of stdin
fails:ARGF.readline reads all lines of stdin
4 changes: 4 additions & 0 deletions spec/truffle/tags/core/argf/set_encoding_tags.txt
Original file line number Diff line number Diff line change
@@ -2,3 +2,7 @@ slow:ARGF.set_encoding sets the external encoding when passed an encoding instan
slow:ARGF.set_encoding sets the external encoding when passed an encoding name
slow:ARGF.set_encoding sets the external, internal encoding when passed two encoding instances
slow:ARGF.set_encoding sets the external, internal encoding when passed 'ext:int' String
fails:ARGF.set_encoding sets the external encoding when passed an encoding instance
fails:ARGF.set_encoding sets the external encoding when passed an encoding name
fails:ARGF.set_encoding sets the external, internal encoding when passed two encoding instances
fails:ARGF.set_encoding sets the external, internal encoding when passed 'ext:int' String
3 changes: 3 additions & 0 deletions spec/truffle/tags/core/encoding/default_external_tags.txt
Original file line number Diff line number Diff line change
@@ -3,3 +3,6 @@ windows:Encoding.default_external with command line options returns the encoding
slow:Encoding.default_external with command line options is not changed by the -U option
slow:Encoding.default_external with command line options returns the encoding specified by '-E external'
slow:Encoding.default_external with command line options returns the encoding specified by '-E external:'
fails:Encoding.default_external with command line options is not changed by the -U option
fails:Encoding.default_external with command line options returns the encoding specified by '-E external'
fails:Encoding.default_external with command line options returns the encoding specified by '-E external:'
3 changes: 3 additions & 0 deletions spec/truffle/tags/core/encoding/default_internal_tags.txt
Original file line number Diff line number Diff line change
@@ -4,3 +4,6 @@ windows:Encoding.default_internal with command line options uses the encoding sp
slow:Encoding.default_internal with command line options returns Encoding::UTF_8 if ruby was invoked with -U
slow:Encoding.default_internal with command line options uses the encoding specified when ruby is invoked with an '-E :internal' argument
slow:Encoding.default_internal with command line options uses the encoding specified when ruby is invoked with an '-E external:internal' argument
fails:Encoding.default_internal with command line options returns Encoding::UTF_8 if ruby was invoked with -U
fails:Encoding.default_internal with command line options uses the encoding specified when ruby is invoked with an '-E :internal' argument
fails:Encoding.default_internal with command line options uses the encoding specified when ruby is invoked with an '-E external:internal' argument
3 changes: 3 additions & 0 deletions spec/truffle/tags/core/kernel/at_exit_tags.txt
Original file line number Diff line number Diff line change
@@ -3,3 +3,6 @@ slow:Kernel.at_exit runs in reverse order of registration
slow:Kernel.at_exit allows calling exit inside at_exit handler
slow:Kernel.at_exit gives access to the last raised exception
fails:Kernel.at_exit gives access to the last raised exception
fails:Kernel.at_exit runs after all other code
fails:Kernel.at_exit runs in reverse order of registration
fails:Kernel.at_exit allows calling exit inside at_exit handler
1 change: 1 addition & 0 deletions spec/truffle/tags/core/kernel/autoload_tags.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
slow:Kernel#autoload when Object is frozen raises a RuntimeError before defining the constant
fails:Kernel#autoload when Object is frozen raises a RuntimeError before defining the constant
2 changes: 2 additions & 0 deletions spec/truffle/tags/core/kernel/caller_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fails:Kernel#caller returns an Array of caller locations using a custom offset
fails:Kernel#caller returns the locations as String instances
6 changes: 6 additions & 0 deletions spec/truffle/tags/core/kernel/exec_tags.txt
Original file line number Diff line number Diff line change
@@ -72,3 +72,9 @@ slow:Kernel.exec with a command array uses the first element as the command name
slow:Kernel.exec with a command array coerces the argument using to_ary
slow:Kernel.exec with a command array raises an ArgumentError if the Array does not have exactly two elements
slow:Kernel.exec with an options Hash with Integer option keys maps the key to a file descriptor in the child that inherits the file descriptor from the parent specified by the value
fails:Kernel#exec flushes STDOUT upon exit when it's not set to sync
fails:Kernel#exec flushes STDERR upon exit when it's not set to sync
fails:Kernel#exec with multiple arguments does not subject the arguments to shell expansion
fails:Kernel.exec flushes STDOUT upon exit when it's not set to sync
fails:Kernel.exec flushes STDERR upon exit when it's not set to sync
fails:Kernel.exec with multiple arguments does not subject the arguments to shell expansion
2 changes: 2 additions & 0 deletions spec/truffle/tags/core/process/exec_tags.txt
Original file line number Diff line number Diff line change
@@ -37,3 +37,5 @@ slow:Process.exec with a command array coerces the argument using to_ary
slow:Process.exec with a command array raises an ArgumentError if the Array does not have exactly two elements
slow:Process.exec with an options Hash with Integer option keys maps the key to a file descriptor in the child that inherits the file descriptor from the parent specified by the value
fails:Process.exec flushes STDOUT upon exit when it's not set to sync
fails:Process.exec with multiple arguments does not subject the arguments to shell expansion

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:Thread::Backtrace::Location#inspect converts the call frame to a String
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:Thread::Backtrace::Location#to_s converts the call frame to a String
1 change: 1 addition & 0 deletions spec/truffle/tags/language/predefined/data_tags.txt
Original file line number Diff line number Diff line change
@@ -10,3 +10,4 @@ windows:The DATA constant exists when the main script contains __END__
windows:The DATA constant does not exist when the main script contains no __END__
windows:The DATA constant does not change when an included files also has a __END__
fails:The DATA constant exists when the main script contains __END__
fails:The DATA constant does not exist when the main script contains no __END__
4 changes: 4 additions & 0 deletions spec/truffle/tags/language/predefined_tags.txt
Original file line number Diff line number Diff line change
@@ -10,3 +10,7 @@ windows:The predefined global constant STDERR has the encodings set by #set_enco
fails:Predefined global $_ is set to the last line read by e.g. StringIO#gets
fails:Predefined global $_ is set at the method-scoped level rather than block-scoped
fails:Global variable $0 actually sets the program name
fails:The predefined global constant STDIN has the encodings set by #set_encoding
fails:The predefined global constant STDIN retains the encoding set by #set_encoding when Encoding.default_external is changed
fails:The predefined global constant STDOUT has the encodings set by #set_encoding
fails:The predefined global constant STDERR has the encodings set by #set_encoding
2 changes: 1 addition & 1 deletion tool/jt.rb
Original file line number Diff line number Diff line change
@@ -242,7 +242,7 @@ def rebuild

def run(*args)
env_vars = args.first.is_a?(Hash) ? args.shift : {}
jruby_args = %w[-X+T]
jruby_args = %w[-X+T -Xtruffle.core.load_path=truffle/src/main/ruby]

{ '--asm' => '--graal', '--igv' => '--graal' }.each_pair do |arg, dep|
args.unshift dep if args.include?(arg)
Original file line number Diff line number Diff line change
@@ -65,7 +65,7 @@
import org.jruby.truffle.runtime.hash.HashOperations;
import org.jruby.truffle.runtime.layouts.Layouts;
import org.jruby.truffle.runtime.methods.InternalMethod;
import org.jruby.truffle.runtime.subsystems.FeatureManager;
import org.jruby.truffle.runtime.loader.FeatureLoader;
import org.jruby.truffle.runtime.subsystems.ThreadManager.BlockingAction;
import org.jruby.truffle.translator.NodeWrapper;
import org.jruby.truffle.translator.TranslatorDriver;
@@ -1172,15 +1172,8 @@ public boolean load(DynamicObject file, boolean wrap) {

try {
getContext().loadFile(file.toString(), this);
} catch (RuntimeException e) {
// TODO (nirvdrum 05-Feb-15) This is ugly, but checked exceptions are wrapped up the call stack. We need to revisit this.
if (e.getCause() instanceof java.io.IOException) {
CompilerDirectives.transferToInterpreter();

throw new RaiseException(getContext().getCoreLibrary().loadErrorCannotLoad(file.toString(), this));
} else {
throw e;
}
} catch (IOException e) {
throw new RaiseException(getContext().getCoreLibrary().loadErrorCannotLoad(file.toString(), this));
}

return true;
@@ -1543,7 +1536,7 @@ public boolean require(DynamicObject featureString) {
}

try {
getContext().getFeatureManager().require(feature, this);
getContext().getFeatureLoader().require(feature, this);
} catch (IOException e) {
throw new RuntimeException(e);
}
@@ -1562,16 +1555,16 @@ public RequireRelativeNode(RubyContext context, SourceSection sourceSection) {
@TruffleBoundary
@Specialization(guards = "isRubyString(feature)")
public boolean requireRelative(DynamicObject feature) {
final FeatureManager featureManager = getContext().getFeatureManager();
final FeatureLoader featureLoader = getContext().getFeatureLoader();

final String featureString = feature.toString();
final String featurePath;

if (featureManager.isAbsolutePath(featureString)) {
if (featureLoader.isAbsolutePath(featureString)) {
featurePath = featureString;
} else {
final Source source = RubyCallStack.getCallerFrame(getContext()).getCallNode().getEncapsulatingSourceSection().getSource();
final String sourcePath = featureManager.getSourcePath(source);
final String sourcePath = featureLoader.getSourcePath(source);

if (sourcePath == null) {
CompilerDirectives.transferToInterpreter();
@@ -1582,7 +1575,7 @@ public boolean requireRelative(DynamicObject feature) {
}

try {
featureManager.require(featurePath, this);
featureLoader.require(featurePath, this);
} catch (IOException e) {
throw new RuntimeException(e);
}
97 changes: 55 additions & 42 deletions truffle/src/main/java/org/jruby/truffle/runtime/RubyContext.java
Original file line number Diff line number Diff line change
@@ -51,6 +51,9 @@
import org.jruby.truffle.runtime.core.CoreLibrary;
import org.jruby.truffle.runtime.core.SymbolTable;
import org.jruby.truffle.runtime.layouts.Layouts;
import org.jruby.truffle.runtime.loader.FeatureLoader;
import org.jruby.truffle.runtime.loader.SourceCache;
import org.jruby.truffle.runtime.loader.SourceLoader;
import org.jruby.truffle.runtime.methods.InternalMethod;
import org.jruby.truffle.runtime.object.ObjectIDOperations;
import org.jruby.truffle.runtime.rubinius.RubiniusConfiguration;
@@ -62,6 +65,7 @@
import org.jruby.util.cli.Options;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
@@ -88,7 +92,7 @@ public class RubyContext extends ExecutionContext implements TruffleContextInter
private final NativeSockets nativeSockets;

private final CoreLibrary coreLibrary;
private final FeatureManager featureManager;
private final FeatureLoader featureLoader;
private final TraceManager traceManager;
private final ObjectSpaceManager objectSpaceManager;
private final ThreadManager threadManager;
@@ -102,7 +106,7 @@ public class RubyContext extends ExecutionContext implements TruffleContextInter
private final CoverageTracker coverageTracker;
private final InstrumentationServerManager instrumentationServerManager;
private final AttachmentsManager attachmentsManager;
private final SourceManager sourceManager;
private final SourceCache sourceCache;
private final RubiniusConfiguration rubiniusConfiguration;

private final AtomicLong nextObjectID = new AtomicLong(ObjectIDOperations.FIRST_OBJECT_ID);
@@ -157,7 +161,7 @@ public RubyContext(Ruby runtime) {
rootLexicalScope = new LexicalScope(null, coreLibrary.getObjectClass());
coreLibrary.initialize();

featureManager = new FeatureManager(this);
featureLoader = new FeatureLoader(this);
traceManager = new TraceManager();
atExitManager = new AtExitManager(this);

@@ -177,7 +181,7 @@ public RubyContext(Ruby runtime) {
runningOnWindows = Platform.getPlatform().getOS() == OS_TYPE.WINDOWS;

attachmentsManager = new AttachmentsManager(this);
sourceManager = new SourceManager(this);
sourceCache = new SourceCache(new SourceLoader(this));
rubiniusConfiguration = RubiniusConfiguration.create(this);

final PrintStream configStandardOut = runtime.getInstanceConfig().getOutput();
@@ -218,39 +222,53 @@ public void initialize() {
DynamicObject receiver = coreLibrary.getGlobalVariablesObject();
final DynamicObject loadPath = (DynamicObject) receiver.get("$:", Layouts.MODULE.getFields(Layouts.BASIC_OBJECT.getLogicalClass(receiver)).getContext().getCoreLibrary().getNilObject());

final String home = runtime.getInstanceConfig().getJRubyHome();
for (IRubyObject path : ((org.jruby.RubyArray) runtime.getLoadService().getLoadPath()).toJavaArray()) {
String pathString = path.toString();

// We don't want JRuby's stdlib paths, but we do want any extra paths set by -I and things like that
if (!(pathString.endsWith("lib/ruby/2.2/site_ruby")
|| pathString.endsWith("lib/ruby/shared")
|| pathString.endsWith("lib/ruby/stdlib"))) {

final List<String> excludedLibPaths = new ArrayList<>();
excludedLibPaths.add(new File(home, "lib/ruby/2.2/site_ruby").toString().replace('\\', '/'));
excludedLibPaths.add(new File(home, "lib/ruby/shared").toString().replace('\\', '/'));
excludedLibPaths.add(new File(home, "lib/ruby/stdlib").toString().replace('\\', '/'));
if (pathString.startsWith("uri:classloader:")) {
pathString = SourceLoader.JRUBY_SCHEME + pathString.substring("uri:classloader:".length());
}

for (IRubyObject path : ((org.jruby.RubyArray) runtime.getLoadService().getLoadPath()).toJavaArray()) {
if (!excludedLibPaths.contains(path.toString())) {
ArrayOperations.append(loadPath, StringNodes.createString(coreLibrary.getStringClass(), new File(path.toString()).getAbsolutePath()));
ArrayOperations.append(loadPath, StringNodes.createString(coreLibrary.getStringClass(), pathString));
}
}

// Load our own stdlib path

String home = runtime.getInstanceConfig().getJRubyHome();

if (home.startsWith("uri:classloader:")) {
home = home.substring("uri:classloader:".length());

while (home.startsWith("/")) {
home = home.substring(1);
}

home = SourceLoader.JRUBY_SCHEME + "/" + home;
}

home = home + "/";

// Libraries copied unmodified from MRI
ArrayOperations.append(loadPath, StringNodes.createString(coreLibrary.getStringClass(), new File(home, "lib/ruby/truffle/mri").toString()));
ArrayOperations.append(loadPath, StringNodes.createString(coreLibrary.getStringClass(), home + "lib/ruby/truffle/mri"));

// Our own implementations
ArrayOperations.append(loadPath, StringNodes.createString(coreLibrary.getStringClass(), new File(home, "lib/ruby/truffle/truffle").toString()));
ArrayOperations.append(loadPath, StringNodes.createString(coreLibrary.getStringClass(), home + "lib/ruby/truffle/truffle"));

// Libraries from RubySL
for (String lib : Arrays.asList("rubysl-strscan", "rubysl-stringio",
"rubysl-complex", "rubysl-date", "rubysl-pathname",
"rubysl-tempfile", "rubysl-socket", "rubysl-securerandom",
"rubysl-timeout", "rubysl-webrick")) {
ArrayOperations.append(loadPath, StringNodes.createString(coreLibrary.getStringClass(), new File(home, "lib/ruby/truffle/rubysl/" + lib + "/lib").toString()));
ArrayOperations.append(loadPath, StringNodes.createString(coreLibrary.getStringClass(), home + "lib/ruby/truffle/rubysl/" + lib + "/lib"));
}

// Shims
ArrayOperations.append(loadPath, StringNodes.createString(coreLibrary.getStringClass(), new File(home, "lib/ruby/truffle/shims").toString()));
ArrayOperations.append(loadPath, StringNodes.createString(coreLibrary.getStringClass(), home + "lib/ruby/truffle/shims"));
}

public static String checkInstanceVariableName(RubyContext context, String name, Node currentNode) {
@@ -273,16 +291,16 @@ public boolean isRunningOnWindows() {
return runningOnWindows;
}

public void loadFile(String fileName, Node currentNode) {
if (new File(fileName).isAbsolute()) {
public void loadFile(String fileName, Node currentNode) throws IOException {
if (new File(fileName).isAbsolute() || fileName.startsWith("jruby:") || fileName.startsWith("truffle:")) {
loadFileAbsolute(fileName, currentNode);
} else {
loadFileAbsolute(this.getRuntime().getCurrentDirectory() + File.separator + fileName, currentNode);
loadFileAbsolute(new File(this.getRuntime().getCurrentDirectory() + File.separator + fileName).getCanonicalPath(), currentNode);
}
}

private void loadFileAbsolute(String fileName, Node currentNode) {
final Source source = sourceManager.forFile(fileName);
private void loadFileAbsolute(String fileName, Node currentNode) throws IOException {
final Source source = sourceCache.getSource(fileName);
load(source, currentNode, NodeWrapper.IDENTITY);
}

@@ -331,15 +349,6 @@ public Object instanceEval(ByteList code, Object self, Node currentNode) {
return instanceEval(code, self, "(eval)", currentNode);
}

public Object eval(Source source) {
return execute(source, UTF8Encoding.INSTANCE, TranslatorDriver.ParserContext.EVAL, getCoreLibrary().getMainObject(), null, null, new NodeWrapper() {
@Override
public RubyNode wrap(RubyNode node) {
return new SetMethodDeclarationContext(node.getContext(), node.getSourceSection(), Visibility.PRIVATE, "simple eval", node);
}
});
}

@TruffleBoundary
public Object eval(String code, DynamicObject binding, boolean ownScopeForAssignments, String filename, Node currentNode) {
assert RubyGuards.isRubyBinding(binding);
@@ -544,8 +553,8 @@ public CoreLibrary getCoreLibrary() {
return coreLibrary;
}

public FeatureManager getFeatureManager() {
return featureManager;
public FeatureLoader getFeatureLoader() {
return featureLoader;
}

public ObjectSpaceManager getObjectSpaceManager() {
@@ -616,8 +625,8 @@ public AttachmentsManager getAttachmentsManager() {
return attachmentsManager;
}

public SourceManager getSourceManager() {
return sourceManager;
public SourceCache getSourceCache() {
return sourceCache;
}

public RubiniusConfiguration getRubiniusConfiguration() {
@@ -636,17 +645,21 @@ public NativeSockets getNativeSockets() {
public Object execute(final org.jruby.ast.RootNode rootNode) {
coreLibrary.getGlobalVariablesObject().define("$0", toTruffle(runtime.getGlobalVariables().get("$0")), 0);

final String inputFile = rootNode.getPosition().getFile();
String inputFile = rootNode.getPosition().getFile();

if (!inputFile.equals("-e")) {
inputFile = new File(inputFile).getAbsolutePath();
}

final Source source;

if (inputFile.equals("-e")) {
// Assume UTF-8 for the moment
source = Source.fromText(new String(runtime.getInstanceConfig().inlineScript(), StandardCharsets.UTF_8), "-e");
} else {
source = sourceManager.forFile(inputFile);
try {
source = sourceCache.getSource(inputFile);
} catch (IOException e) {
throw new RuntimeException(e);
}

featureManager.setMainScriptSource(source);
featureLoader.setMainScriptSource(source);

load(source, null, new NodeWrapper() {
@Override
Original file line number Diff line number Diff line change
@@ -17,6 +17,7 @@
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.layouts.Layouts;
import org.jruby.truffle.runtime.loader.SourceLoader;
import org.jruby.util.cli.Options;

import java.io.PrintWriter;
@@ -191,7 +192,7 @@ private SourceSection nextUserSourceSection(List<Activation> activations, int n)
}

private boolean isCore(SourceSection sourceSection) {
return sourceSection instanceof NullSourceSection || sourceSection.getSource().getPath().startsWith("core:");
return sourceSection instanceof NullSourceSection || sourceSection.getSource().getPath().startsWith(SourceLoader.TRUFFLE_SCHEME);
}

}
Original file line number Diff line number Diff line change
@@ -51,13 +51,15 @@
import org.jruby.truffle.runtime.layouts.Layouts;
import org.jruby.truffle.runtime.layouts.ThreadBacktraceLocationLayoutImpl;
import org.jruby.truffle.runtime.layouts.ext.DigestLayoutImpl;
import org.jruby.truffle.runtime.loader.SourceLoader;
import org.jruby.truffle.runtime.methods.InternalMethod;
import org.jruby.truffle.runtime.rubinius.RubiniusTypes;
import org.jruby.truffle.runtime.signal.SignalOperations;
import org.jruby.truffle.translator.NodeWrapper;
import org.jruby.util.cli.Options;
import org.jruby.util.cli.OutputStrings;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -67,6 +69,8 @@

public class CoreLibrary {

public static final String CORE_LOAD_PATH = getCoreLoadPath();

private static final String CLI_RECORD_SEPARATOR = Options.CLI_RECORD_SEPARATOR.load();

private final RubyContext context;
@@ -167,6 +171,24 @@ public class CoreLibrary {

@CompilationFinal private InternalMethod basicObjectSendMethod;

private static String getCoreLoadPath() {
String path = Options.TRUFFLE_CORE_LOAD_PATH.load();

while (path.endsWith("/")) {
path = path.substring(0, path.length() - 1);
}

if (path.startsWith("truffle:")) {
return path;
}

try {
return new File(path).getCanonicalPath();
} catch (IOException e) {
throw new RuntimeException(e);
}
}

private enum State {
INITIALIZING,
LOADING_RUBY_CORE,
@@ -634,7 +656,11 @@ public void initializeAfterMethodsAdded() {

try {
state = State.LOADING_RUBY_CORE;
loadRubyCore("core.rb");
try {
context.load(context.getSourceCache().getSource(CoreLibrary.CORE_LOAD_PATH + "/core.rb"), node, NodeWrapper.IDENTITY);
} catch (IOException e) {
throw new RuntimeException(e);
}
} catch (RaiseException e) {
final Object rubyException = e.getRubyException();
BacktraceFormatter.createDefaultFormatter(getContext()).printBacktrace((DynamicObject) rubyException, Layouts.EXCEPTION.getBacktrace((DynamicObject) rubyException));
@@ -667,10 +693,6 @@ private void initializeRubiniusFFI() {
Layouts.MODULE.getFields(rubiniusFFIModule).setConstant(node, "TYPE_VARARGS", RubiniusTypes.TYPE_VARARGS);
}

public void loadRubyCore(String fileName) {
loadRubyCore(fileName, "core:/");
}

public void loadRubyCore(String fileName, String prefix) {
final Source source;

Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.runtime.subsystems;
package org.jruby.truffle.runtime.loader;

import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.object.DynamicObject;
@@ -24,26 +24,18 @@

import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;

/**
* Manages the features loaded into Ruby. This basically means which library files are loaded, but
* Ruby often talks about requiring features, not files.
*
*/
public class FeatureManager {
public class FeatureLoader {

private final RubyContext context;

private Source mainScriptSource = null;
private String mainScriptFullPath = null;

public FeatureManager(RubyContext context) {
public FeatureLoader(RubyContext context) {
this.context = context;
}

// TODO CS 27-May-15 we should do lookup in one phase, returning a path, and then do the load

public boolean require(String feature, Node currentNode) throws IOException {
final RubyConstant dataConstantBefore = ModuleOperations.lookupConstant(context, context.getCoreLibrary().getObjectClass(), "DATA");

@@ -59,7 +51,7 @@ public boolean require(String feature, Node currentNode) throws IOException {
if (isAbsolutePath(feature)) {
// Try as a full path

if (requireInPath(null, feature, currentNode)) {
if (tryToRequireFileInPath(null, feature, currentNode)) {
return true;
}
} else {
@@ -71,7 +63,7 @@ public boolean require(String feature, Node currentNode) throws IOException {
loadPath = expandPath(context, loadPath);
}

if (requireInPath(loadPath, feature, currentNode)) {
if (tryToRequireFileInPath(loadPath, feature, currentNode)) {
return true;
}
}
@@ -87,69 +79,28 @@ public boolean require(String feature, Node currentNode) throws IOException {
}
}

private boolean requireInPath(String path, String feature, Node currentNode) throws IOException {
private boolean tryToRequireFileInPath(String path, String feature, Node currentNode) throws IOException {
String fullPath = new File(path, feature).getPath();

if (requireFile(feature, fullPath, currentNode)) {
if (tryToRequireFile(feature, fullPath, currentNode)) {
return true;
}

if (requireFile(feature, fullPath + ".rb", currentNode)) {
if (tryToRequireFile(feature, fullPath + ".rb", currentNode)) {
return true;
}

return false;
}

public boolean isAbsolutePath(String path) {
return path.startsWith("uri:classloader:") || path.startsWith("core:") || new File(path).isAbsolute();
}

private boolean requireFile(String feature, String path, Node currentNode) throws IOException {
private boolean tryToRequireFile(String feature, String path, Node currentNode) throws IOException {
// We expect '/' in various classpath URLs, so normalize Windows file paths to use '/'
path = path.replace('\\', '/');
final DynamicObject loadedFeatures = context.getCoreLibrary().getLoadedFeatures();

if (path.startsWith("uri:classloader:/")) {
// TODO CS 13-Feb-15 this uri:classloader:/ and core:/ thing is a hack - simplify it

for (Object loaded : ArrayOperations.toIterable(loadedFeatures)) {
if (loaded.toString().equals(path)) {
return true;
}
}

String coreFileName = path.substring("uri:classloader:/".length());

coreFileName = FileSystems.getDefault().getPath(coreFileName).normalize().toString();

if (context.getRuntime().getLoadService().getClassPathResource(context.getRuntime().getJRubyClassLoader(), coreFileName) == null) {
return false;
}
final String expandedPath;

ArrayOperations.append(loadedFeatures, StringNodes.createString(context.getCoreLibrary().getStringClass(), path));
context.getCoreLibrary().loadRubyCore(coreFileName, "uri:classloader:/");

return true;
}
else if (path.startsWith("core:/")) {
for (Object loaded : ArrayOperations.toIterable(loadedFeatures)) {
if (loaded.toString().equals(path)) {
return true;
}
}

final String coreFileName = path.substring("core:/".length());

if (context.getRuntime().getLoadService().getClassPathResource(context.getRuntime().getJRubyClassLoader(), coreFileName) == null) {
return false;
}

ArrayOperations.append(loadedFeatures, StringNodes.createString(context.getCoreLibrary().getStringClass(), path));
context.getCoreLibrary().loadRubyCore(coreFileName, "core:/");

return true;
} else {
if (!(path.startsWith(SourceLoader.TRUFFLE_SCHEME) || path.startsWith(SourceLoader.JRUBY_SCHEME))) {
final File file = new File(path);

assert file.isAbsolute();
@@ -158,33 +109,37 @@ else if (path.startsWith("core:/")) {
return false;
}

final String expandedPath = expandPath(context, path);
expandedPath = new File(expandPath(context, path)).getCanonicalPath();
} else {
expandedPath = path;
}

for (Object loaded : ArrayOperations.toIterable(loadedFeatures)) {
if (loaded.toString().equals(expandedPath)) {
return true;
}
for (Object loaded : ArrayOperations.toIterable(loadedFeatures)) {
if (loaded.toString().equals(expandedPath)) {
return true;
}
}

// TODO (nirvdrum 15-Jan-15): If we fail to load, we should remove the path from the loaded features because subsequent requires of the same statement may succeed.
final DynamicObject pathString = StringNodes.createString(context.getCoreLibrary().getStringClass(), expandedPath);
ArrayOperations.append(loadedFeatures, pathString);
try {
context.loadFile(path, currentNode);
} catch (RaiseException e) {
final ArrayMirror mirror = ArrayReflector.reflect((Object[]) Layouts.ARRAY.getStore(loadedFeatures));
final int length = Layouts.ARRAY.getSize(loadedFeatures);
for (int i = length - 1; i >= 0; i--) {
if (mirror.get(i) == pathString) {
for (int j = length - 1; j > i; j--) {
mirror.set(i - 1, mirror.get(i));
}
Layouts.ARRAY.setSize(loadedFeatures, length - 1);
break;
// TODO (nirvdrum 15-Jan-15): If we fail to load, we should remove the path from the loaded features because subsequent requires of the same statement may succeed.
final DynamicObject pathString = StringNodes.createString(context.getCoreLibrary().getStringClass(), expandedPath);
ArrayOperations.append(loadedFeatures, pathString);
try {
context.loadFile(expandedPath, currentNode);
} catch (RaiseException e) {
final ArrayMirror mirror = ArrayReflector.reflect((Object[]) Layouts.ARRAY.getStore(loadedFeatures));
final int length = Layouts.ARRAY.getSize(loadedFeatures);
for (int i = length - 1; i >= 0; i--) {
if (mirror.get(i) == pathString) {
for (int j = length - 1; j > i; j--) {
mirror.set(i - 1, mirror.get(i));
}
Layouts.ARRAY.setSize(loadedFeatures, length - 1);
break;
}
throw e;
}
throw e;
} catch (IOException e) {
return false;
}

return true;
@@ -197,6 +152,18 @@ public void setMainScriptSource(Source source) {
}
}

public String getSourcePath(Source source) {
if (source == mainScriptSource) {
return mainScriptFullPath;
} else {
return source.getPath();
}
}

public boolean isAbsolutePath(String path) {
return path.startsWith(SourceLoader.TRUFFLE_SCHEME) || path.startsWith(SourceLoader.JRUBY_SCHEME) || new File(path).isAbsolute();
}

public static String expandPath(RubyContext context, String fileName) {
// TODO (nirvdrum 11-Feb-15) This needs to work on Windows without calling into non-Truffle JRuby.
if (context.isRunningOnWindows()) {
@@ -222,13 +189,4 @@ public static String expandPath(String fileName, String dir) {
return org.jruby.RubyFile.canonicalize(new File(dir, fileName).getAbsolutePath());
}


public String getSourcePath(Source source) {
if (source == mainScriptSource) {
return mainScriptFullPath;
} else {
return source.getPath();
}
}

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

import com.oracle.truffle.api.source.Source;

import java.io.IOException;
import java.util.*;

public class SourceCache {

private final SourceLoader loader;

private final Map<String, Source> sources = new HashMap<>();

public SourceCache(SourceLoader loader) {
this.loader = loader;
}

public synchronized Source getSource(String canonicalPath) throws IOException {
Source source = sources.get(canonicalPath);

if (source == null) {
source = loader.load(canonicalPath);
sources.put(canonicalPath, source);
}

return source;
}

public synchronized Source getBestSourceFuzzily(final String fuzzyPath) {
final List<Map.Entry<String, Source>> matches = new ArrayList<>(sources.entrySet());

Collections.sort(matches, new Comparator<Map.Entry<String, Source>>() {

@Override
public int compare(Map.Entry<String, Source> a, Map.Entry<String, Source> b) {
return Integer.compare(
lengthOfCommonPrefix(fuzzyPath, b.getKey()),
lengthOfCommonPrefix(fuzzyPath, a.getKey()));
}

});

if (matches.isEmpty()) {
return null;
} else {
return matches.get(0).getValue();
}
}

private int lengthOfCommonPrefix(String a, String b) {
int n = 0;

while (n < a.length()
&& n < b.length()
&& a.charAt(a.length() - n - 1) == b.charAt(b.length() - n - 1)) {
n++;
}

return n;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Copyright (c) 2013, 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.runtime.loader;

import com.oracle.truffle.api.source.Source;
import org.jruby.Ruby;
import org.jruby.truffle.runtime.RubyContext;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Locale;

public class SourceLoader {

public static final String TRUFFLE_SCHEME = "truffle:";
public static final String JRUBY_SCHEME = "jruby:";

private final RubyContext context;

public SourceLoader(RubyContext context) {
this.context = context;
}

public Source load(String canonicalPath) throws IOException {
if (canonicalPath.equals("-e")) {
return loadInlineScript();
} else if (canonicalPath.startsWith(TRUFFLE_SCHEME) || canonicalPath.startsWith(JRUBY_SCHEME)) {
return loadResource(canonicalPath);
} else {
assert new File(canonicalPath).getCanonicalPath().equals(canonicalPath) : canonicalPath;
return Source.fromFileName(canonicalPath);
}
}

private Source loadInlineScript() {
return Source.fromText(new String(context.getRuntime().getInstanceConfig().inlineScript(),
StandardCharsets.UTF_8), "-e");
}

private Source loadResource(String canonicalPath) throws IOException {
if (!canonicalPath.toLowerCase(Locale.ENGLISH).endsWith(".rb")) {
throw new FileNotFoundException(canonicalPath);
}

final Class relativeClass;
final String relativePath;

if (canonicalPath.startsWith(TRUFFLE_SCHEME)) {
relativeClass = RubyContext.class;
relativePath = canonicalPath.substring(TRUFFLE_SCHEME.length());
} else if (canonicalPath.startsWith(JRUBY_SCHEME)) {
relativeClass = Ruby.class;
relativePath = canonicalPath.substring(JRUBY_SCHEME.length());
} else {
throw new UnsupportedOperationException();
}

final InputStream stream = relativeClass.getResourceAsStream(relativePath);

if (stream == null) {
throw new FileNotFoundException(canonicalPath);
}

return Source.fromReader(new InputStreamReader(stream, StandardCharsets.UTF_8), canonicalPath);
}

}
Original file line number Diff line number Diff line change
@@ -71,7 +71,7 @@ public void returnExceptional(Probe probe, Node node, VirtualFrame virtualFrame,

}, String.format("Truffle::Primitive.attach@%s:%d", file, line));

final Source source = context.getSourceManager().forFileBestFuzzily(file);
final Source source = context.getSourceCache().getBestSourceFuzzily(file);

final LineLocation lineLocation = source.createLineLocation(line);

@@ -95,7 +95,7 @@ public void returnExceptional(Probe probe, Node node, VirtualFrame virtualFrame,
}

public synchronized void detach(String file, int line) {
final Source source = context.getSourceManager().forFileBestFuzzily(file);
final Source source = context.getSourceCache().getBestSourceFuzzily(file);

final LineLocation lineLocation = source.createLineLocation(line);

This file was deleted.

Original file line number Diff line number Diff line change
@@ -432,7 +432,7 @@ public RubyNode visitCallNode(CallNode node) {
}
} else if (receiver instanceof VCallNode // undefined.equal?(obj)
&& ((VCallNode) receiver).getName().equals("undefined")
&& sourceSection.getSource().getPath().startsWith("core:/core/")
&& sourceSection.getSource().getPath().startsWith(CoreLibrary.CORE_LOAD_PATH + "/core/")
&& methodName.equals("equal?")) {
RubyNode argument = translateArgumentsAndBlock(sourceSection, null, node.getArgsNode(), null, methodName).getArguments()[0];
final RubyNode ret = new IsRubiniusUndefinedNode(context, sourceSection, argument);
@@ -988,7 +988,7 @@ public RubyNode visitConstNode(org.jruby.ast.ConstNode node) {

final String name = ConstantReplacer.replacementName(sourceSection, node.getName());

if (name.equals("Rubinius") && sourceSection.getSource().getPath().startsWith("core:/core/rubinius")) {
if (name.equals("Rubinius") && sourceSection.getSource().getPath().startsWith(CoreLibrary.CORE_LOAD_PATH + "/core/rubinius")) {
final RubyNode ret = new org.jruby.ast.Colon3Node(node.getPosition(), name).accept(this);
return addNewlineIfNeeded(node, ret);
}
@@ -1504,7 +1504,7 @@ public RubyNode visitGlobalVarNode(org.jruby.ast.GlobalVarNode node) {
RubyNode readNode = environment.findLocalVarNode(name, sourceSection);

if (name.equals("$_")) {
if (sourceSection.getSource().getPath().equals("core:/core/rubinius/common/regexp.rb")) {
if (sourceSection.getSource().getPath().equals(CoreLibrary.CORE_LOAD_PATH + "/core/rubinius/common/regexp.rb")) {
readNode = new RubiniusLastStringReadNode(context, sourceSection);
} else {
readNode = GetFromThreadLocalNodeGen.create(context, sourceSection, readNode);
@@ -1605,7 +1605,7 @@ public RubyNode visitInstAsgnNode(org.jruby.ast.InstAsgnNode node) {
// Also note the check for frozen.
final RubyNode self = new RaiseIfFrozenNode(new SelfNode(context, sourceSection));

if (sourceSection.getSource().getPath().equals("core:/core/rubinius/common/time.rb")) {
if (sourceSection.getSource().getPath().equals(CoreLibrary.CORE_LOAD_PATH + "/core/rubinius/common/time.rb")) {
if (name.equals("@is_gmt")) {
final RubyNode ret = TimeNodesFactory.InternalSetGMTNodeFactory.create(context, sourceSection, self, rhs);
return addNewlineIfNeeded(node, ret);
@@ -1615,7 +1615,7 @@ public RubyNode visitInstAsgnNode(org.jruby.ast.InstAsgnNode node) {
}
}

if (sourceSection.getSource().getPath().equals("core:/core/rubinius/common/hash.rb")) {
if (sourceSection.getSource().getPath().equals(CoreLibrary.CORE_LOAD_PATH + "/core/rubinius/common/hash.rb")) {
if (name.equals("@default")) {
final RubyNode ret = HashNodesFactory.SetDefaultValueNodeFactory.create(context, sourceSection, self, rhs);
return addNewlineIfNeeded(node, ret);
@@ -1625,16 +1625,16 @@ public RubyNode visitInstAsgnNode(org.jruby.ast.InstAsgnNode node) {
}
}

if (sourceSection.getSource().getPath().equals("core:/core/rubinius/bootstrap/string.rb") ||
sourceSection.getSource().getPath().equals("core:/core/rubinius/common/string.rb")) {
if (sourceSection.getSource().getPath().equals(CoreLibrary.CORE_LOAD_PATH + "/core/rubinius/bootstrap/string.rb") ||
sourceSection.getSource().getPath().equals(CoreLibrary.CORE_LOAD_PATH + "/core/rubinius/common/string.rb")) {

if (name.equals("@hash")) {
final RubyNode ret = StringNodesFactory.ModifyBangNodeFactory.create(context, sourceSection, new RubyNode[]{});
return addNewlineIfNeeded(node, ret);
}
}

if (sourceSection.getSource().getPath().equals("core:/core/rubinius/common/range.rb")) {
if (sourceSection.getSource().getPath().equals(CoreLibrary.CORE_LOAD_PATH + "/core/rubinius/common/range.rb")) {
if (name.equals("@begin")) {
final RubyNode ret = RangeNodesFactory.InternalSetBeginNodeGen.create(context, sourceSection, self, rhs);
return addNewlineIfNeeded(node, ret);
@@ -1648,7 +1648,7 @@ public RubyNode visitInstAsgnNode(org.jruby.ast.InstAsgnNode node) {
}

// TODO (pitr 08-Aug-2015): values of predefined OM properties should be casted to defined types automatically
if (sourceSection.getSource().getPath().equals("core:/core/rubinius/common/io.rb")) {
if (sourceSection.getSource().getPath().equals(CoreLibrary.CORE_LOAD_PATH + "/core/rubinius/common/io.rb")) {
if (name.equals("@start") || name.equals("@used") || name.equals("@total") || name.equals("@lineno")) {
// Cast int-fitting longs back to int
return addNewlineIfNeeded(
@@ -1677,8 +1677,8 @@ public RubyNode visitInstVarNode(org.jruby.ast.InstVarNode node) {
* self, and @start to be 0.
*/

if (sourceSection.getSource().getPath().equals("core:/core/rubinius/common/array.rb") ||
sourceSection.getSource().getPath().equals("core:/core/rubinius/api/shims/array.rb")) {
if (sourceSection.getSource().getPath().equals(CoreLibrary.CORE_LOAD_PATH + "/core/rubinius/common/array.rb") ||
sourceSection.getSource().getPath().equals(CoreLibrary.CORE_LOAD_PATH + "/core/rubinius/api/shims/array.rb")) {

if (name.equals("@total")) {
final RubyNode ret = new RubyCallNode(context, sourceSection, "size", self, null, false);
@@ -1692,7 +1692,7 @@ public RubyNode visitInstVarNode(org.jruby.ast.InstVarNode node) {
}
}

if (sourceSection.getSource().getPath().equals("core:/core/rubinius/common/regexp.rb")) {
if (sourceSection.getSource().getPath().equals(CoreLibrary.CORE_LOAD_PATH + "/core/rubinius/common/regexp.rb")) {
if (name.equals("@source")) {
final RubyNode ret = MatchDataNodesFactory.RubiniusSourceNodeGen.create(context, sourceSection, self);
return addNewlineIfNeeded(node, ret);
@@ -1709,8 +1709,8 @@ public RubyNode visitInstVarNode(org.jruby.ast.InstVarNode node) {
}
}

if (sourceSection.getSource().getPath().equals("core:/core/rubinius/bootstrap/string.rb") ||
sourceSection.getSource().getPath().equals("core:/core/rubinius/common/string.rb")) {
if (sourceSection.getSource().getPath().equals(CoreLibrary.CORE_LOAD_PATH + "/core/rubinius/bootstrap/string.rb") ||
sourceSection.getSource().getPath().equals(CoreLibrary.CORE_LOAD_PATH + "/core/rubinius/common/string.rb")) {

if (name.equals("@num_bytes")) {
final RubyNode ret = StringNodesFactory.ByteSizeNodeFactory.create(context, sourceSection, new RubyNode[] { self });
@@ -1724,7 +1724,7 @@ public RubyNode visitInstVarNode(org.jruby.ast.InstVarNode node) {
}
}

if (sourceSection.getSource().getPath().equals("core:/core/rubinius/common/time.rb")) {
if (sourceSection.getSource().getPath().equals(CoreLibrary.CORE_LOAD_PATH + "/core/rubinius/common/time.rb")) {
if (name.equals("@is_gmt")) {
final RubyNode ret = TimeNodesFactory.InternalGMTNodeFactory.create(context, sourceSection, self);
return addNewlineIfNeeded(node, ret);
@@ -1734,7 +1734,7 @@ public RubyNode visitInstVarNode(org.jruby.ast.InstVarNode node) {
}
}

if (sourceSection.getSource().getPath().equals("core:/core/rubinius/common/hash.rb")) {
if (sourceSection.getSource().getPath().equals(CoreLibrary.CORE_LOAD_PATH + "/core/rubinius/common/hash.rb")) {
if (name.equals("@default")) {
final RubyNode ret = HashNodesFactory.DefaultValueNodeFactory.create(context, sourceSection, self);
return addNewlineIfNeeded(node, ret);
@@ -1747,8 +1747,8 @@ public RubyNode visitInstVarNode(org.jruby.ast.InstVarNode node) {
}
}

if (sourceSection.getSource().getPath().equals("core:/core/rubinius/common/range.rb") ||
sourceSection.getSource().getPath().equals("core:/core/rubinius/api/shims/range.rb")) {
if (sourceSection.getSource().getPath().equals(CoreLibrary.CORE_LOAD_PATH + "/core/rubinius/common/range.rb") ||
sourceSection.getSource().getPath().equals(CoreLibrary.CORE_LOAD_PATH + "/core/rubinius/api/shims/range.rb")) {

if (name.equals("@begin")) {
final RubyNode ret = RangeNodesFactory.BeginNodeFactory.create(context, sourceSection, new RubyNode[] { self });
@@ -2751,7 +2751,7 @@ public RubyNode visitUntilNode(org.jruby.ast.UntilNode node) {
@Override
public RubyNode visitVCallNode(org.jruby.ast.VCallNode node) {
final SourceSection sourceSection = translate(node.getPosition());
if (node.getName().equals("undefined") && sourceSection.getSource().getPath().startsWith("core:/core/")) {
if (node.getName().equals("undefined") && sourceSection.getSource().getPath().startsWith(CoreLibrary.CORE_LOAD_PATH + "/core/")) {
final RubyNode ret = new LiteralNode(context, sourceSection, context.getCoreLibrary().getRubiniusUndefined());
return addNewlineIfNeeded(node, ret);
}
Original file line number Diff line number Diff line change
@@ -23,6 +23,7 @@
import org.jruby.truffle.nodes.methods.SetMethodDeclarationContext;
import org.jruby.truffle.nodes.objects.SelfNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.CoreLibrary;

/**
* Translates module and class nodes.
@@ -82,11 +83,11 @@ public RubyNode visitDefnNode(org.jruby.ast.DefnNode node) {
String methodName = node.getName();
boolean rubiniusMethodRename = false;

if (sourceSection.getSource().getPath().equals("core:/core/rubinius/common/array.rb")) {
if (sourceSection.getSource().getPath().equals(CoreLibrary.CORE_LOAD_PATH + "/core/rubinius/common/array.rb")) {
rubiniusMethodRename = methodName.equals("zip");
} else if (sourceSection.getSource().getPath().equals("core:/core/rubinius/common/float.rb")) {
} else if (sourceSection.getSource().getPath().equals(CoreLibrary.CORE_LOAD_PATH + "/core/rubinius/common/float.rb")) {
rubiniusMethodRename = methodName.equals("round");
} else if (sourceSection.getSource().getPath().equals("core:/core/rubinius/common/range.rb")) {
} else if (sourceSection.getSource().getPath().equals(CoreLibrary.CORE_LOAD_PATH + "/core/rubinius/common/range.rb")) {
rubiniusMethodRename = methodName.equals("each") || methodName.equals("step") || methodName.equals("to_a");
}

2 changes: 1 addition & 1 deletion truffle/src/main/ruby/core/library.rb
Original file line number Diff line number Diff line change
@@ -60,7 +60,7 @@ def attach_function(name, a2, a3, a4=nil, a5=nil)

caller = Truffle::Primitive.source_of_caller

suffixes = ['ruby/truffle/rubysl/rubysl-socket/lib/rubysl/socket.rb', 'core:/core/rubinius/platform/env.rb']
suffixes = ['ruby/truffle/rubysl/rubysl-socket/lib/rubysl/socket.rb', 'core/rubinius/platform/env.rb']

suffixes.each do |suffix|
if caller[-suffix.length, suffix.length] == suffix

0 comments on commit cbc7c76

Please sign in to comment.