
org.apache.commons.javaflow.providers.asm3.FastClassVerifier Maven / Gradle / Ivy
/**
* Original work: copyright 1999-2004 The Apache Software Foundation
* (http://www.apache.org/)
*
* This project is based on the work licensed to the Apache Software
* Foundation (ASF) under one or more contributor license agreements.
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
* Modified work: copyright 2013-2022 Valery Silaev (http://vsilaev.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.javaflow.providers.asm3;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.analysis.BasicValue;
import org.objectweb.asm.tree.analysis.SimpleVerifier;
import org.objectweb.asm.tree.analysis.Value;
class FastClassVerifier extends SimpleVerifier {
private final ClassHierarchy classHierarchy;
public FastClassVerifier(ClassHierarchy classHierarchy) {
this.classHierarchy = classHierarchy;
}
@Override
protected boolean isAssignableFrom(Type t, Type u) {
if (t.equals(u)) {
return true;
}
// Null is assignable to any reference type
if ("Lnull;".equals(u.getDescriptor()) && t.getSort() >= Type.ARRAY) {
return true;
}
Type et, eu;
if (t.getSort() == Type.ARRAY) {
if (u.getSort() != Type.ARRAY ) {
return false;
}
et = t.getElementType();
eu = u.getElementType();
int dt = t.getDimensions();
int du = u.getDimensions();
boolean isObject = et.equals(((BasicValue)BasicValue.REFERENCE_VALUE).getType());
// u must be an array of equals dimension or bigger dimension if t is Object
if (dt == du || dt < du && isObject) {
// Ok
} else {
return false;
}
} else {
et = t;
eu = u;
}
/*
Type commonType = classHierarchy.getCommonSuperType(et, eu);
*/
// isAssignableFrom(Number, Integer) => getCommonSuperType(Integer, Number) == Number
// Use ClassHierarchy.isSubclass biased behavior (for performance)
Type commonType = classHierarchy.getCommonSuperType(eu, et);
return commonType.equals(et);
}
@Override
public Value merge(Value v, Value w) {
if (!v.equals(w)) {
Type t = ((BasicValue)v).getType();
Type u = ((BasicValue)w).getType();
int tsort = t == null ? -1 : t.getSort();
if (tsort == Type.OBJECT || tsort == Type.ARRAY) {
int usort = u == null ? -1 : u.getSort();
if (usort == Type.OBJECT || usort == Type.ARRAY) {
if ("Lnull;".equals(t.getDescriptor())) {
return w;
}
if ("Lnull;".equals(u.getDescriptor())) {
return v;
}
if (isAssignableFrom(t, u)) {
return v;
}
if (isAssignableFrom(u, t)) {
return w;
}
return new BasicValue(classHierarchy.getCommonSuperType(t, u));
}
}
return BasicValue.UNINITIALIZED_VALUE;
}
return v;
}
@Override
protected Class> getClass(Type t) {
throw new UnsupportedOperationException();
}
@Override
protected boolean isInterface(Type t) {
throw new UnsupportedOperationException();
}
@Override
protected Type getSuperClass(Type t) {
throw new UnsupportedOperationException();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy