Skip to content

Commit

Permalink
Showing 3 changed files with 55 additions and 7 deletions.
1 change: 0 additions & 1 deletion spec/truffle/tags/core/class/initialize_tags.txt

This file was deleted.

Original file line number Diff line number Diff line change
@@ -407,6 +407,26 @@ public DynamicObject typeErrorAlreadyInitializedClass(Node currentNode) {
return typeError("already initialized class", currentNode);
}

@TruffleBoundary
public DynamicObject typeErrorSubclassSingletonClass(Node currentNode) {
return typeError("can't make subclass of singleton class", currentNode);
}

@TruffleBoundary
public DynamicObject typeErrorSubclassClass(Node currentNode) {
return typeError("can't make subclass of Class", currentNode);
}

@TruffleBoundary
public DynamicObject typeErrorSuperclassMustBeClass(Node currentNode) {
return typeError("superclass must be a Class", currentNode);
}

@TruffleBoundary
public DynamicObject typeErrorInheritUninitializedClass(Node currentNode) {
return typeError("can't inherit uninitialized class", currentNode);
}

@TruffleBoundary
public DynamicObject typeError(String message, Node currentNode, Throwable javaThrowable) {
return ExceptionOperations.createRubyException(
41 changes: 35 additions & 6 deletions truffle/src/main/java/org/jruby/truffle/core/klass/ClassNodes.java
Original file line number Diff line number Diff line change
@@ -309,48 +309,77 @@ void moduleInitialize(VirtualFrame frame, DynamicObject rubyClass, DynamicObject

@Specialization
public DynamicObject initialize(VirtualFrame frame, DynamicObject rubyClass, NotProvided superclass, NotProvided block) {
return initializeGeneralWithoutBlock(frame, rubyClass, coreLibrary().getObjectClass());
return initializeGeneralWithoutBlock(frame, rubyClass, coreLibrary().getObjectClass(), false);
}

@Specialization(guards = "isRubyClass(superclass)")
public DynamicObject initialize(VirtualFrame frame, DynamicObject rubyClass, DynamicObject superclass, NotProvided block) {
return initializeGeneralWithoutBlock(frame, rubyClass, superclass);
return initializeGeneralWithoutBlock(frame, rubyClass, superclass, true);
}

@Specialization
public DynamicObject initialize(VirtualFrame frame, DynamicObject rubyClass, NotProvided superclass, DynamicObject block) {
return initializeGeneralWithBlock(frame, rubyClass, coreLibrary().getObjectClass(), block);
return initializeGeneralWithBlock(frame, rubyClass, coreLibrary().getObjectClass(), block, false);
}

@Specialization(guards = "isRubyClass(superclass)")
public DynamicObject initialize(VirtualFrame frame, DynamicObject rubyClass, DynamicObject superclass, DynamicObject block) {
return initializeGeneralWithBlock(frame, rubyClass, superclass, block);
return initializeGeneralWithBlock(frame, rubyClass, superclass, block, true);
}

private DynamicObject initializeGeneralWithoutBlock(VirtualFrame frame, DynamicObject rubyClass, DynamicObject superclass) {
private DynamicObject initializeGeneralWithoutBlock(VirtualFrame frame, DynamicObject rubyClass, DynamicObject superclass, boolean superClassProvided) {
assert RubyGuards.isRubyClass(rubyClass);
assert RubyGuards.isRubyClass(superclass);

if (Layouts.CLASS.getSuperclass(rubyClass) != null || rubyClass == coreLibrary().getBasicObjectClass()) {
throw new RaiseException(getContext().getCoreExceptions().typeErrorAlreadyInitializedClass(this));
}
if (superClassProvided) {
checkInheritable(superclass);
if (superclass != coreLibrary().getBasicObjectClass() && Layouts.CLASS.getSuperclass(superclass) == null) {
throw new RaiseException(getContext().getCoreExceptions().typeErrorInheritUninitializedClass(this));
}
}

ClassNodes.initialize(getContext(), rubyClass, superclass);
triggerInheritedHook(frame, rubyClass, superclass);

return rubyClass;
}

private DynamicObject initializeGeneralWithBlock(VirtualFrame frame, DynamicObject rubyClass, DynamicObject superclass, DynamicObject block) {
private DynamicObject initializeGeneralWithBlock(VirtualFrame frame, DynamicObject rubyClass, DynamicObject superclass, DynamicObject block, boolean superClassProvided) {
assert RubyGuards.isRubyClass(superclass);

if (Layouts.CLASS.getSuperclass(rubyClass) != null || rubyClass == coreLibrary().getBasicObjectClass()) {
throw new RaiseException(getContext().getCoreExceptions().typeErrorAlreadyInitializedClass(this));
}
if (superClassProvided) {
checkInheritable(superclass);
if (superclass != coreLibrary().getBasicObjectClass() && Layouts.CLASS.getSuperclass(superclass) == null) {
throw new RaiseException(getContext().getCoreExceptions().typeErrorInheritUninitializedClass(this));
}
}

ClassNodes.initialize(getContext(), rubyClass, superclass);
triggerInheritedHook(frame, rubyClass, superclass);
moduleInitialize(frame, rubyClass, block);

return rubyClass;
}

// rb_check_inheritable
private void checkInheritable(DynamicObject superClass) {
if (!RubyGuards.isRubyClass(superClass)) {
throw new RaiseException(coreExceptions().typeErrorSuperclassMustBeClass(this));
}
if (Layouts.CLASS.getIsSingleton(superClass)) {
throw new RaiseException(coreExceptions().typeErrorSubclassSingletonClass(this));
}
if (superClass == coreLibrary().getClassClass()) {
throw new RaiseException(coreExceptions().typeErrorSubclassClass(this));
}
}

}

@CoreMethod(names = "inherited", required = 1, visibility = Visibility.PRIVATE)

0 comments on commit 9c6e3c9

Please sign in to comment.