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

Commits on Sep 6, 2016

  1. Copy the full SHA
    78e273c View commit details
  2. Copy the full SHA
    1113d5a View commit details
  3. Copy the full SHA
    df803e0 View commit details
2 changes: 0 additions & 2 deletions spec/truffle/tags/core/kernel/public_send_tags.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
fails:Kernel#public_send raises a NoMethodError if the method is protected
fails:Kernel#public_send raises a NoMethodError if the named method is an alias of a protected method
fails:Kernel#public_send called from own public method raises a NoMethodError if the method is protected
4 changes: 2 additions & 2 deletions truffle/.factorypath
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<factorypath>
<factorypathentry kind="VARJAR" id="M2_REPO/com/oracle/truffle/truffle-api/0.13/truffle-api-0.13.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/com/oracle/truffle/truffle-dsl-processor/0.13/truffle-dsl-processor-0.13.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/com/oracle/truffle/truffle-api/0.16/truffle-api-0.16.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/com/oracle/truffle/truffle-dsl-processor/0.16/truffle-dsl-processor-0.16.jar" enabled="true" runInBatchMode="false"/>
</factorypath>
20 changes: 17 additions & 3 deletions truffle/src/main/java/org/jruby/truffle/core/CoreLibrary.java
Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@
*/
package org.jruby.truffle.core;

import com.oracle.truffle.api.CallTarget;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
@@ -20,7 +21,9 @@
import com.oracle.truffle.api.object.DynamicObjectFactory;
import com.oracle.truffle.api.object.Layout;
import com.oracle.truffle.api.object.Property;

import jnr.constants.platform.Errno;

import org.jcodings.EncodingDB;
import org.jcodings.specific.UTF8Encoding;
import org.jcodings.transcode.EConvFlags;
@@ -279,6 +282,7 @@ public class CoreLibrary {
private final Map<Errno, DynamicObject> errnoClasses = new HashMap<>();

@CompilationFinal private InternalMethod basicObjectSendMethod;
@CompilationFinal private InternalMethod kernelPublicSendMethod;

@CompilationFinal private GlobalVariableStorage loadPathStorage;
@CompilationFinal private GlobalVariableStorage loadedFeaturesStorage;
@@ -798,8 +802,16 @@ public void addCoreMethods(PrimitiveManager primitiveManager) {

coreMethodNodeManager.allMethodInstalled();

basicObjectSendMethod = Layouts.MODULE.getFields(basicObjectClass).getMethod("__send__");
assert basicObjectSendMethod != null;
basicObjectSendMethod = getMethod(basicObjectClass, "__send__");
kernelPublicSendMethod = getMethod(kernelModule, "public_send");
}

private InternalMethod getMethod(DynamicObject module, String name) {
InternalMethod method = Layouts.MODULE.getFields(module).getMethod(name);
if (method == null) {
throw new AssertionError();
}
return method;
}

private void initializeGlobalVariables() {
@@ -1417,7 +1429,9 @@ public boolean isLoaded() {
}

public boolean isSend(InternalMethod method) {
return method.getCallTarget() == basicObjectSendMethod.getCallTarget();
CallTarget callTarget = method.getCallTarget();
return callTarget == basicObjectSendMethod.getCallTarget() ||
callTarget == kernelPublicSendMethod.getCallTarget();
}

public DynamicObjectFactory getIntRangeFactory() {
Original file line number Diff line number Diff line change
@@ -81,7 +81,7 @@ public DynamicObject bind(DynamicObject unboundMethod, Object object,
if (!canBindMethodToModuleNode.executeCanBindMethodToModule(Layouts.UNBOUND_METHOD.getMethod(unboundMethod), objectMetaClass)) {
errorProfile.enter();
final DynamicObject declaringModule = Layouts.UNBOUND_METHOD.getMethod(unboundMethod).getDeclaringModule();
if (RubyGuards.isRubyClass(declaringModule) && Layouts.CLASS.getIsSingleton(declaringModule)) {
if (RubyGuards.isSingletonClass(declaringModule)) {
throw new RaiseException(coreExceptions().typeError(
"singleton method called for a different object", this));
} else {
Original file line number Diff line number Diff line change
@@ -353,7 +353,7 @@ public void addMethod(RubyContext context, Node currentNode, InternalMethod meth
}

if (context.getCoreLibrary().isLoaded() && !method.isUndefined()) {
if (Layouts.CLASS.isClass(rubyModuleObject) && Layouts.CLASS.getIsSingleton(rubyModuleObject)) {
if (RubyGuards.isSingletonClass(rubyModuleObject)) {
DynamicObject receiver = Layouts.CLASS.getAttached(rubyModuleObject);
context.send(
receiver,
Original file line number Diff line number Diff line change
@@ -1026,7 +1026,7 @@ public DynamicObject defineMethodMethod(DynamicObject module, String name, Dynam

if (!canBindMethodToModuleNode.executeCanBindMethodToModule(method, module)) {
final DynamicObject declaringModule = method.getDeclaringModule();
if (RubyGuards.isRubyClass(declaringModule) && Layouts.CLASS.getIsSingleton(declaringModule)) {
if (RubyGuards.isSingletonClass(declaringModule)) {
throw new RaiseException(coreExceptions().typeError(
"can't bind singleton method to a different class", this));
} else {
@@ -1745,7 +1745,7 @@ private void removeMethod(VirtualFrame frame, DynamicObject module, String name)

if (Layouts.MODULE.getFields(module).getMethod(name) != null) {
Layouts.MODULE.getFields(module).removeMethod(name);
if(Layouts.CLASS.isClass(module) && Layouts.CLASS.getIsSingleton(module)){
if (RubyGuards.isSingletonClass(module)) {
final DynamicObject receiver = Layouts.CLASS.getAttached(module);
methodRemovedNode.call(frame, receiver, "singleton_method_removed", getSymbol(name));
} else {
@@ -1768,7 +1768,7 @@ public abstract static class ToSNode extends CoreMethodArrayArgumentsNode {
public DynamicObject toS(VirtualFrame frame, DynamicObject module) {

final String moduleName;
if (Layouts.CLASS.isClass(module) && Layouts.CLASS.getIsSingleton(module)) {
if (RubyGuards.isSingletonClass(module)) {
final DynamicObject attached = Layouts.CLASS.getAttached(module);
final String name;
if (Layouts.CLASS.isClass(attached) || Layouts.MODULE.isModule(attached)) {
@@ -1820,7 +1820,7 @@ private void undefMethod(VirtualFrame frame, DynamicObject module, String name)
raiseIfFrozenNode.execute(frame);

Layouts.MODULE.getFields(module).undefMethod(getContext(), this, name);
if (Layouts.CLASS.isClass(module) && Layouts.CLASS.getIsSingleton(module)) {
if (RubyGuards.isSingletonClass(module)) {
final DynamicObject receiver = Layouts.CLASS.getAttached(module);
methodUndefinedNode.call(frame, receiver, "singleton_method_undefined", getSymbol(name));
} else {
Original file line number Diff line number Diff line change
@@ -132,7 +132,7 @@ public int eachObject(VirtualFrame frame, DynamicObject ofClass, DynamicObject b
}

private boolean isHidden(DynamicObject object) {
return !RubyGuards.isRubyBasicObject(object) || (RubyGuards.isRubyClass(object) && Layouts.CLASS.getIsSingleton(object));
return !RubyGuards.isRubyBasicObject(object) || RubyGuards.isSingletonClass(object);
}

}
Original file line number Diff line number Diff line change
@@ -12,7 +12,6 @@
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.object.DynamicObject;
import org.jruby.truffle.Layouts;

public class LexicalScope {

@@ -48,7 +47,7 @@ public DynamicObject resolveTargetModuleForClassVariables() {
LexicalScope scope = this;

// MRI logic: ignore lexical scopes (cref) referring to singleton classes
while (RubyGuards.isRubyClass(scope.liveModule) && Layouts.CLASS.getIsSingleton(scope.liveModule)) {
while (RubyGuards.isSingletonClass(scope.liveModule)) {
scope = scope.parent;
}

Original file line number Diff line number Diff line change
@@ -293,4 +293,10 @@ public static boolean isInfinity(double value) {
return Double.isInfinite(value);
}

// Composite

public static boolean isSingletonClass(DynamicObject value) {
return isRubyClass(value) && Layouts.CLASS.getIsSingleton(value);
}

}
Original file line number Diff line number Diff line change
@@ -161,7 +161,14 @@ private DispatchNode doDynamicObject(
callerClass = coreLibrary().getMetaClass(RubyArguments.getSelf(callerFrame));
}
} else {
callerClass = coreLibrary().getMetaClass(RubyArguments.getSelf(frame));
InternalMethod method = RubyArguments.getMethod(frame);
if (!coreLibrary().isSend(method)) {
callerClass = coreLibrary().getMetaClass(RubyArguments.getSelf(frame));
} else {
FrameInstance instance = getContext().getCallStack().getCallerFrameIgnoringSend();
Frame callerFrame = instance.getFrame(FrameInstance.FrameAccess.READ_ONLY, true);
callerClass = coreLibrary().getMetaClass(RubyArguments.getSelf(callerFrame));
}
}

final InternalMethod method = lookup(callerClass, receiverObject, toString(methodName), ignoreVisibility);