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: 3463e1843201
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: d8ea3c71a03c
Choose a head ref
  • 5 commits
  • 15 files changed
  • 2 contributors

Commits on Apr 28, 2016

  1. Copy the full SHA
    a1b3ff3 View commit details

Commits on Apr 29, 2016

  1. Copy the full SHA
    bde5fb1 View commit details
  2. Copy the full SHA
    58b7d32 View commit details
  3. Copy the full SHA
    100d655 View commit details
  4. Merge pull request #3837 from jruby/truffle-message-resolution

    [Truffle] Adopt @MessageResolution
    chrisseaton committed Apr 29, 2016
    Copy the full SHA
    d8ea3c7 View commit details
2 changes: 1 addition & 1 deletion truffle/pom.rb
Original file line number Diff line number Diff line change
@@ -45,7 +45,7 @@
'annotationProcessors' => [ 'com.oracle.truffle.object.dsl.processor.LayoutProcessor',
'com.oracle.truffle.dsl.processor.InstrumentableProcessor',
'com.oracle.truffle.dsl.processor.TruffleProcessor',
'com.oracle.truffle.dsl.processor.InteropProcessor',
'com.oracle.truffle.dsl.processor.interop.InteropDSLProcessor',
'com.oracle.truffle.dsl.processor.verify.VerifyTruffleProcessor',
'com.oracle.truffle.dsl.processor.LanguageRegistrationProcessor', ],
'generatedSourcesDirectory' => 'target/generated-sources',
2 changes: 1 addition & 1 deletion truffle/pom.xml
Original file line number Diff line number Diff line change
@@ -106,7 +106,7 @@ DO NOT MODIFIY - GENERATED CODE
<annotationProcessor>com.oracle.truffle.object.dsl.processor.LayoutProcessor</annotationProcessor>
<annotationProcessor>com.oracle.truffle.dsl.processor.InstrumentableProcessor</annotationProcessor>
<annotationProcessor>com.oracle.truffle.dsl.processor.TruffleProcessor</annotationProcessor>
<annotationProcessor>com.oracle.truffle.dsl.processor.InteropProcessor</annotationProcessor>
<annotationProcessor>com.oracle.truffle.dsl.processor.interop.InteropDSLProcessor</annotationProcessor>
<annotationProcessor>com.oracle.truffle.dsl.processor.verify.VerifyTruffleProcessor</annotationProcessor>
<annotationProcessor>com.oracle.truffle.dsl.processor.LanguageRegistrationProcessor</annotationProcessor>
</annotationProcessors>

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

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

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.interop.CanResolve;
import com.oracle.truffle.api.interop.Message;
import com.oracle.truffle.api.interop.MessageResolution;
import com.oracle.truffle.api.interop.Resolve;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.profiles.ConditionProfile;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.RubyLanguage;
import org.jruby.truffle.core.Layouts;
import org.jruby.truffle.core.rope.Rope;
import org.jruby.truffle.core.string.StringOperations;
import org.jruby.truffle.language.RubyGuards;
import org.jruby.truffle.language.RubyObjectType;
import org.jruby.truffle.language.dispatch.DispatchAction;
import org.jruby.truffle.language.dispatch.DispatchHeadNode;
import org.jruby.truffle.language.dispatch.MissingBehavior;

@MessageResolution(
receiverType = RubyObjectType.class,
language = RubyLanguage.class
)
public class RubyMessageResolution {

@CanResolve
public abstract static class Check extends Node {

protected static boolean test(TruffleObject receiver) {
return RubyGuards.isRubyBasicObject(receiver);
}

}

@Resolve(message = "EXECUTE")
public static abstract class ForeignExecuteNode extends Node {

@Child private Node findContextNode;
@Child private ForeignExecuteHelperNode executeMethodNode;

protected Object access(VirtualFrame frame, DynamicObject object, Object[] arguments) {
return getHelperNode().executeCall(frame, object, arguments);
}

private ForeignExecuteHelperNode getHelperNode() {
if (executeMethodNode == null) {
CompilerDirectives.transferToInterpreter();
findContextNode = insert(RubyLanguage.INSTANCE.unprotectedCreateFindContextNode());
final RubyContext context = RubyLanguage.INSTANCE.unprotectedFindContext(findContextNode);
executeMethodNode = insert(ForeignExecuteHelperNodeGen.create(context, null, null));
}

return executeMethodNode;
}

}

@Resolve(message = "GET_SIZE")
public static abstract class ForeignGetSizeNode extends Node {

@Child private Node findContextNode;
@Child private DispatchHeadNode dispatchNode;

protected Object access(VirtualFrame frame, DynamicObject object) {
return getDispatchNode().dispatch(frame, object, "size", null, new Object[] {});
}

private DispatchHeadNode getDispatchNode() {
if (dispatchNode == null) {
CompilerDirectives.transferToInterpreter();
findContextNode = insert(RubyLanguage.INSTANCE.unprotectedCreateFindContextNode());
final RubyContext context = RubyLanguage.INSTANCE.unprotectedFindContext(findContextNode);
dispatchNode = insert(new DispatchHeadNode(context, true, MissingBehavior.CALL_METHOD_MISSING, DispatchAction.CALL_METHOD));
}

return dispatchNode;
}

}

@Resolve(message = "HAS_SIZE")
public static abstract class ForeignHasSizeNode extends Node {

protected Object access(DynamicObject object) {
return RubyGuards.isRubyArray(object) || RubyGuards.isRubyHash(object) || RubyGuards.isRubyString(object);
}

}

@Resolve(message = "INVOKE")
public static abstract class ForeignInvokeNode extends Node {

@Child private Node findContextNode;
@Child private DispatchHeadNode dispatchHeadNode;

protected Object access(VirtualFrame frame, DynamicObject receiver, String name, Object[] arguments) {
return getDispatchHeadNode().dispatch(frame, receiver, name, null, arguments);
}

private DispatchHeadNode getDispatchHeadNode() {
if (dispatchHeadNode == null) {
CompilerDirectives.transferToInterpreter();
findContextNode = insert(RubyLanguage.INSTANCE.unprotectedCreateFindContextNode());
final RubyContext context = RubyLanguage.INSTANCE.unprotectedFindContext(findContextNode);
dispatchHeadNode = insert(new DispatchHeadNode(context, true, MissingBehavior.CALL_METHOD_MISSING, DispatchAction.CALL_METHOD));
}

return dispatchHeadNode;
}

}

@Resolve(message = "IS_BOXED")
public static abstract class ForeignIsBoxedNode extends Node {

protected Object access(DynamicObject object) {
return RubyGuards.isRubyString(object) && StringOperations.rope(object).byteLength() == 1;
}

}

@Resolve(message = "IS_EXECUTABLE")
public static abstract class ForeignIsExecutableNode extends Node {

protected Object access(VirtualFrame frame, DynamicObject object) {
return RubyGuards.isRubyMethod(object) || RubyGuards.isRubyProc(object);
}

}

@Resolve(message = "IS_NULL")
public static abstract class ForeignIsNullNode extends Node {

@Child private Node findContextNode;
@CompilationFinal RubyContext context;

protected Object access(DynamicObject object) {
return object == getContext().getCoreLibrary().getNilObject();
}

private RubyContext getContext() {
if (context == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
findContextNode = insert(RubyLanguage.INSTANCE.unprotectedCreateFindContextNode());
context = RubyLanguage.INSTANCE.unprotectedFindContext(findContextNode);
}

return context;
}

}

@Resolve(message = "READ")
public static abstract class ForeignReadNode extends Node {

@Child private Node findContextNode;
@Child private ForeignReadStringCachingHelperNode helperNode;

protected Object access(VirtualFrame frame, DynamicObject object, Object name) {
return getHelperNode().executeStringCachingHelper(frame, object, name);
}

private ForeignReadStringCachingHelperNode getHelperNode() {
if (helperNode == null) {
CompilerDirectives.transferToInterpreter();
findContextNode = insert(RubyLanguage.INSTANCE.unprotectedCreateFindContextNode());
final RubyContext context = RubyLanguage.INSTANCE.unprotectedFindContext(findContextNode);
helperNode = insert(ForeignReadStringCachingHelperNodeGen.create(context, null, null));
}

return helperNode;
}

}

@Resolve(message = "UNBOX")
public static abstract class ForeignUnboxNode extends Node {

private final ConditionProfile stringProfile = ConditionProfile.createBinaryProfile();
private final ConditionProfile emptyProfile = ConditionProfile.createBinaryProfile();

protected Object access(DynamicObject object) {
if (stringProfile.profile(RubyGuards.isRubyString(object))) {
final Rope rope = Layouts.STRING.getRope(object);

if (emptyProfile.profile(rope.byteLength() == 0)) {
throw UnsupportedMessageException.raise(Message.UNBOX);
} else {
return rope.get(0);
}
} else {
return object;
}
}

}

@Resolve(message = "WRITE")
public static abstract class ForeignWriteNode extends Node {

@Child private Node findContextNode;
@Child private ForeignWriteStringCachingHelperNode helperNode;

protected Object access(VirtualFrame frame, DynamicObject object, Object name, Object value) {
return getHelperNode().executeStringCachingHelper(frame, object, name, value);
}

private ForeignWriteStringCachingHelperNode getHelperNode() {
if (helperNode == null) {
CompilerDirectives.transferToInterpreter();
findContextNode = insert(RubyLanguage.INSTANCE.unprotectedCreateFindContextNode());
final RubyContext context = RubyLanguage.INSTANCE.unprotectedFindContext(findContextNode);
helperNode = insert(ForeignWriteStringCachingHelperNodeGen.create(context, null, null, null));
}

return helperNode;
}

}

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

import com.oracle.truffle.api.interop.ForeignAccess;

public abstract class RubyMessageResolutionAccessor {

public static final ForeignAccess ACCESS = RubyMessageResolutionForeign.ACCESS;

}
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@
import org.jruby.truffle.core.Layouts;
import org.jruby.truffle.core.rope.RopeOperations;
import org.jruby.truffle.core.string.StringOperations;
import org.jruby.truffle.interop.RubyMessageResolutionAccessor;

public class RubyObjectType extends ObjectType {

@@ -41,7 +42,7 @@ public String toString(DynamicObject object) {

@Override
public ForeignAccess getForeignAccessFactory(DynamicObject object) {
return RubyObjectTypeForeign.ACCESS;
return RubyMessageResolutionAccessor.ACCESS;
}

public static boolean isInstance(TruffleObject object) {