Skip to content

Commit ac705be

Browse files
Ensure Crema doesn't load Hybrid types
1 parent 85207da commit ac705be

File tree

5 files changed

+88
-5
lines changed

5 files changed

+88
-5
lines changed

espresso-shared/src/com.oracle.truffle.espresso.classfile/src/com/oracle/truffle/espresso/classfile/ClassfileParser.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1126,7 +1126,10 @@ private static Attribute[] spawnAttributesArray(int attributeCount) {
11261126
return attributeCount == 0 ? Attribute.EMPTY_ARRAY : new Attribute[attributeCount];
11271127
}
11281128

1129-
private static int parseAnnotation(ClassfileStream subStream) {
1129+
/**
1130+
* Parse one annotation in an annotation attribute and return the annotation type index.
1131+
*/
1132+
public static int parseAnnotation(ClassfileStream subStream) {
11301133
int typeIndex = subStream.readU2();
11311134
int numElementValuePairs = subStream.readU2();
11321135
for (int k = 0; k < numElementValuePairs; k++) {

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/DynamicHub.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,10 @@ public static DynamicHub allocate(String name, DynamicHub superHub, Object inter
486486
} else {
487487
// instance class
488488
assert !"java.lang.Class".equals(name);
489-
// @Hybrid is ignored
489+
/*
490+
* @Hybrid types are not supported. The absence of the annotation is assumed to be
491+
* checked by callers. See AbstractRuntimeClassRegistry.checkNotHybrid.
492+
*/
490493
if (Modifier.isAbstract(modifiers)) {
491494
layoutEncoding = LayoutEncoding.forAbstract();
492495
} else {

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/registry/AbstractRuntimeClassRegistry.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import com.oracle.svm.core.hub.DynamicHub;
4848
import com.oracle.svm.core.hub.RuntimeClassLoading;
4949
import com.oracle.svm.core.hub.RuntimeClassLoading.ClassDefinitionInfo;
50+
import com.oracle.svm.core.hub.registry.SVMSymbols.SVMTypes;
5051
import com.oracle.svm.core.jdk.Target_java_lang_ClassLoader;
5152
import com.oracle.svm.core.util.VMError;
5253
import com.oracle.svm.espresso.classfile.ClassfileParser;
@@ -56,6 +57,7 @@
5657
import com.oracle.svm.espresso.classfile.ParserField;
5758
import com.oracle.svm.espresso.classfile.ParserKlass;
5859
import com.oracle.svm.espresso.classfile.ParserMethod;
60+
import com.oracle.svm.espresso.classfile.attributes.Attribute;
5961
import com.oracle.svm.espresso.classfile.attributes.InnerClassesAttribute;
6062
import com.oracle.svm.espresso.classfile.attributes.NestHostAttribute;
6163
import com.oracle.svm.espresso.classfile.attributes.PermittedSubclassesAttribute;
@@ -408,6 +410,8 @@ private Class<?> createClass(ParserKlass parsed, ClassDefinitionInfo info, Symbo
408410
// GR-62339
409411
Module module = getClassLoader().getUnnamedModule();
410412

413+
checkNotHybrid(parsed);
414+
411415
DynamicHub hub = DynamicHub.allocate(externalName, superHub, interfacesEncoding, null,
412416
sourceFile, modifiers, flags, getClassLoader(), nestHost, simpleBinaryName, module, enclosingClass, classSignature,
413417
typeID, numClassTypes, typeIDDepth, numInterfacesTypes, openTypeWorldTypeCheckSlots, dispatchTableLength, afterFieldsOffset, isValueBased);
@@ -417,6 +421,23 @@ sourceFile, modifiers, flags, getClassLoader(), nestHost, simpleBinaryName, modu
417421
return DynamicHub.toClass(hub);
418422
}
419423

424+
private static void checkNotHybrid(ParserKlass parsed) {
425+
Attribute attribute = parsed.getAttribute(ParserNames.RuntimeVisibleAnnotations);
426+
if (attribute == null) {
427+
return;
428+
}
429+
ClassfileStream stream = new ClassfileStream(attribute.getData(), null);
430+
int count = stream.readU2();
431+
for (int j = 0; j < count; j++) {
432+
int typeIndex = ClassfileParser.parseAnnotation(stream);
433+
Symbol<?> annotType = parsed.getConstantPool().utf8At(typeIndex, "annotation type");
434+
if (SVMTypes.com_oracle_svm_core_hub_Hybrid.equals(annotType)) {
435+
throw new ClassFormatError("Cannot load @Hybrid classes at runtime");
436+
}
437+
}
438+
439+
}
440+
420441
private static boolean declaresDefaultMethods(ParserKlass parsed) {
421442
for (ParserMethod method : parsed.getMethods()) {
422443
int flags = method.getFlags();
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Copyright (c) 2025, 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package com.oracle.svm.core.hub.registry;
26+
27+
import com.oracle.svm.espresso.classfile.descriptors.ParserSymbols;
28+
import com.oracle.svm.espresso.classfile.descriptors.StaticSymbols;
29+
import com.oracle.svm.espresso.classfile.descriptors.Symbol;
30+
import com.oracle.svm.espresso.classfile.descriptors.Type;
31+
32+
public final class SVMSymbols {
33+
// Pre-allocate enough slots to avoid resizing the underlying map.
34+
// But not too much, since these maps will be persisted in the image heap (Native Image).
35+
public static final StaticSymbols SYMBOLS = new StaticSymbols(ParserSymbols.SYMBOLS, 1 << 8);
36+
37+
private SVMSymbols() {
38+
}
39+
40+
static {
41+
SVMTypes.ensureInitialized();
42+
}
43+
44+
public static void ensureInitialized() {
45+
/* nop */
46+
}
47+
48+
public static final class SVMTypes {
49+
public static final Symbol<Type> com_oracle_svm_core_hub_Hybrid = SYMBOLS.putType("Lcom/oracle/svm/core/hub/Hybrid;");
50+
51+
private SVMTypes() {
52+
}
53+
54+
public static void ensureInitialized() {
55+
/* nop */
56+
}
57+
}
58+
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/registry/SymbolsSupport.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
import org.graalvm.nativeimage.Platforms;
3131

3232
import com.oracle.svm.espresso.classfile.descriptors.NameSymbols;
33-
import com.oracle.svm.espresso.classfile.descriptors.ParserSymbols;
3433
import com.oracle.svm.espresso.classfile.descriptors.SignatureSymbols;
3534
import com.oracle.svm.espresso.classfile.descriptors.Symbols;
3635
import com.oracle.svm.espresso.classfile.descriptors.TypeSymbols;
@@ -49,9 +48,8 @@ public final class SymbolsSupport {
4948

5049
@Platforms(Platform.HOSTED_ONLY.class)
5150
public SymbolsSupport() {
52-
ParserSymbols.ensureInitialized();
5351
int initialSymbolTableCapacity = 4 * 1024;
54-
Symbols symbols = Symbols.fromExisting(ParserSymbols.SYMBOLS.freeze(), initialSymbolTableCapacity, 0);
52+
Symbols symbols = Symbols.fromExisting(SVMSymbols.SYMBOLS.freeze(), initialSymbolTableCapacity, 0);
5553
// let this resize when first used at runtime
5654
utf8 = new Utf8Symbols(symbols);
5755
names = new NameSymbols(symbols);

0 commit comments

Comments
 (0)