use of com.oracle.truffle.espresso.runtime.EspressoThreadLocalState in project graal by oracle.
the class ClassRegistry method createKlass.
@SuppressWarnings("try")
private ObjectKlass createKlass(Meta meta, ParserKlass parserKlass, Symbol<Type> type, Symbol<Type> superKlassType, ClassDefinitionInfo info) {
EspressoThreadLocalState threadLocalState = meta.getContext().getLanguage().getThreadLocalState();
TypeStack chain = threadLocalState.getTypeStack();
ObjectKlass superKlass = null;
ObjectKlass[] superInterfaces = null;
LinkedKlass[] linkedInterfaces = null;
chain.push(type);
try {
if (superKlassType != null) {
if (chain.contains(superKlassType)) {
throw meta.throwException(meta.java_lang_ClassCircularityError);
}
superKlass = loadKlassRecursively(meta, superKlassType, true);
}
final Symbol<Type>[] superInterfacesTypes = parserKlass.getSuperInterfaces();
linkedInterfaces = superInterfacesTypes.length == 0 ? LinkedKlass.EMPTY_ARRAY : new LinkedKlass[superInterfacesTypes.length];
superInterfaces = superInterfacesTypes.length == 0 ? ObjectKlass.EMPTY_ARRAY : new ObjectKlass[superInterfacesTypes.length];
for (int i = 0; i < superInterfacesTypes.length; ++i) {
if (chain.contains(superInterfacesTypes[i])) {
throw meta.throwException(meta.java_lang_ClassCircularityError);
}
ObjectKlass interf = loadKlassRecursively(meta, superInterfacesTypes[i], false);
superInterfaces[i] = interf;
linkedInterfaces[i] = interf.getLinkedKlass();
}
} finally {
chain.pop();
}
if (getContext().getJavaVersion().java16OrLater() && superKlass != null) {
if (superKlass.isFinalFlagSet()) {
throw meta.throwExceptionWithMessage(meta.java_lang_IncompatibleClassChangeError, "class " + type + " is a subclass of final class " + superKlassType);
}
}
ObjectKlass klass;
try (DebugCloseable define = KLASS_DEFINE.scope(context.getTimers())) {
// FIXME(peterssen): Do NOT create a LinkedKlass every time, use a global cache.
ContextDescription description = new ContextDescription(context.getLanguage(), context.getJavaVersion());
LinkedKlass linkedKlass = LinkedKlass.create(description, parserKlass, superKlass == null ? null : superKlass.getLinkedKlass(), linkedInterfaces);
klass = new ObjectKlass(context, linkedKlass, superKlass, superInterfaces, getClassLoader(), info);
}
if (superKlass != null) {
if (!Klass.checkAccess(superKlass, klass)) {
throw meta.throwExceptionWithMessage(meta.java_lang_IllegalAccessError, "class " + type + " cannot access its superclass " + superKlassType);
}
if (!superKlass.permittedSubclassCheck(klass)) {
throw meta.throwExceptionWithMessage(meta.java_lang_IncompatibleClassChangeError, "class " + type + " is not a permitted subclass of class " + superKlassType);
}
}
for (ObjectKlass interf : superInterfaces) {
if (interf != null) {
if (!Klass.checkAccess(interf, klass)) {
throw meta.throwExceptionWithMessage(meta.java_lang_IllegalAccessError, "class " + type + " cannot access its superinterface " + interf.getType());
}
if (!interf.permittedSubclassCheck(klass)) {
throw meta.throwExceptionWithMessage(meta.java_lang_IncompatibleClassChangeError, "class " + type + " is not a permitted subclass of interface " + superKlassType);
}
}
}
return klass;
}
Aggregations