void emitNewArray(Name name) { Class rtype = name.function.methodType().returnType(); if (name.arguments.Length == 0) { // The array will be a constant. object emptyArray; try { emptyArray = name.function._resolvedHandle().invoke(); } catch (Exception ex) { throw new java.lang.InternalError(ex); } //assert(java.lang.reflect.Array.getLength(emptyArray) == 0); //assert(emptyArray.getClass() == rtype); // exact typing //mv.visitLdcInsn(constantPlaceholder(emptyArray)); EmitConstant(emptyArray); emitReferenceCast(rtype, emptyArray); return; } Class arrayElementType = rtype.getComponentType(); //assert(arrayElementType != null); emitIconstInsn(name.arguments.Length); OpCode xas = OpCodes.Stelem_Ref; if (!arrayElementType.isPrimitive()) { TypeWrapper tw = TypeWrapper.FromClass(arrayElementType); if (tw.IsUnloadable || tw.IsGhost || tw.IsGhostArray || tw.IsNonPrimitiveValueType) { throw new BailoutException(Bailout.UnsupportedArrayType, tw); } ilgen.Emit(OpCodes.Newarr, tw.TypeAsArrayType); } else { byte tc = arrayTypeCode(Wrapper.forPrimitiveType(arrayElementType)); xas = arrayInsnOpcode(tc); //mv.visitIntInsn(Opcodes.NEWARRAY, tc); ilgen.Emit(OpCodes.Newarr, TypeWrapper.FromClass(arrayElementType).TypeAsArrayType); } // store arguments for (int i = 0; i < name.arguments.Length; i++) { //mv.visitInsn(Opcodes.DUP); ilgen.Emit(OpCodes.Dup); emitIconstInsn(i); emitPushArgument(name, i); //mv.visitInsn(xas); ilgen.Emit(xas); } // the array is left on the stack assertStaticType(rtype, name); }
void emitArrayLoad(Name name) { OpCode arrayOpcode = OpCodes.Ldelem_Ref; Class elementType = name.function.methodType().parameterType(0).getComponentType(); emitPushArguments(name); if (elementType.isPrimitive()) { Wrapper w = Wrapper.forPrimitiveType(elementType); arrayOpcode = arrayLoadOpcode(arrayTypeCode(w)); } ilgen.Emit(arrayOpcode); }
static bool isStaticallyInvocable(MemberName member) { if (member == null) { return(false); } if (member.isConstructor()) { return(false); } Class cls = member.getDeclaringClass(); if (cls.isArray() || cls.isPrimitive()) { return(false); // FIXME } /* * if (cls.isAnonymousClass() || cls.isLocalClass()) * return false; // inner class of some sort * if (cls.getClassLoader() != MethodHandle.class.getClassLoader()) * return false; // not on BCP * if (ReflectUtil.isVMAnonymousClass(cls)) // FIXME: switch to supported API once it is added * return false; * MethodType mtype = member.getMethodOrFieldType(); * if (!isStaticallyNameable(mtype.returnType())) * return false; * for (Class<?> ptype : mtype.parameterArray()) * if (!isStaticallyNameable(ptype)) * return false; * if (!member.isPrivate() && VerifyAccess.isSamePackage(MethodHandle.class, cls)) * return true; // in java.lang.invoke package * if (member.isPublic() && isStaticallyNameable(cls)) * return true; */ if (member.isMethod()) { // [IKVM] If we can't call the method directly, invoke it via the invokeBasic infrastructure. return(IsMethodHandleLinkTo(member) || IsMethodHandleInvokeBasic(member) || IsStaticallyInvocable(GetMethodWrapper(member))); } if (member.isField()) { // [IKVM] If we can't access the field directly, use the invokeBasic infrastructure. return(IsStaticallyInvocable(GetFieldWrapper(member))); } return(false); }
internal static string JavaSignature(Class clazz) { string name = clazz.FullName; if (clazz.isPrimitive()) { switch (name) { case "boolean": return "Z"; case "int": return "I"; case "double": return "D"; case "float": return "F"; case "short": return "S"; case "long": return "J"; case "char": return "C"; case "byte": return "B"; case "void": return "V"; default: throw new NotImplementedException(); } } if (clazz.isArray()) { return name.Replace('.', '/'); } return "L" + name.Replace('.', '/') + ";"; }
public static string getCPPTypeName(Class type) { if (type == ClassLiteral<Buffer>.Value || type == ClassLiteral<Pointer>.Value) return "void*"; if (type == ClassLiteral<byte[]>.Value || type == ClassLiteral<ByteBuffer>.Value || type == ClassLiteral<BytePointer>.Value) return "signed char*"; if (type == ClassLiteral<short[]>.Value || type == ClassLiteral<ShortBuffer>.Value || type == ClassLiteral<ShortPointer>.Value) return "short*"; if (type == ClassLiteral<int[]>.Value || type == ClassLiteral<IntBuffer>.Value || type == ClassLiteral<IntPointer>.Value) return "int*"; if (type == ClassLiteral<long[]>.Value || type == ClassLiteral<LongBuffer>.Value || type == ClassLiteral<LongPointer>.Value) return "jlong*"; if (type == ClassLiteral<float[]>.Value || type == ClassLiteral<FloatBuffer>.Value || type == ClassLiteral<FloatPointer>.Value) return "float*"; if (type == ClassLiteral<double[]>.Value || type == ClassLiteral<DoubleBuffer>.Value || type == ClassLiteral<DoublePointer>.Value) return "double*"; if (type == ClassLiteral<char[]>.Value || type == ClassLiteral<CharBuffer>.Value || type == ClassLiteral<CharPointer>.Value) return "unsigned short*"; if (type == ClassLiteral<PointerPointer>.Value) return "void**"; if (type == ClassLiteral<String>.Value) return "const char*"; if (type == Byte.TYPE) return "signed char"; if (type == Character.TYPE) return "unsigned short"; if (type == Long.TYPE) return "jlong"; if (type == Boolean.TYPE) return "unsigned char"; if (type.isPrimitive()) return type.getName(); else if (((Class) ClassLiteral<FunctionPointer>.Value).isAssignableFrom(type)) { return new StringBuilder().append("JavaCPP_").append(Generator.mangle(type.getName())).append("*").toString(); } else { string str1 = ""; for (; type != null; type = type.getDeclaringClass()) { Namespace @namespace = (Namespace) type.getAnnotation((Class) ClassLiteral<Namespace>.Value); string str2 = @namespace == null ? "" : @namespace.value(); if (((Class) ClassLiteral<Pointer>.Value).isAssignableFrom(type)) { Name name1 = (Name) type.getAnnotation((Class) ClassLiteral<Name>.Value); string str3; if (name1 == null) { string name2 = type.getName(); str3 = String.instancehelper_substring(name2, String.instancehelper_lastIndexOf(name2, "$") + 1); } else str3 = name1.value(); str2 = String.instancehelper_length(str2) != 0 ? new StringBuilder().append(str2).append("::").append(str3).toString() : str3; } if (String.instancehelper_length(str1) == 0) str1 = str2; else if (String.instancehelper_length(str2) > 0) str1 = new StringBuilder().append(str2).append("::").append(str1).toString(); } return new StringBuilder().append(str1).append("*").toString(); } }
internal static GType RegisterClass(Class clazz, TypeRegistration registration) { if (knownClasses.ContainsKey(clazz)) { GType known = knownClasses[clazz]; if (registration != null) { known.Registration = registration; } return known; } var res = new GType(); if (clazz.isArray()) { res.ArrayElement = RegisterClass(clazz.getComponentType(), null); res.IsArray = true; string array = "[]"; Class comp = clazz.getComponentType(); while (comp.isArray()) { array += "[]"; comp = comp.getComponentType(); } res.LowerName = ((string) comp.getName()).ToLowerInvariant() + array; } else { res.LowerName = ((string) clazz.getName()).ToLowerInvariant(); } res.Attributes = 0; var classModifiers = (ModifierFlags) clazz.getModifiers(); if ((classModifiers & ModifierFlags.Abstract) != 0) { res.IsAbstract = true; res.Attributes |= TypeAttributes.Abstract; } if ((classModifiers & ModifierFlags.Final) != 0) { res.IsFinal = true; } if ((classModifiers & ModifierFlags.Public) != 0) { res.Attributes |= TypeAttributes.Public; } else if ((classModifiers & ModifierFlags.Private) != 0) { res.Attributes |= TypeAttributes.NotPublic; } //TODO internal ? if (knownNames.ContainsKey(res.LowerName)) { res = knownNames[res.LowerName]; } if (res.Registration == null && registration != null) { res.Registration = registration; } res.JVMType = clazz; res.JVMFullName = clazz.getName(); if (res.IsArray) { string array = "[]"; Class comp = clazz.getComponentType(); while (comp.isArray()) { array += "[]"; comp = comp.getComponentType(); } res.JVMFullName = comp.getName() + array; } else { res.JVMFullName = clazz.getName(); } res.IsJVMType = true; res.IsPrimitive = clazz.isPrimitive(); res.IsException = Throwable._class.isAssignableFrom(clazz); res.IsInterface = clazz.isInterface(); res.IsCLRProxy = clrProxyClass != null && clrProxyClass.isAssignableFrom(clazz); if (!res.IsCLRProxy) { res.IsJVMRealType = true; } Class superclass = clazz.getSuperclass(); var isBaseClassPublic = superclass == null || ((ModifierFlags)superclass.getModifiers() & ModifierFlags.Public) != 0; if (superclass != null && res.Base == null && clazz != Object._class && clazz != Throwable._class && res.JVMFullName != "system.Object" && res.JVMFullName != "system.Exception" && isBaseClassPublic) { res.Base = RegisterClass(superclass); } List<Class> interfaces = new List<Class>(clazz.getInterfaces()); if (!isBaseClassPublic) { interfaces.AddRange(superclass.getInterfaces()); res.Base = RegisterClass(superclass.getSuperclass()); } foreach (Class ifc in interfaces) { GType gifc = RegisterClass(ifc); if (!res.Interfaces.Contains(gifc)) { if (res.IsInterface && res.Base == null) { res.Base = gifc; } res.Interfaces.Add(gifc); res.AllInterfaces.Add(gifc); } } Register(res); return res; }