Skip to content

Commit 8513c31

Browse files
Improve wiring for redefinition errors to JDWP and Instrumentation
Use a checked exception up to the point where redefinition is used by either JDWP or java agents. Translate those to either JDWP error codes or exceptions. Make sure that parser exceptions are translated correctly to JDWP error codes. Make sure unsupported cases are also translated to JDWP error codes.
1 parent 6a14dba commit 8513c31

File tree

9 files changed

+240
-124
lines changed

9 files changed

+240
-124
lines changed

espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/api/ErrorCodes.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ public final class ErrorCodes {
3737
public static final int INVALID_SLOT = 35;
3838
public static final int INVALID_MODULE = 42;
3939
public static final int INVALID_CLASS_FORMAT = 60;
40+
public static final int CIRCULAR_CLASS_DEFINITION = 61;
4041
public static final int FAILS_VERIFICATION = 62;
4142
public static final int ADD_METHOD_NOT_IMPLEMENTED = 63;
4243
public static final int SCHEMA_CHANGE_NOT_IMPLEMENTED = 64;
@@ -46,6 +47,7 @@ public final class ErrorCodes {
4647
public static final int NAMES_DONT_MATCH = 69;
4748
public static final int CLASS_MODIFIERS_CHANGE_NOT_IMPLEMENTED = 70;
4849
public static final int METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED = 71;
50+
public static final int CLASS_ATTRIBUTE_CHANGE_NOT_IMPLEMENTED = 72;
4951
public static final int NOT_IMPLEMENTED = 99;
5052
public static final int ABSENT_INFORMATION = 101;
5153
public static final int INVALID_EVENT_TYPE = 102;

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/preinit/ParserKlassProvider.java

Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -47,39 +47,49 @@ default int getCachedParserKlassCount() {
4747
return 0;
4848
}
4949

50-
static ParserKlass parseKlass(ClassRegistry.ClassDefinitionInfo info, ClassLoadingEnv env, StaticObject loader, Symbol<Type> typeOrNull, byte[] bytes) {
50+
/**
51+
* Like {@link #parseKlass} but throws host exceptions that must be caught an handled by the
52+
* called.
53+
*
54+
* @throws ValidationException a descriptor validation caused a class format error.
55+
* @throws ParserException various exceptions, see subclasses.
56+
*/
57+
static ParserKlass parseKlassWithHostErrors(ClassRegistry.ClassDefinitionInfo info, ClassLoadingEnv env, StaticObject loader, Symbol<Type> typeOrNull, byte[] bytes) throws ValidationException {
5158
boolean verifiable = EspressoVerifier.needsVerify(env.getLanguage(), loader);
5259
boolean loaderIsBootOrPlatform = env.loaderIsBootOrPlatform(loader);
53-
Meta meta = env.getMeta();
54-
try {
55-
// Classes from trusted class loaders can create strongly referenced symbols directly
56-
// during parsing.
57-
boolean ensureStrongSymbols = env.loaderIsBootOrPlatform(loader) || env.loaderIsAppLoader(loader);
58-
ParsingContext parsingContext = ClassLoadingEnv.createParsingContext(env, ensureStrongSymbols);
60+
// Classes from trusted class loaders can create strongly referenced symbols directly
61+
// during parsing.
62+
boolean ensureStrongSymbols = env.loaderIsBootOrPlatform(loader) || env.loaderIsAppLoader(loader);
63+
ParsingContext parsingContext = ClassLoadingEnv.createParsingContext(env, ensureStrongSymbols);
5964

60-
// Trusted classes do not need validation/verification.
61-
boolean validate = verifiable;
62-
ParserKlass parserKlass = ClassfileParser.parse(parsingContext, new ClassfileStream(bytes, null), verifiable, loaderIsBootOrPlatform, typeOrNull, info.isHidden,
63-
info.forceAllowVMAnnotations, validate);
64-
if (info.isHidden) {
65-
Symbol<Type> requestedClassType = typeOrNull;
66-
assert requestedClassType != null;
67-
long hiddenKlassId = env.getNewKlassId();
68-
Symbol<Name> thisKlassName = parsingContext.getOrCreateName(TypeSymbols.hiddenClassName(requestedClassType, hiddenKlassId));
69-
Symbol<Type> thisKlassType = parsingContext.getOrCreateTypeFromName(thisKlassName);
70-
var pool = parserKlass.getConstantPool().patchForHiddenClass(parserKlass.getThisKlassIndex(), thisKlassName);
71-
var classFlags = parserKlass.getFlags() | Constants.ACC_IS_HIDDEN_CLASS;
72-
return new ParserKlass(pool, classFlags, thisKlassName, thisKlassType,
73-
parserKlass.getSuperKlass(), parserKlass.getSuperInterfaces(),
74-
parserKlass.getMethods(), parserKlass.getFields(),
75-
parserKlass.getAttributes(),
76-
parserKlass.getThisKlassIndex(),
77-
parserKlass.getMajorVersion(), parserKlass.getMinorVersion(),
78-
parserKlass.getHiddenKlassId());
79-
}
65+
// Trusted classes do not need validation/verification.
66+
boolean validate = verifiable;
67+
ParserKlass parserKlass = ClassfileParser.parse(parsingContext, new ClassfileStream(bytes, null), verifiable, loaderIsBootOrPlatform, typeOrNull, info.isHidden,
68+
info.forceAllowVMAnnotations, validate);
69+
if (info.isHidden) {
70+
Symbol<Type> requestedClassType = typeOrNull;
71+
assert requestedClassType != null;
72+
long hiddenKlassId = env.getNewKlassId();
73+
Symbol<Name> thisKlassName = parsingContext.getOrCreateName(TypeSymbols.hiddenClassName(requestedClassType, hiddenKlassId));
74+
Symbol<Type> thisKlassType = parsingContext.getOrCreateTypeFromName(thisKlassName);
75+
var pool = parserKlass.getConstantPool().patchForHiddenClass(parserKlass.getThisKlassIndex(), thisKlassName);
76+
var classFlags = parserKlass.getFlags() | Constants.ACC_IS_HIDDEN_CLASS;
77+
return new ParserKlass(pool, classFlags, thisKlassName, thisKlassType,
78+
parserKlass.getSuperKlass(), parserKlass.getSuperInterfaces(),
79+
parserKlass.getMethods(), parserKlass.getFields(),
80+
parserKlass.getAttributes(),
81+
parserKlass.getThisKlassIndex(),
82+
parserKlass.getMajorVersion(), parserKlass.getMinorVersion(),
83+
parserKlass.getHiddenKlassId());
84+
}
8085

81-
return parserKlass;
86+
return parserKlass;
87+
}
8288

89+
static ParserKlass parseKlass(ClassRegistry.ClassDefinitionInfo info, ClassLoadingEnv env, StaticObject loader, Symbol<Type> typeOrNull, byte[] bytes) {
90+
Meta meta = env.getMeta();
91+
try {
92+
return parseKlassWithHostErrors(info, env, loader, typeOrNull, bytes);
8393
} catch (ValidationException | ParserException.ClassFormatError validationOrBadFormat) {
8494
throw meta.throwExceptionWithMessage(meta.java_lang_ClassFormatError, validationOrBadFormat.getMessage());
8595
} catch (ParserException.UnsupportedClassVersionError unsupportedClassVersionError) {

0 commit comments

Comments
 (0)