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

Commits on May 10, 2016

  1. 3
    Copy the full SHA
    3eff054 View commit details
  2. Copy the full SHA
    3b89483 View commit details
  3. [Truffle] Greatly simplify the superclass mismatch checking.

    * See #3858 for background.
    * Fix WeakRef superclass.
    eregon committed May 10, 2016
    Copy the full SHA
    7ed9a36 View commit details
Showing with 85 additions and 41 deletions.
  1. +53 −0 spec/ruby/language/class_spec.rb
  2. +1 −1 truffle/src/main/java/org/jruby/truffle/builtins/CallPrimitiveNode.java
  3. +1 −1 truffle/src/main/java/org/jruby/truffle/core/CoreLibrary.java
  4. +2 −2 truffle/src/main/java/org/jruby/truffle/core/MainNodes.java
  5. +2 −2 truffle/src/main/java/org/jruby/truffle/core/array/ArrayNodes.java
  6. +1 −1 truffle/src/main/java/org/jruby/truffle/core/cast/ToIntNode.java
  7. +1 −1 truffle/src/main/java/org/jruby/truffle/core/cast/ToSNode.java
  8. +2 −2 truffle/src/main/java/org/jruby/truffle/core/fiber/FiberNodes.java
  9. +1 −1 truffle/src/main/java/org/jruby/truffle/core/format/convert/ToStringNode.java
  10. +2 −2 truffle/src/main/java/org/jruby/truffle/core/hash/HashNodes.java
  11. +1 −1 truffle/src/main/java/org/jruby/truffle/core/hash/LookupEntryNode.java
  12. +1 −1 truffle/src/main/java/org/jruby/truffle/core/hash/SetNode.java
  13. +4 −4 truffle/src/main/java/org/jruby/truffle/core/kernel/KernelNodes.java
  14. +1 −1 truffle/src/main/java/org/jruby/truffle/core/klass/ClassNodes.java
  15. +1 −1 truffle/src/main/java/org/jruby/truffle/core/method/MethodNodes.java
  16. +2 −2 truffle/src/main/java/org/jruby/truffle/core/module/ModuleNodes.java
  17. +3 −3 truffle/src/main/java/org/jruby/truffle/core/numeric/FixnumNodes.java
  18. +3 −3 truffle/src/main/java/org/jruby/truffle/core/rubinius/VMPrimitiveNodes.java
  19. +1 −3 truffle/src/main/java/org/jruby/truffle/core/string/StringNodes.java
  20. +2 −9 truffle/src/main/java/org/jruby/truffle/language/objects/DefineClassNode.java
53 changes: 53 additions & 0 deletions spec/ruby/language/class_spec.rb
Original file line number Diff line number Diff line change
@@ -58,6 +58,46 @@ class ClassSpecsNumber::MyClass
}.should raise_error(TypeError)
end

it "inherits from Object by default" do
ClassSpecs::A.superclass.should == Object
end

it "raises an error when trying to change the superclass" do
module ClassSpecs
class SuperclassResetToSubclass < L
end
lambda {
class SuperclassResetToSubclass < M
end
}.should raise_error(TypeError, /superclass mismatch/)
end
end

it "raises an error when reopening a class with BasicObject as superclass" do
module ClassSpecs
class SuperclassReopenedBasicObject < A
end
SuperclassReopenedBasicObject.superclass.should == A

lambda {
class SuperclassReopenedBasicObject < BasicObject
end
}.should raise_error(TypeError, /superclass mismatch/)
end
end

it "does not allow to set the superclass even if it was not specified by the first declaration" do
module ClassSpecs
class NoSuperclassSet
end

lambda {
class NoSuperclassSet < String
end
}.should raise_error(TypeError, /superclass mismatch/)
end
end

it "allows using self as the superclass if self is a class" do
ClassSpecs::I::J.superclass.should == ClassSpecs::I

@@ -66,6 +106,19 @@ class ShouldNotWork < self; end
}.should raise_error(TypeError)
end

it "first evaluates the superclass before checking if the class already exists" do
module ClassSpecs
class SuperclassEvaluatedFirst
end
a = SuperclassEvaluatedFirst

class SuperclassEvaluatedFirst < remove_const(:SuperclassEvaluatedFirst)
end
b = SuperclassEvaluatedFirst
b.superclass.should == a
end
end

it "raises a TypeError if inheriting from a metaclass" do
obj = mock("metaclass super")
meta = obj.singleton_class
Original file line number Diff line number Diff line change
@@ -34,8 +34,8 @@ public CallPrimitiveNode(RubyContext context, SourceSection sourceSection, RubyN
public Object execute(VirtualFrame frame) {
final Object value = primitive.execute(frame);

// Primitives fail by returning null, allowing the method to continue (the fallback)
if (failedProfile.profile(value == null)) {
// Primitives fail by returning null, allowing the method to continue (the fallback)
return nil();
} else {
// If the primitive didn't fail its value is returned in the calling method
Original file line number Diff line number Diff line change
@@ -543,7 +543,7 @@ public CoreLibrary(RubyContext context) {
Layouts.CLASS.setInstanceFactoryUnsafe(ioClass, Layouts.IO.createIOShape(ioClass, ioClass));
internalBufferClass = defineClass(ioClass, objectClass, "InternalBuffer");
Layouts.CLASS.setInstanceFactoryUnsafe(internalBufferClass, Layouts.IO_BUFFER.createIOBufferShape(internalBufferClass, internalBufferClass));
weakRefClass = defineClass("WeakRef");
weakRefClass = defineClass(basicObjectClass, "WeakRef");
weakRefFactory = Layouts.WEAK_REF_LAYOUT.createWeakRefShape(weakRefClass, weakRefClass);
Layouts.CLASS.setInstanceFactoryUnsafe(weakRefClass, weakRefFactory);
final DynamicObject tracePointClass = defineClass("TracePoint");
4 changes: 2 additions & 2 deletions truffle/src/main/java/org/jruby/truffle/core/MainNodes.java
Original file line number Diff line number Diff line change
@@ -32,7 +32,7 @@ public abstract static class PublicNode extends CoreMethodArrayArgumentsNode {

public PublicNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
publicNode = ModuleNodesFactory.PublicNodeFactory.create(context, sourceSection, new RubyNode[]{null, null});
publicNode = ModuleNodesFactory.PublicNodeFactory.create(context, sourceSection, null);
}

@Specialization
@@ -49,7 +49,7 @@ public abstract static class PrivateNode extends CoreMethodArrayArgumentsNode {

public PrivateNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
privateNode = ModuleNodesFactory.PrivateNodeFactory.create(context, sourceSection, new RubyNode[]{null, null});
privateNode = ModuleNodesFactory.PrivateNodeFactory.create(context, sourceSection, null);
}

@Specialization
Original file line number Diff line number Diff line change
@@ -696,7 +696,7 @@ public abstract static class DeleteNode extends ArrayCoreMethodNode {

public DeleteNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
equalNode = KernelNodesFactory.SameOrEqualNodeFactory.create(new RubyNode[]{null,null});
equalNode = KernelNodesFactory.SameOrEqualNodeFactory.create(null);
}

@Specialization(guards = "isNullArray(array)")
@@ -891,7 +891,7 @@ public abstract static class IncludeNode extends ArrayCoreMethodNode {

public IncludeNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
equalNode = KernelNodesFactory.SameOrEqualNodeFactory.create(new RubyNode[]{null,null});
equalNode = KernelNodesFactory.SameOrEqualNodeFactory.create(null);
}

@Specialization(guards = "isNullArray(array)")
Original file line number Diff line number Diff line change
@@ -86,7 +86,7 @@ public DynamicObject coerceRubyBignum(DynamicObject value) {
public Object coerceDouble(VirtualFrame frame, double value) {
if (floatToIntNode == null) {
CompilerDirectives.transferToInterpreter();
floatToIntNode = insert(FloatNodesFactory.ToINodeFactory.create(getContext(), getSourceSection(), new RubyNode[] { null }));
floatToIntNode = insert(FloatNodesFactory.ToINodeFactory.create(getContext(), getSourceSection(), null));
}
return floatToIntNode.executeToI(frame, value);
}
Original file line number Diff line number Diff line change
@@ -38,7 +38,7 @@ public ToSNode(RubyContext context, SourceSection sourceSection) {
protected DynamicObject kernelToS(VirtualFrame frame, Object object) {
if (kernelToSNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
kernelToSNode = insert(KernelNodesFactory.ToSNodeFactory.create(getContext(), getSourceSection(), new RubyNode[] {null}));
kernelToSNode = insert(KernelNodesFactory.ToSNodeFactory.create(getContext(), getSourceSection(), null));
}
return kernelToSNode.executeToS(frame, object);
}
Original file line number Diff line number Diff line change
@@ -260,7 +260,7 @@ public abstract static class ResumeNode extends CoreMethodArrayArgumentsNode {

public ResumeNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
fiberTransferNode = FiberNodesFactory.FiberTransferNodeFactory.create(new RubyNode[] { null, null, null });
fiberTransferNode = FiberNodesFactory.FiberTransferNodeFactory.create(null);
}

@Specialization
@@ -277,7 +277,7 @@ public abstract static class YieldNode extends CoreMethodArrayArgumentsNode {

public YieldNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
fiberTransferNode = FiberNodesFactory.FiberTransferNodeFactory.create(new RubyNode[] { null, null, null });
fiberTransferNode = FiberNodesFactory.FiberTransferNodeFactory.create(null);
}

@Specialization
Original file line number Diff line number Diff line change
@@ -138,7 +138,7 @@ public byte[] toString(VirtualFrame frame, Object object) {
if (inspectNode == null) {
CompilerDirectives.transferToInterpreter();
inspectNode = insert(KernelNodesFactory.ToSNodeFactory.create(getContext(),
getEncapsulatingSourceSection(), new RubyNode[]{null}));
getEncapsulatingSourceSection(), null));
}

return Layouts.STRING.getRope(inspectNode.toS(frame, object)).getBytes();
Original file line number Diff line number Diff line change
@@ -185,7 +185,7 @@ public GetIndexNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
hashNode = new HashNode(context, sourceSection);
eqlNode = DispatchHeadNodeFactory.createMethodCall(context);
equalNode = BasicObjectNodesFactory.ReferenceEqualNodeFactory.create(new RubyNode[]{null, null});
equalNode = BasicObjectNodesFactory.ReferenceEqualNodeFactory.create(null);
callDefaultNode = DispatchHeadNodeFactory.createMethodCall(context);
lookupEntryNode = new LookupEntryNode(context, sourceSection);
}
@@ -375,7 +375,7 @@ public abstract static class GetOrUndefinedNode extends CoreMethodArrayArguments

public GetOrUndefinedNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
getIndexNode = HashNodesFactory.GetIndexNodeFactory.create(context, sourceSection, new RubyNode[]{null, null});
getIndexNode = HashNodesFactory.GetIndexNodeFactory.create(context, sourceSection, null);
getIndexNode.setUndefinedValue(context.getCoreLibrary().getRubiniusUndefined());
}

Original file line number Diff line number Diff line change
@@ -34,7 +34,7 @@ public LookupEntryNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
hashNode = new HashNode(context, sourceSection);
eqlNode = DispatchHeadNodeFactory.createMethodCall(context);
equalNode = BasicObjectNodesFactory.ReferenceEqualNodeFactory.create(new RubyNode[]{null, null});
equalNode = BasicObjectNodesFactory.ReferenceEqualNodeFactory.create(null);
}

public HashLookupResult lookup(VirtualFrame frame, DynamicObject hash, Object key) {
Original file line number Diff line number Diff line change
@@ -59,7 +59,7 @@ public SetNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
hashNode = new HashNode(context, sourceSection);
eqlNode = DispatchHeadNodeFactory.createMethodCall(context);
equalNode = BasicObjectNodesFactory.ReferenceEqualNodeFactory.create(new RubyNode[]{null, null});
equalNode = BasicObjectNodesFactory.ReferenceEqualNodeFactory.create(null);
}

public abstract Object executeSet(VirtualFrame frame, DynamicObject hash, Object key, Object value, boolean byIdentity);
Original file line number Diff line number Diff line change
@@ -231,7 +231,7 @@ public boolean sameOrEqual(VirtualFrame frame, Object a, Object b) {
private boolean areSame(VirtualFrame frame, Object left, Object right) {
if (referenceEqualNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
referenceEqualNode = insert(BasicObjectNodesFactory.ReferenceEqualNodeFactory.create(new RubyNode[]{null, null}));
referenceEqualNode = insert(BasicObjectNodesFactory.ReferenceEqualNodeFactory.create(null));
}

return referenceEqualNode.executeReferenceEqual(frame, left, right);
@@ -282,7 +282,7 @@ public abstract static class CompareNode extends CoreMethodArrayArgumentsNode {

public CompareNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
equalNode = SameOrEqualNodeFactory.create(new RubyNode[]{ null, null });
equalNode = SameOrEqualNodeFactory.create(null);
}

@Specialization
@@ -1931,8 +1931,8 @@ public abstract static class ToSNode extends CoreMethodArrayArgumentsNode {
public ToSNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
classNode = LogicalClassNodeGen.create(context, sourceSection, null);
objectIDNode = ObjectNodesFactory.ObjectIDPrimitiveNodeFactory.create(new RubyNode[]{ null });
toHexStringNode = KernelNodesFactory.ToHexStringNodeFactory.create(new RubyNode[]{ null });
objectIDNode = ObjectNodesFactory.ObjectIDPrimitiveNodeFactory.create(null);
toHexStringNode = KernelNodesFactory.ToHexStringNodeFactory.create(null);
}

public abstract DynamicObject executeToS(VirtualFrame frame, Object self);
Original file line number Diff line number Diff line change
@@ -277,7 +277,7 @@ void triggerInheritedHook(VirtualFrame frame, DynamicObject subClass, DynamicObj
void moduleInitialize(VirtualFrame frame, DynamicObject rubyClass, DynamicObject block) {
if (moduleInitializeNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
moduleInitializeNode = insert(ModuleNodesFactory.InitializeNodeFactory.create(new RubyNode[]{ null, null }));
moduleInitializeNode = insert(ModuleNodesFactory.InitializeNodeFactory.create(null));
}
moduleInitializeNode.executeInitialize(frame, rubyClass, block);
}
Original file line number Diff line number Diff line change
@@ -58,7 +58,7 @@ public abstract static class EqualNode extends CoreMethodArrayArgumentsNode {
protected boolean areSame(VirtualFrame frame, Object left, Object right) {
if (referenceEqualNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
referenceEqualNode = insert(BasicObjectNodesFactory.ReferenceEqualNodeFactory.create(new RubyNode[]{null, null}));
referenceEqualNode = insert(BasicObjectNodesFactory.ReferenceEqualNodeFactory.create(null));
}
return referenceEqualNode.executeReferenceEqual(frame, left, right);
}
Original file line number Diff line number Diff line change
@@ -256,7 +256,7 @@ public abstract static class CompareNode extends CoreMethodArrayArgumentsNode {
private Object isSubclass(DynamicObject self, DynamicObject other) {
if (subclassNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
subclassNode = insert(ModuleNodesFactory.IsSubclassOfOrEqualToNodeFactory.create(new RubyNode[]{null, null}));
subclassNode = insert(ModuleNodesFactory.IsSubclassOfOrEqualToNodeFactory.create(null));
}
return subclassNode.executeIsSubclassOfOrEqualTo(self, other);
}
@@ -1132,7 +1132,7 @@ public abstract static class InitializeNode extends CoreMethodArrayArgumentsNode
void classEval(VirtualFrame frame, DynamicObject module, DynamicObject block) {
if (classExecNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
classExecNode = insert(ModuleNodesFactory.ClassExecNodeFactory.create(getContext(), getSourceSection(), new RubyNode[]{null,null,null}));
classExecNode = insert(ModuleNodesFactory.ClassExecNodeFactory.create(getContext(), getSourceSection(), null));
}
classExecNode.executeClassExec(frame, module, new Object[]{}, block);
}
Original file line number Diff line number Diff line change
@@ -880,7 +880,7 @@ public Object leftShiftWithOverflow(long a, int b) {
public Object leftShiftNeg(VirtualFrame frame, long a, int b) {
if (rightShiftNode == null) {
CompilerDirectives.transferToInterpreter();
rightShiftNode = insert(FixnumNodesFactory.RightShiftNodeFactory.create(new RubyNode[]{ null, null }));
rightShiftNode = insert(FixnumNodesFactory.RightShiftNodeFactory.create(null));
}
return rightShiftNode.executeRightShift(frame, a, -b);
}
@@ -940,7 +940,7 @@ public Object rightShift(VirtualFrame frame, long a, int b,
public Object rightShiftNeg(VirtualFrame frame, long a, int b) {
if (leftShiftNode == null) {
CompilerDirectives.transferToInterpreter();
leftShiftNode = insert(FixnumNodesFactory.LeftShiftNodeFactory.create(new RubyNode[]{ null, null }));
leftShiftNode = insert(FixnumNodesFactory.LeftShiftNodeFactory.create(null));
}
return leftShiftNode.executeLeftShift(frame, a, -b);
}
@@ -960,7 +960,7 @@ public int rightShift(long a, DynamicObject b) {
public Object rightShiftNeg(VirtualFrame frame, long a, DynamicObject b) {
if (leftShiftNode == null) {
CompilerDirectives.transferToInterpreter();
leftShiftNode = insert(FixnumNodesFactory.LeftShiftNodeFactory.create(new RubyNode[]{ null, null }));
leftShiftNode = insert(FixnumNodesFactory.LeftShiftNodeFactory.create(null));
}
return leftShiftNode.executeLeftShift(frame, a, Layouts.BIGNUM.getValue(b).negate());
}
Original file line number Diff line number Diff line change
@@ -107,7 +107,7 @@ public CatchNode(RubyContext context, SourceSection sourceSection) {
private boolean areSame(VirtualFrame frame, Object left, Object right) {
if (referenceEqualNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
referenceEqualNode = insert(BasicObjectNodesFactory.ReferenceEqualNodeFactory.create(new RubyNode[]{null, null}));
referenceEqualNode = insert(BasicObjectNodesFactory.ReferenceEqualNodeFactory.create(null));
}
return referenceEqualNode.executeReferenceEqual(frame, left, right);
}
@@ -237,7 +237,7 @@ public static abstract class VMObjectEqualPrimitiveNode extends PrimitiveArrayAr

public VMObjectEqualPrimitiveNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
referenceEqualNode = ReferenceEqualNodeFactory.create(new RubyNode[]{null, null});
referenceEqualNode = ReferenceEqualNodeFactory.create(null);
}

@Specialization
@@ -288,7 +288,7 @@ public static abstract class VMObjectSingletonClassPrimitiveNode extends Primiti

public VMObjectSingletonClassPrimitiveNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
singletonClassNode = KernelNodesFactory.SingletonClassMethodNodeFactory.create(context, sourceSection, new RubyNode[]{ null });
singletonClassNode = KernelNodesFactory.SingletonClassMethodNodeFactory.create(context, sourceSection, null);
}

@Specialization
Original file line number Diff line number Diff line change
@@ -615,9 +615,7 @@ private ToIntNode getToIntNode() {
private StringSubstringPrimitiveNode getSubstringNode() {
if (substringNode == null) {
CompilerDirectives.transferToInterpreter();

substringNode = insert(StringNodesFactory.StringSubstringPrimitiveNodeFactory.create(
new RubyNode[] { null, null, null }));
substringNode = insert(StringNodesFactory.StringSubstringPrimitiveNodeFactory.create(null));
}

return substringNode;
Original file line number Diff line number Diff line change
@@ -96,12 +96,9 @@ public Object execute(VirtualFrame frame) {

final DynamicObject currentSuperClass = ClassNodes.getSuperClass(definingClass);

if (!isBlankOrRootClass(superClassModule)
&& !isBlankOrRootClass(definingClass)
&& currentSuperClass != superClassModule
&& (superClassModule != definingClass || currentSuperClass == coreLibrary().getObjectClass())) {
if (currentSuperClass != superClassModule
&& superClassModule != coreLibrary().getObjectClass()) { // bug-compat with MRI https://bugs.ruby-lang.org/issues/12367
errorProfile.enter();

throw new RaiseException(coreExceptions().superclassMismatch(
Layouts.MODULE.getFields(definingClass).getName(), this));
}
@@ -110,8 +107,4 @@ public Object execute(VirtualFrame frame) {
return definingClass;
}

private boolean isBlankOrRootClass(DynamicObject rubyClass) {
return rubyClass == coreLibrary().getBasicObjectClass() || rubyClass == coreLibrary().getObjectClass();
}

}