Skip to content

Commit

Permalink
[Truffle] Do not ignore super class mismatch for explicitly declared …
Browse files Browse the repository at this point in the history
…superclass as Object
  • Loading branch information
pitr-ch committed Dec 2, 2016
1 parent d94afea commit edfbe20
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 13 deletions.
1 change: 0 additions & 1 deletion spec/truffle/tags/language/class_tags.txt

This file was deleted.

Expand Up @@ -36,10 +36,12 @@ public class DefineClassNode extends RubyNode {
@Child CallDispatchHeadNode inheritedNode;

private final ConditionProfile needToDefineProfile = ConditionProfile.createBinaryProfile();
private final ConditionProfile noSuperClassSupplied = ConditionProfile.createBinaryProfile();
private final BranchProfile errorProfile = BranchProfile.create();

public DefineClassNode(RubyContext context, SourceSection sourceSection, String name,
RubyNode lexicalParent, RubyNode superClass) {
public DefineClassNode(
RubyContext context, SourceSection sourceSection, String name,
RubyNode lexicalParent, RubyNode superClass) {
super(context, sourceSection);
this.name = name;
this.lexicalParentModule = lexicalParent;
Expand All @@ -56,12 +58,18 @@ public Object execute(VirtualFrame frame) {
}

final DynamicObject lexicalParentModule = (DynamicObject) lexicalParentObject;
final DynamicObject superClass = executeSuperClass(frame);
final DynamicObject suppliedSuperClass = executeSuperClass(frame);
final RubyConstant constant = lookupForExistingModule(frame, name, lexicalParentModule);

final DynamicObject definedClass;

if (needToDefineProfile.profile(constant == null)) {
final DynamicObject superClass;
if (noSuperClassSupplied.profile(suppliedSuperClass == null)) {
superClass = getContext().getCoreLibrary().getObjectClass();
} else {
superClass = suppliedSuperClass;
}
definedClass = ClassNodes.createInitializedRubyClass(getContext(), lexicalParentModule, superClass, name);
callInherited(frame, superClass, definedClass);
} else {
Expand All @@ -74,8 +82,7 @@ public Object execute(VirtualFrame frame) {

final DynamicObject currentSuperClass = ClassNodes.getSuperClass(definedClass);

if (currentSuperClass != superClass
&& superClass != coreLibrary().getObjectClass()) { // bug-compat with MRI https://bugs.ruby-lang.org/issues/12367
if (suppliedSuperClass != null && currentSuperClass != suppliedSuperClass) { // bug-compat with MRI https://bugs.ruby-lang.org/issues/12367
errorProfile.enter();
throw new RaiseException(coreExceptions().superclassMismatch(
Layouts.MODULE.getFields(definedClass).getName(), this));
Expand All @@ -86,6 +93,9 @@ public Object execute(VirtualFrame frame) {
}

private DynamicObject executeSuperClass(VirtualFrame frame) {
if (superClassNode == null) {
return null;
}
final Object superClassObject = superClassNode.execute(frame);

if (!RubyGuards.isRubyClass(superClassObject)) {
Expand Down
Expand Up @@ -1078,13 +1078,7 @@ public RubyNode visitClassNode(ClassParseNode node) {

RubyNode lexicalParent = translateCPath(sourceSection, node.getCPath());

RubyNode superClass;
if (node.getSuperNode() != null) {
superClass = node.getSuperNode().accept(this);
} else {
superClass = new ObjectLiteralNode(context, fullSourceSection, context.getCoreLibrary().getObjectClass());
}

final RubyNode superClass = node.getSuperNode() != null ? node.getSuperNode().accept(this) : null;
final DefineClassNode defineOrGetClass = new DefineClassNode(context, fullSourceSection, name, lexicalParent, superClass);

final RubyNode ret = openModule(sourceSection, defineOrGetClass, name, node.getBodyNode(), false);
Expand Down

0 comments on commit edfbe20

Please sign in to comment.