private ValueType simplifyParamType(ValueType type) { if (type instanceof ValueType.Object) { return ValueType.object("java.lang.Object"); } else if (type instanceof ValueType.Array) { ValueType.Array array = (ValueType.Array) type; return ValueType.arrayOf(simplifyParamType(array.getItemType())); } else { return type; } } }
private static ValueType[] convertSignature(Class<?>... signature) { ValueType[] types = new ValueType[signature.length]; for (int i = 0; i < types.length; ++i) { types[i] = ValueType.parse(signature[i]); } return types; }
@Override public boolean canHandle(MethodReference method) { if (!characteristics.isStructure(method.getClassName())) { return false; } switch (method.getName()) { case "cast": case "toAddress": return method.parameterCount() == 0; case "sizeOf": return method.parameterCount() == 1 && method.parameterType(0).equals(ValueType.parse(Class.class)); case "add": return method.parameterCount() == 3 && method.parameterType(0).equals(ValueType.parse(Class.class)) && method.parameterType(1).equals(ValueType.parse(Structure.class)) && method.parameterType(2).equals(ValueType.INTEGER); default: return false; } }
private ValueType findClass(String name) { // TODO: dirty hack due to bugs somewhere in TeaVM if (name.startsWith("[")) { ValueType type = ValueType.parseIfPossible(name); if (type != null) { return type; } int degree = 0; while (name.charAt(degree) == '[') { ++degree; } type = ValueType.object(name.substring(degree)); while (degree-- > 0) { type = ValueType.arrayOf(type); } return type; } else { return ValueType.object(name); } }
private static ValueType parseImpl(String string) { switch (string.charAt(0)) { case 'Z': return primitive(PrimitiveType.BOOLEAN); case 'B': return primitive(PrimitiveType.BYTE); case 'S': return primitive(PrimitiveType.SHORT); case 'I': return primitive(PrimitiveType.INTEGER); case 'J': return primitive(PrimitiveType.LONG); case 'F': return primitive(PrimitiveType.FLOAT); case 'D': return primitive(PrimitiveType.DOUBLE); case 'C': return primitive(PrimitiveType.CHARACTER); case 'V': return VOID; case 'L': if (!string.endsWith(";")) { return null; } return object(string.substring(1, string.length() - 1).replace('/', '.')); default: return null; } }
public int getClassAlignment(String className) { ValueType type = ValueType.object(className); addClass(type); ClassBinaryData data = binaryDataMap.get(type); return data.alignment; }
private ValueType getWrappedType(ValueType type) { if (type instanceof ValueType.Array) { ValueType itemType = ((ValueType.Array) type).getItemType(); if (itemType instanceof ValueType.Array) { return ValueType.parse(Object[].class); } else { return ValueType.arrayOf(getWrappedType(itemType)); } } else if (type instanceof ValueType.Object) { if (type.isObject(String.class)) { return type; } else { return JSMethods.JS_OBJECT; } } else { return type; } }
@SuppressWarnings("unchecked") public static <T> ReflectClass<T[]> arrayClass(ReflectClass<T> componentType) { ReflectClassImpl<T> componentTypeImpl = (ReflectClassImpl<T>) componentType; return (ReflectClassImpl<T[]>) reflectContext.getClass(ValueType.arrayOf(componentTypeImpl.type)); }
@Override public void transformClass(ClassHolder cls, ClassHolderTransformerContext context) { int index = 0; for (MethodHolder method : cls.getMethods().toArray(new MethodHolder[0])) { AnnotationReader providerAnnot = method.getAnnotations().get(MetadataProvider.class.getName()); if (providerAnnot != null) { transformMetadataMethod(cls, method, context.getDiagnostics(), context.getHierarchy(), index++); } providerAnnot = method.getAnnotations().get(ClassScopedMetadataProvider.class.getName()); if (providerAnnot != null) { ValueType[] params = method.getParameterTypes(); if (params.length != 1 && params[0].isObject(PlatformClass.class.getName())) { context.getDiagnostics().error(new CallLocation(method.getReference()), "Method {{m0}} marked with {{c1}} must take exactly one parameter of type {{c2}}", method.getReference(), ClassScopedMetadataProvider.class.getName(), PlatformClass.class.getName()); } AnnotationHolder genAnnot = new AnnotationHolder(GeneratedBy.class.getName()); genAnnot.getValues().put("value", new AnnotationValue(ValueType.object( ClassScopedMetadataProviderNativeGenerator.class.getName()))); method.getAnnotations().add(genAnnot); } } }
private static boolean isArray(ValueType type) { if (type == null || type.isObject("java.lang.Object")) { return true; } return type instanceof ValueType.Array; }
break; } else if (type.isObject(String.class)) { return value.getString(); } else if (type instanceof ValueType.Array) { } else if (type.isObject(Class.class)) { return convertClass(value.getJavaClass()); } else if (hierarchy.isSuperType(ValueType.parse(Enum.class), type, false)) { FieldReference fieldRef = value.getEnumValue(); Class<?> enumClass = Class.forName(fieldRef.getClassName(), true, classLoader); return enumClass.getField(fieldRef.getFieldName()).get(null); } else if (hierarchy.isSuperType(ValueType.parse(Annotation.class), type, false)) { Class<?> annotType = convertClass(type); AnnotationProxy handler = new AnnotationProxy(classLoader, hierarchy, value.getAnnotation(), annotType);
public boolean isSuperType(ValueType superType, ValueType subType, boolean defaultValue) { if (superType.equals(subType)) { return true; } if (superType instanceof ValueType.Primitive || subType instanceof ValueType.Primitive) { return false; } if (superType.isObject("java.lang.Object")) { return true; } if (superType instanceof ValueType.Object && subType instanceof ValueType.Object) { return isSuperType(((ValueType.Object) superType).getClassName(), ((ValueType.Object) subType).getClassName(), defaultValue); } else if (superType instanceof ValueType.Array & subType instanceof ValueType.Array) { return isSuperType(((ValueType.Array) superType).getItemType(), ((ValueType.Array) subType).getItemType(), defaultValue); } else { return false; } }
public static ValueType[] parseManyIfPossible(String text) { List<ValueType> types = new ArrayList<>(); int index = 0; while (index < text.length()) { int nextIndex = cut(text, index); ValueType type = parse(text.substring(index, nextIndex)); if (type == null) { return null; } types.add(type); index = nextIndex; } return types.toArray(new ValueType[types.size()]); }
private static boolean sameParams(MethodDescriptor a, MethodDescriptor b) { if (a.parameterCount() != b.parameterCount()) { return false; } for (int i = 0; i < a.parameterCount(); ++i) { if (!a.parameterType(i).equals(b.parameterType(i))) { return false; } } return true; } }
public static ValueType parseIfPossible(String string) { int arrayDegree = 0; int left = 0; while (string.charAt(left) == '[') { ++arrayDegree; ++left; } string = string.substring(left); if (string.isEmpty()) { return null; } ValueType type = parseImpl(string); if (type == null) { return null; } while (arrayDegree-- > 0) { type = arrayOf(type); } return type; }
private ValueEmitter tryConvertArgument(ValueEmitter arg, ValueType from, ValueType to) { if (from.equals(to)) { return arg; } if (from instanceof ValueType.Primitive && to instanceof ValueType.Primitive) { return arg.cast(to); } else if (from instanceof ValueType.Primitive && to instanceof ValueType.Object) { String primitiveClass = ((ValueType.Object) to).getClassName(); PrimitiveType toType = getWrappedPrimitive(primitiveClass); if (toType == null) { return arg; } arg = tryConvertArgument(arg, from, ValueType.primitive(toType)); return arg.getProgramEmitter().invoke(primitiveClass, "valueOf", to, arg); } else if (from instanceof ValueType.Object && to instanceof ValueType.Primitive) { String primitiveClass = ((ValueType.Object) from).getClassName(); PrimitiveType fromType = getWrappedPrimitive(primitiveClass); if (fromType == null) { return arg; } arg = arg.invokeVirtual(primitiveName(fromType) + "Value", ValueType.primitive(fromType)); return tryConvertArgument(arg, ValueType.primitive(fromType), to); } else { return arg.cast(to); } }
public static ValueType parse(String string) { ValueType type = parseIfPossible(string); if (type == null) { throw new IllegalArgumentException("Illegal type signature: " + string); } return type; }
public ValueEmitter neg() { if (!(type instanceof ValueType.Primitive)) { throw new EmitException("Can't negate non-primitive: " + type); } ValueEmitter value = this; PrimitiveType type = ((ValueType.Primitive) this.type).getKind(); IntegerSubtype subtype = convertToIntegerSubtype(type); if (subtype != null) { value = value.castToInteger(subtype); type = PrimitiveType.INTEGER; } ValueEmitter result = pe.newVar(ValueType.primitive(type)); NegateInstruction insn = new NegateInstruction(convertToNumeric(type)); insn.setOperand(value.variable); insn.setReceiver(result.variable); pe.addInstruction(insn); return result; }
private void propagateAlongCasts() { for (ValueCast cast : casts) { int fromNode = nodeMapping[packNodeAndDegree(cast.fromVariable, 0)]; if (!formerNodeChanged[fromNode] && !nodeChanged[fromNode]) { continue; } int toNode = nodeMapping[packNodeAndDegree(cast.toVariable, 0)]; IntHashSet targetTypes = getNodeTypes(toNode); for (IntCursor cursor : types[fromNode]) { if (targetTypes.contains(cursor.value)) { continue; } String className = typeList.get(cursor.value); ValueType type; if (className.startsWith("[")) { type = ValueType.parseIfPossible(className); if (type == null) { type = ValueType.arrayOf(ValueType.object("java.lang.Object")); } } else { type = ValueType.object(className); } if (hierarchy.isSuperType(cast.targetType, type, false)) { changed = true; nodeChanged[toNode] = true; targetTypes.add(cursor.value); } } } }