From 5d8f89b7d28856c45cb8e52a515c394b7c3d71de Mon Sep 17 00:00:00 2001 From: jochen Date: Thu, 17 Jun 1999 11:07:34 +0000 Subject: [PATCH] handle arrays of unknowns correctly git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@857 379699f6-c40d-0410-875b-85095c16579e --- jode/jode/jvm/CodeVerifier.java | 69 +++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 25 deletions(-) diff --git a/jode/jode/jvm/CodeVerifier.java b/jode/jode/jvm/CodeVerifier.java index 0c79a1c..2211772 100644 --- a/jode/jode/jvm/CodeVerifier.java +++ b/jode/jode/jvm/CodeVerifier.java @@ -187,6 +187,8 @@ public class CodeVerifier implements Opcodes { GlobalOptions.err.println("isOfType("+t1+","+t2+")"); if (t1.equals(t2)) return true; + if (t2.getTypeCode() == Type.TC_UNKNOWN) + return true; if (t1.getTypeCode() == Type.TC_INTEGER && t2.getTypeCode() == Type.TC_INTEGER) return true; @@ -198,16 +200,19 @@ public class CodeVerifier implements Opcodes { return (t1.getTypeCode() == Type.TC_CLASS || t1.getTypeCode() == Type.TC_ARRAY || t1.getTypeCode() == -Type.TC_CLASS); - if ((t1.getTypeCode() == Type.TC_CLASS - || t1.getTypeCode() == Type.TC_ARRAY) - && (t2.getTypeCode() == Type.TC_CLASS - || t2.getTypeCode() == Type.TC_ARRAY)) { - if (t1.getTypeCode() == Type.TC_ARRAY) { - if (t2.getTypeCode() == Type.TC_CLASS) - return (((ClassInterfacesType)t2).getClazz() - == ClassInfo.javaLangObject); + if (t1.getTypeCode() == Type.TC_ARRAY) { + if (t2.getTypeCode() == Type.TC_CLASS) + return (((ClassInterfacesType)t2).getClazz() + == ClassInfo.javaLangObject); + else if (t2.getTypeCode() == Type.TC_ARRAY) { Type e1 = ((ArrayType)t1).getElementType(); Type e2 = ((ArrayType)t2).getElementType(); + if (e2.getTypeCode() == Type.TC_UNKNOWN) + return true; + + /* Note that short[] is not compatible to int[], + * therefore this extra check. + */ if ((e1.getTypeCode() == Type.TC_CLASS || e1.getTypeCode() == Type.TC_ARRAY || e1.equals(Type.tUObject)) @@ -215,10 +220,11 @@ public class CodeVerifier implements Opcodes { || e2.getTypeCode() == Type.TC_ARRAY || e2.equals(Type.tUObject))) return isOfType(e1, e2); - return false; - } else { - if (t2.getTypeCode() == Type.TC_ARRAY) - return false; + } + return false; + } + if (t1.getTypeCode() == Type.TC_CLASS) { + if (t2.getTypeCode() == Type.TC_CLASS) { ClassInfo c1 = ((ClassInterfacesType) t1).getClazz(); ClassInfo c2 = ((ClassInterfacesType) t2).getClazz(); return c2.superClassOf(c1); @@ -230,6 +236,10 @@ public class CodeVerifier implements Opcodes { public Type mergeType(Type t1, Type t2) { if (t1.equals(t2)) return t1; + if (t1.getTypeCode() == Type.TC_UNKNOWN) + return t2; + if (t2.getTypeCode() == Type.TC_UNKNOWN) + return t1; if (t1.getTypeCode() == Type.TC_INTEGER && t2.getTypeCode() == Type.TC_INTEGER) return t1; @@ -241,15 +251,20 @@ public class CodeVerifier implements Opcodes { return (t1.getTypeCode() == Type.TC_CLASS || t1.getTypeCode() == Type.TC_ARRAY || t1.getTypeCode() == -Type.TC_CLASS) ? t1 : Type.tError; - if ((t1.getTypeCode() == Type.TC_CLASS - || t1.getTypeCode() == Type.TC_ARRAY) - && (t2.getTypeCode() == Type.TC_CLASS - || t2.getTypeCode() == Type.TC_ARRAY)) { - if (t1.getTypeCode() == Type.TC_ARRAY) { - if (t2.getTypeCode() == Type.TC_CLASS) - return Type.tObject; + if (t1.getTypeCode() == Type.TC_ARRAY) { + if (t2.getTypeCode() == Type.TC_CLASS) + return Type.tObject; + else if (t2.getTypeCode() == Type.TC_ARRAY) { Type e1 = ((ArrayType)t1).getElementType(); Type e2 = ((ArrayType)t2).getElementType(); + + if (e1.getTypeCode() == Type.TC_UNKNOWN) + return t2; + if (e2.getTypeCode() == Type.TC_UNKNOWN) + return t1; + /* Note that short[] is not compatible to int[], + * therefore this extra check. + */ if ((e1.getTypeCode() == Type.TC_CLASS || e1.getTypeCode() == Type.TC_ARRAY || e1.equals(Type.tUObject)) @@ -258,9 +273,13 @@ public class CodeVerifier implements Opcodes { || e2.equals(Type.tUObject))) return Type.tArray(mergeType(e1, e2)); return Type.tObject; - } else { - if (t2.getTypeCode() == Type.TC_ARRAY) - return Type.tObject; + } + return Type.tError; + } + if (t1.getTypeCode() == Type.TC_CLASS) { + if (t2.getTypeCode() == Type.TC_ARRAY) + return Type.tObject; + if (t2.getTypeCode() == Type.TC_CLASS) { ClassInfo c1 = ((ClassInterfacesType) t1).getClazz(); ClassInfo c2 = ((ClassInterfacesType) t2).getClazz(); if (c1.superClassOf(c2)) @@ -419,7 +438,8 @@ public class CodeVerifier implements Opcodes { || !isOfType(arrType, Type.tArray(Type.tBoolean)))) throw new VerifyException(instr.getDescription()); - Type elemType = (arrType.equals(Type.tUObject) ? Type.tUObject + Type elemType = (arrType.equals(Type.tUObject) + ? types[instr.opcode - opc_iaload] :((ArrayType)arrType).getElementType()); result.push(elemType); if (((1 << instr.opcode - opc_iaload) & 0xa) != 0) @@ -827,8 +847,7 @@ public class CodeVerifier implements Opcodes { break; } case opc_arraylength: { - if (result.pop().getTypeCode() - != Type.TC_ARRAY) + if (!isOfType(result.pop(), Type.tArray(Type.tUnknown))) throw new VerifyException(instr.getDescription()); result.push(Type.tInt); break;