use of java.lang.reflect.Array in project lucene-solr by apache.
the class RamUsageTester method measureObjectSize.
/*
* Non-recursive version of object descend. This consumes more memory than recursive in-depth
* traversal but prevents stack overflows on long chains of objects
* or complex graphs (a max. recursion depth on my machine was ~5000 objects linked in a chain
* so not too much).
*/
private static long measureObjectSize(Object root, Accumulator accumulator) {
// Objects seen so far.
final Set<Object> seen = Collections.newSetFromMap(new IdentityHashMap<Object, Boolean>());
// Class cache with reference Field and precalculated shallow size.
final IdentityHashMap<Class<?>, ClassCache> classCache = new IdentityHashMap<>();
// Stack of objects pending traversal. Recursion caused stack overflows.
final ArrayList<Object> stack = new ArrayList<>();
stack.add(root);
long totalSize = 0;
while (!stack.isEmpty()) {
final Object ob = stack.remove(stack.size() - 1);
if (ob == null || seen.contains(ob)) {
continue;
}
seen.add(ob);
final Class<?> obClazz = ob.getClass();
assert obClazz != null : "jvm bug detected (Object.getClass() == null). please report this to your vendor";
if (obClazz.isArray()) {
/*
* Consider an array, possibly of primitive types. Push any of its references to
* the processing stack and accumulate this array's shallow size.
*/
final long shallowSize = RamUsageEstimator.shallowSizeOf(ob);
final int len = Array.getLength(ob);
final List<Object> values;
Class<?> componentClazz = obClazz.getComponentType();
if (componentClazz.isPrimitive()) {
values = Collections.emptyList();
} else {
values = new AbstractList<Object>() {
@Override
public Object get(int index) {
return Array.get(ob, index);
}
@Override
public int size() {
return len;
}
};
}
totalSize += accumulator.accumulateArray(ob, shallowSize, values, stack);
} else {
/*
* Consider an object. Push any references it has to the processing stack
* and accumulate this object's shallow size.
*/
try {
ClassCache cachedInfo = classCache.get(obClazz);
if (cachedInfo == null) {
classCache.put(obClazz, cachedInfo = createCacheEntry(obClazz));
}
boolean needsReflection = true;
if (Constants.JRE_IS_MINIMUM_JAVA9 && obClazz.getName().startsWith("java.")) {
// Java 9: Best guess for some known types, as we cannot precisely look into runtime classes:
final ToLongFunction<Object> func = SIMPLE_TYPES.get(obClazz);
if (func != null) {
// some simple type like String where the size is easy to get from public properties
totalSize += accumulator.accumulateObject(ob, cachedInfo.alignedShallowInstanceSize + func.applyAsLong(ob), Collections.emptyMap(), stack);
needsReflection = false;
} else if (ob instanceof Iterable) {
final List<Object> values = StreamSupport.stream(((Iterable<?>) ob).spliterator(), false).collect(Collectors.toList());
totalSize += accumulator.accumulateArray(ob, cachedInfo.alignedShallowInstanceSize + RamUsageEstimator.NUM_BYTES_ARRAY_HEADER, values, stack);
needsReflection = false;
} else if (ob instanceof Map) {
final List<Object> values = ((Map<?, ?>) ob).entrySet().stream().flatMap(e -> Stream.of(e.getKey(), e.getValue())).collect(Collectors.toList());
totalSize += accumulator.accumulateArray(ob, cachedInfo.alignedShallowInstanceSize + RamUsageEstimator.NUM_BYTES_ARRAY_HEADER, values, stack);
totalSize += RamUsageEstimator.NUM_BYTES_ARRAY_HEADER;
needsReflection = false;
}
}
if (needsReflection) {
final Map<Field, Object> fieldValues = new HashMap<>();
for (Field f : cachedInfo.referenceFields) {
fieldValues.put(f, f.get(ob));
}
totalSize += accumulator.accumulateObject(ob, cachedInfo.alignedShallowInstanceSize, fieldValues, stack);
}
} catch (IllegalAccessException e) {
// this should never happen as we enabled setAccessible().
throw new RuntimeException("Reflective field access failed?", e);
}
}
}
// Help the GC (?).
seen.clear();
stack.clear();
classCache.clear();
return totalSize;
}
use of java.lang.reflect.Array in project intellij-community by JetBrains.
the class Test method counter.
private long counter(Class<? extends Array> list) {
long count = 0L;
for (Iterator<? extends Array> it = stream(list).iterator(); it.hasNext(); ) {
Array array = it.next();
count++;
}
return count;
}
use of java.lang.reflect.Array in project groovity by disney.
the class GroovityObjectConverter method convert.
@SuppressWarnings({ "unchecked", "rawtypes" })
public static Object convert(Object in, Type type) {
if (in == null) {
return null;
}
Class<?> out;
Type[] typeArguments = null;
if (type instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) type;
out = (Class<?>) pt.getRawType();
typeArguments = pt.getActualTypeArguments();
} else {
out = (Class<?>) type;
}
if (out.equals(Object.class)) {
// special case, no conversion at all
return in;
}
if (type.equals(in.getClass())) {
return in;
}
if (typeArguments == null && out.isAssignableFrom(in.getClass())) {
return in;
}
if (in.getClass().isArray()) {
return convertIterable(new ArrayIterable(in), out, typeArguments);
}
if (List.class.isAssignableFrom(in.getClass())) {
List inList = (List) in;
return convertIterable(inList, out, typeArguments);
}
if (out.equals(String.class)) {
return in.toString();
}
if (out.isArray()) {
Object val = convert(in, out.getComponentType());
if (val != null) {
// if we're expecting an array back but the input is not an array, let's wrap it
Object[] ra = (Object[]) Array.newInstance(out.getComponentType(), 1);
ra[0] = val;
return ra;
}
return Array.newInstance(out.getComponentType(), 0);
}
if (out.isEnum()) {
Enum val = Enum.valueOf((Class<Enum>) out, in.toString());
return val;
}
if (!Number.class.isAssignableFrom(in.getClass())) {
if (Number.class.isAssignableFrom(out)) {
String ps = getParseable(in);
if (ps == null) {
return null;
}
// groovy can only convert single digit number strings for some odd reason, so we have to roll our own
if (Integer.class.isAssignableFrom(out)) {
return Integer.parseInt(ps);
}
if (Long.class.isAssignableFrom(out)) {
return Long.parseLong(ps);
}
if (Float.class.isAssignableFrom(out)) {
return Float.parseFloat(ps);
}
if (Double.class.isAssignableFrom(out)) {
return Double.parseDouble(ps);
}
}
if (out.isPrimitive()) {
String ps = getParseable(in);
if (ps == null) {
return null;
}
if (out.equals(Integer.TYPE)) {
return Integer.parseInt(ps);
}
if (out.equals(Long.TYPE)) {
return Long.parseLong(ps);
}
if (out.equals(Float.TYPE)) {
return Float.parseFloat(ps);
}
if (out.equals(Double.TYPE)) {
return Double.parseDouble(ps);
}
}
}
if (Boolean.class.equals(out) || out == Boolean.TYPE) {
Class ic = in.getClass();
if (!Boolean.class.equals(ic) && ic != Boolean.TYPE) {
String ps = getParseable(in);
if (ps != null) {
return Boolean.parseBoolean(ps);
}
}
}
if (Map.class.isAssignableFrom(out)) {
Map<Object, Object> result = null;
if (!out.isInterface()) {
try {
result = (Map<Object, Object>) out.newInstance();
} catch (Exception e) {
}
}
if (result == null) {
result = new LinkedHashMap<>();
}
Type kType;
Type vType;
if (typeArguments != null) {
kType = typeArguments[0];
vType = typeArguments[1];
} else {
kType = Object.class;
vType = Object.class;
}
Map<Object, Object> finalResult = result;
ModelConsumer consumer = (k, v) -> {
finalResult.put(convert(k, kType), convert(v, vType));
};
consume(in, consumer);
return finalResult;
}
// TODO special handling for string inputs, look for string-based constructors
if (!out.isPrimitive() && !out.isInterface()) {
try {
Constructor<?> c = out.getConstructor();
Object o = c.newInstance();
if (o instanceof Model) {
consume(in, ((Model) o)::put);
} else {
consume(in, (k, v) -> {
Model.put(o, k, v);
});
}
// System.out.println("USED MODEL TO CONVERT "+in.getClass().getName()+" to "+out.getName());
return o;
} catch (Exception e) {
// e.printStackTrace();
}
}
return DefaultTypeTransformation.castToType(in, out);
}
use of java.lang.reflect.Array in project raml-module-builder by folio-org.
the class AnnotationGrabber method generateMappings.
// ^http.*?//.*?/apis/patrons/.*?/fines/.*
// ^http.*?\/\/.*?\/apis\/patrons\/?(.+?)*
// ^http.*?\/\/.*?\/apis\/([^\/]+)\/([^\/]+)(\?.*)
public static JsonObject generateMappings() throws Exception {
/* this class is one of the drivers for the client generation
* check if the plugin set the system property in the pom and only if
* so generate */
String clientGen = System.getProperty("client.generate");
String modDescr = System.getProperty("modDescrptor.generate");
if (clientGen != null) {
generateClient = true;
}
if ("true".equals(modDescr)) {
generateModDescrptor = true;
}
JsonObject globalClassMapping = new JsonObject();
// get classes in generated package
ClassPath classPath = ClassPath.from(Thread.currentThread().getContextClassLoader());
ImmutableSet<ClassPath.ClassInfo> classes = classPath.getTopLevelClasses(RTFConsts.INTERFACE_PACKAGE);
Collection<Object> classNames = Collections2.transform(classes, new Function<ClassPath.ClassInfo, Object>() {
@Override
public Object apply(ClassPath.ClassInfo input) {
log.info("Mapping functions in " + input.getName() + " class to appropriate urls");
// not needed - dont need transform function,
return input.getName();
// remove
}
});
// loop over all the classes from the package
classNames.forEach(val -> {
try {
ClientGenerator cGen = new ClientGenerator();
// ----------------- class level annotations -----------------------//
// -----------------------------------------------------------------//
// will contain all mappings for a specific class in the package
JsonObject classSpecificMapping = new JsonObject();
// get annotations via reflection for a class
Annotation[] annotations = Class.forName(val.toString()).getAnnotations();
// create an entry for the class name = ex. "class":"com.sling.rest.jaxrs.resource.BibResource"
classSpecificMapping.put(CLASS_NAME, val.toString());
classSpecificMapping.put(INTERFACE_NAME, val.toString());
// needed info - these are class level annotation - not method level
for (int i = 0; i < annotations.length; i++) {
// get the annotation type - example in jersey would we javax.ws.rs.Path
Class<? extends Annotation> type = annotations[i].annotationType();
// function
for (Method method : type.getDeclaredMethods()) {
Object value = method.invoke(annotations[i], (Object[]) null);
if (type.isAssignableFrom(Path.class)) {
classSpecificMapping.put(CLASS_URL, "^/" + value);
if (generateClient) {
cGen.generateClassMeta(val.toString(), value);
}
if (generateModDescrptor && classSpecificMapping.getString(CLASS_URL) != null) {
String url = classSpecificMapping.getString(CLASS_URL).substring(2);
if (!url.contains("rmbtests")) {
MDGenerator.ProvidesEntry pe = MDGenerator.INSTANCE.new ProvidesEntry();
if (url.contains("_/tenant")) {
url = "_tenant";
}
pe.setId(url);
MDGenerator.INSTANCE.addProvidesEntry(pe);
}
}
}
}
}
// ----------------- method level annotations ------------ //
// ------------------------------------------------------- //
/**
* will be used only if ModuleDescriptor generation is turned on
* maps all http verbs to a single url
*/
mdUrl2Verbs = new HashMap<>();
JsonArray methodsInAPath;
// iterate over all functions in the class
Method[] methods = Class.forName(val.toString()).getMethods();
for (int i = 0; i < methods.length; i++) {
JsonObject methodObj = new JsonObject();
JsonObject params = getParameterNames(methods[i]);
// get annotations on the method and add all info per method to its
// own methodObj
Annotation[] methodAn = methods[i].getAnnotations();
// System.out.println(methods[i].getName());
// put the name of the function
methodObj.put(FUNCTION_NAME, methods[i].getName());
methodObj.put(METHOD_PARAMS, params);
for (int j = 0; j < methodAn.length; j++) {
Class<? extends Annotation> type = methodAn[j].annotationType();
// System.out.println("Values of " + type.getName());
if (RTFConsts.POSSIBLE_HTTP_METHOD.contains(type.getName())) {
// put the method - get or post, etc..
methodObj.put(HTTP_METHOD, type.getName());
}
boolean replaceAccept = false;
if (type.isAssignableFrom(Produces.class)) {
// this is the accept header, right now can not send */*
// so if accept header equals any/ - change this to */*
replaceAccept = true;
}
for (Method method : type.getDeclaredMethods()) {
Object value = method.invoke(methodAn[j], (Object[]) null);
if (value.getClass().isArray()) {
List<Object> retList = new ArrayList<>();
for (int k = 0; k < Array.getLength(value); k++) {
if (replaceAccept) {
// replace any/any with */* to allow declaring accpet */* which causes compilation issues
// when declared in raml. so declare any/any in raml instead and replaced here
retList.add(((String) Array.get(value, k)).replaceAll("any/any", ""));
} else {
retList.add(Array.get(value, k));
}
}
// put generically things like consumes, produces as arrays
// since they can have multi values
methodObj.put(type.getName(), retList);
} else {
if (type.isAssignableFrom(Path.class)) {
String path = classSpecificMapping.getString(CLASS_URL) + URL_PATH_DELIMITER + value;
String regexPath = getRegexForPath(path);
// put path to function
methodObj.put(METHOD_URL, path);
// put regex path to function
methodObj.put(REGEX_URL, regexPath);
}
// System.out.println(" " + method.getName() + ": " + value.toString());
}
}
}
if (generateClient) {
cGen.generateMethodMeta(methodObj.getString(FUNCTION_NAME), methodObj.getJsonObject(METHOD_PARAMS), methodObj.getString(METHOD_URL), methodObj.getString(HTTP_METHOD), methodObj.getJsonArray(CONSUMES), methodObj.getJsonArray(PRODUCES));
}
// class
if (methodObj.getString(METHOD_URL) == null) {
methodObj.put(METHOD_URL, classSpecificMapping.getString(CLASS_URL));
methodObj.put(REGEX_URL, getRegexForPath(classSpecificMapping.getString(CLASS_URL)));
}
if (generateModDescrptor) {
String verb = methodObj.getString(HTTP_METHOD);
verb = verb.substring(verb.lastIndexOf(".") + 1);
String rootURL4Service = classSpecificMapping.getString(CLASS_URL).substring(1);
/*if(mdUrl2Verbs.get(path.substring(1)) != null){
mdUrl2Verbs.get(path.substring(1)).add(verb);
} else {
mdUrl2Verbs.put(path.substring(1), new JsonArray());
mdUrl2Verbs.get(path.substring(1)).add(verb);
}*/
if (mdUrl2Verbs.get(rootURL4Service) != null) {
mdUrl2Verbs.get(rootURL4Service).add(verb);
} else {
mdUrl2Verbs.put(rootURL4Service, new HashSet<String>());
mdUrl2Verbs.get(rootURL4Service).add(verb);
}
}
// this is the key - the regex path is the key to the functions
// represented by this url
// an array of functions which answer to this url (with get, delete,
// post, etc... methods)
methodsInAPath = classSpecificMapping.getJsonArray(methodObj.getString(REGEX_URL));
if (methodsInAPath == null) {
methodsInAPath = new JsonArray();
classSpecificMapping.put(methodObj.getString(REGEX_URL), methodsInAPath);
}
methodsInAPath.add(methodObj);
}
// System.out.println( val.toString() );
globalClassMapping.put(classSpecificMapping.getString(CLASS_URL), classSpecificMapping);
if (generateClient) {
cGen.generateClass(classSpecificMapping);
}
if (generateModDescrptor) {
BiConsumer<String, Set<String>> biConsumer = (key, value) -> {
if (!key.contains("_/tenant") && !key.contains("rmbtests")) {
MDGenerator.RoutingEntry re = MDGenerator.INSTANCE.new RoutingEntry();
JsonArray ja = new JsonArray();
value.forEach(verb -> {
ja.add(verb);
});
re.setMethods(ja);
re.setEntryPath(key);
re.setLevel("30");
re.setType("request-response");
MDGenerator.INSTANCE.addRoutingEntry(re);
}
};
mdUrl2Verbs.forEach(biConsumer);
MDGenerator.INSTANCE.generateMD();
// this is needed when the MDGenerator is used to generate
// partial MDs in submodules. the system variable is maintained
// across the sub module builds and if not reset will generate a
// partial MD for all sub modules
System.setProperty("modDescrptor.generate", "false");
}
} catch (Exception e) {
log.error(e.getMessage(), e);
}
});
// writeMappings(globalClassMapping);
return globalClassMapping;
}
use of java.lang.reflect.Array in project Bytecoder by mirkosertic.
the class NaiveProgramGenerator method initializeBlockWith.
private void initializeBlockWith(BytecodeClass aOwningClass, BytecodeMethod aMethod, RegionNode aTargetBlock, Function<BytecodeOpcodeAddress, BytecodeBasicBlock> aBlocksByAddress, ParsingHelper aHelper) {
// Finally we can start to parse the program
BytecodeBasicBlock theBytecodeBlock = aBlocksByAddress.apply(aTargetBlock.getStartAddress());
for (BytecodeInstruction theInstruction : theBytecodeBlock.getInstructions()) {
if (theInstruction instanceof BytecodeInstructionNOP) {
BytecodeInstructionNOP theINS = (BytecodeInstructionNOP) theInstruction;
// Completely ignored
} else if (theInstruction instanceof BytecodeInstructionMONITORENTER) {
BytecodeInstructionMONITORENTER theINS = (BytecodeInstructionMONITORENTER) theInstruction;
// Pop the reference for the lock from the stack
aHelper.pop();
// Completely ignored
} else if (theInstruction instanceof BytecodeInstructionMONITOREXIT) {
BytecodeInstructionMONITOREXIT theINS = (BytecodeInstructionMONITOREXIT) theInstruction;
// Pop the reference for the lock from the stack
aHelper.pop();
// Completely ignored
} else if (theInstruction instanceof BytecodeInstructionCHECKCAST) {
BytecodeInstructionCHECKCAST theINS = (BytecodeInstructionCHECKCAST) theInstruction;
Value theValue = aHelper.peek();
aTargetBlock.getExpressions().add(new CheckCastExpression(theValue, theINS.getTypeCheck()));
} else if (theInstruction instanceof BytecodeInstructionPOP) {
BytecodeInstructionPOP theINS = (BytecodeInstructionPOP) theInstruction;
aHelper.pop();
} else if (theInstruction instanceof BytecodeInstructionPOP2) {
BytecodeInstructionPOP2 theINS = (BytecodeInstructionPOP2) theInstruction;
Value theValue = aHelper.pop();
switch(theValue.resolveType().resolve()) {
case LONG:
break;
case DOUBLE:
break;
default:
aHelper.pop();
}
} else if (theInstruction instanceof BytecodeInstructionDUP) {
BytecodeInstructionDUP theINS = (BytecodeInstructionDUP) theInstruction;
Value theValue = aHelper.peek();
aHelper.push(theValue);
} else if (theInstruction instanceof BytecodeInstructionDUP2) {
BytecodeInstructionDUP2 theINS = (BytecodeInstructionDUP2) theInstruction;
Value theValue1 = aHelper.pop();
if (theValue1.resolveType().resolve() == TypeRef.Native.LONG || theValue1.resolveType().resolve() == TypeRef.Native.DOUBLE) {
// Category 2
aHelper.push(theValue1);
aHelper.push(theValue1);
} else {
// Category 1
Value theValue2 = aHelper.pop();
aHelper.push(theValue2);
aHelper.push(theValue1);
aHelper.push(theValue2);
aHelper.push(theValue1);
}
} else if (theInstruction instanceof BytecodeInstructionDUP2X1) {
BytecodeInstructionDUP2X1 theINS = (BytecodeInstructionDUP2X1) theInstruction;
Value theValue1 = aHelper.pop();
if (theValue1.resolveType().resolve() == TypeRef.Native.LONG || theValue1.resolveType().resolve() == TypeRef.Native.DOUBLE) {
Value theValue2 = aHelper.pop();
aHelper.push(theValue1);
aHelper.push(theValue2);
aHelper.push(theValue2);
} else {
Value theValue2 = aHelper.pop();
Value theValue3 = aHelper.pop();
aHelper.push(theValue2);
aHelper.push(theValue1);
aHelper.push(theValue3);
aHelper.push(theValue2);
aHelper.push(theValue2);
}
} else if (theInstruction instanceof BytecodeInstructionDUPX1) {
BytecodeInstructionDUPX1 theINS = (BytecodeInstructionDUPX1) theInstruction;
Value theValue1 = aHelper.pop();
Value theValue2 = aHelper.pop();
aHelper.push(theValue1);
aHelper.push(theValue2);
aHelper.push(theValue1);
} else if (theInstruction instanceof BytecodeInstructionDUPX2) {
BytecodeInstructionDUPX2 theINS = (BytecodeInstructionDUPX2) theInstruction;
Value theValue1 = aHelper.pop();
Value theValue2 = aHelper.pop();
if (theValue2.resolveType().resolve() == TypeRef.Native.LONG || theValue2.resolveType().resolve() == TypeRef.Native.DOUBLE) {
// Form 2
aHelper.push(theValue1);
aHelper.push(theValue2);
aHelper.push(theValue1);
} else {
// Form 1
Value theValue3 = aHelper.pop();
aHelper.push(theValue1);
aHelper.push(theValue3);
aHelper.push(theValue2);
aHelper.push(theValue1);
}
} else if (theInstruction instanceof BytecodeInstructionGETSTATIC) {
BytecodeInstructionGETSTATIC theINS = (BytecodeInstructionGETSTATIC) theInstruction;
GetStaticExpression theValue = new GetStaticExpression(theINS.getConstant());
Variable theVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getConstant().getNameAndTypeIndex().getNameAndType().getDescriptorIndex().fieldType()), theValue);
aHelper.push(theVariable);
} else if (theInstruction instanceof BytecodeInstructionASTORE) {
BytecodeInstructionASTORE theINS = (BytecodeInstructionASTORE) theInstruction;
Value theValue = aHelper.pop();
aHelper.setLocalVariable(theInstruction.getOpcodeAddress(), theINS.getVariableIndex(), theValue);
} else if (theInstruction instanceof BytecodeInstructionGenericSTORE) {
BytecodeInstructionGenericSTORE theINS = (BytecodeInstructionGenericSTORE) theInstruction;
Value theValue = aHelper.pop();
Variable theOtherVariable = aTargetBlock.newVariable(theValue.resolveType().resolve(), theValue);
aHelper.setLocalVariable(theInstruction.getOpcodeAddress(), theINS.getVariableIndex(), theOtherVariable);
} else if (theInstruction instanceof BytecodeInstructionObjectArrayLOAD) {
BytecodeInstructionObjectArrayLOAD theINS = (BytecodeInstructionObjectArrayLOAD) theInstruction;
Value theIndex = aHelper.pop();
Value theTarget = aHelper.pop();
TypeRef theType = theTarget.resolveType();
if (theType instanceof TypeRef.ArrayTypeRef) {
TypeRef.ArrayTypeRef theArrayTypeRef = (TypeRef.ArrayTypeRef) theTarget.resolveType();
Variable theVariable = aTargetBlock.newVariable(TypeRef.toType(theArrayTypeRef.arrayType()), new ArrayEntryExpression(TypeRef.Native.REFERENCE, theTarget, theIndex));
aHelper.push(theVariable);
} else {
Variable theVariable = aTargetBlock.newVariable(TypeRef.Native.REFERENCE, new ArrayEntryExpression(TypeRef.Native.REFERENCE, theTarget, theIndex));
aHelper.push(theVariable);
}
} else if (theInstruction instanceof BytecodeInstructionGenericArrayLOAD) {
BytecodeInstructionGenericArrayLOAD theINS = (BytecodeInstructionGenericArrayLOAD) theInstruction;
Value theIndex = aHelper.pop();
Value theTarget = aHelper.pop();
Variable theVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getType()), new ArrayEntryExpression(TypeRef.toType(theINS.getType()), theTarget, theIndex));
aHelper.push(theVariable);
} else if (theInstruction instanceof BytecodeInstructionGenericArraySTORE) {
BytecodeInstructionGenericArraySTORE theINS = (BytecodeInstructionGenericArraySTORE) theInstruction;
Value theValue = aHelper.pop();
Value theIndex = aHelper.pop();
Value theTarget = aHelper.pop();
aTargetBlock.getExpressions().add(new ArrayStoreExpression(TypeRef.toType(theINS.getType()), theTarget, theIndex, theValue));
} else if (theInstruction instanceof BytecodeInstructionObjectArraySTORE) {
BytecodeInstructionObjectArraySTORE theINS = (BytecodeInstructionObjectArraySTORE) theInstruction;
Value theValue = aHelper.pop();
Value theIndex = aHelper.pop();
Value theTarget = aHelper.pop();
aTargetBlock.getExpressions().add(new ArrayStoreExpression(TypeRef.Native.REFERENCE, theTarget, theIndex, theValue));
} else if (theInstruction instanceof BytecodeInstructionACONSTNULL) {
BytecodeInstructionACONSTNULL theINS = (BytecodeInstructionACONSTNULL) theInstruction;
aHelper.push(new NullValue());
} else if (theInstruction instanceof BytecodeInstructionPUTFIELD) {
BytecodeInstructionPUTFIELD theINS = (BytecodeInstructionPUTFIELD) theInstruction;
Value theValue = aHelper.pop();
Value theTarget = aHelper.pop();
aTargetBlock.getExpressions().add(new PutFieldExpression(theINS.getFieldRefConstant(), theTarget, theValue));
} else if (theInstruction instanceof BytecodeInstructionGETFIELD) {
BytecodeInstructionGETFIELD theINS = (BytecodeInstructionGETFIELD) theInstruction;
Value theTarget = aHelper.pop();
Variable theVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getFieldRefConstant().getNameAndTypeIndex().getNameAndType().getDescriptorIndex().fieldType()), new GetFieldExpression(theINS.getFieldRefConstant(), theTarget));
aHelper.push(theVariable);
} else if (theInstruction instanceof BytecodeInstructionPUTSTATIC) {
BytecodeInstructionPUTSTATIC theINS = (BytecodeInstructionPUTSTATIC) theInstruction;
Value theValue = aHelper.pop();
aTargetBlock.getExpressions().add(new PutStaticExpression(theINS.getConstant(), theValue));
} else if (theInstruction instanceof BytecodeInstructionGenericLDC) {
BytecodeInstructionGenericLDC theINS = (BytecodeInstructionGenericLDC) theInstruction;
BytecodeConstant theConstant = theINS.constant();
if (theConstant instanceof BytecodeDoubleConstant) {
BytecodeDoubleConstant theC = (BytecodeDoubleConstant) theConstant;
aHelper.push(new DoubleValue(theC.getDoubleValue()));
} else if (theConstant instanceof BytecodeLongConstant) {
BytecodeLongConstant theC = (BytecodeLongConstant) theConstant;
aHelper.push(new LongValue(theC.getLongValue()));
} else if (theConstant instanceof BytecodeFloatConstant) {
BytecodeFloatConstant theC = (BytecodeFloatConstant) theConstant;
aHelper.push(new FloatValue(theC.getFloatValue()));
} else if (theConstant instanceof BytecodeIntegerConstant) {
BytecodeIntegerConstant theC = (BytecodeIntegerConstant) theConstant;
aHelper.push(new IntegerValue(theC.getIntegerValue()));
} else if (theConstant instanceof BytecodeStringConstant) {
BytecodeStringConstant theC = (BytecodeStringConstant) theConstant;
Variable theVariable = aTargetBlock.newVariable(TypeRef.toType(BytecodeObjectTypeRef.fromRuntimeClass(String.class)), new StringValue(theC.getValue().stringValue()));
aHelper.push(theVariable);
} else if (theConstant instanceof BytecodeClassinfoConstant) {
BytecodeClassinfoConstant theC = (BytecodeClassinfoConstant) theConstant;
BytecodeUtf8Constant theUTF8 = theC.getConstant();
if (theUTF8.stringValue().startsWith("[")) {
aHelper.push(new ClassReferenceValue(BytecodeObjectTypeRef.fromRuntimeClass(Array.class)));
} else {
aHelper.push(new ClassReferenceValue(BytecodeObjectTypeRef.fromUtf8Constant(theC.getConstant())));
}
} else {
throw new IllegalArgumentException("Unsupported constant type : " + theConstant);
}
} else if (theInstruction instanceof BytecodeInstructionBIPUSH) {
BytecodeInstructionBIPUSH theINS = (BytecodeInstructionBIPUSH) theInstruction;
aHelper.push(new IntegerValue(theINS.getByteValue()));
} else if (theInstruction instanceof BytecodeInstructionSIPUSH) {
BytecodeInstructionSIPUSH theINS = (BytecodeInstructionSIPUSH) theInstruction;
aHelper.push(new IntegerValue(theINS.getShortValue()));
} else if (theInstruction instanceof BytecodeInstructionICONST) {
BytecodeInstructionICONST theINS = (BytecodeInstructionICONST) theInstruction;
aHelper.push(new IntegerValue(theINS.getIntConst()));
} else if (theInstruction instanceof BytecodeInstructionFCONST) {
BytecodeInstructionFCONST theINS = (BytecodeInstructionFCONST) theInstruction;
aHelper.push(new FloatValue(theINS.getFloatValue()));
} else if (theInstruction instanceof BytecodeInstructionDCONST) {
BytecodeInstructionDCONST theINS = (BytecodeInstructionDCONST) theInstruction;
aHelper.push(new DoubleValue(theINS.getDoubleConst()));
} else if (theInstruction instanceof BytecodeInstructionLCONST) {
BytecodeInstructionLCONST theINS = (BytecodeInstructionLCONST) theInstruction;
aHelper.push(new LongValue(theINS.getLongConst()));
} else if (theInstruction instanceof BytecodeInstructionGenericNEG) {
BytecodeInstructionGenericNEG theINS = (BytecodeInstructionGenericNEG) theInstruction;
Value theValue = aHelper.pop();
Variable theNegatedValue = aTargetBlock.newVariable(theValue.resolveType(), new NegatedExpression(theValue));
aHelper.push(theNegatedValue);
} else if (theInstruction instanceof BytecodeInstructionARRAYLENGTH) {
BytecodeInstructionARRAYLENGTH theINS = (BytecodeInstructionARRAYLENGTH) theInstruction;
Value theValue = aHelper.pop();
Variable theNegatedValue = aTargetBlock.newVariable(TypeRef.Native.INT, new ArrayLengthExpression(theValue));
aHelper.push(theNegatedValue);
} else if (theInstruction instanceof BytecodeInstructionGenericLOAD) {
BytecodeInstructionGenericLOAD theINS = (BytecodeInstructionGenericLOAD) theInstruction;
Value theValue = aHelper.getLocalVariable(theINS.getVariableIndex());
aHelper.push(theValue);
} else if (theInstruction instanceof BytecodeInstructionALOAD) {
BytecodeInstructionALOAD theINS = (BytecodeInstructionALOAD) theInstruction;
Value theValue = aHelper.getLocalVariable(theINS.getVariableIndex());
aHelper.push(theValue);
} else if (theInstruction instanceof BytecodeInstructionGenericCMP) {
BytecodeInstructionGenericCMP theINS = (BytecodeInstructionGenericCMP) theInstruction;
Value theValue2 = aHelper.pop();
Value theValue1 = aHelper.pop();
Variable theNewVariable = aTargetBlock.newVariable(TypeRef.Native.INT, new CompareExpression(theValue1, theValue2));
aHelper.push(theNewVariable);
} else if (theInstruction instanceof BytecodeInstructionLCMP) {
BytecodeInstructionLCMP theINS = (BytecodeInstructionLCMP) theInstruction;
Value theValue2 = aHelper.pop();
Value theValue1 = aHelper.pop();
Variable theNewVariable = aTargetBlock.newVariable(TypeRef.Native.INT, new CompareExpression(theValue1, theValue2));
aHelper.push(theNewVariable);
} else if (theInstruction instanceof BytecodeInstructionIINC) {
BytecodeInstructionIINC theINS = (BytecodeInstructionIINC) theInstruction;
Value theValueToIncrement = aHelper.getLocalVariable(theINS.getIndex());
Value theNewVariable = aTargetBlock.newVariable(TypeRef.Native.INT, new BinaryExpression(TypeRef.Native.INT, theValueToIncrement, BinaryExpression.Operator.ADD, new IntegerValue(theINS.getConstant())));
aHelper.setLocalVariable(theInstruction.getOpcodeAddress(), theINS.getIndex(), theNewVariable);
} else if (theInstruction instanceof BytecodeInstructionGenericREM) {
BytecodeInstructionGenericREM theINS = (BytecodeInstructionGenericREM) theInstruction;
Value theValue2 = aHelper.pop();
Value theValue1 = aHelper.pop();
Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getType()), new BinaryExpression(TypeRef.toType(theINS.getType()), theValue1, BinaryExpression.Operator.REMAINDER, theValue2));
aHelper.push(theNewVariable);
} else if (theInstruction instanceof BytecodeInstructionGenericADD) {
BytecodeInstructionGenericADD theINS = (BytecodeInstructionGenericADD) theInstruction;
Value theValue2 = aHelper.pop();
Value theValue1 = aHelper.pop();
Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getType()), new BinaryExpression(TypeRef.toType(theINS.getType()), theValue1, BinaryExpression.Operator.ADD, theValue2));
aHelper.push(theNewVariable);
} else if (theInstruction instanceof BytecodeInstructionGenericDIV) {
BytecodeInstructionGenericDIV theINS = (BytecodeInstructionGenericDIV) theInstruction;
Value theValue2 = aHelper.pop();
Value theValue1 = aHelper.pop();
Variable theNewVariable;
Value theDivValue = new BinaryExpression(TypeRef.toType(theINS.getType()), theValue1, BinaryExpression.Operator.DIV, theValue2);
switch(theINS.getType()) {
case FLOAT:
theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getType()), theDivValue);
break;
case DOUBLE:
theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getType()), theDivValue);
break;
default:
theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getType()), new FloorExpression(theDivValue, TypeRef.toType(theINS.getType())));
break;
}
aHelper.push(theNewVariable);
} else if (theInstruction instanceof BytecodeInstructionGenericMUL) {
BytecodeInstructionGenericMUL theINS = (BytecodeInstructionGenericMUL) theInstruction;
Value theValue2 = aHelper.pop();
Value theValue1 = aHelper.pop();
Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getType()), new BinaryExpression(TypeRef.toType(theINS.getType()), theValue1, BinaryExpression.Operator.MUL, theValue2));
aHelper.push(theNewVariable);
} else if (theInstruction instanceof BytecodeInstructionGenericSUB) {
BytecodeInstructionGenericSUB theINS = (BytecodeInstructionGenericSUB) theInstruction;
Value theValue2 = aHelper.pop();
Value theValue1 = aHelper.pop();
Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getType()), new BinaryExpression(TypeRef.toType(theINS.getType()), theValue1, BinaryExpression.Operator.SUB, theValue2));
aHelper.push(theNewVariable);
} else if (theInstruction instanceof BytecodeInstructionGenericXOR) {
BytecodeInstructionGenericXOR theINS = (BytecodeInstructionGenericXOR) theInstruction;
Value theValue2 = aHelper.pop();
Value theValue1 = aHelper.pop();
Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getType()), new BinaryExpression(TypeRef.toType(theINS.getType()), theValue1, BinaryExpression.Operator.BINARYXOR, theValue2));
aHelper.push(theNewVariable);
} else if (theInstruction instanceof BytecodeInstructionGenericOR) {
BytecodeInstructionGenericOR theINS = (BytecodeInstructionGenericOR) theInstruction;
Value theValue2 = aHelper.pop();
Value theValue1 = aHelper.pop();
Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getType()), new BinaryExpression(TypeRef.toType(theINS.getType()), theValue1, BinaryExpression.Operator.BINARYOR, theValue2));
aHelper.push(theNewVariable);
} else if (theInstruction instanceof BytecodeInstructionGenericAND) {
BytecodeInstructionGenericAND theINS = (BytecodeInstructionGenericAND) theInstruction;
Value theValue2 = aHelper.pop();
Value theValue1 = aHelper.pop();
Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getType()), new BinaryExpression(TypeRef.toType(theINS.getType()), theValue1, BinaryExpression.Operator.BINARYAND, theValue2));
aHelper.push(theNewVariable);
} else if (theInstruction instanceof BytecodeInstructionGenericSHL) {
BytecodeInstructionGenericSHL theINS = (BytecodeInstructionGenericSHL) theInstruction;
Value theValue2 = aHelper.pop();
Value theValue1 = aHelper.pop();
Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getType()), new BinaryExpression(TypeRef.toType(theINS.getType()), theValue1, BinaryExpression.Operator.BINARYSHIFTLEFT, theValue2));
aHelper.push(theNewVariable);
} else if (theInstruction instanceof BytecodeInstructionGenericSHR) {
BytecodeInstructionGenericSHR theINS = (BytecodeInstructionGenericSHR) theInstruction;
Value theValue2 = aHelper.pop();
Value theValue1 = aHelper.pop();
Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getType()), new BinaryExpression(TypeRef.toType(theINS.getType()), theValue1, BinaryExpression.Operator.BINARYSHIFTRIGHT, theValue2));
aHelper.push(theNewVariable);
} else if (theInstruction instanceof BytecodeInstructionGenericUSHR) {
BytecodeInstructionGenericUSHR theINS = (BytecodeInstructionGenericUSHR) theInstruction;
Value theValue2 = aHelper.pop();
Value theValue1 = aHelper.pop();
Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getType()), new BinaryExpression(TypeRef.toType(theINS.getType()), theValue1, BinaryExpression.Operator.BINARYUNSIGNEDSHIFTRIGHT, theValue2));
aHelper.push(theNewVariable);
} else if (theInstruction instanceof BytecodeInstructionIFNULL) {
BytecodeInstructionIFNULL theINS = (BytecodeInstructionIFNULL) theInstruction;
Value theValue = aHelper.pop();
FixedBinaryExpression theBinaryValue = new FixedBinaryExpression(theValue, FixedBinaryExpression.Operator.ISNULL);
ExpressionList theExpressions = new ExpressionList();
theExpressions.add(new GotoExpression(theINS.getJumpTarget()));
aTargetBlock.getExpressions().add(new IFExpression(theINS.getOpcodeAddress(), theINS.getJumpTarget(), theBinaryValue, theExpressions));
} else if (theInstruction instanceof BytecodeInstructionIFNONNULL) {
BytecodeInstructionIFNONNULL theINS = (BytecodeInstructionIFNONNULL) theInstruction;
Value theValue = aHelper.pop();
FixedBinaryExpression theBinaryValue = new FixedBinaryExpression(theValue, FixedBinaryExpression.Operator.ISNONNULL);
ExpressionList theExpressions = new ExpressionList();
theExpressions.add(new GotoExpression(theINS.getJumpTarget()));
aTargetBlock.getExpressions().add(new IFExpression(theINS.getOpcodeAddress(), theINS.getJumpTarget(), theBinaryValue, theExpressions));
} else if (theInstruction instanceof BytecodeInstructionIFICMP) {
BytecodeInstructionIFICMP theINS = (BytecodeInstructionIFICMP) theInstruction;
Value theValue2 = aHelper.pop();
Value theValue1 = aHelper.pop();
BinaryExpression theBinaryValue;
switch(theINS.getType()) {
case lt:
theBinaryValue = new BinaryExpression(TypeRef.Native.BOOLEAN, theValue1, BinaryExpression.Operator.LESSTHAN, theValue2);
break;
case eq:
theBinaryValue = new BinaryExpression(TypeRef.Native.BOOLEAN, theValue1, BinaryExpression.Operator.EQUALS, theValue2);
break;
case gt:
theBinaryValue = new BinaryExpression(TypeRef.Native.BOOLEAN, theValue1, BinaryExpression.Operator.GREATERTHAN, theValue2);
break;
case ge:
theBinaryValue = new BinaryExpression(TypeRef.Native.BOOLEAN, theValue1, BinaryExpression.Operator.GREATEROREQUALS, theValue2);
break;
case le:
theBinaryValue = new BinaryExpression(TypeRef.Native.BOOLEAN, theValue1, BinaryExpression.Operator.LESSTHANOREQUALS, theValue2);
break;
case ne:
theBinaryValue = new BinaryExpression(TypeRef.Native.BOOLEAN, theValue1, BinaryExpression.Operator.NOTEQUALS, theValue2);
break;
default:
throw new IllegalStateException("Not supported operation : " + theINS.getType());
}
ExpressionList theExpressions = new ExpressionList();
theExpressions.add(new GotoExpression(theINS.getJumpTarget()));
aTargetBlock.getExpressions().add(new IFExpression(theINS.getOpcodeAddress(), theINS.getJumpTarget(), theBinaryValue, theExpressions));
} else if (theInstruction instanceof BytecodeInstructionIFACMP) {
BytecodeInstructionIFACMP theINS = (BytecodeInstructionIFACMP) theInstruction;
Value theValue2 = aHelper.pop();
Value theValue1 = aHelper.pop();
BinaryExpression theBinaryValue;
switch(theINS.getType()) {
case eq:
theBinaryValue = new BinaryExpression(TypeRef.Native.BOOLEAN, theValue1, BinaryExpression.Operator.EQUALS, theValue2);
break;
case ne:
theBinaryValue = new BinaryExpression(TypeRef.Native.BOOLEAN, theValue1, BinaryExpression.Operator.NOTEQUALS, theValue2);
break;
default:
throw new IllegalStateException("Not supported operation : " + theINS.getType());
}
ExpressionList theExpressions = new ExpressionList();
theExpressions.add(new GotoExpression(theINS.getJumpTarget()));
aTargetBlock.getExpressions().add(new IFExpression(theINS.getOpcodeAddress(), theINS.getJumpTarget(), theBinaryValue, theExpressions));
} else if (theInstruction instanceof BytecodeInstructionIFCOND) {
BytecodeInstructionIFCOND theINS = (BytecodeInstructionIFCOND) theInstruction;
Value theValue = aHelper.pop();
BinaryExpression theBinaryValue;
switch(theINS.getType()) {
case lt:
theBinaryValue = new BinaryExpression(TypeRef.Native.BOOLEAN, theValue, BinaryExpression.Operator.LESSTHAN, new IntegerValue(0));
break;
case eq:
theBinaryValue = new BinaryExpression(TypeRef.Native.BOOLEAN, theValue, BinaryExpression.Operator.EQUALS, new IntegerValue(0));
break;
case gt:
theBinaryValue = new BinaryExpression(TypeRef.Native.BOOLEAN, theValue, BinaryExpression.Operator.GREATERTHAN, new IntegerValue(0));
break;
case ge:
theBinaryValue = new BinaryExpression(TypeRef.Native.BOOLEAN, theValue, BinaryExpression.Operator.GREATEROREQUALS, new IntegerValue(0));
break;
case le:
theBinaryValue = new BinaryExpression(TypeRef.Native.BOOLEAN, theValue, BinaryExpression.Operator.LESSTHANOREQUALS, new IntegerValue(0));
break;
case ne:
theBinaryValue = new BinaryExpression(TypeRef.Native.BOOLEAN, theValue, BinaryExpression.Operator.NOTEQUALS, new IntegerValue(0));
break;
default:
throw new IllegalStateException("Not supported operation : " + theINS.getType());
}
ExpressionList theExpressions = new ExpressionList();
theExpressions.add(new GotoExpression(theINS.getJumpTarget()));
aTargetBlock.getExpressions().add(new IFExpression(theINS.getOpcodeAddress(), theINS.getJumpTarget(), theBinaryValue, theExpressions));
} else if (theInstruction instanceof BytecodeInstructionObjectRETURN) {
BytecodeInstructionObjectRETURN theINS = (BytecodeInstructionObjectRETURN) theInstruction;
Value theValue = aHelper.pop();
aTargetBlock.getExpressions().add(new ReturnValueExpression(theValue));
} else if (theInstruction instanceof BytecodeInstructionGenericRETURN) {
BytecodeInstructionGenericRETURN theINS = (BytecodeInstructionGenericRETURN) theInstruction;
Value theValue = aHelper.pop();
aTargetBlock.getExpressions().add(new ReturnValueExpression(theValue));
} else if (theInstruction instanceof BytecodeInstructionATHROW) {
BytecodeInstructionATHROW theINS = (BytecodeInstructionATHROW) theInstruction;
Value theValue = aHelper.pop();
aTargetBlock.getExpressions().add(new ThrowExpression(theValue));
} else if (theInstruction instanceof BytecodeInstructionRETURN) {
BytecodeInstructionRETURN theINS = (BytecodeInstructionRETURN) theInstruction;
aTargetBlock.getExpressions().add(new ReturnExpression());
} else if (theInstruction instanceof BytecodeInstructionNEW) {
BytecodeInstructionNEW theINS = (BytecodeInstructionNEW) theInstruction;
BytecodeClassinfoConstant theClassInfo = theINS.getClassInfoForObjectToCreate();
BytecodeObjectTypeRef theObjectType = BytecodeObjectTypeRef.fromUtf8Constant(theClassInfo.getConstant());
if (Objects.equals(theObjectType.name(), Address.class.getName())) {
// At this time the exact location is unknown, the value
// will be set at constructor invocation time
Variable theNewVariable = aTargetBlock.newVariable(TypeRef.Native.INT);
aHelper.push(theNewVariable);
} else {
if (Objects.equals(theObjectType, BytecodeObjectTypeRef.fromRuntimeClass(VM.RuntimeGeneratedType.class))) {
Variable theNewVariable = aTargetBlock.newVariable(TypeRef.Native.REFERENCE, new RuntimeGeneratedTypeExpression());
aHelper.push(theNewVariable);
} else {
Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theObjectType), new NewObjectExpression(theClassInfo));
aHelper.push(theNewVariable);
}
}
} else if (theInstruction instanceof BytecodeInstructionNEWARRAY) {
BytecodeInstructionNEWARRAY theINS = (BytecodeInstructionNEWARRAY) theInstruction;
Value theLength = aHelper.pop();
Variable theNewVariable = aTargetBlock.newVariable(TypeRef.Native.REFERENCE, new NewArrayExpression(theINS.getPrimitiveType(), theLength));
aHelper.push(theNewVariable);
} else if (theInstruction instanceof BytecodeInstructionNEWMULTIARRAY) {
BytecodeInstructionNEWMULTIARRAY theINS = (BytecodeInstructionNEWMULTIARRAY) theInstruction;
List<Value> theDimensions = new ArrayList<>();
for (int i = 0; i < theINS.getDimensions(); i++) {
theDimensions.add(aHelper.pop());
}
Collections.reverse(theDimensions);
BytecodeTypeRef theTypeRef = linkerContext.getSignatureParser().toFieldType(new BytecodeUtf8Constant(theINS.getTypeConstant().getConstant().stringValue()));
Variable theNewVariable = aTargetBlock.newVariable(TypeRef.Native.REFERENCE, new NewMultiArrayExpression(theTypeRef, theDimensions));
aHelper.push(theNewVariable);
} else if (theInstruction instanceof BytecodeInstructionANEWARRAY) {
BytecodeInstructionANEWARRAY theINS = (BytecodeInstructionANEWARRAY) theInstruction;
Value theLength = aHelper.pop();
Variable theNewVariable = aTargetBlock.newVariable(TypeRef.Native.REFERENCE, new NewArrayExpression(theINS.getObjectType(), theLength));
aHelper.push(theNewVariable);
} else if (theInstruction instanceof BytecodeInstructionGOTO) {
BytecodeInstructionGOTO theINS = (BytecodeInstructionGOTO) theInstruction;
aTargetBlock.getExpressions().add(new GotoExpression(theINS.getJumpAddress()));
} else if (theInstruction instanceof BytecodeInstructionL2Generic) {
BytecodeInstructionL2Generic theINS = (BytecodeInstructionL2Generic) theInstruction;
Value theValue = aHelper.pop();
Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getTargetType()), new TypeConversionExpression(theValue, TypeRef.toType(theINS.getTargetType())));
aHelper.push(theNewVariable);
} else if (theInstruction instanceof BytecodeInstructionI2Generic) {
BytecodeInstructionI2Generic theINS = (BytecodeInstructionI2Generic) theInstruction;
Value theValue = aHelper.pop();
Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getTargetType()), new TypeConversionExpression(theValue, TypeRef.toType(theINS.getTargetType())));
aHelper.push(theNewVariable);
} else if (theInstruction instanceof BytecodeInstructionF2Generic) {
BytecodeInstructionF2Generic theINS = (BytecodeInstructionF2Generic) theInstruction;
Value theValue = aHelper.pop();
Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getTargetType()), new TypeConversionExpression(theValue, TypeRef.toType(theINS.getTargetType())));
aHelper.push(theNewVariable);
} else if (theInstruction instanceof BytecodeInstructionD2Generic) {
BytecodeInstructionD2Generic theINS = (BytecodeInstructionD2Generic) theInstruction;
Value theValue = aHelper.pop();
Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getTargetType()), new TypeConversionExpression(theValue, TypeRef.toType(theINS.getTargetType())));
aHelper.push(theNewVariable);
} else if (theInstruction instanceof BytecodeInstructionINVOKESPECIAL) {
BytecodeInstructionINVOKESPECIAL theINS = (BytecodeInstructionINVOKESPECIAL) theInstruction;
BytecodeMethodSignature theSignature = theINS.getMethodReference().getNameAndTypeIndex().getNameAndType().getDescriptorIndex().methodSignature();
List<Value> theArguments = new ArrayList<>();
BytecodeTypeRef[] theArgumentTypes = theSignature.getArguments();
for (BytecodeTypeRef theArgumentType : theArgumentTypes) {
theArguments.add(aHelper.pop());
}
Collections.reverse(theArguments);
Variable theTarget = (Variable) aHelper.pop();
BytecodeObjectTypeRef theType = BytecodeObjectTypeRef.fromUtf8Constant(theINS.getMethodReference().getClassIndex().getClassConstant().getConstant());
if (Objects.equals(theType, BytecodeObjectTypeRef.fromRuntimeClass(VM.RuntimeGeneratedType.class))) {
RuntimeGeneratedTypeExpression theValue = (RuntimeGeneratedTypeExpression) theTarget.incomingDataFlows().get(0);
theValue.setType(theArguments.get(0));
theValue.setMethodRef(theArguments.get(1));
} else if (Objects.equals(theType, BytecodeObjectTypeRef.fromRuntimeClass(Address.class))) {
theTarget.initializeWith(theArguments.get(0));
aTargetBlock.getExpressions().add(new VariableAssignmentExpression(theTarget, theArguments.get(0)));
} else {
String theMethodName = theINS.getMethodReference().getNameAndTypeIndex().getNameAndType().getNameIndex().getName().stringValue();
if ("getClass".equals(theMethodName) && BytecodeLinkedClass.GET_CLASS_SIGNATURE.metchesExactlyTo(theSignature)) {
Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theSignature.getReturnType()), new TypeOfExpression(theTarget));
aHelper.push(theNewVariable);
} else {
DirectInvokeMethodExpression theExpression = new DirectInvokeMethodExpression(theType, theMethodName, theSignature, theTarget, theArguments);
if (theSignature.getReturnType().isVoid()) {
aTargetBlock.getExpressions().add(theExpression);
} else {
Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theSignature.getReturnType()), theExpression);
aHelper.push(theNewVariable);
}
}
}
} else if (theInstruction instanceof BytecodeInstructionINVOKEVIRTUAL) {
BytecodeInstructionINVOKEVIRTUAL theINS = (BytecodeInstructionINVOKEVIRTUAL) theInstruction;
BytecodeMethodSignature theSignature = theINS.getMethodReference().getNameAndTypeIndex().getNameAndType().getDescriptorIndex().methodSignature();
if (theSignature.metchesExactlyTo(BytecodeLinkedClass.GET_CLASS_SIGNATURE) && "getClass".equals(theINS.getMethodReference().getNameAndTypeIndex().getNameAndType().getNameIndex().getName().stringValue())) {
Value theValue = new TypeOfExpression(aHelper.pop());
Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theSignature.getReturnType()), theValue);
aHelper.push(theNewVariable);
continue;
}
List<Value> theArguments = new ArrayList<>();
BytecodeTypeRef[] theArgumentTypes = theSignature.getArguments();
for (BytecodeTypeRef theArgumentType : theArgumentTypes) {
theArguments.add(aHelper.pop());
}
Collections.reverse(theArguments);
Value theTarget = aHelper.pop();
InvokeVirtualMethodExpression theExpression = new InvokeVirtualMethodExpression(theINS.getMethodReference().getNameAndTypeIndex().getNameAndType(), theTarget, theArguments);
if (theSignature.getReturnType().isVoid()) {
aTargetBlock.getExpressions().add(theExpression);
} else {
Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theSignature.getReturnType()), theExpression);
aHelper.push(theNewVariable);
}
} else if (theInstruction instanceof BytecodeInstructionINVOKEINTERFACE) {
BytecodeInstructionINVOKEINTERFACE theINS = (BytecodeInstructionINVOKEINTERFACE) theInstruction;
BytecodeMethodSignature theSignature = theINS.getMethodDescriptor().getNameAndTypeIndex().getNameAndType().getDescriptorIndex().methodSignature();
List<Value> theArguments = new ArrayList<>();
BytecodeTypeRef[] theArgumentTypes = theSignature.getArguments();
for (BytecodeTypeRef theArgumentType : theArgumentTypes) {
theArguments.add(aHelper.pop());
}
Collections.reverse(theArguments);
Value theTarget = aHelper.pop();
InvokeVirtualMethodExpression theExpression = new InvokeVirtualMethodExpression(theINS.getMethodDescriptor().getNameAndTypeIndex().getNameAndType(), theTarget, theArguments);
if (theSignature.getReturnType().isVoid()) {
aTargetBlock.getExpressions().add(theExpression);
} else {
Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theSignature.getReturnType()), theExpression);
aHelper.push(theNewVariable);
}
} else if (theInstruction instanceof BytecodeInstructionINVOKESTATIC) {
BytecodeInstructionINVOKESTATIC theINS = (BytecodeInstructionINVOKESTATIC) theInstruction;
BytecodeMethodSignature theSignature = theINS.getMethodReference().getNameAndTypeIndex().getNameAndType().getDescriptorIndex().methodSignature();
List<Value> theArguments = new ArrayList<>();
BytecodeTypeRef[] theArgumentTypes = theSignature.getArguments();
for (BytecodeTypeRef theArgumentType : theArgumentTypes) {
theArguments.add(aHelper.pop());
}
Collections.reverse(theArguments);
BytecodeClassinfoConstant theTargetClass = theINS.getMethodReference().getClassIndex().getClassConstant();
BytecodeObjectTypeRef theObjectType = BytecodeObjectTypeRef.fromUtf8Constant(theTargetClass.getConstant());
if (Objects.equals(theObjectType.name(), MemoryManager.class.getName()) && "initTestMemory".equals(theINS.getMethodReference().getNameAndTypeIndex().getNameAndType().getNameIndex().getName().stringValue())) {
// This invocation can be skipped!!!
} else if (Objects.equals(theObjectType.name(), Address.class.getName())) {
String theMethodName = theINS.getMethodReference().getNameAndTypeIndex().getNameAndType().getNameIndex().getName().stringValue();
switch(theMethodName) {
case "setIntValue":
{
Value theTarget = theArguments.get(0);
Value theOffset = theArguments.get(1);
Value theNewValue = theArguments.get(2);
ComputedMemoryLocationWriteExpression theLocation = new ComputedMemoryLocationWriteExpression(theTarget, theOffset);
Variable theNewVariable = aTargetBlock.newVariable(TypeRef.Native.INT, theLocation);
aTargetBlock.getExpressions().add(new SetMemoryLocationExpression(theNewVariable, theNewValue));
break;
}
case "getStart":
{
Value theTarget = theArguments.get(0);
Variable theNewVariable = aTargetBlock.newVariable(TypeRef.Native.INT, theTarget);
aHelper.push(theNewVariable);
break;
}
case "getStackTop":
{
Variable theNewVariable = aTargetBlock.newVariable(TypeRef.Native.INT, new StackTopExpression());
aHelper.push(theNewVariable);
break;
}
case "getMemorySize":
{
Variable theNewVariable = aTargetBlock.newVariable(TypeRef.Native.INT, new MemorySizeExpression());
aHelper.push(theNewVariable);
break;
}
case "getIntValue":
{
Value theTarget = theArguments.get(0);
Value theOffset = theArguments.get(1);
ComputedMemoryLocationReadExpression theLocation = new ComputedMemoryLocationReadExpression(theTarget, theOffset);
Variable theNewVariable = aTargetBlock.newVariable(TypeRef.Native.INT, theLocation);
aHelper.push(theNewVariable);
break;
}
case "unreachable":
{
aTargetBlock.getExpressions().add(new UnreachableExpression());
break;
}
default:
throw new IllegalStateException("Not implemented : " + theMethodName);
}
} else {
BytecodeObjectTypeRef theClassToInvoke = BytecodeObjectTypeRef.fromUtf8Constant(theINS.getMethodReference().getClassIndex().getClassConstant().getConstant());
linkerContext.resolveClass(theClassToInvoke).resolveStaticMethod(theINS.getMethodReference().getNameAndTypeIndex().getNameAndType().getNameIndex().getName().stringValue(), theINS.getMethodReference().getNameAndTypeIndex().getNameAndType().getDescriptorIndex().methodSignature());
BytecodeMethodSignature theCalledSignature = theINS.getMethodReference().getNameAndTypeIndex().getNameAndType().getDescriptorIndex().methodSignature();
if ("sqrt".equals(theINS.getMethodReference().getNameAndTypeIndex().getNameAndType().getNameIndex().getName().stringValue()) && "java.lang.StrictMath".equals(theClassToInvoke.name())) {
Value theValue = new SqrtExpression(TypeRef.toType(theCalledSignature.getReturnType()), theArguments.get(0));
Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theSignature.getReturnType()), theValue);
aHelper.push(theNewVariable);
} else if ("newInstance".equals(theINS.getMethodReference().getNameAndTypeIndex().getNameAndType().getNameIndex().getName().stringValue()) && "java.lang.reflect.Array".equals(theClassToInvoke.name())) {
Value theArrayType = theArguments.get(0);
Value theArraySize = theArguments.get(1);
Value theValue = new NewArrayExpression(BytecodeObjectTypeRef.fromRuntimeClass(Object.class), theArraySize);
Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theSignature.getReturnType()), theValue);
aHelper.push(theNewVariable);
} else {
InvokeStaticMethodExpression theExpression = new InvokeStaticMethodExpression(theClassToInvoke, theINS.getMethodReference().getNameAndTypeIndex().getNameAndType().getNameIndex().getName().stringValue(), theCalledSignature, theArguments);
if (theSignature.getReturnType().isVoid()) {
aTargetBlock.getExpressions().add(theExpression);
} else {
Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theSignature.getReturnType()), theExpression);
aHelper.push(theNewVariable);
}
}
}
} else if (theInstruction instanceof BytecodeInstructionINSTANCEOF) {
BytecodeInstructionINSTANCEOF theINS = (BytecodeInstructionINSTANCEOF) theInstruction;
Value theValueToCheck = aHelper.pop();
InstanceOfExpression theValue = new InstanceOfExpression(theValueToCheck, theINS.getTypeRef());
Variable theCheckResult = aTargetBlock.newVariable(TypeRef.Native.BOOLEAN, theValue);
aHelper.push(theCheckResult);
} else if (theInstruction instanceof BytecodeInstructionTABLESWITCH) {
BytecodeInstructionTABLESWITCH theINS = (BytecodeInstructionTABLESWITCH) theInstruction;
Value theValue = aHelper.pop();
ExpressionList theDefault = new ExpressionList();
theDefault.add(new GotoExpression(theINS.getDefaultJumpTarget()));
Map<Long, ExpressionList> theOffsets = new HashMap<>();
long[] theJumpTargets = theINS.getOffsets();
for (int i = 0; i < theJumpTargets.length; i++) {
ExpressionList theJump = new ExpressionList();
theJump.add(new GotoExpression(theINS.getOpcodeAddress().add((int) theJumpTargets[i])));
theOffsets.put((long) i, theJump);
}
aTargetBlock.getExpressions().add(new TableSwitchExpression(theValue, theINS.getLowValue(), theINS.getHighValue(), theDefault, theOffsets));
} else if (theInstruction instanceof BytecodeInstructionLOOKUPSWITCH) {
BytecodeInstructionLOOKUPSWITCH theINS = (BytecodeInstructionLOOKUPSWITCH) theInstruction;
Value theValue = aHelper.pop();
ExpressionList theDefault = new ExpressionList();
theDefault.add(new GotoExpression(theINS.getDefaultJumpTarget()));
Map<Long, ExpressionList> thePairs = new HashMap<>();
for (BytecodeInstructionLOOKUPSWITCH.Pair thePair : theINS.getPairs()) {
ExpressionList thePairExpressions = new ExpressionList();
thePairExpressions.add(new GotoExpression(theINS.getOpcodeAddress().add((int) thePair.getOffset())));
thePairs.put(thePair.getMatch(), thePairExpressions);
}
aTargetBlock.getExpressions().add(new LookupSwitchExpression(theValue, theDefault, thePairs));
} else if (theInstruction instanceof BytecodeInstructionINVOKEDYNAMIC) {
BytecodeInstructionINVOKEDYNAMIC theINS = (BytecodeInstructionINVOKEDYNAMIC) theInstruction;
BytecodeInvokeDynamicConstant theConstant = theINS.getCallSite();
BytecodeMethodSignature theInitSignature = theConstant.getNameAndTypeIndex().getNameAndType().getDescriptorIndex().methodSignature();
BytecodeBootstrapMethodsAttributeInfo theBootStrapMethods = aOwningClass.getAttributes().getByType(BytecodeBootstrapMethodsAttributeInfo.class);
BytecodeBootstrapMethod theBootstrapMethod = theBootStrapMethods.methodByIndex(theConstant.getBootstrapMethodAttributeIndex().getIndex());
BytecodeMethodHandleConstant theMethodRef = theBootstrapMethod.getMethodRef();
BytecodeMethodRefConstant theBootstrapMethodToInvoke = (BytecodeMethodRefConstant) theMethodRef.getReferenceIndex().getConstant();
Program theProgram = new Program();
RegionNode theInitNode = theProgram.getControlFlowGraph().createAt(BytecodeOpcodeAddress.START_AT_ZERO, RegionNode.BlockType.NORMAL);
switch(theMethodRef.getReferenceKind()) {
case REF_invokeStatic:
{
BytecodeObjectTypeRef theClassWithBootstrapMethod = BytecodeObjectTypeRef.fromUtf8Constant(theBootstrapMethodToInvoke.getClassIndex().getClassConstant().getConstant());
BytecodeMethodSignature theSignature = theBootstrapMethodToInvoke.getNameAndTypeIndex().getNameAndType().getDescriptorIndex().methodSignature();
List<Value> theArguments = new ArrayList<>();
// Add the three default constants
// TMethodHandles.Lookup aCaller,
theArguments.add(theInitNode.newVariable(TypeRef.Native.REFERENCE, new MethodHandlesGeneratedLookupExpression(theClassWithBootstrapMethod)));
theArguments.add(theInitNode.newVariable(TypeRef.Native.REFERENCE, new StringValue(theConstant.getNameAndTypeIndex().getNameAndType().getNameIndex().getName().stringValue())));
// TMethodType aInvokedType,
theArguments.add(theInitNode.newVariable(TypeRef.Native.REFERENCE, new MethodTypeExpression(theInitSignature)));
// Revolve the static arguments
for (BytecodeConstant theArgumentConstant : theBootstrapMethod.getArguments()) {
if (theArgumentConstant instanceof BytecodeMethodTypeConstant) {
BytecodeMethodTypeConstant theMethodType = (BytecodeMethodTypeConstant) theArgumentConstant;
theArguments.add(theInitNode.newVariable(TypeRef.Native.REFERENCE, new MethodTypeExpression(theMethodType.getDescriptorIndex().methodSignature())));
continue;
}
if (theArgumentConstant instanceof BytecodeStringConstant) {
BytecodeStringConstant thePrimitive = (BytecodeStringConstant) theArgumentConstant;
theArguments.add(theInitNode.newVariable(TypeRef.Native.REFERENCE, new StringValue(thePrimitive.getValue().stringValue())));
continue;
}
if (theArgumentConstant instanceof BytecodeLongConstant) {
BytecodeLongConstant thePrimitive = (BytecodeLongConstant) theArgumentConstant;
theArguments.add(theInitNode.newVariable(TypeRef.Native.LONG, new LongValue(thePrimitive.getLongValue())));
continue;
}
if (theArgumentConstant instanceof BytecodeIntegerConstant) {
BytecodeIntegerConstant thePrimitive = (BytecodeIntegerConstant) theArgumentConstant;
theArguments.add(theInitNode.newVariable(TypeRef.Native.INT, new LongValue(thePrimitive.getIntegerValue())));
continue;
}
if (theArgumentConstant instanceof BytecodeFloatConstant) {
BytecodeFloatConstant thePrimitive = (BytecodeFloatConstant) theArgumentConstant;
theArguments.add(theInitNode.newVariable(TypeRef.Native.FLOAT, new FloatValue(thePrimitive.getFloatValue())));
continue;
}
if (theArgumentConstant instanceof BytecodeDoubleConstant) {
BytecodeDoubleConstant thePrimitive = (BytecodeDoubleConstant) theArgumentConstant;
theArguments.add(theInitNode.newVariable(TypeRef.Native.DOUBLE, new DoubleValue(thePrimitive.getDoubleValue())));
continue;
}
if (theArgumentConstant instanceof BytecodeMethodHandleConstant) {
BytecodeMethodHandleConstant theMethodHandle = (BytecodeMethodHandleConstant) theArgumentConstant;
BytecodeReferenceIndex theReference = theMethodHandle.getReferenceIndex();
BytecodeMethodRefConstant theReferenceConstant = (BytecodeMethodRefConstant) theReference.getConstant();
theArguments.add(theInitNode.newVariable(TypeRef.Native.REFERENCE, new MethodRefExpression(theReferenceConstant)));
continue;
}
throw new IllegalStateException("Unsupported argument type : " + theArgumentConstant);
}
// Ok, is the last argument of the bootstrap method a vararg argument
BytecodeTypeRef theLastArgument = theSignature.getArguments()[theSignature.getArguments().length - 1];
if (theLastArgument.isArray()) {
// Yes, so we have to wrap everything from this position on in an array
int theSignatureLength = theSignature.getArguments().length;
int theArgumentsLength = theArguments.size();
int theVarArgsLength = theArgumentsLength - theSignatureLength + 1;
Variable theNewVarargsArray = theInitNode.newVariable(TypeRef.Native.REFERENCE, new NewArrayExpression(BytecodeObjectTypeRef.fromRuntimeClass(Object.class), new IntegerValue(theVarArgsLength)));
for (int i = theSignatureLength - 1; i < theArgumentsLength; i++) {
Value theVariable = theArguments.get(i);
theArguments.remove(theVariable);
theInitNode.getExpressions().add(new ArrayStoreExpression(TypeRef.Native.REFERENCE, theNewVarargsArray, new IntegerValue(i - theSignatureLength + 1), theVariable));
}
theArguments.add(theNewVarargsArray);
}
InvokeStaticMethodExpression theInvokeStaticValue = new InvokeStaticMethodExpression(BytecodeObjectTypeRef.fromUtf8Constant(theBootstrapMethodToInvoke.getClassIndex().getClassConstant().getConstant()), theBootstrapMethodToInvoke.getNameAndTypeIndex().getNameAndType().getNameIndex().getName().stringValue(), theBootstrapMethodToInvoke.getNameAndTypeIndex().getNameAndType().getDescriptorIndex().methodSignature(), theArguments);
Variable theNewVariable = theInitNode.newVariable(TypeRef.Native.REFERENCE, theInvokeStaticValue);
theInitNode.getExpressions().add(new ReturnValueExpression(theNewVariable));
// First step, we construct a callsite
ResolveCallsiteObjectExpression theValue = new ResolveCallsiteObjectExpression(aOwningClass.getThisInfo().getConstant().stringValue() + "_" + aMethod.getName().stringValue() + "_" + theINS.getOpcodeAddress().getAddress(), aOwningClass, theProgram, theInitNode);
Variable theCallsiteVariable = aTargetBlock.newVariable(TypeRef.Native.REFERENCE, theValue);
List<Value> theInvokeArguments = new ArrayList<>();
Variable theArray = aTargetBlock.newVariable(TypeRef.Native.REFERENCE, new NewArrayExpression(BytecodeObjectTypeRef.fromRuntimeClass(Object.class), new IntegerValue(theInitSignature.getArguments().length)));
for (int i = theInitSignature.getArguments().length - 1; i >= 0; i--) {
Value theIndex = new IntegerValue(i);
Value theStoredValue = aHelper.pop();
if (theStoredValue.resolveType() == TypeRef.Native.INT) {
// Create Integer object to contain int
BytecodeObjectTypeRef theType = BytecodeObjectTypeRef.fromRuntimeClass(Integer.class);
BytecodeTypeRef[] args_def = new BytecodeTypeRef[] { BytecodePrimitiveTypeRef.INT };
BytecodeMethodSignature sig = new BytecodeMethodSignature(theType, args_def);
List<Value> args = new ArrayList<>();
args.add(theStoredValue);
theStoredValue = new InvokeStaticMethodExpression(theType, "valueOf", sig, args);
theStoredValue = aTargetBlock.newVariable(TypeRef.Native.REFERENCE, theStoredValue);
}
aTargetBlock.getExpressions().add(new ArrayStoreExpression(TypeRef.Native.REFERENCE, theArray, theIndex, theStoredValue));
}
theInvokeArguments.add(theArray);
InvokeVirtualMethodExpression theInvokeValue = new InvokeVirtualMethodExpression("invokeExact", new BytecodeMethodSignature(BytecodeObjectTypeRef.fromRuntimeClass(Object.class), new BytecodeTypeRef[] { new BytecodeArrayTypeRef(BytecodeObjectTypeRef.fromRuntimeClass(Object.class), 1) }), theCallsiteVariable, theInvokeArguments);
Variable theInvokeExactResult = aTargetBlock.newVariable(TypeRef.Native.REFERENCE, theInvokeValue);
aHelper.push(theInvokeExactResult);
break;
}
default:
throw new IllegalStateException("Nut supported reference kind for invoke dynamic : " + theMethodRef.getReferenceKind());
}
} else {
throw new IllegalArgumentException("Not implemented : " + theInstruction);
}
}
aHelper.finalizeExportState();
}
Aggregations