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: 066e1cc03ad7
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: b4dd5bd1d014
Choose a head ref
  • 10 commits
  • 8 files changed
  • 1 contributor

Commits on Apr 12, 2016

  1. Copy the full SHA
    566a4eb View commit details
  2. Copy the full SHA
    c70c157 View commit details
  3. Copy the full SHA
    ee154d6 View commit details
  4. Copy the full SHA
    bca7fa7 View commit details
  5. Copy the full SHA
    06b8b3f View commit details
  6. Copy the full SHA
    fa410b6 View commit details
  7. Copy the full SHA
    541aaf1 View commit details
  8. Copy the full SHA
    8a097f2 View commit details
  9. Copy the full SHA
    18e5037 View commit details
  10. Copy the full SHA
    b4dd5bd View commit details
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -15,6 +15,7 @@
*~
*.tokens
*.su
*.ll

.DS_Store
.debug.properties
3 changes: 3 additions & 0 deletions core/src/main/java/org/jruby/util/RubyFiletypeDetector.java
Original file line number Diff line number Diff line change
@@ -43,6 +43,9 @@ public String probeContentType(Path path) throws IOException {
if (firstLine != null && SHEBANG_REGEXP.matcher(firstLine).matches()) {
return RUBY_MIME;
}
} catch (Exception e) {
// Reading random files as UTF-8 could cause all sorts of errors
return null;
}

return null;
3 changes: 3 additions & 0 deletions test/truffle/cexts/minimum/bin/minimum
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env ruby

require 'minimum'
12 changes: 0 additions & 12 deletions test/truffle/cexts/minimum/ext/minimum/minimum.ll

This file was deleted.

6 changes: 0 additions & 6 deletions truffle/src/main/java/org/jruby/truffle/JRubyTruffleImpl.java
Original file line number Diff line number Diff line change
@@ -28,12 +28,6 @@ public class JRubyTruffleImpl implements JRubyTruffleInterface {
// Created by reflection from Ruby#loadTruffle

public JRubyTruffleImpl(Ruby runtime) {
try {
Class.forName("com.oracle.truffle.llvm.LLVM", true, ClassLoader.getSystemClassLoader());
} catch (ClassNotFoundException e) {
// Sulong may not be on the classpath, or if it genuinely failed we'll be happy with the exception later on
}

engine = PolyglotEngine.newBuilder()
.globalSymbol(JRubyTruffleInterface.RUNTIME_SYMBOL, new JRubyContextWrapper(runtime))
.build();
3 changes: 3 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/RubyLanguage.java
Original file line number Diff line number Diff line change
@@ -46,6 +46,9 @@ public class RubyLanguage extends TruffleLanguage<RubyContext> {
public static final String MIME_TYPE = "application/x-ruby";
public static final String EXTENSION = ".rb";

public static final String CEXT_MIME_TYPE = "application/x-sulong-library";
public static final String CEXT_EXTENSION = ".su";

private RubyLanguage() {
}

Original file line number Diff line number Diff line change
@@ -1584,6 +1584,8 @@ public RubyNode coerceFeatureToPath(RubyNode feature) {

@Specialization(guards = "isRubyString(featureString)")
public boolean require(VirtualFrame frame, DynamicObject featureString, @Cached("create()") IndirectCallNode callNode) {
// We transfer because we want the virtual frame when requring but can't compile that code

CompilerDirectives.transferToInterpreter();

final String feature = featureString.toString();
Original file line number Diff line number Diff line change
@@ -9,8 +9,16 @@
*/
package org.jruby.truffle.language.loader;

import com.oracle.truffle.api.CallTarget;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.interop.ArityException;
import com.oracle.truffle.api.interop.ForeignAccess;
import com.oracle.truffle.api.interop.Message;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.interop.UnsupportedTypeException;
import com.oracle.truffle.api.nodes.IndirectCallNode;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.Source;
import org.jcodings.specific.UTF8Encoding;
@@ -78,6 +86,12 @@ private String findFeature(String feature) {
}

private String findFeatureWithAndWithoutExtension(String path) {
final String asCExt = findFeatureWithExactPath(path + RubyLanguage.CEXT_EXTENSION);

if (asCExt != null) {
return asCExt;
}

final String withExtension = findFeatureWithExactPath(path + RubyLanguage.EXTENSION);

if (withExtension != null) {
@@ -158,25 +172,78 @@ public Boolean block() throws InterruptedException {
return false;
}

final String mimeType = source.getMimeType();

switch (mimeType) {
case RubyLanguage.MIME_TYPE: {
final RubyRootNode rootNode = context.getCodeLoader().parse(
source,
UTF8Encoding.INSTANCE,
ParserContext.TOP_LEVEL,
null,
true,
callNode);

final CodeLoader.DeferredCall deferredCall = context.getCodeLoader().prepareExecute(
ParserContext.TOP_LEVEL,
DeclarationContext.TOP_LEVEL,
rootNode, null,
context.getCoreLibrary().getMainObject());

deferredCall.call(frame, callNode);
} break;

case RubyLanguage.CEXT_MIME_TYPE: {
final CallTarget callTarget;

try {
callTarget = context.getEnv().parse(source);
} catch (IOException e) {
throw new RuntimeException(e);
}

callNode.call(frame, callTarget, new Object[]{});

final String fileName = new File(expandedPath).getName();
final String moduleName;
final int dotIndex = fileName.indexOf('.');
if (dotIndex == -1) {
moduleName = fileName;
} else {
moduleName = fileName.substring(0, dotIndex);
}

final Object initFunction = context.getEnv().importSymbol("@Init_" + moduleName);

if (!(initFunction instanceof TruffleObject)) {
throw new UnsupportedOperationException();
}

final TruffleObject initFunctionObject = (TruffleObject) initFunction;

final Node isExecutableNode = Message.IS_EXECUTABLE.createNode();

if (!ForeignAccess.sendIsExecutable(isExecutableNode, frame, initFunctionObject)) {
throw new UnsupportedOperationException();
}

final Node executeNode = Message.createExecute(0).createNode();

try {
ForeignAccess.sendExecute(executeNode, frame, initFunctionObject);
} catch (UnsupportedTypeException | ArityException | UnsupportedMessageException e) {
throw new RuntimeException(e);
}
} break;

default:
throw new RaiseException(
context.getCoreLibrary().internalError("unknown language " + expandedPath, callNode));
}

final DynamicObject pathString = StringOperations.createString(context,
StringOperations.encodeRope(expandedPath, UTF8Encoding.INSTANCE));

final RubyRootNode rootNode = context.getCodeLoader().parse(
source,
UTF8Encoding.INSTANCE,
ParserContext.TOP_LEVEL,
null,
true,
callNode);

final CodeLoader.DeferredCall deferredCall = context.getCodeLoader().prepareExecute(
ParserContext.TOP_LEVEL,
DeclarationContext.TOP_LEVEL,
rootNode, null,
context.getCoreLibrary().getMainObject());

deferredCall.call(frame, callNode);

addToLoadedFeatures(pathString);

return true;