From 70e863f6b492c70a0eb2fabb926ae65b68a80955 Mon Sep 17 00:00:00 2001 From: aionick Date: Thu, 2 May 2019 15:39:45 -0400 Subject: [PATCH] AKI-101: Remove SYSTEM_EXCEPTION_DETECTION_PREFIX - The ExceptionWrapping class now checks for java/lang/ exceptions via a set obtained from the CommonType enum, which holds all of the jcl exception types. --- .../classgeneration/CommonGenerators.java | 12 ------- .../exceptionwrapping/ExceptionWrapping.java | 31 ++++++++++++++----- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/org.aion.avm.core/src/org/aion/avm/core/classgeneration/CommonGenerators.java b/org.aion.avm.core/src/org/aion/avm/core/classgeneration/CommonGenerators.java index bd13558ce..b24ecbf21 100644 --- a/org.aion.avm.core/src/org/aion/avm/core/classgeneration/CommonGenerators.java +++ b/org.aion.avm.core/src/org/aion/avm/core/classgeneration/CommonGenerators.java @@ -24,18 +24,6 @@ public class CommonGenerators { .filter((type) -> (type.isShadowException && !type.isVirtualMachineErrorOrChildError && !type.dotName.equals(CommonType.SHADOW_THROWABLE.dotName))) .map((type) -> (ClassNameExtractor.getOriginalClassName(type.dotName))) .toArray(String[]::new); - private static Set allJclExceptions = null; - - public static boolean isJclExceptionType(String className) { - if (allJclExceptions == null) { - Set exceptions = new HashSet<>(Arrays.asList(CommonGenerators.kExceptionClassNames)); - exceptions.addAll(CommonGenerators.kHandWrittenExceptionClassNames); - exceptions.addAll(CommonGenerators.kLegacyExceptionClassNames); - exceptions.add(CommonType.JAVA_LANG_THROWABLE.dotName); // Missing from the other lists, but definitely an exception. - allJclExceptions = exceptions; - } - return allJclExceptions.contains(className); - } // We don't generate the shadows for these ones since we have hand-written them (but wrappers are still required). public static final Set kHandWrittenExceptionClassNames = Set.of(new String[] { diff --git a/org.aion.avm.core/src/org/aion/avm/core/exceptionwrapping/ExceptionWrapping.java b/org.aion.avm.core/src/org/aion/avm/core/exceptionwrapping/ExceptionWrapping.java index ee6c0fdf9..2c7c024e6 100644 --- a/org.aion.avm.core/src/org/aion/avm/core/exceptionwrapping/ExceptionWrapping.java +++ b/org.aion.avm.core/src/org/aion/avm/core/exceptionwrapping/ExceptionWrapping.java @@ -1,5 +1,6 @@ package org.aion.avm.core.exceptionwrapping; +import i.RuntimeAssertionError; import org.aion.avm.core.ClassToolchain; import org.aion.avm.core.classgeneration.StubGenerator; import org.aion.avm.core.types.ClassHierarchy; @@ -16,21 +17,17 @@ public class ExceptionWrapping extends ClassToolchain.ToolChainClassVisitor { - /** - * We need to handle the case of how to unify exceptions originating directly from the JVM, so we check the "java/lang/" prefix. - * NOTE: This prefix handles all the cases which are thrown asynchronously from the JVM. - * TODO (AKI-101): Replace this explicit prefix check with a more general name mapper. - */ - private static final String SYSTEM_EXCEPTION_DETECTION_PREFIX = "java/lang/"; - private final GeneratedClassConsumer generatedClassesSink; private final ClassHierarchy classHierarchy; + private final Set jclExceptionsSlashStyle; public ExceptionWrapping(GeneratedClassConsumer generatedClassesSink, ClassHierarchy classHierarchy) { super(Opcodes.ASM6); this.generatedClassesSink = generatedClassesSink; this.classHierarchy = classHierarchy; + this.jclExceptionsSlashStyle = fetchAllJavaLangExceptionsSlashStyle(); + } @Override @@ -100,7 +97,15 @@ public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[ // (without this, the verifier will complain about the operand stack containing the wrong type when used). // Note that this type also needs to be translated into our namespace, since we won't be giving the user direct access to // real exceptions. - String mappedCastType = castType.startsWith(SYSTEM_EXCEPTION_DETECTION_PREFIX) + boolean isPreRenameJavaException = jclExceptionsSlashStyle.contains(castType); + + // We only expect to find java.lang.Throwable by this point when it is synthesized in finally blocks. + // Everything else should have already been renamed. + if (isPreRenameJavaException) { + RuntimeAssertionError.assertTrue(castType.equals("java/lang/Throwable")); + } + + String mappedCastType = isPreRenameJavaException ? PackageConstants.kShadowSlashPrefix + castType : castType; super.visitTypeInsn(Opcodes.CHECKCAST, mappedCastType); @@ -152,4 +157,14 @@ public void visitInsn(int opcode) { } }; } + + private Set fetchAllJavaLangExceptionsSlashStyle() { + Set javaLangExceptions = new HashSet<>(); + for (CommonType type : CommonType.values()) { + if (type.isShadowException) { + javaLangExceptions.add(type.dotName.substring(PackageConstants.kShadowDotPrefix.length()).replaceAll("\\.", "/")); + } + } + return javaLangExceptions; + } }