ikvm-commit Mailing List for IKVM.NET (Page 11)
Brought to you by:
jfrijters
You can subscribe to this list here.
| 2007 |
Jan
(25) |
Feb
(22) |
Mar
(32) |
Apr
(77) |
May
(111) |
Jun
(129) |
Jul
(223) |
Aug
(109) |
Sep
(60) |
Oct
(60) |
Nov
(36) |
Dec
(55) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2008 |
Jan
(23) |
Feb
(76) |
Mar
(42) |
Apr
(49) |
May
(33) |
Jun
(64) |
Jul
(19) |
Aug
(124) |
Sep
(16) |
Oct
|
Nov
(87) |
Dec
(54) |
| 2009 |
Jan
(53) |
Feb
(116) |
Mar
(86) |
Apr
(64) |
May
(101) |
Jun
(99) |
Jul
(105) |
Aug
(63) |
Sep
(20) |
Oct
(110) |
Nov
(102) |
Dec
(36) |
| 2010 |
Jan
(87) |
Feb
(67) |
Mar
(5) |
Apr
(100) |
May
(178) |
Jun
(95) |
Jul
(22) |
Aug
(85) |
Sep
(82) |
Oct
(99) |
Nov
(119) |
Dec
(132) |
| 2011 |
Jan
(130) |
Feb
(18) |
Mar
(114) |
Apr
(8) |
May
(21) |
Jun
(53) |
Jul
(127) |
Aug
(111) |
Sep
(29) |
Oct
(28) |
Nov
(64) |
Dec
(94) |
| 2012 |
Jan
(56) |
Feb
(8) |
Mar
(65) |
Apr
(48) |
May
(22) |
Jun
(52) |
Jul
(73) |
Aug
(38) |
Sep
(18) |
Oct
(59) |
Nov
(16) |
Dec
(21) |
| 2013 |
Jan
(83) |
Feb
(151) |
Mar
(102) |
Apr
(13) |
May
(37) |
Jun
(1) |
Jul
(7) |
Aug
(42) |
Sep
(28) |
Oct
(13) |
Nov
(5) |
Dec
(3) |
| 2014 |
Jan
(3) |
Feb
(39) |
Mar
(11) |
Apr
(40) |
May
(62) |
Jun
(54) |
Jul
(21) |
Aug
(3) |
Sep
|
Oct
(15) |
Nov
(26) |
Dec
(7) |
| 2015 |
Jan
(6) |
Feb
(12) |
Mar
(51) |
Apr
(15) |
May
(7) |
Jun
(41) |
Jul
(2) |
Aug
(8) |
Sep
(5) |
Oct
(6) |
Nov
(11) |
Dec
(1) |
| 2016 |
Jan
|
Feb
(1) |
Mar
|
Apr
(1) |
May
|
Jun
(2) |
Jul
(19) |
Aug
(2) |
Sep
(2) |
Oct
|
Nov
|
Dec
|
| 2017 |
Jan
|
Feb
(2) |
Mar
|
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: Jeroen F. <jfr...@us...> - 2014-07-09 12:25:10
|
Update of /cvsroot/ikvm/ikvm/runtime In directory sfp-cvs-1.v30.ch3.sourceforge.com:/tmp/cvs-serv26692 Modified Files: LambdaMetafactory.cs TypeWrapper.cs Log Message: Added method and field reflection support for lambda classes. Index: TypeWrapper.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/TypeWrapper.cs,v retrieving revision 1.477 retrieving revision 1.478 diff -C2 -d -r1.477 -r1.478 *** TypeWrapper.cs 9 Jul 2014 08:45:25 -0000 1.477 --- TypeWrapper.cs 9 Jul 2014 12:25:08 -0000 1.478 *************** *** 4990,4994 **** } ! private static TypeWrapper GetFieldTypeWrapper(FieldInfo field) { return TypeWrapperFromModOpt(field.GetOptionalCustomModifiers()) --- 4990,4994 ---- } ! internal static TypeWrapper GetFieldTypeWrapper(FieldInfo field) { return TypeWrapperFromModOpt(field.GetOptionalCustomModifiers()) *************** *** 4996,5000 **** } ! private static TypeWrapper GetParameterTypeWrapper(ParameterInfo param) { TypeWrapper tw = TypeWrapperFromModOpt(param.GetOptionalCustomModifiers()); --- 4996,5000 ---- } ! internal static TypeWrapper GetParameterTypeWrapper(ParameterInfo param) { TypeWrapper tw = TypeWrapperFromModOpt(param.GetOptionalCustomModifiers()); *************** *** 5761,5776 **** protected override void LazyPublishMembers() { ! MethodInfo mi = type.GetMethod("writeReplace", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly, null, Type.EmptyTypes, null); ! if (mi != null) { ! SetMethods(new MethodWrapper[] { ! new TypicalMethodWrapper(this, "writeReplace", "()Ljava.lang.Object;", mi, CoreClasses.java.lang.Object.Wrapper, TypeWrapper.EmptyArray, Modifiers.Private, MemberFlags.None) ! }); } ! else { ! SetMethods(MethodWrapper.EmptyArray); } ! SetFields(FieldWrapper.EmptyArray); } } --- 5761,5809 ---- protected override void LazyPublishMembers() { ! List<MethodWrapper> methods = new List<MethodWrapper>(); ! foreach (MethodInfo mi in type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)) { ! if (mi.IsSpecialName) ! { ! // we use special name to hide default methods ! } ! else if (mi.IsPublic) ! { ! TypeWrapper returnType; ! TypeWrapper[] parameterTypes; ! string signature; ! GetSig(mi, out returnType, out parameterTypes, out signature); ! methods.Add(new TypicalMethodWrapper(this, mi.Name, signature, mi, returnType, parameterTypes, Modifiers.Public, MemberFlags.None)); ! } ! else if (mi.Name == "writeReplace") ! { ! methods.Add(new TypicalMethodWrapper(this, "writeReplace", "()Ljava.lang.Object;", mi, CoreClasses.java.lang.Object.Wrapper, TypeWrapper.EmptyArray, ! Modifiers.Private | Modifiers.Final, MemberFlags.None)); ! } } ! SetMethods(methods.ToArray()); ! List<FieldWrapper> fields = new List<FieldWrapper>(); ! foreach (FieldInfo fi in type.GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)) { ! TypeWrapper fieldType = CompiledTypeWrapper.GetFieldTypeWrapper(fi); ! fields.Add(new SimpleFieldWrapper(this, fieldType, fi, fi.Name, fieldType.SigName, new ExModifiers(Modifiers.Private | Modifiers.Final, false))); } ! SetFields(fields.ToArray()); ! } ! ! private void GetSig(MethodInfo mi, out TypeWrapper returnType, out TypeWrapper[] parameterTypes, out string signature) ! { ! returnType = CompiledTypeWrapper.GetParameterTypeWrapper(mi.ReturnParameter); ! ParameterInfo[] parameters = mi.GetParameters(); ! parameterTypes = new TypeWrapper[parameters.Length]; ! System.Text.StringBuilder sb = new System.Text.StringBuilder("("); ! for (int i = 0; i < parameters.Length; i++) ! { ! parameterTypes[i] = CompiledTypeWrapper.GetParameterTypeWrapper(parameters[i]); ! sb.Append(parameterTypes[i].SigName); ! } ! sb.Append(')'); ! sb.Append(returnType.SigName); ! signature = sb.ToString(); } } Index: LambdaMetafactory.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/LambdaMetafactory.cs,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** LambdaMetafactory.cs 9 Jul 2014 08:45:25 -0000 1.7 --- LambdaMetafactory.cs 9 Jul 2014 12:25:08 -0000 1.8 *************** *** 404,408 **** attr |= FieldAttributes.InitOnly; } ! capturedFields[i] = tb.DefineField("c" + i, capturedTypes[i], attr); } --- 404,408 ---- attr |= FieldAttributes.InitOnly; } ! capturedFields[i] = tb.DefineField("arg$" + (i + 1), capturedTypes[i], attr); } *************** *** 480,484 **** ClassFile.ConstantPoolItemMethodHandle implMethod, ClassFile.ConstantPoolItemMethodType instantiatedMethodType, FieldBuilder[] capturedFields) { ! MethodBuilder mb = interfaceMethod.GetDefineMethodHelper().DefineMethod(context.TypeWrapper, tb, interfaceMethod.RealName, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final); CodeEmitter ilgen = CodeEmitter.Create(mb); for (int i = 0; i < capturedFields.Length; i++) --- 480,488 ---- ClassFile.ConstantPoolItemMethodHandle implMethod, ClassFile.ConstantPoolItemMethodType instantiatedMethodType, FieldBuilder[] capturedFields) { ! MethodBuilder mb = interfaceMethod.GetDefineMethodHelper().DefineMethod(context.TypeWrapper, tb, interfaceMethod.Name, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final); ! if (interfaceMethod.Name != interfaceMethod.RealName) ! { ! tb.DefineMethodOverride(mb, (MethodInfo)interfaceMethod.GetMethod()); ! } CodeEmitter ilgen = CodeEmitter.Create(mb); for (int i = 0; i < capturedFields.Length; i++) *************** *** 681,684 **** --- 685,690 ---- private static void AddDefaultInterfaceMethods(DynamicTypeWrapper.FinishContext context, MethodWrapper[] methodList, TypeBuilder tb) { + // we use special name to hide these from Java reflection + const MethodAttributes attr = MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final | MethodAttributes.SpecialName; TypeWrapperFactory factory = context.TypeWrapper.GetClassLoader().GetTypeWrapperFactory(); foreach (MethodWrapper mw in methodList) *************** *** 686,695 **** if (!mw.IsAbstract) { ! MethodBuilder mb = mw.GetDefineMethodHelper().DefineMethod(factory, tb, mw.RealName, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final); DynamicTypeWrapper.FinishContext.EmitCallDefaultInterfaceMethod(mb, mw); } else if (IsObjectMethod(mw)) { ! MethodBuilder mb = mw.GetDefineMethodHelper().DefineMethod(factory, tb, mw.RealName, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final); CodeEmitter ilgen = CodeEmitter.Create(mb); for (int i = 0, count = mw.GetParameters().Length; i <= count; i++) --- 692,709 ---- if (!mw.IsAbstract) { ! MethodBuilder mb = mw.GetDefineMethodHelper().DefineMethod(factory, tb, mw.Name, attr); ! if (mw.Name != mw.RealName) ! { ! tb.DefineMethodOverride(mb, (MethodInfo)mw.GetMethod()); ! } DynamicTypeWrapper.FinishContext.EmitCallDefaultInterfaceMethod(mb, mw); } else if (IsObjectMethod(mw)) { ! MethodBuilder mb = mw.GetDefineMethodHelper().DefineMethod(factory, tb, mw.Name, attr); ! if (mw.Name != mw.RealName) ! { ! tb.DefineMethodOverride(mb, (MethodInfo)mw.GetMethod()); ! } CodeEmitter ilgen = CodeEmitter.Create(mb); for (int i = 0, count = mw.GetParameters().Length; i <= count; i++) |
|
From: Jeroen F. <jfr...@us...> - 2014-07-09 08:45:28
|
Update of /cvsroot/ikvm/ikvm/runtime In directory sfp-cvs-1.v30.ch3.sourceforge.com:/tmp/cvs-serv11123 Modified Files: LambdaMetafactory.cs Serialization.cs TypeWrapper.cs Log Message: Added .NET serialization interop to lambda classes. Index: TypeWrapper.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/TypeWrapper.cs,v retrieving revision 1.476 retrieving revision 1.477 diff -C2 -d -r1.476 -r1.477 *** TypeWrapper.cs 8 Jul 2014 08:23:41 -0000 1.476 --- TypeWrapper.cs 9 Jul 2014 08:45:25 -0000 1.477 *************** *** 5731,5735 **** internal override TypeWrapper[] Interfaces { ! get { return GetImplementedInterfacesAsTypeWrappers(type); } } --- 5731,5746 ---- internal override TypeWrapper[] Interfaces { ! get ! { ! TypeWrapper[] interfaces = GetImplementedInterfacesAsTypeWrappers(type); ! if (type.IsSerializable) ! { ! // we have to remove the System.Runtime.Serialization.ISerializable interface ! List<TypeWrapper> list = new List<TypeWrapper>(interfaces); ! list.RemoveAll(Serialization.IsISerializable); ! return list.ToArray(); ! } ! return interfaces; ! } } Index: Serialization.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/Serialization.cs,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** Serialization.cs 14 Feb 2013 16:09:04 -0000 1.18 --- Serialization.cs 9 Jul 2014 08:45:25 -0000 1.19 *************** *** 53,56 **** --- 53,61 ---- } + internal static bool IsISerializable(TypeWrapper wrapper) + { + return wrapper == iserializable; + } + private static bool IsSafeForAutomagicSerialization(TypeWrapper wrapper) { *************** *** 148,160 **** } ! private static void MarkSerializable(TypeBuilder tb) { tb.SetCustomAttribute(serializableAttribute); } ! private static void AddGetObjectData(TypeBuilder tb) { tb.AddInterfaceImplementation(JVM.Import(typeof(ISerializable))); ! MethodBuilder getObjectData = tb.DefineMethod("GetObjectData", MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.NewSlot, null, new Type[] { JVM.Import(typeof(SerializationInfo)), JVM.Import(typeof(StreamingContext)) }); getObjectData.SetCustomAttribute(securityCriticalAttribute); --- 153,171 ---- } ! internal static void MarkSerializable(TypeBuilder tb) { tb.SetCustomAttribute(serializableAttribute); } ! internal static void AddGetObjectData(TypeBuilder tb) { + string name = tb.IsSealed + ? "System.Runtime.Serialization.ISerializable.GetObjectData" + : "GetObjectData"; + MethodAttributes attr = tb.IsSealed + ? MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final + : MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.CheckAccessOnOverride; tb.AddInterfaceImplementation(JVM.Import(typeof(ISerializable))); ! MethodBuilder getObjectData = tb.DefineMethod(name, attr, null, new Type[] { JVM.Import(typeof(SerializationInfo)), JVM.Import(typeof(StreamingContext)) }); getObjectData.SetCustomAttribute(securityCriticalAttribute); Index: LambdaMetafactory.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/LambdaMetafactory.cs,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** LambdaMetafactory.cs 8 Jul 2014 14:30:31 -0000 1.6 --- LambdaMetafactory.cs 9 Jul 2014 08:45:25 -0000 1.7 *************** *** 465,468 **** --- 465,475 ---- ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); + + if (!context.TypeWrapper.GetClassLoader().NoAutomagicSerialization) + { + // add .NET serialization interop support + Serialization.MarkSerializable(tb); + Serialization.AddGetObjectData(tb); + } } *************** *** 741,748 **** } private static bool CheckSupportedInterfaces(TypeWrapper caller, TypeWrapper tw, TypeWrapper[] markers, ClassFile.ConstantPoolItemMethodType[] bridges, out MethodWrapper[] methodList) { // we don't need to check for unloadable, because we already did that while validating the invoke signature ! if (!tw.IsInterface || tw.IsGhost || !tw.IsAccessibleFrom(caller)) { methodList = null; --- 748,763 ---- } + private static bool IsSupportedInterface(TypeWrapper tw, TypeWrapper caller) + { + return tw.IsInterface + && !tw.IsGhost + && tw.IsAccessibleFrom(caller) + && !Serialization.IsISerializable(tw); + } + private static bool CheckSupportedInterfaces(TypeWrapper caller, TypeWrapper tw, TypeWrapper[] markers, ClassFile.ConstantPoolItemMethodType[] bridges, out MethodWrapper[] methodList) { // we don't need to check for unloadable, because we already did that while validating the invoke signature ! if (!IsSupportedInterface(tw, caller)) { methodList = null; *************** *** 756,760 **** foreach (TypeWrapper marker in markers) { ! if (!marker.IsInterface || marker.IsGhost || !marker.IsAccessibleFrom(caller)) { methodList = null; --- 771,775 ---- foreach (TypeWrapper marker in markers) { ! if (!IsSupportedInterface(marker, caller)) { methodList = null; |
|
From: Jeroen F. <jfr...@us...> - 2014-07-08 14:30:33
|
Update of /cvsroot/ikvm/ikvm/runtime In directory sfp-cvs-1.v30.ch3.sourceforge.com:/tmp/cvs-serv31414 Modified Files: LambdaMetafactory.cs Log Message: Added support for bridge methods. Index: LambdaMetafactory.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/LambdaMetafactory.cs,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** LambdaMetafactory.cs 8 Jul 2014 13:22:29 -0000 1.5 --- LambdaMetafactory.cs 8 Jul 2014 14:30:31 -0000 1.6 *************** *** 73,76 **** --- 73,77 ---- bool serializable = false; TypeWrapper[] markers = TypeWrapper.EmptyArray; + ClassFile.ConstantPoolItemMethodType[] bridges = null; if (bsm.ArgumentCount > 3) { *************** *** 92,100 **** if ((flags & AltFlags.Bridges) != 0) { ! int bridgeCount = classFile.GetConstantPoolConstantInteger(bsm.GetArgument(argpos++)); ! if (bridgeCount != 0) { ! Fail("bridges"); ! return false; } } --- 93,105 ---- if ((flags & AltFlags.Bridges) != 0) { ! bridges = new ClassFile.ConstantPoolItemMethodType[classFile.GetConstantPoolConstantInteger(bsm.GetArgument(argpos++))]; ! for (int i = 0; i < bridges.Length; i++) { ! bridges[i] = classFile.GetConstantPoolConstantMethodType(bsm.GetArgument(argpos++)); ! if (HasUnloadable(bridges[i])) ! { ! Fail("unloadable bridge"); ! return false; ! } } } *************** *** 112,116 **** TypeWrapper interfaceType = cpi.GetRetType(); MethodWrapper[] methodList; ! if (!CheckSupportedInterfaces(context.TypeWrapper, interfaceType, markers, out methodList)) { Fail("unsupported interface"); --- 117,121 ---- TypeWrapper interfaceType = cpi.GetRetType(); MethodWrapper[] methodList; ! if (!CheckSupportedInterfaces(context.TypeWrapper, interfaceType, markers, bridges, out methodList)) { Fail("unsupported interface"); *************** *** 127,155 **** return false; } - if (!IsSubTypeOf(instantiatedMethodType, samMethodType)) - { - Fail("instantiatedMethodType <= samMethodType"); - return false; - } TypeWrapper[] implParameters = GetImplParameters(implMethod); ! if (cpi.GetArgTypes().Length + samMethodType.GetArgTypes().Length != implParameters.Length) ! { ! Fail("K + N = M"); ! return false; ! } ! for (int i = 0, K = cpi.GetArgTypes().Length; i < K; i++) ! { ! if (!cpi.GetArgTypes()[i].IsSubTypeOf(implParameters[i])) ! { ! Fail("For i=1..K, Di = Ai"); ! return false; ! } ! } ! for (int i = 0, N = samMethodType.GetArgTypes().Length, k = cpi.GetArgTypes().Length; i < N; i++) { ! if (!IsAdaptable(instantiatedMethodType.GetArgTypes()[i], implParameters[i + k], false)) { ! Fail("For i=1..N, Ti is adaptable to Aj, where j=i+k (in" + context.TypeWrapper.Name + ")"); ! return false; } } --- 132,151 ---- return false; } TypeWrapper[] implParameters = GetImplParameters(implMethod); ! CheckConstraints(instantiatedMethodType, samMethodType, cpi.GetArgTypes(), implParameters); ! if (bridges != null) { ! foreach (ClassFile.ConstantPoolItemMethodType bridge in bridges) { ! if (bridge.Signature == samMethodType.Signature) ! { ! Fail("bridge signature matches sam"); ! return false; ! } ! if (!CheckConstraints(instantiatedMethodType, bridge, cpi.GetArgTypes(), implParameters)) ! { ! Fail("bridge constraints"); ! return false; ! } } } *************** *** 161,170 **** { Fail("The return type Rt is void, or the return type Ra is not void and is adaptable to Rt"); - Console.WriteLine("Ra = " + Ra.SigName); - Console.WriteLine("Rt = " + Rt.SigName); return false; } } MethodWrapper interfaceMethod = null; foreach (MethodWrapper mw in methodList) { --- 157,165 ---- { Fail("The return type Rt is void, or the return type Ra is not void and is adaptable to Rt"); return false; } } MethodWrapper interfaceMethod = null; + List<MethodWrapper> methods = new List<MethodWrapper>(); foreach (MethodWrapper mw in methodList) { *************** *** 172,176 **** { interfaceMethod = mw; ! break; } } --- 167,175 ---- { interfaceMethod = mw; ! methods.Add(mw); ! } ! else if (mw.IsAbstract && !IsObjectMethod(mw)) ! { ! methods.Add(mw); } } *************** *** 193,197 **** tb.AddInterfaceImplementation(marker.TypeAsBaseType); } ! ctor = CreateConstructorAndDispatch(context, interfaceType, cpi.GetArgTypes(), tb, interfaceMethod, implParameters, samMethodType, implMethod, instantiatedMethodType, serializable); AddDefaultInterfaceMethods(context, methodList, tb); return true; --- 192,196 ---- tb.AddInterfaceImplementation(marker.TypeAsBaseType); } ! ctor = CreateConstructorAndDispatch(context, cpi, tb, methods, implParameters, samMethodType, implMethod, instantiatedMethodType, serializable); AddDefaultInterfaceMethods(context, methodList, tb); return true; *************** *** 204,207 **** --- 203,237 ---- } + private static bool CheckConstraints(ClassFile.ConstantPoolItemMethodType instantiatedMethodType, ClassFile.ConstantPoolItemMethodType methodType, TypeWrapper[] args, TypeWrapper[] implParameters) + { + if (!IsSubTypeOf(instantiatedMethodType, methodType)) + { + Fail("instantiatedMethodType <= methodType"); + return false; + } + if (args.Length + methodType.GetArgTypes().Length != implParameters.Length) + { + Fail("K + N = M"); + return false; + } + for (int i = 0, K = args.Length; i < K; i++) + { + if (!args[i].IsSubTypeOf(implParameters[i])) + { + Fail("For i=1..K, Di = Ai"); + return false; + } + } + for (int i = 0, N = methodType.GetArgTypes().Length, k = args.Length; i < N; i++) + { + if (!IsAdaptable(instantiatedMethodType.GetArgTypes()[i], implParameters[i + k], false)) + { + Fail("For i=1..N, Ti is adaptable to Aj, where j=i+k"); + return false; + } + } + return true; + } + private static TypeWrapper[] GetImplParameters(ClassFile.ConstantPoolItemMethodHandle implMethod) { *************** *** 357,364 **** } ! private static MethodBuilder CreateConstructorAndDispatch(DynamicTypeWrapper.FinishContext context, TypeWrapper interfaceType, TypeWrapper[] args, TypeBuilder tb, ! MethodWrapper interfaceMethod, TypeWrapper[] implParameters, ClassFile.ConstantPoolItemMethodType samMethodType, ClassFile.ConstantPoolItemMethodHandle implMethod, ClassFile.ConstantPoolItemMethodType instantiatedMethodType, bool serializable) { // captured values Type[] capturedTypes = new Type[args.Length]; --- 387,396 ---- } ! private static MethodBuilder CreateConstructorAndDispatch(DynamicTypeWrapper.FinishContext context, ClassFile.ConstantPoolItemInvokeDynamic cpi, TypeBuilder tb, ! List<MethodWrapper> methods, TypeWrapper[] implParameters, ClassFile.ConstantPoolItemMethodType samMethodType, ClassFile.ConstantPoolItemMethodHandle implMethod, ClassFile.ConstantPoolItemMethodType instantiatedMethodType, bool serializable) { + TypeWrapper[] args = cpi.GetArgTypes(); + // captured values Type[] capturedTypes = new Type[args.Length]; *************** *** 389,396 **** ilgen.DoEmit(); ! // dispatch method MethodBuilder mb = interfaceMethod.GetDefineMethodHelper().DefineMethod(context.TypeWrapper, tb, interfaceMethod.RealName, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final); ! ilgen = CodeEmitter.Create(mb); ! for (int i = 0; i < capturedTypes.Length; i++) { ilgen.EmitLdarg(0); --- 421,479 ---- ilgen.DoEmit(); ! // dispatch methods ! foreach (MethodWrapper mw in methods) ! { ! EmitDispatch(context, args, tb, mw, implParameters, implMethod, instantiatedMethodType, capturedFields); ! } ! ! // writeReplace method ! if (serializable) ! { ! MethodBuilder writeReplace = tb.DefineMethod("writeReplace", MethodAttributes.Private, Types.Object, Type.EmptyTypes); ! ilgen = CodeEmitter.Create(writeReplace); ! context.TypeWrapper.EmitClassLiteral(ilgen); ! ilgen.Emit(OpCodes.Ldstr, cpi.GetRetType().Name.Replace('.', '/')); ! ilgen.Emit(OpCodes.Ldstr, cpi.Name); ! ilgen.Emit(OpCodes.Ldstr, samMethodType.Signature.Replace('.', '/')); ! ilgen.EmitLdc_I4((int)implMethod.Kind); ! ilgen.Emit(OpCodes.Ldstr, implMethod.Class.Replace('.', '/')); ! ilgen.Emit(OpCodes.Ldstr, implMethod.Name); ! ilgen.Emit(OpCodes.Ldstr, implMethod.Signature.Replace('.', '/')); ! ilgen.Emit(OpCodes.Ldstr, instantiatedMethodType.Signature.Replace('.', '/')); ! ilgen.EmitLdc_I4(capturedFields.Length); ! ilgen.Emit(OpCodes.Newarr, Types.Object); ! for (int i = 0; i < capturedFields.Length; i++) ! { ! ilgen.Emit(OpCodes.Dup); ! ilgen.EmitLdc_I4(i); ! ilgen.EmitLdarg(0); ! ilgen.Emit(OpCodes.Ldfld, capturedFields[i]); ! if (args[i].IsPrimitive) ! { ! Boxer.EmitBox(ilgen, args[i]); ! } ! else if (args[i].IsGhost) ! { ! args[i].EmitConvSignatureTypeToStackType(ilgen); ! } ! ilgen.Emit(OpCodes.Stelem, Types.Object); ! } ! MethodWrapper ctorSerializedLambda = ClassLoaderWrapper.LoadClassCritical("java.lang.invoke.SerializedLambda").GetMethodWrapper(StringConstants.INIT, ! "(Ljava.lang.Class;Ljava.lang.String;Ljava.lang.String;Ljava.lang.String;ILjava.lang.String;Ljava.lang.String;Ljava.lang.String;Ljava.lang.String;[Ljava.lang.Object;)V", false); ! ctorSerializedLambda.Link(); ! ctorSerializedLambda.EmitNewobj(ilgen); ! ilgen.Emit(OpCodes.Ret); ! ilgen.DoEmit(); ! } ! ! return ctor; ! } ! ! private static void EmitDispatch(DynamicTypeWrapper.FinishContext context, TypeWrapper[] args, TypeBuilder tb, MethodWrapper interfaceMethod, TypeWrapper[] implParameters, ! ClassFile.ConstantPoolItemMethodHandle implMethod, ClassFile.ConstantPoolItemMethodType instantiatedMethodType, FieldBuilder[] capturedFields) ! { MethodBuilder mb = interfaceMethod.GetDefineMethodHelper().DefineMethod(context.TypeWrapper, tb, interfaceMethod.RealName, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final); ! CodeEmitter ilgen = CodeEmitter.Create(mb); ! for (int i = 0; i < capturedFields.Length; i++) { ilgen.EmitLdarg(0); *************** *** 412,416 **** { ilgen.EmitLdarg(i + 1); ! TypeWrapper Ui = samMethodType.GetArgTypes()[i]; TypeWrapper Ti = instantiatedMethodType.GetArgTypes()[i]; TypeWrapper Aj = implParameters[i + k]; --- 495,499 ---- { ilgen.EmitLdarg(i + 1); ! TypeWrapper Ui = interfaceMethod.GetParameters()[i]; TypeWrapper Ti = instantiatedMethodType.GetArgTypes()[i]; TypeWrapper Aj = implParameters[i + k]; *************** *** 547,592 **** ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); - - // writeReplace method - if (serializable) - { - MethodBuilder writeReplace = tb.DefineMethod("writeReplace", MethodAttributes.Private, Types.Object, Type.EmptyTypes); - ilgen = CodeEmitter.Create(writeReplace); - context.TypeWrapper.EmitClassLiteral(ilgen); - ilgen.Emit(OpCodes.Ldstr, interfaceType.Name.Replace('.', '/')); - ilgen.Emit(OpCodes.Ldstr, interfaceMethod.Name); - ilgen.Emit(OpCodes.Ldstr, interfaceMethod.Signature.Replace('.', '/')); - ilgen.EmitLdc_I4((int)implMethod.Kind); - ilgen.Emit(OpCodes.Ldstr, implMethod.Class.Replace('.', '/')); - ilgen.Emit(OpCodes.Ldstr, implMethod.Name); - ilgen.Emit(OpCodes.Ldstr, implMethod.Signature.Replace('.', '/')); - ilgen.Emit(OpCodes.Ldstr, instantiatedMethodType.Signature.Replace('.', '/')); - ilgen.EmitLdc_I4(capturedFields.Length); - ilgen.Emit(OpCodes.Newarr, Types.Object); - for (int i = 0; i < capturedFields.Length; i++) - { - ilgen.Emit(OpCodes.Dup); - ilgen.EmitLdc_I4(i); - ilgen.EmitLdarg(0); - ilgen.Emit(OpCodes.Ldfld, capturedFields[i]); - if (args[i].IsPrimitive) - { - Boxer.EmitBox(ilgen, args[i]); - } - else if (args[i].IsGhost) - { - args[i].EmitConvSignatureTypeToStackType(ilgen); - } - ilgen.Emit(OpCodes.Stelem, Types.Object); - } - MethodWrapper ctorSerializedLambda = ClassLoaderWrapper.LoadClassCritical("java.lang.invoke.SerializedLambda").GetMethodWrapper(StringConstants.INIT, - "(Ljava.lang.Class;Ljava.lang.String;Ljava.lang.String;Ljava.lang.String;ILjava.lang.String;Ljava.lang.String;Ljava.lang.String;Ljava.lang.String;[Ljava.lang.Object;)V", false); - ctorSerializedLambda.Link(); - ctorSerializedLambda.EmitNewobj(ilgen); - ilgen.Emit(OpCodes.Ret); - ilgen.DoEmit(); - } - - return ctor; } --- 630,633 ---- *************** *** 700,704 **** } ! private static bool CheckSupportedInterfaces(TypeWrapper caller, TypeWrapper tw, TypeWrapper[] markers, out MethodWrapper[] methodList) { // we don't need to check for unloadable, because we already did that while validating the invoke signature --- 741,745 ---- } ! private static bool CheckSupportedInterfaces(TypeWrapper caller, TypeWrapper tw, TypeWrapper[] markers, ClassFile.ConstantPoolItemMethodType[] bridges, out MethodWrapper[] methodList) { // we don't need to check for unloadable, because we already did that while validating the invoke signature *************** *** 710,714 **** Dictionary<MethodKey, MethodWrapper> methods = new Dictionary<MethodKey,MethodWrapper>(); int abstractMethodCount = 0; ! if (GatherAllInterfaceMethods(tw, methods, ref abstractMethodCount) && abstractMethodCount == 1) { foreach (TypeWrapper marker in markers) --- 751,756 ---- Dictionary<MethodKey, MethodWrapper> methods = new Dictionary<MethodKey,MethodWrapper>(); int abstractMethodCount = 0; ! int bridgeMethodCount = 0; ! if (GatherAllInterfaceMethods(tw, bridges, methods, ref abstractMethodCount, ref bridgeMethodCount) && abstractMethodCount == 1) { foreach (TypeWrapper marker in markers) *************** *** 719,723 **** return false; } ! if (!GatherAllInterfaceMethods(marker, methods, ref abstractMethodCount) || abstractMethodCount != 1) { methodList = null; --- 761,765 ---- return false; } ! if (!GatherAllInterfaceMethods(marker, null, methods, ref abstractMethodCount, ref bridgeMethodCount) || abstractMethodCount != 1) { methodList = null; *************** *** 725,728 **** --- 767,775 ---- } } + if (bridges != null && bridgeMethodCount != bridges.Length) + { + methodList = null; + return false; + } methodList = new MethodWrapper[methods.Count]; methods.Values.CopyTo(methodList, 0); *************** *** 733,737 **** } ! private static bool GatherAllInterfaceMethods(TypeWrapper tw, Dictionary<MethodKey, MethodWrapper> methods, ref int abstractMethodCount) { foreach (MethodWrapper mw in tw.GetMethods()) --- 780,785 ---- } ! private static bool GatherAllInterfaceMethods(TypeWrapper tw, ClassFile.ConstantPoolItemMethodType[] bridges, Dictionary<MethodKey, MethodWrapper> methods, ! ref int abstractMethodCount, ref int bridgeMethodCount) { foreach (MethodWrapper mw in tw.GetMethods()) *************** *** 763,767 **** if (mw.IsAbstract && !IsObjectMethod(mw)) { ! abstractMethodCount++; } } --- 811,822 ---- if (mw.IsAbstract && !IsObjectMethod(mw)) { ! if (bridges != null && IsBridge(mw, bridges)) ! { ! bridgeMethodCount++; ! } ! else ! { ! abstractMethodCount++; ! } } } *************** *** 775,779 **** foreach (TypeWrapper tw1 in tw.Interfaces) { ! if (!GatherAllInterfaceMethods(tw1, methods, ref abstractMethodCount)) { return false; --- 830,834 ---- foreach (TypeWrapper tw1 in tw.Interfaces) { ! if (!GatherAllInterfaceMethods(tw1, bridges, methods, ref abstractMethodCount, ref bridgeMethodCount)) { return false; *************** *** 783,786 **** --- 838,853 ---- } + private static bool IsBridge(MethodWrapper mw, ClassFile.ConstantPoolItemMethodType[] bridges) + { + foreach (ClassFile.ConstantPoolItemMethodType bridge in bridges) + { + if (bridge.Signature == mw.Signature) + { + return true; + } + } + return false; + } + private static bool IsObjectMethod(MethodWrapper mw) { |
|
From: Jeroen F. <jfr...@us...> - 2014-07-08 13:22:32
|
Update of /cvsroot/ikvm/ikvm/runtime In directory sfp-cvs-1.v30.ch3.sourceforge.com:/tmp/cvs-serv26568 Modified Files: LambdaMetafactory.cs Log Message: Fixed serialization issue. Index: LambdaMetafactory.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/LambdaMetafactory.cs,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** LambdaMetafactory.cs 8 Jul 2014 11:21:12 -0000 1.4 --- LambdaMetafactory.cs 8 Jul 2014 13:22:29 -0000 1.5 *************** *** 193,197 **** tb.AddInterfaceImplementation(marker.TypeAsBaseType); } ! ctor = CreateConstructorAndDispatch(context, cpi.GetArgTypes(), tb, interfaceMethod, implParameters, samMethodType, implMethod, instantiatedMethodType, serializable); AddDefaultInterfaceMethods(context, methodList, tb); return true; --- 193,197 ---- tb.AddInterfaceImplementation(marker.TypeAsBaseType); } ! ctor = CreateConstructorAndDispatch(context, interfaceType, cpi.GetArgTypes(), tb, interfaceMethod, implParameters, samMethodType, implMethod, instantiatedMethodType, serializable); AddDefaultInterfaceMethods(context, methodList, tb); return true; *************** *** 357,361 **** } ! private static MethodBuilder CreateConstructorAndDispatch(DynamicTypeWrapper.FinishContext context, TypeWrapper[] args, TypeBuilder tb, MethodWrapper interfaceMethod, TypeWrapper[] implParameters, ClassFile.ConstantPoolItemMethodType samMethodType, ClassFile.ConstantPoolItemMethodHandle implMethod, ClassFile.ConstantPoolItemMethodType instantiatedMethodType, bool serializable) --- 357,361 ---- } ! private static MethodBuilder CreateConstructorAndDispatch(DynamicTypeWrapper.FinishContext context, TypeWrapper interfaceType, TypeWrapper[] args, TypeBuilder tb, MethodWrapper interfaceMethod, TypeWrapper[] implParameters, ClassFile.ConstantPoolItemMethodType samMethodType, ClassFile.ConstantPoolItemMethodHandle implMethod, ClassFile.ConstantPoolItemMethodType instantiatedMethodType, bool serializable) *************** *** 554,558 **** ilgen = CodeEmitter.Create(writeReplace); context.TypeWrapper.EmitClassLiteral(ilgen); ! ilgen.Emit(OpCodes.Ldstr, interfaceMethod.DeclaringType.Name.Replace('.', '/')); ilgen.Emit(OpCodes.Ldstr, interfaceMethod.Name); ilgen.Emit(OpCodes.Ldstr, interfaceMethod.Signature.Replace('.', '/')); --- 554,558 ---- ilgen = CodeEmitter.Create(writeReplace); context.TypeWrapper.EmitClassLiteral(ilgen); ! ilgen.Emit(OpCodes.Ldstr, interfaceType.Name.Replace('.', '/')); ilgen.Emit(OpCodes.Ldstr, interfaceMethod.Name); ilgen.Emit(OpCodes.Ldstr, interfaceMethod.Signature.Replace('.', '/')); |
|
From: Jeroen F. <jfr...@us...> - 2014-07-08 11:21:14
|
Update of /cvsroot/ikvm/ikvm/runtime In directory sfp-cvs-1.v30.ch3.sourceforge.com:/tmp/cvs-serv19154 Modified Files: LambdaMetafactory.cs Log Message: Added support for marker interfaces. Index: LambdaMetafactory.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/LambdaMetafactory.cs,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** LambdaMetafactory.cs 8 Jul 2014 08:44:08 -0000 1.3 --- LambdaMetafactory.cs 8 Jul 2014 11:21:12 -0000 1.4 *************** *** 72,87 **** } bool serializable = false; if (bsm.ArgumentCount > 3) { AltFlags flags = (AltFlags)classFile.GetConstantPoolConstantInteger(bsm.GetArgument(3)); serializable = (flags & AltFlags.Serializable) != 0; if ((flags & AltFlags.Markers) != 0) { ! Fail("markers"); ! return false; } if ((flags & AltFlags.Bridges) != 0) { ! int bridgeCount = classFile.GetConstantPoolConstantInteger(bsm.GetArgument(4)); if (bridgeCount != 0) { --- 72,96 ---- } bool serializable = false; + TypeWrapper[] markers = TypeWrapper.EmptyArray; if (bsm.ArgumentCount > 3) { AltFlags flags = (AltFlags)classFile.GetConstantPoolConstantInteger(bsm.GetArgument(3)); serializable = (flags & AltFlags.Serializable) != 0; + int argpos = 4; if ((flags & AltFlags.Markers) != 0) { ! markers = new TypeWrapper[classFile.GetConstantPoolConstantInteger(bsm.GetArgument(argpos++))]; ! for (int i = 0; i < markers.Length; i++) ! { ! if ((markers[i] = classFile.GetConstantPoolClassType(bsm.GetArgument(argpos++))).IsUnloadable) ! { ! Fail("unloadable marker"); ! return false; ! } ! } } if ((flags & AltFlags.Bridges) != 0) { ! int bridgeCount = classFile.GetConstantPoolConstantInteger(bsm.GetArgument(argpos++)); if (bridgeCount != 0) { *************** *** 103,114 **** TypeWrapper interfaceType = cpi.GetRetType(); MethodWrapper[] methodList; ! if (!IsSupportedInterface(interfaceType, out methodList)) ! { ! Fail("interfaceType " + interfaceType.Name); ! return false; ! } ! if (!interfaceType.IsAccessibleFrom(context.TypeWrapper)) { ! Fail("interfaceType not accessible"); return false; } --- 112,118 ---- TypeWrapper interfaceType = cpi.GetRetType(); MethodWrapper[] methodList; ! if (!CheckSupportedInterfaces(context.TypeWrapper, interfaceType, markers, out methodList)) { ! Fail("unsupported interface"); return false; } *************** *** 181,188 **** // but should we decide to do that, we'd need to somehow communicate to AnonymousTypeWrapper what the 'real' interface is tb.AddInterfaceImplementation(interfaceType.TypeAsBaseType); ! if (serializable) { tb.AddInterfaceImplementation(CoreClasses.java.io.Serializable.Wrapper.TypeAsBaseType); } ctor = CreateConstructorAndDispatch(context, cpi.GetArgTypes(), tb, interfaceMethod, implParameters, samMethodType, implMethod, instantiatedMethodType, serializable); AddDefaultInterfaceMethods(context, methodList, tb); --- 185,196 ---- // but should we decide to do that, we'd need to somehow communicate to AnonymousTypeWrapper what the 'real' interface is tb.AddInterfaceImplementation(interfaceType.TypeAsBaseType); ! if (serializable && Array.IndexOf(markers, CoreClasses.java.io.Serializable.Wrapper) == -1) { tb.AddInterfaceImplementation(CoreClasses.java.io.Serializable.Wrapper.TypeAsBaseType); } + foreach (TypeWrapper marker in markers) + { + tb.AddInterfaceImplementation(marker.TypeAsBaseType); + } ctor = CreateConstructorAndDispatch(context, cpi.GetArgTypes(), tb, interfaceMethod, implParameters, samMethodType, implMethod, instantiatedMethodType, serializable); AddDefaultInterfaceMethods(context, methodList, tb); *************** *** 692,699 **** } ! private static bool IsSupportedInterface(TypeWrapper tw, out MethodWrapper[] methodList) { // we don't need to check for unloadable, because we already did that while validating the invoke signature ! if (!tw.IsInterface || tw.IsGhost) { methodList = null; --- 700,707 ---- } ! private static bool CheckSupportedInterfaces(TypeWrapper caller, TypeWrapper tw, TypeWrapper[] markers, out MethodWrapper[] methodList) { // we don't need to check for unloadable, because we already did that while validating the invoke signature ! if (!tw.IsInterface || tw.IsGhost || !tw.IsAccessibleFrom(caller)) { methodList = null; *************** *** 704,707 **** --- 712,728 ---- if (GatherAllInterfaceMethods(tw, methods, ref abstractMethodCount) && abstractMethodCount == 1) { + foreach (TypeWrapper marker in markers) + { + if (!marker.IsInterface || marker.IsGhost || !marker.IsAccessibleFrom(caller)) + { + methodList = null; + return false; + } + if (!GatherAllInterfaceMethods(marker, methods, ref abstractMethodCount) || abstractMethodCount != 1) + { + methodList = null; + return false; + } + } methodList = new MethodWrapper[methods.Count]; methods.Values.CopyTo(methodList, 0); |
|
From: Jeroen F. <jfr...@us...> - 2014-07-08 08:44:10
|
Update of /cvsroot/ikvm/ikvm/runtime In directory sfp-cvs-1.v30.ch3.sourceforge.com:/tmp/cvs-serv10390 Modified Files: LambdaMetafactory.cs compiler.cs Log Message: Use the same nested type for lambdas that are created with an invokedynamic to the same constant pool item (so that deserialization uses the same class as the original). Index: LambdaMetafactory.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/LambdaMetafactory.cs,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** LambdaMetafactory.cs 8 Jul 2014 08:23:41 -0000 1.2 --- LambdaMetafactory.cs 8 Jul 2014 08:44:08 -0000 1.3 *************** *** 36,42 **** namespace IKVM.Internal { ! static class LambdaMetafactory { ! internal static bool Emit(DynamicTypeWrapper.FinishContext context, ClassFile classFile, ClassFile.ConstantPoolItemInvokeDynamic cpi, CodeEmitter ilgen) { ClassFile.BootstrapMethod bsm = classFile.GetBootstrapMethod(cpi.BootstrapMethod); --- 36,44 ---- namespace IKVM.Internal { ! sealed class LambdaMetafactory { ! private MethodBuilder ctor; ! ! internal static bool Emit(DynamicTypeWrapper.FinishContext context, ClassFile classFile, int constantPoolIndex, ClassFile.ConstantPoolItemInvokeDynamic cpi, CodeEmitter ilgen) { ClassFile.BootstrapMethod bsm = classFile.GetBootstrapMethod(cpi.BootstrapMethod); *************** *** 45,49 **** return false; } ! if (!EmitImpl(context, classFile, cpi, bsm, ilgen)) { #if STATIC_COMPILER --- 47,52 ---- return false; } ! LambdaMetafactory lmf = context.GetValue<LambdaMetafactory>(constantPoolIndex); ! if (lmf.ctor == null && !lmf.EmitImpl(context, classFile, cpi, bsm, ilgen)) { #if STATIC_COMPILER *************** *** 55,62 **** return false; } return true; } ! private static bool EmitImpl(DynamicTypeWrapper.FinishContext context, ClassFile classFile, ClassFile.ConstantPoolItemInvokeDynamic cpi, ClassFile.BootstrapMethod bsm, CodeEmitter ilgen) { if (HasUnloadable(cpi)) --- 58,68 ---- return false; } + ilgen.Emit(OpCodes.Newobj, lmf.ctor); + // the CLR verification rules about type merging mean we have to explicitly cast to the interface type here + ilgen.Emit(OpCodes.Castclass, cpi.GetRetType().TypeAsBaseType); return true; } ! private bool EmitImpl(DynamicTypeWrapper.FinishContext context, ClassFile classFile, ClassFile.ConstantPoolItemInvokeDynamic cpi, ClassFile.BootstrapMethod bsm, CodeEmitter ilgen) { if (HasUnloadable(cpi)) *************** *** 179,187 **** tb.AddInterfaceImplementation(CoreClasses.java.io.Serializable.Wrapper.TypeAsBaseType); } ! MethodBuilder ctor = CreateConstructorAndDispatch(context, cpi.GetArgTypes(), tb, interfaceMethod, implParameters, samMethodType, implMethod, instantiatedMethodType, serializable); AddDefaultInterfaceMethods(context, methodList, tb); - ilgen.Emit(OpCodes.Newobj, ctor); - // the CLR verification rules about type merging mean we have to explicitly cast to the interface type here - ilgen.Emit(OpCodes.Castclass, interfaceType.TypeAsBaseType); return true; } --- 185,190 ---- tb.AddInterfaceImplementation(CoreClasses.java.io.Serializable.Wrapper.TypeAsBaseType); } ! ctor = CreateConstructorAndDispatch(context, cpi.GetArgTypes(), tb, interfaceMethod, implParameters, samMethodType, implMethod, instantiatedMethodType, serializable); AddDefaultInterfaceMethods(context, methodList, tb); return true; } Index: compiler.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/compiler.cs,v retrieving revision 1.251 retrieving revision 1.252 diff -C2 -d -r1.251 -r1.252 *** compiler.cs 1 Jul 2014 15:12:34 -0000 1.251 --- compiler.cs 8 Jul 2014 08:44:08 -0000 1.252 *************** *** 1435,1440 **** ClassFile.ConstantPoolItemInvokeDynamic cpi = classFile.GetInvokeDynamic(instr.Arg1); CastInterfaceArgs(null, cpi.GetArgTypes(), i, false); ! EmitInvokeDynamic(cpi); ! EmitReturnTypeConversion(cpi.GetRetType()); nonleaf = true; break; --- 1435,1443 ---- ClassFile.ConstantPoolItemInvokeDynamic cpi = classFile.GetInvokeDynamic(instr.Arg1); CastInterfaceArgs(null, cpi.GetArgTypes(), i, false); ! if (!LambdaMetafactory.Emit(context, classFile, instr.Arg1, cpi, ilGenerator)) ! { ! EmitInvokeDynamic(cpi); ! EmitReturnTypeConversion(cpi.GetRetType()); ! } nonleaf = true; break; *************** *** 3209,3217 **** private void EmitInvokeDynamic(ClassFile.ConstantPoolItemInvokeDynamic cpi) { - if (LambdaMetafactory.Emit(context, classFile, cpi, ilGenerator)) - { - // we intrinsified the lambda factory - return; - } CodeEmitter ilgen = ilGenerator; TypeWrapper[] args = cpi.GetArgTypes(); --- 3212,3215 ---- |
|
From: Jeroen F. <jfr...@us...> - 2014-07-08 08:23:44
|
Update of /cvsroot/ikvm/ikvm/runtime In directory sfp-cvs-1.v30.ch3.sourceforge.com:/tmp/cvs-serv9277 Modified Files: DynamicTypeWrapper.cs LambdaMetafactory.cs TypeWrapper.cs Log Message: Added support for intrinsifying serializable lambdas. Index: TypeWrapper.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/TypeWrapper.cs,v retrieving revision 1.475 retrieving revision 1.476 diff -C2 -d -r1.475 -r1.476 *** TypeWrapper.cs 7 Jul 2014 07:40:35 -0000 1.475 --- TypeWrapper.cs 8 Jul 2014 08:23:41 -0000 1.476 *************** *** 5747,5750 **** --- 5747,5766 ---- { } + + protected override void LazyPublishMembers() + { + MethodInfo mi = type.GetMethod("writeReplace", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly, null, Type.EmptyTypes, null); + if (mi != null) + { + SetMethods(new MethodWrapper[] { + new TypicalMethodWrapper(this, "writeReplace", "()Ljava.lang.Object;", mi, CoreClasses.java.lang.Object.Wrapper, TypeWrapper.EmptyArray, Modifiers.Private, MemberFlags.None) + }); + } + else + { + SetMethods(MethodWrapper.EmptyArray); + } + SetFields(FieldWrapper.EmptyArray); + } } } Index: LambdaMetafactory.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/LambdaMetafactory.cs,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** LambdaMetafactory.cs 1 Jul 2014 15:12:34 -0000 1.1 --- LambdaMetafactory.cs 8 Jul 2014 08:23:41 -0000 1.2 *************** *** 41,45 **** { ClassFile.BootstrapMethod bsm = classFile.GetBootstrapMethod(cpi.BootstrapMethod); ! if (!IsLambdaMetafactory(classFile, bsm)) { return false; --- 41,45 ---- { ClassFile.BootstrapMethod bsm = classFile.GetBootstrapMethod(cpi.BootstrapMethod); ! if (!IsLambdaMetafactory(classFile, bsm) && !IsLambdaAltMetafactory(classFile, bsm)) { return false; *************** *** 65,68 **** --- 65,88 ---- return false; } + bool serializable = false; + if (bsm.ArgumentCount > 3) + { + AltFlags flags = (AltFlags)classFile.GetConstantPoolConstantInteger(bsm.GetArgument(3)); + serializable = (flags & AltFlags.Serializable) != 0; + if ((flags & AltFlags.Markers) != 0) + { + Fail("markers"); + return false; + } + if ((flags & AltFlags.Bridges) != 0) + { + int bridgeCount = classFile.GetConstantPoolConstantInteger(bsm.GetArgument(4)); + if (bridgeCount != 0) + { + Fail("bridges"); + return false; + } + } + } ClassFile.ConstantPoolItemMethodType samMethodType = classFile.GetConstantPoolConstantMethodType(bsm.GetArgument(0)); ClassFile.ConstantPoolItemMethodHandle implMethod = classFile.GetConstantPoolConstantMethodHandle(bsm.GetArgument(1)); *************** *** 87,90 **** --- 107,115 ---- return false; } + if (serializable && Array.Exists(methodList, delegate(MethodWrapper mw) { return mw.Name == "writeReplace" && mw.Signature == "()Ljava.lang.Object;"; })) + { + Fail("writeReplace"); + return false; + } if (!IsSupportedImplMethod(implMethod, context.TypeWrapper, cpi.GetArgTypes(), instantiatedMethodType)) { *************** *** 150,156 **** // but should we decide to do that, we'd need to somehow communicate to AnonymousTypeWrapper what the 'real' interface is tb.AddInterfaceImplementation(interfaceType.TypeAsBaseType); ! TypeWrapperFactory factory = context.TypeWrapper.GetClassLoader().GetTypeWrapperFactory(); ! MethodBuilder ctor = CreateConstructorAndDispatch(factory, cpi.GetArgTypes(), tb, interfaceMethod, implParameters, samMethodType, implMethod, instantiatedMethodType); ! AddDefaultInterfaceMethods(factory, methodList, tb); ilgen.Emit(OpCodes.Newobj, ctor); // the CLR verification rules about type merging mean we have to explicitly cast to the interface type here --- 175,184 ---- // but should we decide to do that, we'd need to somehow communicate to AnonymousTypeWrapper what the 'real' interface is tb.AddInterfaceImplementation(interfaceType.TypeAsBaseType); ! if (serializable) ! { ! tb.AddInterfaceImplementation(CoreClasses.java.io.Serializable.Wrapper.TypeAsBaseType); ! } ! MethodBuilder ctor = CreateConstructorAndDispatch(context, cpi.GetArgTypes(), tb, interfaceMethod, implParameters, samMethodType, implMethod, instantiatedMethodType, serializable); ! AddDefaultInterfaceMethods(context, methodList, tb); ilgen.Emit(OpCodes.Newobj, ctor); // the CLR verification rules about type merging mean we have to explicitly cast to the interface type here *************** *** 318,323 **** } ! private static MethodBuilder CreateConstructorAndDispatch(TypeWrapperFactory context, TypeWrapper[] args, TypeBuilder tb, MethodWrapper interfaceMethod, TypeWrapper[] implParameters, ! ClassFile.ConstantPoolItemMethodType samMethodType, ClassFile.ConstantPoolItemMethodHandle implMethod, ClassFile.ConstantPoolItemMethodType instantiatedMethodType) { // captured values --- 346,352 ---- } ! private static MethodBuilder CreateConstructorAndDispatch(DynamicTypeWrapper.FinishContext context, TypeWrapper[] args, TypeBuilder tb, ! MethodWrapper interfaceMethod, TypeWrapper[] implParameters, ClassFile.ConstantPoolItemMethodType samMethodType, ClassFile.ConstantPoolItemMethodHandle implMethod, ! ClassFile.ConstantPoolItemMethodType instantiatedMethodType, bool serializable) { // captured values *************** *** 350,354 **** // dispatch method ! MethodBuilder mb = interfaceMethod.GetDefineMethodHelper().DefineMethod(context, tb, interfaceMethod.RealName, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final); ilgen = CodeEmitter.Create(mb); for (int i = 0; i < capturedTypes.Length; i++) --- 379,383 ---- // dispatch method ! MethodBuilder mb = interfaceMethod.GetDefineMethodHelper().DefineMethod(context.TypeWrapper, tb, interfaceMethod.RealName, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final); ilgen = CodeEmitter.Create(mb); for (int i = 0; i < capturedTypes.Length; i++) *************** *** 508,511 **** --- 537,580 ---- ilgen.DoEmit(); + // writeReplace method + if (serializable) + { + MethodBuilder writeReplace = tb.DefineMethod("writeReplace", MethodAttributes.Private, Types.Object, Type.EmptyTypes); + ilgen = CodeEmitter.Create(writeReplace); + context.TypeWrapper.EmitClassLiteral(ilgen); + ilgen.Emit(OpCodes.Ldstr, interfaceMethod.DeclaringType.Name.Replace('.', '/')); + ilgen.Emit(OpCodes.Ldstr, interfaceMethod.Name); + ilgen.Emit(OpCodes.Ldstr, interfaceMethod.Signature.Replace('.', '/')); + ilgen.EmitLdc_I4((int)implMethod.Kind); + ilgen.Emit(OpCodes.Ldstr, implMethod.Class.Replace('.', '/')); + ilgen.Emit(OpCodes.Ldstr, implMethod.Name); + ilgen.Emit(OpCodes.Ldstr, implMethod.Signature.Replace('.', '/')); + ilgen.Emit(OpCodes.Ldstr, instantiatedMethodType.Signature.Replace('.', '/')); + ilgen.EmitLdc_I4(capturedFields.Length); + ilgen.Emit(OpCodes.Newarr, Types.Object); + for (int i = 0; i < capturedFields.Length; i++) + { + ilgen.Emit(OpCodes.Dup); + ilgen.EmitLdc_I4(i); + ilgen.EmitLdarg(0); + ilgen.Emit(OpCodes.Ldfld, capturedFields[i]); + if (args[i].IsPrimitive) + { + Boxer.EmitBox(ilgen, args[i]); + } + else if (args[i].IsGhost) + { + args[i].EmitConvSignatureTypeToStackType(ilgen); + } + ilgen.Emit(OpCodes.Stelem, Types.Object); + } + MethodWrapper ctorSerializedLambda = ClassLoaderWrapper.LoadClassCritical("java.lang.invoke.SerializedLambda").GetMethodWrapper(StringConstants.INIT, + "(Ljava.lang.Class;Ljava.lang.String;Ljava.lang.String;Ljava.lang.String;ILjava.lang.String;Ljava.lang.String;Ljava.lang.String;Ljava.lang.String;[Ljava.lang.Object;)V", false); + ctorSerializedLambda.Link(); + ctorSerializedLambda.EmitNewobj(ilgen); + ilgen.Emit(OpCodes.Ret); + ilgen.DoEmit(); + } + return ctor; } *************** *** 551,566 **** } ! private static void AddDefaultInterfaceMethods(TypeWrapperFactory context, MethodWrapper[] methodList, TypeBuilder tb) { foreach (MethodWrapper mw in methodList) { if (!mw.IsAbstract) { ! MethodBuilder mb = mw.GetDefineMethodHelper().DefineMethod(context, tb, mw.RealName, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final); DynamicTypeWrapper.FinishContext.EmitCallDefaultInterfaceMethod(mb, mw); } else if (IsObjectMethod(mw)) { ! MethodBuilder mb = mw.GetDefineMethodHelper().DefineMethod(context, tb, mw.RealName, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final); CodeEmitter ilgen = CodeEmitter.Create(mb); for (int i = 0, count = mw.GetParameters().Length; i <= count; i++) --- 620,636 ---- } ! private static void AddDefaultInterfaceMethods(DynamicTypeWrapper.FinishContext context, MethodWrapper[] methodList, TypeBuilder tb) { + TypeWrapperFactory factory = context.TypeWrapper.GetClassLoader().GetTypeWrapperFactory(); foreach (MethodWrapper mw in methodList) { if (!mw.IsAbstract) { ! MethodBuilder mb = mw.GetDefineMethodHelper().DefineMethod(factory, tb, mw.RealName, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final); DynamicTypeWrapper.FinishContext.EmitCallDefaultInterfaceMethod(mb, mw); } else if (IsObjectMethod(mw)) { ! MethodBuilder mb = mw.GetDefineMethodHelper().DefineMethod(factory, tb, mw.RealName, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final); CodeEmitter ilgen = CodeEmitter.Create(mb); for (int i = 0, count = mw.GetParameters().Length; i <= count; i++) *************** *** 742,745 **** --- 812,874 ---- } + [Flags] + enum AltFlags + { + Serializable = 1, + Markers = 2, + Bridges = 4, + Mask = Serializable | Markers | Bridges + } + + private static bool IsLambdaAltMetafactory(ClassFile classFile, ClassFile.BootstrapMethod bsm) + { + ClassFile.ConstantPoolItemMethodHandle mh; + AltFlags flags; + int argpos = 4; + return bsm.ArgumentCount >= 4 + && (mh = classFile.GetConstantPoolConstantMethodHandle(bsm.BootstrapMethodIndex)).Kind == ClassFile.RefKind.invokeStatic + && IsLambdaAltMetafactory(mh.Member) + && classFile.GetConstantPoolConstantType(bsm.GetArgument(0)) == ClassFile.ConstantType.MethodType + && classFile.GetConstantPoolConstantType(bsm.GetArgument(1)) == ClassFile.ConstantType.MethodHandle + && classFile.GetConstantPoolConstantType(bsm.GetArgument(2)) == ClassFile.ConstantType.MethodType + && classFile.GetConstantPoolConstantType(bsm.GetArgument(3)) == ClassFile.ConstantType.Integer + && ((flags = (AltFlags)classFile.GetConstantPoolConstantInteger(bsm.GetArgument(3))) & ~AltFlags.Mask) == 0 + && ((flags & AltFlags.Markers) == 0 || CheckOptionalArgs(classFile, bsm, ClassFile.ConstantType.Class, ref argpos)) + && ((flags & AltFlags.Bridges) == 0 || CheckOptionalArgs(classFile, bsm, ClassFile.ConstantType.MethodType, ref argpos)) + && argpos == bsm.ArgumentCount; + } + + private static bool IsLambdaAltMetafactory(MemberWrapper mw) + { + return mw.Name == "altMetafactory" + && mw.Signature == "(Ljava.lang.invoke.MethodHandles$Lookup;Ljava.lang.String;Ljava.lang.invoke.MethodType;[Ljava.lang.Object;)Ljava.lang.invoke.CallSite;" + && mw.DeclaringType.Name == "java.lang.invoke.LambdaMetafactory"; + } + + private static bool CheckOptionalArgs(ClassFile classFile, ClassFile.BootstrapMethod bsm, ClassFile.ConstantType type, ref int argpos) + { + if (bsm.ArgumentCount - argpos < 1) + { + return false; + } + if (classFile.GetConstantPoolConstantType(bsm.GetArgument(argpos)) != ClassFile.ConstantType.Integer) + { + return false; + } + int count = classFile.GetConstantPoolConstantInteger(bsm.GetArgument(argpos++)); + if (count < 0 || bsm.ArgumentCount - argpos < count) + { + return false; + } + for (int i = 0; i < count; i++) + { + if (classFile.GetConstantPoolConstantType(bsm.GetArgument(argpos++)) != type) + { + return false; + } + } + return true; + } + private static bool HasUnloadable(ClassFile.ConstantPoolItemInvokeDynamic cpi) { Index: DynamicTypeWrapper.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/DynamicTypeWrapper.cs,v retrieving revision 1.253 retrieving revision 1.254 diff -C2 -d -r1.253 -r1.254 *** DynamicTypeWrapper.cs 4 Jul 2014 11:06:06 -0000 1.253 --- DynamicTypeWrapper.cs 8 Jul 2014 08:23:41 -0000 1.254 *************** *** 4000,4004 **** } ! internal TypeWrapper TypeWrapper { get { return wrapper; } --- 4000,4004 ---- } ! internal DynamicTypeWrapper TypeWrapper { get { return wrapper; } |
|
From: Jeroen F. <jfr...@us...> - 2014-07-07 07:40:37
|
Update of /cvsroot/ikvm/ikvm/runtime In directory sfp-cvs-1.v30.ch3.sourceforge.com:/tmp/cvs-serv9504/runtime Modified Files: DynamicClassLoader.cs TypeWrapper.cs Log Message: Simplified the anonymous class name mangling. Index: TypeWrapper.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/TypeWrapper.cs,v retrieving revision 1.474 retrieving revision 1.475 diff -C2 -d -r1.474 -r1.475 *** TypeWrapper.cs 4 Jul 2014 11:06:06 -0000 1.474 --- TypeWrapper.cs 7 Jul 2014 07:40:35 -0000 1.475 *************** *** 5696,5700 **** internal AnonymousTypeWrapper(Type type) ! : base(TypeFlags.None, Modifiers.Final | Modifiers.Synthetic, GetName(type)) { this.type = type; --- 5696,5700 ---- internal AnonymousTypeWrapper(Type type) ! : base(TypeFlags.Anonymous, Modifiers.Final | Modifiers.Synthetic, GetName(type)) { this.type = type; *************** *** 5708,5716 **** } ! internal static string GetName(Type type) { return ClassLoaderWrapper.GetWrapperFromType(type.DeclaringType).Name ! + type.Name.Replace(NestedTypeName.IntrinsifiedAnonymousClass, "$$Lambda$") ! + "/" + (type.GetHashCode() & Int32.MaxValue); } --- 5708,5715 ---- } ! private static string GetName(Type type) { return ClassLoaderWrapper.GetWrapperFromType(type.DeclaringType).Name ! + type.Name.Replace(NestedTypeName.IntrinsifiedAnonymousClass, "$$Lambda$"); } Index: DynamicClassLoader.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/DynamicClassLoader.cs,v retrieving revision 1.84 retrieving revision 1.85 diff -C2 -d -r1.84 -r1.85 *** DynamicClassLoader.cs 15 May 2014 06:13:34 -0000 1.84 --- DynamicClassLoader.cs 7 Jul 2014 07:40:35 -0000 1.85 *************** *** 244,251 **** { // we're defining an anonymous class, so we don't need any locking ! java.lang.Class clazz = TieClassAndWrapper(type, protectionDomain); ! // for OpenJDK compatibility and debugging convenience we modify the class name to ! // include the identity hashcode of the class object ! clazz.name = f.Name + "/" + java.lang.System.identityHashCode(clazz); return type; } --- 244,248 ---- { // we're defining an anonymous class, so we don't need any locking ! TieClassAndWrapper(type, protectionDomain); return type; } |
|
From: Jeroen F. <jfr...@us...> - 2014-07-04 11:06:09
|
Update of /cvsroot/ikvm/ikvm/runtime In directory sfp-cvs-1.v30.ch3.sourceforge.com:/tmp/cvs-serv11613 Modified Files: DynamicTypeWrapper.cs ExceptionHelper.cs TypeWrapper.cs Log Message: Include full class name of anonymous classes in stack trace (i.e. including the "/<identityHashCode>" suffix.) Index: TypeWrapper.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/TypeWrapper.cs,v retrieving revision 1.473 retrieving revision 1.474 diff -C2 -d -r1.473 -r1.474 *** TypeWrapper.cs 1 Jul 2014 15:12:34 -0000 1.473 --- TypeWrapper.cs 4 Jul 2014 11:06:06 -0000 1.474 *************** *** 1948,1951 **** --- 1948,1952 ---- ClassFormatError = 16, HasUnsupportedAbstractMethods = 32, + Anonymous = 64, } *************** *** 2365,2368 **** --- 2366,2375 ---- } + // is this an anonymous class (in the sense of Unsafe.defineAnonymousClass(), not the JLS) + internal bool IsUnsafeAnonymous + { + get { return (flags & TypeFlags.Anonymous) != 0; } + } + // a ghost is an interface that appears to be implemented by a .NET type // (e.g. System.String (aka java.lang.String) appears to implement java.lang.CharSequence, Index: ExceptionHelper.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/ExceptionHelper.cs,v retrieving revision 1.69 retrieving revision 1.70 diff -C2 -d -r1.69 -r1.70 *** ExceptionHelper.cs 13 Jun 2014 06:54:06 -0000 1.69 --- ExceptionHelper.cs 4 Jul 2014 11:06:06 -0000 1.70 *************** *** 341,344 **** --- 341,350 ---- return DotNetTypeWrapper.GetName(type); } + #if !FIRST_PASS + if(tw.IsUnsafeAnonymous) + { + return tw.ClassObject.getName(); + } + #endif return tw.Name; } Index: DynamicTypeWrapper.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/DynamicTypeWrapper.cs,v retrieving revision 1.252 retrieving revision 1.253 diff -C2 -d -r1.252 -r1.253 *** DynamicTypeWrapper.cs 1 Jul 2014 15:12:34 -0000 1.252 --- DynamicTypeWrapper.cs 4 Jul 2014 11:06:06 -0000 1.253 *************** *** 113,117 **** internal DynamicTypeWrapper(TypeWrapper host, ClassFile f, ClassLoaderWrapper classLoader, ProtectionDomain pd) #endif ! : base(f.IsInternal ? TypeFlags.InternalAccess : TypeFlags.None, f.Modifiers, f.Name) { Profiler.Count("DynamicTypeWrapper"); --- 113,117 ---- internal DynamicTypeWrapper(TypeWrapper host, ClassFile f, ClassLoaderWrapper classLoader, ProtectionDomain pd) #endif ! : base(f.IsInternal ? TypeFlags.InternalAccess : host != null ? TypeFlags.Anonymous : TypeFlags.None, f.Modifiers, f.Name) { Profiler.Count("DynamicTypeWrapper"); |
|
From: Jeroen F. <jfr...@us...> - 2014-07-04 10:21:48
|
Update of /cvsroot/ikvm/ikvm/runtime/openjdk In directory sfp-cvs-1.v30.ch3.sourceforge.com:/tmp/cvs-serv9248 Modified Files: java.lang.cs Log Message: Intrinsified lambda anonymous classes should return protection domain from host class. Index: java.lang.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/openjdk/java.lang.cs,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** java.lang.cs 23 Jun 2014 15:09:43 -0000 1.17 --- java.lang.cs 4 Jul 2014 10:21:46 -0000 1.18 *************** *** 352,355 **** --- 352,361 ---- pd = acl.GetProtectionDomain(); } + else if (wrapper is AnonymousTypeWrapper) + { + // dynamically compiled intrinsified lamdba anonymous types end up here and should get their + // protection domain from the host class + pd = ClassLoaderWrapper.GetWrapperFromType(wrapper.TypeAsTBD.DeclaringType).ClassObject.pd; + } } return pd; |
Update of /cvsroot/ikvm/ikvm/runtime In directory sfp-cvs-1.v30.ch3.sourceforge.com:/tmp/cvs-serv785/runtime Modified Files: ClassLoaderWrapper.cs DynamicTypeWrapper.cs IKVM.Runtime.8.csproj TypeWrapper.cs compiler.cs runtime.build Added Files: LambdaMetafactory.cs Log Message: Added intrinsic for LambdaMetafactory.metafactory(). Index: TypeWrapper.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/TypeWrapper.cs,v retrieving revision 1.472 retrieving revision 1.473 diff -C2 -d -r1.472 -r1.473 *** TypeWrapper.cs 13 Jun 2014 06:54:06 -0000 1.472 --- TypeWrapper.cs 1 Jul 2014 15:12:34 -0000 1.473 *************** *** 1978,1981 **** --- 1978,1982 ---- internal const string MethodHandleConstant = "__<>MHC"; internal const string MethodTypeConstant = "__<>MTC"; + internal const string IntrinsifiedAnonymousClass = "__<>Anon"; } *************** *** 5681,5683 **** --- 5682,5744 ---- } } + + // this represents an intrinsified anonymous class (currently used only by LambdaMetafactory) + sealed class AnonymousTypeWrapper : TypeWrapper + { + private readonly Type type; + + internal AnonymousTypeWrapper(Type type) + : base(TypeFlags.None, Modifiers.Final | Modifiers.Synthetic, GetName(type)) + { + this.type = type; + } + + internal static bool IsAnonymous(Type type) + { + return type.IsSpecialName + && type.Name.StartsWith(NestedTypeName.IntrinsifiedAnonymousClass, StringComparison.Ordinal) + && AttributeHelper.IsJavaModule(type.Module); + } + + internal static string GetName(Type type) + { + return ClassLoaderWrapper.GetWrapperFromType(type.DeclaringType).Name + + type.Name.Replace(NestedTypeName.IntrinsifiedAnonymousClass, "$$Lambda$") + + "/" + (type.GetHashCode() & Int32.MaxValue); + } + + internal override ClassLoaderWrapper GetClassLoader() + { + return ClassLoaderWrapper.GetWrapperFromType(type.DeclaringType).GetClassLoader(); + } + + internal override Type TypeAsTBD + { + get { return type; } + } + + internal override TypeWrapper BaseTypeWrapper + { + get { return CoreClasses.java.lang.Object.Wrapper; } + } + + internal override TypeWrapper[] Interfaces + { + get { return GetImplementedInterfacesAsTypeWrappers(type); } + } + + internal override TypeWrapper[] InnerClasses + { + get { return TypeWrapper.EmptyArray; } + } + + internal override TypeWrapper DeclaringTypeWrapper + { + get { return null; } + } + + internal override void Finish() + { + } + } } --- NEW FILE: LambdaMetafactory.cs --- /* Copyright (C) 2014 Jeroen Frijters This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. Jeroen Frijters je...@fr... */ using System; using System.Collections.Generic; using System.Diagnostics; #if STATIC_COMPILER using IKVM.Reflection; using IKVM.Reflection.Emit; using Type = IKVM.Reflection.Type; #else using System.Reflection; using System.Reflection.Emit; #endif namespace IKVM.Internal { static class LambdaMetafactory { internal static bool Emit(DynamicTypeWrapper.FinishContext context, ClassFile classFile, ClassFile.ConstantPoolItemInvokeDynamic cpi, CodeEmitter ilgen) { ClassFile.BootstrapMethod bsm = classFile.GetBootstrapMethod(cpi.BootstrapMethod); if (!IsLambdaMetafactory(classFile, bsm)) { return false; } if (!EmitImpl(context, classFile, cpi, bsm, ilgen)) { #if STATIC_COMPILER if (context.TypeWrapper.GetClassLoader().DisableDynamicBinding) { StaticCompiler.IssueMessage(Message.UnableToCreateLambdaFactory); } #endif return false; } return true; } private static bool EmitImpl(DynamicTypeWrapper.FinishContext context, ClassFile classFile, ClassFile.ConstantPoolItemInvokeDynamic cpi, ClassFile.BootstrapMethod bsm, CodeEmitter ilgen) { if (HasUnloadable(cpi)) { Fail("cpi has unloadable"); return false; } ClassFile.ConstantPoolItemMethodType samMethodType = classFile.GetConstantPoolConstantMethodType(bsm.GetArgument(0)); ClassFile.ConstantPoolItemMethodHandle implMethod = classFile.GetConstantPoolConstantMethodHandle(bsm.GetArgument(1)); ClassFile.ConstantPoolItemMethodType instantiatedMethodType = classFile.GetConstantPoolConstantMethodType(bsm.GetArgument(2)); if (HasUnloadable(samMethodType) || HasUnloadable((ClassFile.ConstantPoolItemMI)implMethod.MemberConstantPoolItem) || HasUnloadable(instantiatedMethodType)) { Fail("bsm args has unloadable"); return false; } TypeWrapper interfaceType = cpi.GetRetType(); MethodWrapper[] methodList; if (!IsSupportedInterface(interfaceType, out methodList)) { Fail("interfaceType " + interfaceType.Name); return false; } if (!interfaceType.IsAccessibleFrom(context.TypeWrapper)) { Fail("interfaceType not accessible"); return false; } if (!IsSupportedImplMethod(implMethod, context.TypeWrapper, cpi.GetArgTypes(), instantiatedMethodType)) { Fail("implMethod " + implMethod.MemberConstantPoolItem.Class + "::" + implMethod.MemberConstantPoolItem.Name + implMethod.MemberConstantPoolItem.Signature); return false; } if (!IsSubTypeOf(instantiatedMethodType, samMethodType)) { Fail("instantiatedMethodType <= samMethodType"); return false; } TypeWrapper[] implParameters = GetImplParameters(implMethod); if (cpi.GetArgTypes().Length + samMethodType.GetArgTypes().Length != implParameters.Length) { Fail("K + N = M"); return false; } for (int i = 0, K = cpi.GetArgTypes().Length; i < K; i++) { if (!cpi.GetArgTypes()[i].IsSubTypeOf(implParameters[i])) { Fail("For i=1..K, Di = Ai"); return false; } } for (int i = 0, N = samMethodType.GetArgTypes().Length, k = cpi.GetArgTypes().Length; i < N; i++) { if (!IsAdaptable(instantiatedMethodType.GetArgTypes()[i], implParameters[i + k], false)) { Fail("For i=1..N, Ti is adaptable to Aj, where j=i+k (in" + context.TypeWrapper.Name + ")"); return false; } } if (instantiatedMethodType.GetRetType() != PrimitiveTypeWrapper.VOID) { TypeWrapper Rt = instantiatedMethodType.GetRetType(); TypeWrapper Ra = GetImplReturnType(implMethod); if (Ra == PrimitiveTypeWrapper.VOID || !IsAdaptable(Ra, Rt, true)) { Fail("The return type Rt is void, or the return type Ra is not void and is adaptable to Rt"); Console.WriteLine("Ra = " + Ra.SigName); Console.WriteLine("Rt = " + Rt.SigName); return false; } } MethodWrapper interfaceMethod = null; foreach (MethodWrapper mw in methodList) { if (mw.Name == cpi.Name && mw.Signature == samMethodType.Signature) { interfaceMethod = mw; break; } } if (interfaceMethod == null || !interfaceMethod.IsAbstract || IsObjectMethod(interfaceMethod) || !MatchSignatures(interfaceMethod, samMethodType)) { Fail("interfaceMethod"); return false; } TypeBuilder tb = context.DefineAnonymousClass(); // we're not implementing the interfaces recursively (because we don't care about .NET Compact anymore), // but should we decide to do that, we'd need to somehow communicate to AnonymousTypeWrapper what the 'real' interface is tb.AddInterfaceImplementation(interfaceType.TypeAsBaseType); TypeWrapperFactory factory = context.TypeWrapper.GetClassLoader().GetTypeWrapperFactory(); MethodBuilder ctor = CreateConstructorAndDispatch(factory, cpi.GetArgTypes(), tb, interfaceMethod, implParameters, samMethodType, implMethod, instantiatedMethodType); AddDefaultInterfaceMethods(factory, methodList, tb); ilgen.Emit(OpCodes.Newobj, ctor); // the CLR verification rules about type merging mean we have to explicitly cast to the interface type here ilgen.Emit(OpCodes.Castclass, interfaceType.TypeAsBaseType); return true; } [Conditional("TRACE_LAMBDA_METAFACTORY")] private static void Fail(string msg) { Console.WriteLine("Fail: " + msg); } private static TypeWrapper[] GetImplParameters(ClassFile.ConstantPoolItemMethodHandle implMethod) { MethodWrapper mw = (MethodWrapper)implMethod.Member; TypeWrapper[] parameters = mw.GetParameters(); if (mw.IsStatic || mw.IsConstructor) { return parameters; } return ArrayUtil.Concat(mw.DeclaringType, parameters); } private static TypeWrapper GetImplReturnType(ClassFile.ConstantPoolItemMethodHandle implMethod) { return implMethod.Kind == ClassFile.RefKind.newInvokeSpecial ? implMethod.Member.DeclaringType : ((MethodWrapper)implMethod.Member).ReturnType; } private static bool IsAdaptable(TypeWrapper Q, TypeWrapper S, bool isReturn) { if (Q == S) { return true; } if (Q.IsPrimitive) { if (S.IsPrimitive) { // Q can be converted to S via a primitive widening conversion switch (Q.SigName[0] | S.SigName[0] << 8) { case 'B' | 'S' << 8: case 'B' | 'I' << 8: case 'B' | 'J' << 8: case 'B' | 'F' << 8: case 'B' | 'D' << 8: case 'S' | 'I' << 8: case 'S' | 'J' << 8: case 'S' | 'F' << 8: case 'S' | 'D' << 8: case 'C' | 'I' << 8: case 'C' | 'J' << 8: case 'C' | 'F' << 8: case 'C' | 'D' << 8: case 'I' | 'J' << 8: case 'I' | 'F' << 8: case 'I' | 'D' << 8: case 'J' | 'F' << 8: case 'J' | 'D' << 8: case 'F' | 'D' << 8: return true; default: return false; } } else { // S is a supertype of the Wrapper(Q) return GetWrapper(Q).IsAssignableTo(S); } } else if (isReturn) { return true; } else { if (S.IsPrimitive) { // If Q is a primitive wrapper, check that Primitive(Q) can be widened to S TypeWrapper primitive = GetPrimitiveFromWrapper(Q); return primitive != null && IsAdaptable(primitive, S, isReturn); } else { // for parameter types: S is a supertype of Q return Q.IsAssignableTo(S); } } } private static TypeWrapper GetWrapper(TypeWrapper primitive) { Debug.Assert(primitive.IsPrimitive); switch (primitive.SigName[0]) { case 'Z': return ClassLoaderWrapper.LoadClassCritical("java.lang.Boolean"); case 'B': return ClassLoaderWrapper.LoadClassCritical("java.lang.Byte"); case 'S': return ClassLoaderWrapper.LoadClassCritical("java.lang.Short"); case 'C': return ClassLoaderWrapper.LoadClassCritical("java.lang.Character"); case 'I': return ClassLoaderWrapper.LoadClassCritical("java.lang.Integer"); case 'J': return ClassLoaderWrapper.LoadClassCritical("java.lang.Long"); case 'F': return ClassLoaderWrapper.LoadClassCritical("java.lang.Float"); case 'D': return ClassLoaderWrapper.LoadClassCritical("java.lang.Double"); default: throw new InvalidOperationException(); } } private static TypeWrapper GetPrimitiveFromWrapper(TypeWrapper wrapper) { switch (wrapper.Name) { case "java.lang.Boolean": return PrimitiveTypeWrapper.BOOLEAN; case "java.lang.Byte": return PrimitiveTypeWrapper.BYTE; case "java.lang.Short": return PrimitiveTypeWrapper.SHORT; case "java.lang.Character": return PrimitiveTypeWrapper.CHAR; case "java.lang.Integer": return PrimitiveTypeWrapper.INT; case "java.lang.Long": return PrimitiveTypeWrapper.LONG; case "java.lang.Float": return PrimitiveTypeWrapper.FLOAT; case "java.lang.Double": return PrimitiveTypeWrapper.DOUBLE; default: return null; } } private static bool IsSubTypeOf(ClassFile.ConstantPoolItemMethodType instantiatedMethodType, ClassFile.ConstantPoolItemMethodType samMethodType) { TypeWrapper[] T = instantiatedMethodType.GetArgTypes(); TypeWrapper[] U = samMethodType.GetArgTypes(); if (T.Length != U.Length) { return false; } for (int i = 0; i < T.Length; i++) { if (!T[i].IsAssignableTo(U[i])) { return false; } } TypeWrapper Rt = instantiatedMethodType.GetRetType(); TypeWrapper Ru = samMethodType.GetRetType(); return Rt.IsAssignableTo(Ru); } private static MethodBuilder CreateConstructorAndDispatch(TypeWrapperFactory context, TypeWrapper[] args, TypeBuilder tb, MethodWrapper interfaceMethod, TypeWrapper[] implParameters, ClassFile.ConstantPoolItemMethodType samMethodType, ClassFile.ConstantPoolItemMethodHandle implMethod, ClassFile.ConstantPoolItemMethodType instantiatedMethodType) { // captured values Type[] capturedTypes = new Type[args.Length]; FieldBuilder[] capturedFields = new FieldBuilder[capturedTypes.Length]; for (int i = 0; i < capturedTypes.Length; i++) { capturedTypes[i] = args[i].TypeAsSignatureType; FieldAttributes attr = FieldAttributes.Private; if (i > 0 || !args[0].IsGhost) { attr |= FieldAttributes.InitOnly; } capturedFields[i] = tb.DefineField("c" + i, capturedTypes[i], attr); } // constructor MethodBuilder ctor = ReflectUtil.DefineConstructor(tb, MethodAttributes.Assembly, capturedTypes); CodeEmitter ilgen = CodeEmitter.Create(ctor); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Call, Types.Object.GetConstructor(Type.EmptyTypes)); for (int i = 0; i < capturedTypes.Length; i++) { ilgen.EmitLdarg(0); ilgen.EmitLdarg(i + 1); ilgen.Emit(OpCodes.Stfld, capturedFields[i]); } ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); // dispatch method MethodBuilder mb = interfaceMethod.GetDefineMethodHelper().DefineMethod(context, tb, interfaceMethod.RealName, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final); ilgen = CodeEmitter.Create(mb); for (int i = 0; i < capturedTypes.Length; i++) { ilgen.EmitLdarg(0); OpCode opc = OpCodes.Ldfld; if (i == 0 && args[0].IsGhost) { switch (implMethod.Kind) { case ClassFile.RefKind.invokeInterface: case ClassFile.RefKind.invokeVirtual: case ClassFile.RefKind.invokeSpecial: opc = OpCodes.Ldflda; break; } } ilgen.Emit(opc, capturedFields[i]); } for (int i = 0, count = interfaceMethod.GetParameters().Length, k = capturedFields.Length; i < count; i++) { ilgen.EmitLdarg(i + 1); TypeWrapper Ui = samMethodType.GetArgTypes()[i]; TypeWrapper Ti = instantiatedMethodType.GetArgTypes()[i]; TypeWrapper Aj = implParameters[i + k]; if (Ui == PrimitiveTypeWrapper.BYTE) { ilgen.Emit(OpCodes.Conv_I1); } if (Ti != Ui) { if (Ti.IsGhost) { Ti.EmitConvStackTypeToSignatureType(ilgen, Ui); } else if (Ui.IsGhost) { Ui.EmitConvSignatureTypeToStackType(ilgen); } else { Ti.EmitCheckcast(ilgen); } } if (Ti != Aj) { if (Ti.IsPrimitive && !Aj.IsPrimitive) { Boxer.EmitBox(ilgen, Ti); } else if (!Ti.IsPrimitive && Aj.IsPrimitive) { TypeWrapper primitive = GetPrimitiveFromWrapper(Ti); Boxer.EmitUnbox(ilgen, primitive, false); if (primitive == PrimitiveTypeWrapper.BYTE) { ilgen.Emit(OpCodes.Conv_I1); } } else if (Aj == PrimitiveTypeWrapper.LONG) { ilgen.Emit(OpCodes.Conv_I8); } else if (Aj == PrimitiveTypeWrapper.FLOAT) { ilgen.Emit(OpCodes.Conv_R4); } else if (Aj == PrimitiveTypeWrapper.DOUBLE) { ilgen.Emit(OpCodes.Conv_R8); } } } switch (implMethod.Kind) { case ClassFile.RefKind.invokeVirtual: case ClassFile.RefKind.invokeInterface: ((MethodWrapper)implMethod.Member).EmitCallvirt(ilgen); break; case ClassFile.RefKind.newInvokeSpecial: ((MethodWrapper)implMethod.Member).EmitNewobj(ilgen); break; case ClassFile.RefKind.invokeStatic: case ClassFile.RefKind.invokeSpecial: ((MethodWrapper)implMethod.Member).EmitCall(ilgen); break; default: throw new InvalidOperationException(); } TypeWrapper Ru = interfaceMethod.ReturnType; TypeWrapper Ra = GetImplReturnType(implMethod); TypeWrapper Rt = instantiatedMethodType.GetRetType(); if (Ra == PrimitiveTypeWrapper.BYTE) { ilgen.Emit(OpCodes.Conv_I1); } if (Ra != Ru) { if (Ru == PrimitiveTypeWrapper.VOID) { ilgen.Emit(OpCodes.Pop); } else if (Ra.IsGhost) { Ra.EmitConvSignatureTypeToStackType(ilgen); } else if (Ru.IsGhost) { Ru.EmitConvStackTypeToSignatureType(ilgen, Ra); } } if (Ra != Rt) { if (Rt.IsPrimitive) { if (Rt == PrimitiveTypeWrapper.VOID) { // already popped } else if (!Ra.IsPrimitive) { TypeWrapper primitive = GetPrimitiveFromWrapper(Ra); if (primitive != null) { Boxer.EmitUnbox(ilgen, primitive, false); } else { // If Q is not a primitive wrapper, cast Q to the base Wrapper(S); for example Number for numeric types EmitConvertingUnbox(ilgen, Rt); } } else if (Rt == PrimitiveTypeWrapper.LONG) { ilgen.Emit(OpCodes.Conv_I8); } else if (Rt == PrimitiveTypeWrapper.FLOAT) { ilgen.Emit(OpCodes.Conv_R4); } else if (Rt == PrimitiveTypeWrapper.DOUBLE) { ilgen.Emit(OpCodes.Conv_R8); } } else if (Ra.IsPrimitive) { Boxer.EmitBox(ilgen, GetPrimitiveFromWrapper(Rt)); } else { Rt.EmitCheckcast(ilgen); } } ilgen.EmitTailCallPrevention(); ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); return ctor; } private static void EmitConvertingUnbox(CodeEmitter ilgen, TypeWrapper tw) { switch (tw.SigName[0]) { case 'Z': case 'C': Boxer.EmitUnbox(ilgen, tw, true); break; case 'B': EmitUnboxNumber(ilgen, "byteValue", "()B"); break; case 'S': EmitUnboxNumber(ilgen, "shortValue", "()S"); break; case 'I': EmitUnboxNumber(ilgen, "intValue", "()I"); break; case 'J': EmitUnboxNumber(ilgen, "longValue", "()J"); break; case 'F': EmitUnboxNumber(ilgen, "floatValue", "()F"); break; case 'D': EmitUnboxNumber(ilgen, "doubleValue", "()D"); break; default: throw new InvalidOperationException(); } } private static void EmitUnboxNumber(CodeEmitter ilgen, string methodName, string methodSig) { TypeWrapper tw = ClassLoaderWrapper.LoadClassCritical("java.lang.Number"); tw.EmitCheckcast(ilgen); MethodWrapper mw = tw.GetMethodWrapper(methodName, methodSig, false); mw.Link(); mw.EmitCallvirt(ilgen); } private static void AddDefaultInterfaceMethods(TypeWrapperFactory context, MethodWrapper[] methodList, TypeBuilder tb) { foreach (MethodWrapper mw in methodList) { if (!mw.IsAbstract) { MethodBuilder mb = mw.GetDefineMethodHelper().DefineMethod(context, tb, mw.RealName, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final); DynamicTypeWrapper.FinishContext.EmitCallDefaultInterfaceMethod(mb, mw); } else if (IsObjectMethod(mw)) { MethodBuilder mb = mw.GetDefineMethodHelper().DefineMethod(context, tb, mw.RealName, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final); CodeEmitter ilgen = CodeEmitter.Create(mb); for (int i = 0, count = mw.GetParameters().Length; i <= count; i++) { ilgen.EmitLdarg(i); } CoreClasses.java.lang.Object.Wrapper.GetMethodWrapper(mw.Name, mw.Signature, false).EmitCallvirt(ilgen); ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); } } } private static bool IsSupportedImplMethod(ClassFile.ConstantPoolItemMethodHandle implMethod, TypeWrapper caller, TypeWrapper[] captured, ClassFile.ConstantPoolItemMethodType instantiatedMethodType) { switch (implMethod.Kind) { case ClassFile.RefKind.invokeVirtual: case ClassFile.RefKind.invokeInterface: case ClassFile.RefKind.newInvokeSpecial: case ClassFile.RefKind.invokeStatic: case ClassFile.RefKind.invokeSpecial: break; default: return false; } MethodWrapper mw = (MethodWrapper)implMethod.Member; if (mw == null || mw.HasCallerID || DynamicTypeWrapper.RequiresDynamicReflectionCallerClass(mw.DeclaringType.Name, mw.Name, mw.Signature)) { return false; } TypeWrapper instance; if (mw.IsConstructor) { instance = mw.DeclaringType; } else if (mw.IsStatic) { instance = null; } else { // if implMethod is an instance method, the type of the first captured value must be subtype of implMethod.DeclaringType instance = captured.Length == 0 ? instantiatedMethodType.GetArgTypes()[0] : captured[0]; if (!instance.IsAssignableTo(mw.DeclaringType)) { return false; } } if (!mw.IsAccessibleFrom(mw.DeclaringType, caller, instance)) { return false; } mw.Link(); return true; } private static bool IsSupportedInterface(TypeWrapper tw, out MethodWrapper[] methodList) { // we don't need to check for unloadable, because we already did that while validating the invoke signature if (!tw.IsInterface || tw.IsGhost) { methodList = null; return false; } Dictionary<MethodKey, MethodWrapper> methods = new Dictionary<MethodKey,MethodWrapper>(); int abstractMethodCount = 0; if (GatherAllInterfaceMethods(tw, methods, ref abstractMethodCount) && abstractMethodCount == 1) { methodList = new MethodWrapper[methods.Count]; methods.Values.CopyTo(methodList, 0); return true; } methodList = null; return false; } private static bool GatherAllInterfaceMethods(TypeWrapper tw, Dictionary<MethodKey, MethodWrapper> methods, ref int abstractMethodCount) { foreach (MethodWrapper mw in tw.GetMethods()) { if (mw.IsVirtual) { MirandaMethodWrapper mmw = mw as MirandaMethodWrapper; if (mmw != null) { if (mmw.Error != null) { return false; } continue; } MethodKey key = new MethodKey("", mw.Name, mw.Signature); MethodWrapper current; if (methods.TryGetValue(key, out current)) { if (!MatchSignatures(mw, current)) { // linkage error (or unloadable type) return false; } } else { methods.Add(key, mw); if (mw.IsAbstract && !IsObjectMethod(mw)) { abstractMethodCount++; } } mw.Link(); if (mw.GetMethod() == null) { return false; } } } foreach (TypeWrapper tw1 in tw.Interfaces) { if (!GatherAllInterfaceMethods(tw1, methods, ref abstractMethodCount)) { return false; } } return true; } private static bool IsObjectMethod(MethodWrapper mw) { MethodWrapper objectMethod; return (objectMethod = CoreClasses.java.lang.Object.Wrapper.GetMethodWrapper(mw.Name, mw.Signature, false)) != null && objectMethod.IsPublic; } private static bool MatchSignatures(MethodWrapper interfaceMethod, ClassFile.ConstantPoolItemMethodType samMethodType) { return interfaceMethod.ReturnType == samMethodType.GetRetType() && MatchTypes(interfaceMethod.GetParameters(), samMethodType.GetArgTypes()); } private static bool MatchSignatures(MethodWrapper mw1, MethodWrapper mw2) { return mw1.ReturnType == mw2.ReturnType && MatchTypes(mw1.GetParameters(), mw2.GetParameters()); } private static bool MatchTypes(TypeWrapper[] ar1, TypeWrapper[] ar2) { if (ar1.Length != ar2.Length) { return false; } for (int i = 0; i < ar1.Length; i++) { if (ar1[i] != ar2[i]) { return false; } } return true; } private static bool IsLambdaMetafactory(ClassFile classFile, ClassFile.BootstrapMethod bsm) { ClassFile.ConstantPoolItemMethodHandle mh; return bsm.ArgumentCount == 3 && classFile.GetConstantPoolConstantType(bsm.GetArgument(0)) == ClassFile.ConstantType.MethodType && classFile.GetConstantPoolConstantType(bsm.GetArgument(1)) == ClassFile.ConstantType.MethodHandle && classFile.GetConstantPoolConstantType(bsm.GetArgument(2)) == ClassFile.ConstantType.MethodType && (mh = classFile.GetConstantPoolConstantMethodHandle(bsm.BootstrapMethodIndex)).Kind == ClassFile.RefKind.invokeStatic && IsLambdaMetafactory(mh.Member); } private static bool IsLambdaMetafactory(MemberWrapper mw) { return mw.Name == "metafactory" && mw.Signature == "(Ljava.lang.invoke.MethodHandles$Lookup;Ljava.lang.String;Ljava.lang.invoke.MethodType;Ljava.lang.invoke.MethodType;Ljava.lang.invoke.MethodHandle;Ljava.lang.invoke.MethodType;)Ljava.lang.invoke.CallSite;" && mw.DeclaringType.Name == "java.lang.invoke.LambdaMetafactory"; } private static bool HasUnloadable(ClassFile.ConstantPoolItemInvokeDynamic cpi) { return HasUnloadable(cpi.GetArgTypes()) || cpi.GetRetType().IsUnloadable; } private static bool HasUnloadable(ClassFile.ConstantPoolItemMethodType cpi) { return HasUnloadable(cpi.GetArgTypes()) || cpi.GetRetType().IsUnloadable; } private static bool HasUnloadable(ClassFile.ConstantPoolItemMI cpi) { return HasUnloadable(cpi.GetArgTypes()) || cpi.GetRetType().IsUnloadable; } private static bool HasUnloadable(TypeWrapper[] wrappers) { foreach (TypeWrapper tw in wrappers) { if (tw.IsUnloadable) { return true; } } return false; } } } Index: IKVM.Runtime.8.csproj =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/IKVM.Runtime.8.csproj,v retrieving revision 1.45 retrieving revision 1.46 diff -C2 -d -r1.45 -r1.46 *** IKVM.Runtime.8.csproj 1 Jul 2014 15:09:11 -0000 1.45 --- IKVM.Runtime.8.csproj 1 Jul 2014 15:12:34 -0000 1.46 *************** *** 145,148 **** --- 145,149 ---- </Compile> <Compile Include="JsrInliner.cs" /> + <Compile Include="LambdaMetafactory.cs" /> <Compile Include="LocalVars.cs" /> <Compile Include="MemberWrapper.cs"> Index: ClassLoaderWrapper.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/ClassLoaderWrapper.cs,v retrieving revision 1.227 retrieving revision 1.228 diff -C2 -d -r1.227 -r1.228 *** ClassLoaderWrapper.cs 24 Jun 2014 10:32:16 -0000 1.227 --- ClassLoaderWrapper.cs 1 Jul 2014 15:12:34 -0000 1.228 *************** *** 1094,1097 **** --- 1094,1115 ---- } #endif + if(AnonymousTypeWrapper.IsAnonymous(type)) + { + Dictionary<Type, TypeWrapper> typeToTypeWrapper; + #if CLASSGC + typeToTypeWrapper = loader != null ? loader.typeToTypeWrapper : globalTypeToTypeWrapper; + #else + typeToTypeWrapper = globalTypeToTypeWrapper; + #endif + TypeWrapper tw = new AnonymousTypeWrapper(type); + lock(typeToTypeWrapper) + { + if(!typeToTypeWrapper.TryGetValue(type, out wrapper)) + { + typeToTypeWrapper.Add(type, wrapper = tw); + } + } + return wrapper; + } #if !STATIC_COMPILER && !STUB_GENERATOR if(ReflectUtil.IsReflectionOnly(type)) Index: runtime.build =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/runtime.build,v retrieving revision 1.78 retrieving revision 1.79 diff -C2 -d -r1.78 -r1.79 *** runtime.build 1 Jul 2014 15:09:11 -0000 1.78 --- runtime.build 1 Jul 2014 15:12:34 -0000 1.79 *************** *** 159,162 **** --- 159,163 ---- <include name="JavaException.cs" /> <include name="JsrInliner.cs" /> + <include name="LambdaMetafactory.cs" /> <include name="LocalVars.cs" /> <include name="MemberWrapper.cs" /> Index: DynamicTypeWrapper.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/DynamicTypeWrapper.cs,v retrieving revision 1.251 retrieving revision 1.252 diff -C2 -d -r1.251 -r1.252 *** DynamicTypeWrapper.cs 24 Jun 2014 08:26:13 -0000 1.251 --- DynamicTypeWrapper.cs 1 Jul 2014 15:12:34 -0000 1.252 *************** *** 4000,4003 **** --- 4000,4008 ---- } + internal TypeWrapper TypeWrapper + { + get { return wrapper; } + } + internal T GetValue<T>(int key) where T : class, new() *************** *** 5153,5176 **** typeBuilder, NamePrefix.DefaultMethod + mb.Name, MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.SpecialName, typeBuilder, false); } ! CodeEmitter ilgen = CodeEmitter.Create(mb); ! if (mmw.BaseMethod.DeclaringType.IsGhost) ! { ! CodeEmitterLocal local = ilgen.DeclareLocal(mmw.BaseMethod.DeclaringType.TypeAsSignatureType); ! ilgen.Emit(OpCodes.Ldloca, local); ! ilgen.EmitLdarg(0); ! ilgen.Emit(OpCodes.Stfld, mmw.BaseMethod.DeclaringType.GhostRefField); ! ilgen.Emit(OpCodes.Ldloca, local); ! } ! else ! { ! ilgen.EmitLdarg(0); ! } ! for (int j = 0, count = mmw.GetParameters().Length; j < count; j++) ! { ! ilgen.EmitLdarg(j + 1); ! } ! ilgen.Emit(OpCodes.Call, DefaultInterfaceMethodWrapper.GetImpl(mmw.BaseMethod)); ! ilgen.Emit(OpCodes.Ret); ! ilgen.DoEmit(); } } --- 5158,5162 ---- typeBuilder, NamePrefix.DefaultMethod + mb.Name, MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.SpecialName, typeBuilder, false); } ! EmitCallDefaultInterfaceMethod(mb, mmw.BaseMethod); } } *************** *** 5178,5181 **** --- 5164,5191 ---- } + internal static void EmitCallDefaultInterfaceMethod(MethodBuilder mb, MethodWrapper defaultMethod) + { + CodeEmitter ilgen = CodeEmitter.Create(mb); + if (defaultMethod.DeclaringType.IsGhost) + { + CodeEmitterLocal local = ilgen.DeclareLocal(defaultMethod.DeclaringType.TypeAsSignatureType); + ilgen.Emit(OpCodes.Ldloca, local); + ilgen.EmitLdarg(0); + ilgen.Emit(OpCodes.Stfld, defaultMethod.DeclaringType.GhostRefField); + ilgen.Emit(OpCodes.Ldloca, local); + } + else + { + ilgen.EmitLdarg(0); + } + for (int j = 0, count = defaultMethod.GetParameters().Length; j < count; j++) + { + ilgen.EmitLdarg(j + 1); + } + ilgen.Emit(OpCodes.Call, DefaultInterfaceMethodWrapper.GetImpl(defaultMethod)); + ilgen.Emit(OpCodes.Ret); + ilgen.DoEmit(); + } + #if STATIC_COMPILER private void AddAccessStubs() *************** *** 6413,6416 **** --- 6423,6435 ---- } + // this is used to define intrinsified anonymous classes (in the Unsafe.defineAnonymousClass() sense) + internal TypeBuilder DefineAnonymousClass() + { + int id = nestedTypeBuilders == null ? 0 : nestedTypeBuilders.Count; + TypeBuilder tb = typeBuilder.DefineNestedType(NestedTypeName.IntrinsifiedAnonymousClass + id, TypeAttributes.NestedPrivate | TypeAttributes.Sealed | TypeAttributes.SpecialName | TypeAttributes.BeforeFieldInit); + RegisterNestedTypeBuilder(tb); + return tb; + } + private MethodBuilder DefineHelperMethod(string name, Type returnType, Type[] parameterTypes) { Index: compiler.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/compiler.cs,v retrieving revision 1.250 retrieving revision 1.251 diff -C2 -d -r1.250 -r1.251 *** compiler.cs 1 Jul 2014 15:04:06 -0000 1.250 --- compiler.cs 1 Jul 2014 15:12:34 -0000 1.251 *************** *** 3209,3212 **** --- 3209,3217 ---- private void EmitInvokeDynamic(ClassFile.ConstantPoolItemInvokeDynamic cpi) { + if (LambdaMetafactory.Emit(context, classFile, cpi, ilGenerator)) + { + // we intrinsified the lambda factory + return; + } CodeEmitter ilgen = ilGenerator; TypeWrapper[] args = cpi.GetArgTypes(); |
|
From: Jeroen F. <jfr...@us...> - 2014-07-01 15:12:36
|
Update of /cvsroot/ikvm/ikvm/ikvmc In directory sfp-cvs-1.v30.ch3.sourceforge.com:/tmp/cvs-serv785/ikvmc Modified Files: CompilerClassLoader.cs ikvmc.build Log Message: Added intrinsic for LambdaMetafactory.metafactory(). Index: CompilerClassLoader.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/ikvmc/CompilerClassLoader.cs,v retrieving revision 1.269 retrieving revision 1.270 diff -C2 -d -r1.269 -r1.270 *** CompilerClassLoader.cs 24 Jun 2014 09:44:37 -0000 1.269 --- CompilerClassLoader.cs 1 Jul 2014 15:12:34 -0000 1.270 *************** *** 3682,3685 **** --- 3682,3686 ---- ReflectionCallerClassRequiresCallerID = 136, LegacyAssemblyAttributesFound = 137, + UnableToCreateLambdaFactory = 138, UnknownWarning = 999, // This is where the errors start *************** *** 4036,4039 **** --- 4037,4043 ---- msg = "Legacy assembly attributes container found. Please use the -assemblyattributes:<file> option."; break; + case Message.UnableToCreateLambdaFactory: + msg = "Unable to create static lambda factory."; + break; case Message.UnableToCreateProxy: msg = "Unable to create proxy \"{0}\"" + Environment.NewLine + Index: ikvmc.build =================================================================== RCS file: /cvsroot/ikvm/ikvm/ikvmc/ikvmc.build,v retrieving revision 1.38 retrieving revision 1.39 diff -C2 -d -r1.38 -r1.39 *** ikvmc.build 1 Jul 2014 15:09:11 -0000 1.38 --- ikvmc.build 1 Jul 2014 15:12:34 -0000 1.39 *************** *** 62,65 **** --- 62,66 ---- <include name="../runtime/JavaException.cs" /> <include name="../runtime/JsrInliner.cs" /> + <include name="../runtime/LambdaMetafactory.cs" /> <include name="../runtime/LocalVars.cs" /> <include name="../runtime/MemberWrapper.cs" /> |
|
From: Jeroen F. <jfr...@us...> - 2014-07-01 15:09:14
|
Update of /cvsroot/ikvm/ikvm/runtime In directory sfp-cvs-1.v30.ch3.sourceforge.com:/tmp/cvs-serv518/runtime Modified Files: IKVM.Runtime.8.csproj runtime.build Added Files: Boxer.cs Log Message: Make Boxer helper class available to runtime. Index: IKVM.Runtime.8.csproj =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/IKVM.Runtime.8.csproj,v retrieving revision 1.44 retrieving revision 1.45 diff -C2 -d -r1.44 -r1.45 *** IKVM.Runtime.8.csproj 19 May 2014 12:43:42 -0000 1.44 --- IKVM.Runtime.8.csproj 1 Jul 2014 15:09:11 -0000 1.45 *************** *** 96,99 **** --- 96,100 ---- <SubType>Code</SubType> </Compile> + <Compile Include="Boxer.cs" /> <Compile Include="ByteCode.cs"> <SubType>Code</SubType> --- NEW FILE: Boxer.cs --- /* Copyright (C) 2011-2014 Jeroen Frijters This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. Jeroen Frijters je...@fr... */ using System; namespace IKVM.Internal { static class Boxer { private static readonly TypeWrapper javaLangByte; private static readonly MethodWrapper byteValue; private static readonly MethodWrapper valueOfByte; private static readonly TypeWrapper javaLangBoolean; private static readonly MethodWrapper booleanValue; private static readonly MethodWrapper valueOfBoolean; private static readonly TypeWrapper javaLangShort; private static readonly MethodWrapper shortValue; private static readonly MethodWrapper valueOfShort; private static readonly TypeWrapper javaLangCharacter; private static readonly MethodWrapper charValue; private static readonly MethodWrapper valueOfCharacter; private static readonly TypeWrapper javaLangInteger; private static readonly MethodWrapper intValue; private static readonly MethodWrapper valueOfInteger; private static readonly TypeWrapper javaLangFloat; private static readonly MethodWrapper floatValue; private static readonly MethodWrapper valueOfFloat; private static readonly TypeWrapper javaLangLong; private static readonly MethodWrapper longValue; private static readonly MethodWrapper valueOfLong; private static readonly TypeWrapper javaLangDouble; private static readonly MethodWrapper doubleValue; private static readonly MethodWrapper valueOfDouble; static Boxer() { ClassLoaderWrapper bootClassLoader = ClassLoaderWrapper.GetBootstrapClassLoader(); javaLangByte = bootClassLoader.LoadClassByDottedNameFast("java.lang.Byte"); byteValue = javaLangByte.GetMethodWrapper("byteValue", "()B", false); byteValue.Link(); valueOfByte = javaLangByte.GetMethodWrapper("valueOf", "(B)Ljava.lang.Byte;", false); valueOfByte.Link(); javaLangBoolean = bootClassLoader.LoadClassByDottedNameFast("java.lang.Boolean"); booleanValue = javaLangBoolean.GetMethodWrapper("booleanValue", "()Z", false); booleanValue.Link(); valueOfBoolean = javaLangBoolean.GetMethodWrapper("valueOf", "(Z)Ljava.lang.Boolean;", false); valueOfBoolean.Link(); javaLangShort = bootClassLoader.LoadClassByDottedNameFast("java.lang.Short"); shortValue = javaLangShort.GetMethodWrapper("shortValue", "()S", false); shortValue.Link(); valueOfShort = javaLangShort.GetMethodWrapper("valueOf", "(S)Ljava.lang.Short;", false); valueOfShort.Link(); javaLangCharacter = bootClassLoader.LoadClassByDottedNameFast("java.lang.Character"); charValue = javaLangCharacter.GetMethodWrapper("charValue", "()C", false); charValue.Link(); valueOfCharacter = javaLangCharacter.GetMethodWrapper("valueOf", "(C)Ljava.lang.Character;", false); valueOfCharacter.Link(); javaLangInteger = bootClassLoader.LoadClassByDottedNameFast("java.lang.Integer"); intValue = javaLangInteger.GetMethodWrapper("intValue", "()I", false); intValue.Link(); valueOfInteger = javaLangInteger.GetMethodWrapper("valueOf", "(I)Ljava.lang.Integer;", false); valueOfInteger.Link(); javaLangFloat = bootClassLoader.LoadClassByDottedNameFast("java.lang.Float"); floatValue = javaLangFloat.GetMethodWrapper("floatValue", "()F", false); floatValue.Link(); valueOfFloat = javaLangFloat.GetMethodWrapper("valueOf", "(F)Ljava.lang.Float;", false); valueOfFloat.Link(); javaLangLong = bootClassLoader.LoadClassByDottedNameFast("java.lang.Long"); longValue = javaLangLong.GetMethodWrapper("longValue", "()J", false); longValue.Link(); valueOfLong = javaLangLong.GetMethodWrapper("valueOf", "(J)Ljava.lang.Long;", false); valueOfLong.Link(); javaLangDouble = bootClassLoader.LoadClassByDottedNameFast("java.lang.Double"); doubleValue = javaLangDouble.GetMethodWrapper("doubleValue", "()D", false); doubleValue.Link(); valueOfDouble = javaLangDouble.GetMethodWrapper("valueOf", "(D)Ljava.lang.Double;", false); valueOfDouble.Link(); } internal static void EmitUnbox(CodeEmitter ilgen, TypeWrapper tw, bool cast) { if (tw == PrimitiveTypeWrapper.BYTE) { if (cast) { javaLangByte.EmitCheckcast(ilgen); } byteValue.EmitCall(ilgen); } else if (tw == PrimitiveTypeWrapper.BOOLEAN) { if (cast) { javaLangBoolean.EmitCheckcast(ilgen); } booleanValue.EmitCall(ilgen); } else if (tw == PrimitiveTypeWrapper.SHORT) { if (cast) { javaLangShort.EmitCheckcast(ilgen); } shortValue.EmitCall(ilgen); } else if (tw == PrimitiveTypeWrapper.CHAR) { if (cast) { javaLangCharacter.EmitCheckcast(ilgen); } charValue.EmitCall(ilgen); } else if (tw == PrimitiveTypeWrapper.INT) { if (cast) { javaLangInteger.EmitCheckcast(ilgen); } intValue.EmitCall(ilgen); } else if (tw == PrimitiveTypeWrapper.FLOAT) { if (cast) { javaLangFloat.EmitCheckcast(ilgen); } floatValue.EmitCall(ilgen); } else if (tw == PrimitiveTypeWrapper.LONG) { if (cast) { javaLangLong.EmitCheckcast(ilgen); } longValue.EmitCall(ilgen); } else if (tw == PrimitiveTypeWrapper.DOUBLE) { if (cast) { javaLangDouble.EmitCheckcast(ilgen); } doubleValue.EmitCall(ilgen); } else { throw new InvalidOperationException(); } } internal static void EmitBox(CodeEmitter ilgen, TypeWrapper tw) { if (tw == PrimitiveTypeWrapper.BYTE) { valueOfByte.EmitCall(ilgen); } else if (tw == PrimitiveTypeWrapper.BOOLEAN) { valueOfBoolean.EmitCall(ilgen); } else if (tw == PrimitiveTypeWrapper.SHORT) { valueOfShort.EmitCall(ilgen); } else if (tw == PrimitiveTypeWrapper.CHAR) { valueOfCharacter.EmitCall(ilgen); } else if (tw == PrimitiveTypeWrapper.INT) { valueOfInteger.EmitCall(ilgen); } else if (tw == PrimitiveTypeWrapper.FLOAT) { valueOfFloat.EmitCall(ilgen); } else if (tw == PrimitiveTypeWrapper.LONG) { valueOfLong.EmitCall(ilgen); } else if (tw == PrimitiveTypeWrapper.DOUBLE) { valueOfDouble.EmitCall(ilgen); } else { throw new InvalidOperationException(); } } } } Index: runtime.build =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/runtime.build,v retrieving revision 1.77 retrieving revision 1.78 diff -C2 -d -r1.77 -r1.78 *** runtime.build 19 May 2014 12:43:43 -0000 1.77 --- runtime.build 1 Jul 2014 15:09:11 -0000 1.78 *************** *** 142,145 **** --- 142,146 ---- <include name="attributes.cs" /> <include name="BigEndianBinaryReader.cs" /> + <include name="Boxer.cs" /> <include name="ByteCode.cs" /> <include name="ByteCodeHelper.cs" /> |
|
From: Jeroen F. <jfr...@us...> - 2014-07-01 15:09:13
|
Update of /cvsroot/ikvm/ikvm/ikvmc In directory sfp-cvs-1.v30.ch3.sourceforge.com:/tmp/cvs-serv518/ikvmc Modified Files: Proxy.cs ikvmc.build Log Message: Make Boxer helper class available to runtime. Index: Proxy.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/ikvmc/Proxy.cs,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** Proxy.cs 15 May 2014 06:54:36 -0000 1.8 --- Proxy.cs 1 Jul 2014 15:09:11 -0000 1.9 *************** *** 311,315 **** else if (returnType.IsPrimitive) { ! Boxer.EmitUnbox(ilgen, returnType); } else if (returnType != CoreClasses.java.lang.Object.Wrapper) --- 311,315 ---- else if (returnType.IsPrimitive) { ! Boxer.EmitUnbox(ilgen, returnType, true); } else if (returnType != CoreClasses.java.lang.Object.Wrapper) *************** *** 455,618 **** } } - - static class Boxer - { - private static readonly TypeWrapper javaLangByte; - private static readonly MethodWrapper byteValue; - private static readonly MethodWrapper valueOfByte; - private static readonly TypeWrapper javaLangBoolean; - private static readonly MethodWrapper booleanValue; - private static readonly MethodWrapper valueOfBoolean; - private static readonly TypeWrapper javaLangShort; - private static readonly MethodWrapper shortValue; - private static readonly MethodWrapper valueOfShort; - private static readonly TypeWrapper javaLangCharacter; - private static readonly MethodWrapper charValue; - private static readonly MethodWrapper valueOfCharacter; - private static readonly TypeWrapper javaLangInteger; - private static readonly MethodWrapper intValue; - private static readonly MethodWrapper valueOfInteger; - private static readonly TypeWrapper javaLangFloat; - private static readonly MethodWrapper floatValue; - private static readonly MethodWrapper valueOfFloat; - private static readonly TypeWrapper javaLangLong; - private static readonly MethodWrapper longValue; - private static readonly MethodWrapper valueOfLong; - private static readonly TypeWrapper javaLangDouble; - private static readonly MethodWrapper doubleValue; - private static readonly MethodWrapper valueOfDouble; - - static Boxer() - { - ClassLoaderWrapper bootClassLoader = ClassLoaderWrapper.GetBootstrapClassLoader(); - javaLangByte = bootClassLoader.LoadClassByDottedNameFast("java.lang.Byte"); - byteValue = javaLangByte.GetMethodWrapper("byteValue", "()B", false); - byteValue.Link(); - valueOfByte = javaLangByte.GetMethodWrapper("valueOf", "(B)Ljava.lang.Byte;", false); - valueOfByte.Link(); - javaLangBoolean = bootClassLoader.LoadClassByDottedNameFast("java.lang.Boolean"); - booleanValue = javaLangBoolean.GetMethodWrapper("booleanValue", "()Z", false); - booleanValue.Link(); - valueOfBoolean = javaLangBoolean.GetMethodWrapper("valueOf", "(Z)Ljava.lang.Boolean;", false); - valueOfBoolean.Link(); - javaLangShort = bootClassLoader.LoadClassByDottedNameFast("java.lang.Short"); - shortValue = javaLangShort.GetMethodWrapper("shortValue", "()S", false); - shortValue.Link(); - valueOfShort = javaLangShort.GetMethodWrapper("valueOf", "(S)Ljava.lang.Short;", false); - valueOfShort.Link(); - javaLangCharacter = bootClassLoader.LoadClassByDottedNameFast("java.lang.Character"); - charValue = javaLangCharacter.GetMethodWrapper("charValue", "()C", false); - charValue.Link(); - valueOfCharacter = javaLangCharacter.GetMethodWrapper("valueOf", "(C)Ljava.lang.Character;", false); - valueOfCharacter.Link(); - javaLangInteger = bootClassLoader.LoadClassByDottedNameFast("java.lang.Integer"); - intValue = javaLangInteger.GetMethodWrapper("intValue", "()I", false); - intValue.Link(); - valueOfInteger = javaLangInteger.GetMethodWrapper("valueOf", "(I)Ljava.lang.Integer;", false); - valueOfInteger.Link(); - javaLangFloat = bootClassLoader.LoadClassByDottedNameFast("java.lang.Float"); - floatValue = javaLangFloat.GetMethodWrapper("floatValue", "()F", false); - floatValue.Link(); - valueOfFloat = javaLangFloat.GetMethodWrapper("valueOf", "(F)Ljava.lang.Float;", false); - valueOfFloat.Link(); - javaLangLong = bootClassLoader.LoadClassByDottedNameFast("java.lang.Long"); - longValue = javaLangLong.GetMethodWrapper("longValue", "()J", false); - longValue.Link(); - valueOfLong = javaLangLong.GetMethodWrapper("valueOf", "(J)Ljava.lang.Long;", false); - valueOfLong.Link(); - javaLangDouble = bootClassLoader.LoadClassByDottedNameFast("java.lang.Double"); - doubleValue = javaLangDouble.GetMethodWrapper("doubleValue", "()D", false); - doubleValue.Link(); - valueOfDouble = javaLangDouble.GetMethodWrapper("valueOf", "(D)Ljava.lang.Double;", false); - valueOfDouble.Link(); - } - - internal static void EmitUnbox(CodeEmitter ilgen, TypeWrapper tw) - { - if (tw == PrimitiveTypeWrapper.BYTE) - { - javaLangByte.EmitCheckcast(ilgen); - byteValue.EmitCall(ilgen); - } - else if (tw == PrimitiveTypeWrapper.BOOLEAN) - { - javaLangBoolean.EmitCheckcast(ilgen); - booleanValue.EmitCall(ilgen); - } - else if (tw == PrimitiveTypeWrapper.SHORT) - { - javaLangShort.EmitCheckcast(ilgen); - shortValue.EmitCall(ilgen); - } - else if (tw == PrimitiveTypeWrapper.CHAR) - { - javaLangCharacter.EmitCheckcast(ilgen); - charValue.EmitCall(ilgen); - } - else if (tw == PrimitiveTypeWrapper.INT) - { - javaLangInteger.EmitCheckcast(ilgen); - intValue.EmitCall(ilgen); - } - else if (tw == PrimitiveTypeWrapper.FLOAT) - { - javaLangFloat.EmitCheckcast(ilgen); - floatValue.EmitCall(ilgen); - } - else if (tw == PrimitiveTypeWrapper.LONG) - { - javaLangLong.EmitCheckcast(ilgen); - longValue.EmitCall(ilgen); - } - else if (tw == PrimitiveTypeWrapper.DOUBLE) - { - javaLangDouble.EmitCheckcast(ilgen); - doubleValue.EmitCall(ilgen); - } - else - { - throw new InvalidOperationException(); - } - } - - internal static void EmitBox(CodeEmitter ilgen, TypeWrapper tw) - { - if (tw == PrimitiveTypeWrapper.BYTE) - { - valueOfByte.EmitCall(ilgen); - } - else if (tw == PrimitiveTypeWrapper.BOOLEAN) - { - valueOfBoolean.EmitCall(ilgen); - } - else if (tw == PrimitiveTypeWrapper.SHORT) - { - valueOfShort.EmitCall(ilgen); - } - else if (tw == PrimitiveTypeWrapper.CHAR) - { - valueOfCharacter.EmitCall(ilgen); - } - else if (tw == PrimitiveTypeWrapper.INT) - { - valueOfInteger.EmitCall(ilgen); - } - else if (tw == PrimitiveTypeWrapper.FLOAT) - { - valueOfFloat.EmitCall(ilgen); - } - else if (tw == PrimitiveTypeWrapper.LONG) - { - valueOfLong.EmitCall(ilgen); - } - else if (tw == PrimitiveTypeWrapper.DOUBLE) - { - valueOfDouble.EmitCall(ilgen); - } - else - { - throw new InvalidOperationException(); - } - } - } } --- 455,457 ---- Index: ikvmc.build =================================================================== RCS file: /cvsroot/ikvm/ikvm/ikvmc/ikvmc.build,v retrieving revision 1.37 retrieving revision 1.38 diff -C2 -d -r1.37 -r1.38 *** ikvmc.build 29 Mar 2013 11:28:24 -0000 1.37 --- ikvmc.build 1 Jul 2014 15:09:11 -0000 1.38 *************** *** 49,52 **** --- 49,53 ---- <include name="../runtime/attributes.cs" /> <include name="../runtime/BigEndianBinaryReader.cs" /> + <include name="../runtime/Boxer.cs" /> <include name="../runtime/ByteCode.cs" /> <include name="../runtime/ClassFile.cs" /> |
|
From: Jeroen F. <jfr...@us...> - 2014-07-01 15:04:08
|
Update of /cvsroot/ikvm/ikvm/runtime In directory sfp-cvs-1.v30.ch3.sourceforge.com:/tmp/cvs-serv32577 Modified Files: compiler.cs Log Message: Bug fix. If an invokedynamic bootstrap argument conversion fails, the exception should not be wrapped in BootstrapMethodError. Index: compiler.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/compiler.cs,v retrieving revision 1.249 retrieving revision 1.250 diff -C2 -d -r1.249 -r1.250 *** compiler.cs 1 Jul 2014 15:00:54 -0000 1.249 --- compiler.cs 1 Jul 2014 15:04:06 -0000 1.250 *************** *** 3089,3093 **** for (int i = 0; i < fixedArgs; i++) { ! EmitExtraArg(compiler, ilgen, bsm, i, parameters[i + 3]); } if (varArgs >= 0) --- 3089,3093 ---- for (int i = 0; i < fixedArgs; i++) { ! EmitExtraArg(compiler, ilgen, bsm, i, parameters[i + 3], ok); } if (varArgs >= 0) *************** *** 3100,3104 **** ilgen.Emit(OpCodes.Dup); ilgen.EmitLdc_I4(i); ! EmitExtraArg(compiler, ilgen, bsm, i + fixedArgs, elemType); ilgen.Emit(OpCodes.Stelem_Ref); } --- 3100,3104 ---- ilgen.Emit(OpCodes.Dup); ilgen.EmitLdc_I4(i); ! EmitExtraArg(compiler, ilgen, bsm, i + fixedArgs, elemType, ok); ilgen.Emit(OpCodes.Stelem_Ref); } *************** *** 3117,3121 **** } ! private static void EmitExtraArg(Compiler compiler, CodeEmitter ilgen, ClassFile.BootstrapMethod bsm, int index, TypeWrapper targetType) { int constant = bsm.GetArgument(index); --- 3117,3121 ---- } ! private static void EmitExtraArg(Compiler compiler, CodeEmitter ilgen, ClassFile.BootstrapMethod bsm, int index, TypeWrapper targetType, CodeEmitterLocal wrapException) { int constant = bsm.GetArgument(index); *************** *** 3153,3156 **** --- 3153,3158 ---- if (constType != targetType) { + ilgen.EmitLdc_I4(1); + ilgen.Emit(OpCodes.Stloc, wrapException); if (constType.IsPrimitive) { *************** *** 3171,3174 **** --- 3173,3178 ---- } targetType.EmitConvStackTypeToSignatureType(ilgen, targetType); + ilgen.EmitLdc_I4(0); + ilgen.Emit(OpCodes.Stloc, wrapException); } } |
|
From: Jeroen F. <jfr...@us...> - 2014-07-01 15:00:56
|
Update of /cvsroot/ikvm/ikvm/runtime In directory sfp-cvs-1.v30.ch3.sourceforge.com:/tmp/cvs-serv32298 Modified Files: compiler.cs Log Message: Privileged invokespecial (from anonymous class to host class) should not go through invokespecial stub. Index: compiler.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/compiler.cs,v retrieving revision 1.248 retrieving revision 1.249 diff -C2 -d -r1.248 -r1.249 *** compiler.cs 24 Jun 2014 12:06:44 -0000 1.248 --- compiler.cs 1 Jul 2014 15:00:54 -0000 1.249 *************** *** 1710,1713 **** --- 1710,1717 ---- method.EmitCallvirt(ilGenerator); } + else if(instr.NormalizedOpCode == NormalizedByteCode.__privileged_invokespecial) + { + method.EmitCall(ilGenerator); + } else { |
|
From: Jeroen F. <jfr...@us...> - 2014-07-01 14:57:37
|
Update of /cvsroot/ikvm/ikvm/openjdk/sun/nio/fs In directory sfp-cvs-1.v30.ch3.sourceforge.com:/tmp/cvs-serv32005 Modified Files: NetFileSystemProvider.java Log Message: Bug fix. Calling BasicFileAttributes.size() on a directory didn't work. Thanks to Lucius Junevicus for reporting this. Index: NetFileSystemProvider.java =================================================================== RCS file: /cvsroot/ikvm/ikvm/openjdk/sun/nio/fs/NetFileSystemProvider.java,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** NetFileSystemProvider.java 19 May 2014 12:43:42 -0000 1.15 --- NetFileSystemProvider.java 1 Jul 2014 14:57:34 -0000 1.16 *************** *** 1105,1109 **** public long size() { ! return info.get_Length(); } --- 1105,1109 ---- public long size() { ! return info.get_Exists() ? info.get_Length() : 0; } |
|
From: Jeroen F. <jfr...@us...> - 2014-06-29 07:14:01
|
Update of /cvsroot/ikvm/ikvm/website/build/site/devguide In directory sfp-cvs-1.v30.ch3.sourceforge.com:/tmp/cvs-serv10331/build/site/devguide Modified Files: concepts.html intro.html java2net.html net2java.html Log Message: Updated wiki links. Index: intro.html =================================================================== RCS file: /cvsroot/ikvm/ikvm/website/build/site/devguide/intro.html,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** intro.html 5 May 2011 13:29:40 -0000 1.7 --- intro.html 29 Jun 2014 07:13:58 -0000 1.8 *************** *** 91,99 **** <li> ! <a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=FAQ" title="">FAQ</a> </li> <li> ! <a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=License" title="">License</a> </li> --- 91,99 ---- <li> ! <a href="http://sourceforge.net/p/ikvm/wiki/FAQ/" title="">FAQ</a> </li> <li> ! <a href="http://sourceforge.net/p/ikvm/wiki/License/" title="">License</a> </li> *************** *** 109,125 **** <li> ! <a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=User%27s_Guide">Introduction</a> </li> <li> ! <a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Installation" title="">Installation</a> </li> <li> ! <a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Tutorial" title="">Tutorial</a> </li> <li> ! <a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Tools" title="">Tools Reference</a> </li> --- 109,125 ---- <li> ! <a href="http://sourceforge.net/p/ikvm/wiki/User%27s_Guide/">Introduction</a> </li> <li> ! <a href="http://sourceforge.net/p/ikvm/wiki/Installation/" title="">Installation</a> </li> <li> ! <a href="http://sourceforge.net/p/ikvm/wiki/Tutorial/" title="">Tutorial</a> </li> <li> ! <a href="http://sourceforge.net/p/ikvm/wiki/Tools/" title="">Tools Reference</a> </li> Index: net2java.html =================================================================== RCS file: /cvsroot/ikvm/ikvm/website/build/site/devguide/net2java.html,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** net2java.html 5 May 2011 13:29:40 -0000 1.8 --- net2java.html 29 Jun 2014 07:13:58 -0000 1.9 *************** *** 91,99 **** <li> ! <a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=FAQ" title="">FAQ</a> </li> <li> ! <a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=License" title="">License</a> </li> --- 91,99 ---- <li> ! <a href="http://sourceforge.net/p/ikvm/wiki/FAQ/" title="">FAQ</a> </li> <li> ! <a href="http://sourceforge.net/p/ikvm/wiki/License/" title="">License</a> </li> *************** *** 109,125 **** <li> ! <a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=User%27s_Guide">Introduction</a> </li> <li> ! <a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Installation" title="">Installation</a> </li> <li> ! <a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Tutorial" title="">Tutorial</a> </li> <li> ! <a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Tools" title="">Tools Reference</a> </li> --- 109,125 ---- <li> ! <a href="http://sourceforge.net/p/ikvm/wiki/User%27s_Guide/">Introduction</a> </li> <li> ! <a href="http://sourceforge.net/p/ikvm/wiki/Installation/" title="">Installation</a> </li> <li> ! <a href="http://sourceforge.net/p/ikvm/wiki/Tutorial/" title="">Tutorial</a> </li> <li> ! <a href="http://sourceforge.net/p/ikvm/wiki/Tools/" title="">Tools Reference</a> </li> *************** *** 235,239 **** <ul> ! <li>Convert the Java API to .NET CIL using <a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Ikvmc">ikvmc</a>. This produces a .NET dll that you can reference in your project. </li> --- 235,239 ---- <ul> ! <li>Convert the Java API to .NET CIL using <a href="http://sourceforge.net/p/ikvm/wiki/Ikvmc/">ikvmc</a>. This produces a .NET dll that you can reference in your project. </li> Index: java2net.html =================================================================== RCS file: /cvsroot/ikvm/ikvm/website/build/site/devguide/java2net.html,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** java2net.html 5 May 2011 13:29:40 -0000 1.7 --- java2net.html 29 Jun 2014 07:13:58 -0000 1.8 *************** *** 91,99 **** <li> ! <a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=FAQ" title="">FAQ</a> </li> <li> ! <a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=License" title="">License</a> </li> --- 91,99 ---- <li> ! <a href="http://sourceforge.net/p/ikvm/wiki/FAQ/" title="">FAQ</a> </li> <li> ! <a href="http://sourceforge.net/p/ikvm/wiki/License/" title="">License</a> </li> *************** *** 109,125 **** <li> ! <a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=User%27s_Guide">Introduction</a> </li> <li> ! <a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Installation" title="">Installation</a> </li> <li> ! <a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Tutorial" title="">Tutorial</a> </li> <li> ! <a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Tools" title="">Tools Reference</a> </li> --- 109,125 ---- <li> ! <a href="http://sourceforge.net/p/ikvm/wiki/User%27s_Guide/">Introduction</a> </li> <li> ! <a href="http://sourceforge.net/p/ikvm/wiki/Installation/" title="">Installation</a> </li> <li> ! <a href="http://sourceforge.net/p/ikvm/wiki/Tutorial/" title="">Tutorial</a> </li> <li> ! <a href="http://sourceforge.net/p/ikvm/wiki/Tools/" title="">Tools Reference</a> </li> *************** *** 247,251 **** </li> ! <li>Use the <a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Ikvmstub">ikvmstub</a> application to generate a Java jar file for each dll you identified in step 2. <p>The ikvmstub tool analyzes the .NET classes in the designated dll and generates a jar file containing Java interfaces and stub classes. This information is needed by the Java source compiler, which --- 247,251 ---- </li> ! <li>Use the <a href="http://sourceforge.net/p/ikvm/wiki/Ikvmstub/">ikvmstub</a> application to generate a Java jar file for each dll you identified in step 2. <p>The ikvmstub tool analyzes the .NET classes in the designated dll and generates a jar file containing Java interfaces and stub classes. This information is needed by the Java source compiler, which *************** *** 260,264 **** </ol> ! <p>For an example of this, see the <a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Tutorial">tutorial</a>.</p> </div> --- 260,264 ---- </ol> ! <p>For an example of this, see the <a href="http://sourceforge.net/p/ikvm/wiki/Tutorial/">tutorial</a>.</p> </div> Index: concepts.html =================================================================== RCS file: /cvsroot/ikvm/ikvm/website/build/site/devguide/concepts.html,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** concepts.html 5 May 2011 13:29:40 -0000 1.8 --- concepts.html 29 Jun 2014 07:13:58 -0000 1.9 *************** *** 91,99 **** <li> ! <a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=FAQ" title="">FAQ</a> </li> <li> ! <a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=License" title="">License</a> </li> --- 91,99 ---- <li> ! <a href="http://sourceforge.net/p/ikvm/wiki/FAQ/" title="">FAQ</a> </li> <li> ! <a href="http://sourceforge.net/p/ikvm/wiki/License/" title="">License</a> </li> *************** *** 109,125 **** <li> ! <a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=User%27s_Guide">Introduction</a> </li> <li> ! <a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Installation" title="">Installation</a> </li> <li> ! <a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Tutorial" title="">Tutorial</a> </li> <li> ! <a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Tools" title="">Tools Reference</a> </li> --- 109,125 ---- <li> ! <a href="http://sourceforge.net/p/ikvm/wiki/User%27s_Guide/">Introduction</a> </li> <li> ! <a href="http://sourceforge.net/p/ikvm/wiki/Installation/" title="">Installation</a> </li> <li> ! <a href="http://sourceforge.net/p/ikvm/wiki/Tutorial/" title="">Tutorial</a> </li> <li> ! <a href="http://sourceforge.net/p/ikvm/wiki/Tools/" title="">Tools Reference</a> </li> *************** *** 229,233 **** <div style="margin-left: 0 ; border: 2px"> <p>When you run a Java application using ikvm, ikvm finds and loads Java .class files much like ! other Java VM's. See the <a href="https://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Ikvm">ikvm notes</a> for details.</p> </div> <a name="N1002C"></a><a name="Class+Loading+in+ikvmc-compiled+Java+Applications"></a> --- 229,233 ---- <div style="margin-left: 0 ; border: 2px"> <p>When you run a Java application using ikvm, ikvm finds and loads Java .class files much like ! other Java VM's. See the <a href="http://sourceforge.net/p/ikvm/wiki/Ikvm/">ikvm notes</a> for details.</p> </div> <a name="N1002C"></a><a name="Class+Loading+in+ikvmc-compiled+Java+Applications"></a> |
|
From: Jeroen F. <jfr...@us...> - 2014-06-24 12:06:47
|
Update of /cvsroot/ikvm/ikvm/runtime In directory sfp-cvs-1.v30.ch3.sourceforge.com:/tmp/cvs-serv8992 Modified Files: ClassFile.cs compiler.cs verifier.cs Log Message: Updated ldc <methodhandle> error behavior to match Java 8. Index: verifier.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/verifier.cs,v retrieving revision 1.122 retrieving revision 1.123 diff -C2 -d -r1.122 -r1.123 *** verifier.cs 1 May 2014 08:07:51 -0000 1.122 --- verifier.cs 24 Jun 2014 12:06:44 -0000 1.123 *************** *** 2773,2782 **** case ClassFile.RefKind.putField: case ClassFile.RefKind.putStatic: ! err = HardError.NoSuchFieldException; ! msg = "no such field: {0}.{1}{2}"; break; default: ! err = HardError.NoSuchMethodException; ! msg = "no such method: {0}.{1}{2}"; break; } --- 2773,2782 ---- case ClassFile.RefKind.putField: case ClassFile.RefKind.putStatic: ! err = HardError.NoSuchFieldError; ! msg = cpi.Name; break; default: ! err = HardError.NoSuchMethodError; ! msg = cpi.Class + "." + cpi.Name + cpi.Signature; break; } *************** *** 2791,2795 **** else { ! SetHardError(wrapper.GetClassLoader(), ref instr, HardError.IllegalAccessException, "member is private: {0}.{1}/{2}, from {3}", cpi.Class, cpi.Name, SigToString(cpi.Signature), wrapper.Name); } } --- 2791,2795 ---- else { ! SetHardError(wrapper.GetClassLoader(), ref instr, HardError.IllegalAccessException, "member is private: {0}.{1}/{2}/{3}, from {4}", cpi.Class, cpi.Name, SigToString(cpi.Signature), cpi.Kind, wrapper.Name); } } *************** *** 3568,3574 **** break; case HardError.IncompatibleClassChangeError: - case HardError.NoSuchFieldException: case HardError.IllegalAccessException: - case HardError.NoSuchMethodException: msg = Message.EmittedIncompatibleClassChangeError; break; --- 3568,3572 ---- Index: ClassFile.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/ClassFile.cs,v retrieving revision 1.130 retrieving revision 1.131 diff -C2 -d -r1.130 -r1.131 *** ClassFile.cs 24 Jun 2014 11:15:26 -0000 1.130 --- ClassFile.cs 24 Jun 2014 12:06:44 -0000 1.131 *************** *** 40,45 **** LinkageError, // "exceptions" that are wrapped in an IncompatibleClassChangeError - NoSuchFieldException, - NoSuchMethodException, IllegalAccessException, // if an error is added here, it must also be added to MethodAnalyzer.SetHardError() --- 40,43 ---- Index: compiler.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/compiler.cs,v retrieving revision 1.247 retrieving revision 1.248 diff -C2 -d -r1.247 -r1.248 *** compiler.cs 16 Jun 2014 13:07:11 -0000 1.247 --- compiler.cs 24 Jun 2014 12:06:44 -0000 1.248 *************** *** 2743,2754 **** exceptionType = ClassLoaderWrapper.LoadClassCritical("java.lang.NoSuchMethodError"); break; - case HardError.NoSuchFieldException: - exceptionType = ClassLoaderWrapper.LoadClassCritical("java.lang.NoSuchFieldException"); - wrapIncompatibleClassChangeError = true; - break; - case HardError.NoSuchMethodException: - exceptionType = ClassLoaderWrapper.LoadClassCritical("java.lang.NoSuchMethodException"); - wrapIncompatibleClassChangeError = true; - break; case HardError.IllegalAccessException: exceptionType = ClassLoaderWrapper.LoadClassCritical("java.lang.IllegalAccessException"); --- 2743,2746 ---- |
|
From: Jeroen F. <jfr...@us...> - 2014-06-24 11:15:28
|
Update of /cvsroot/ikvm/ikvm/runtime In directory sfp-cvs-1.v30.ch3.sourceforge.com:/tmp/cvs-serv6100 Modified Files: ClassFile.cs Log Message: Bug fix. Since Java 1.7 class names aren't allowed to have [ and ] characters. Index: ClassFile.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/ClassFile.cs,v retrieving revision 1.129 retrieving revision 1.130 diff -C2 -d -r1.129 -r1.130 *** ClassFile.cs 5 Jun 2014 11:08:57 -0000 1.129 --- ClassFile.cs 24 Jun 2014 11:15:26 -0000 1.130 *************** *** 1453,1457 **** private string name; private TypeWrapper typeWrapper; ! private static char[] invalidJava15Characters = { '.', ';' }; internal ConstantPoolItemClass(BigEndianBinaryReader br) --- 1453,1457 ---- private string name; private TypeWrapper typeWrapper; ! private static char[] invalidJava15Characters = { '.', ';', '[', ']' }; internal ConstantPoolItemClass(BigEndianBinaryReader br) *************** *** 1519,1522 **** --- 1519,1523 ---- { // since 1.5 the restrictions on class names have been greatly reduced + int start = 0; int end = name.Length; if(name[0] == '[') *************** *** 1534,1539 **** end--; } } ! if(name.IndexOfAny(invalidJava15Characters, 0, end) >= 0) { goto barf; --- 1535,1544 ---- end--; } + while(name[start] == '[') + { + start++; + } } ! if(name.IndexOfAny(invalidJava15Characters, start, end - start) >= 0) { goto barf; |
|
From: Jeroen F. <jfr...@us...> - 2014-06-24 10:32:19
|
Update of /cvsroot/ikvm/ikvm/runtime In directory sfp-cvs-1.v30.ch3.sourceforge.com:/tmp/cvs-serv3829 Modified Files: ClassLoaderWrapper.cs JavaException.cs Log Message: Fixed regression introduced by previous commit. We should not introduce SecurityException, because it conflicts with System.Security.SecurityException. Index: JavaException.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/JavaException.cs,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** JavaException.cs 24 Jun 2014 09:44:37 -0000 1.17 --- JavaException.cs 24 Jun 2014 10:32:16 -0000 1.18 *************** *** 218,224 **** } ! sealed class SecurityException : RetargetableJavaException { ! internal SecurityException(string msg) : base(msg) { --- 218,224 ---- } ! sealed class JavaSecurityException : RetargetableJavaException { ! internal JavaSecurityException(string msg) : base(msg) { Index: ClassLoaderWrapper.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/ClassLoaderWrapper.cs,v retrieving revision 1.226 retrieving revision 1.227 diff -C2 -d -r1.226 -r1.227 *** ClassLoaderWrapper.cs 24 Jun 2014 09:44:37 -0000 1.226 --- ClassLoaderWrapper.cs 24 Jun 2014 10:32:16 -0000 1.227 *************** *** 358,362 **** if (className.StartsWith("java.", StringComparison.Ordinal)) { ! throw new SecurityException("Prohibited package name: " + className.Substring(0, className.LastIndexOf('.'))); } } --- 358,362 ---- if (className.StartsWith("java.", StringComparison.Ordinal)) { ! throw new JavaSecurityException("Prohibited package name: " + className.Substring(0, className.LastIndexOf('.'))); } } |
|
From: Jeroen F. <jfr...@us...> - 2014-06-24 09:44:40
|
Update of /cvsroot/ikvm/ikvm/runtime In directory sfp-cvs-1.v30.ch3.sourceforge.com:/tmp/cvs-serv546/runtime Modified Files: AssemblyClassLoader.cs ClassLoaderWrapper.cs JavaException.cs Log Message: Bug fix. Only the bootstrap class loader is allowed to define classes in the java package. Index: JavaException.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/JavaException.cs,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** JavaException.cs 23 Feb 2013 12:41:02 -0000 1.16 --- JavaException.cs 24 Jun 2014 09:44:37 -0000 1.17 *************** *** 1,4 **** /* ! Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Jeroen Frijters This software is provided 'as-is', without any express or implied --- 1,4 ---- /* ! Copyright (C) 2002-2014 Jeroen Frijters This software is provided 'as-is', without any express or implied *************** *** 217,218 **** --- 217,233 ---- #endif } + + sealed class SecurityException : RetargetableJavaException + { + internal SecurityException(string msg) + : base(msg) + { + } + + #if !STATIC_COMPILER && !FIRST_PASS && !STUB_GENERATOR + internal override Exception ToJava() + { + return new java.lang.SecurityException(Message); + } + #endif + } Index: ClassLoaderWrapper.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/ClassLoaderWrapper.cs,v retrieving revision 1.225 retrieving revision 1.226 diff -C2 -d -r1.225 -r1.226 *** ClassLoaderWrapper.cs 3 Jun 2014 12:42:19 -0000 1.225 --- ClassLoaderWrapper.cs 24 Jun 2014 09:44:37 -0000 1.226 *************** *** 354,357 **** --- 354,365 ---- #endif // !STATIC_COMPILER && !STUB_GENERATOR + protected virtual void CheckProhibitedPackage(string className) + { + if (className.StartsWith("java.", StringComparison.Ordinal)) + { + throw new SecurityException("Prohibited package name: " + className.Substring(0, className.LastIndexOf('.'))); + } + } + #if !STUB_GENERATOR internal TypeWrapper DefineClass(ClassFile f, ProtectionDomain protectionDomain) *************** *** 381,384 **** --- 389,393 ---- } #endif + CheckProhibitedPackage(f.Name); // check if the class already exists if we're an AssemblyClassLoader if(FindLoadedClassLazy(f.Name) != null) Index: AssemblyClassLoader.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/AssemblyClassLoader.cs,v retrieving revision 1.64 retrieving revision 1.65 diff -C2 -d -r1.64 -r1.65 *** AssemblyClassLoader.cs 2 Jun 2014 13:25:40 -0000 1.64 --- AssemblyClassLoader.cs 24 Jun 2014 09:44:37 -0000 1.65 *************** *** 1309,1312 **** --- 1309,1316 ---- } + protected override void CheckProhibitedPackage(string className) + { + } + #if !FIRST_PASS && !STATIC_COMPILER && !STUB_GENERATOR internal override java.lang.ClassLoader GetJavaClassLoader() |
|
From: Jeroen F. <jfr...@us...> - 2014-06-24 09:44:39
|
Update of /cvsroot/ikvm/ikvm/ikvmc In directory sfp-cvs-1.v30.ch3.sourceforge.com:/tmp/cvs-serv546/ikvmc Modified Files: CompilerClassLoader.cs Log Message: Bug fix. Only the bootstrap class loader is allowed to define classes in the java package. Index: CompilerClassLoader.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/ikvmc/CompilerClassLoader.cs,v retrieving revision 1.268 retrieving revision 1.269 diff -C2 -d -r1.268 -r1.269 *** CompilerClassLoader.cs 13 Jun 2014 06:54:06 -0000 1.268 --- CompilerClassLoader.cs 24 Jun 2014 09:44:37 -0000 1.269 *************** *** 72,77 **** private List<string> jarList = new List<string>(); private List<TypeWrapper> allwrappers; ! internal CompilerClassLoader(AssemblyClassLoader[] referencedAssemblies, CompilerOptions options, FileInfo assemblyPath, bool targetIsModule, string assemblyName, Dictionary<string, Jar.Item> classes) : base(options.codegenoptions, null) { --- 72,78 ---- private List<string> jarList = new List<string>(); private List<TypeWrapper> allwrappers; + private bool compilingCoreAssembly; ! internal CompilerClassLoader(AssemblyClassLoader[] referencedAssemblies, CompilerOptions options, FileInfo assemblyPath, bool targetIsModule, string assemblyName, Dictionary<string, Jar.Item> classes, bool compilingCoreAssembly) : base(options.codegenoptions, null) { *************** *** 83,86 **** --- 84,88 ---- this.assemblyDir = assemblyPath.DirectoryName; this.targetIsModule = targetIsModule; + this.compilingCoreAssembly = compilingCoreAssembly; Tracer.Info(Tracer.Compiler, "Instantiate CompilerClassLoader for {0}", assemblyName); } *************** *** 2567,2571 **** if (c.Shadows != null && c.Name == "java.lang.Object") { ! return true; } } --- 2569,2573 ---- if (c.Shadows != null && c.Name == "java.lang.Object") { ! return compilingCoreAssembly = true; } } *************** *** 2871,2875 **** referencedAssemblies[i] = acl; } ! loader = new CompilerClassLoader(referencedAssemblies, options, options.path, options.targetIsModule, options.assembly, h); loader.classesToCompile = new List<string>(h.Keys); if(options.remapfile != null) --- 2873,2877 ---- referencedAssemblies[i] = acl; } ! loader = new CompilerClassLoader(referencedAssemblies, options, options.path, options.targetIsModule, options.assembly, h, compilingCoreAssembly); loader.classesToCompile = new List<string>(h.Keys); if(options.remapfile != null) *************** *** 3329,3332 **** --- 3331,3342 ---- get { return options.noParameterReflection; } } + + protected override void CheckProhibitedPackage(string className) + { + if (!compilingCoreAssembly) + { + base.CheckProhibitedPackage(className); + } + } } |
|
From: Jeroen F. <jfr...@us...> - 2014-06-24 08:26:15
|
Update of /cvsroot/ikvm/ikvm/runtime In directory sfp-cvs-1.v30.ch3.sourceforge.com:/tmp/cvs-serv29021 Modified Files: DynamicTypeWrapper.cs Log Message: Bug fix. Interfaces can't "override" final methods in Object. Index: DynamicTypeWrapper.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/DynamicTypeWrapper.cs,v retrieving revision 1.250 retrieving revision 1.251 diff -C2 -d -r1.250 -r1.251 *** DynamicTypeWrapper.cs 13 Jun 2014 06:54:06 -0000 1.250 --- DynamicTypeWrapper.cs 24 Jun 2014 08:26:13 -0000 1.251 *************** *** 118,124 **** this.classLoader = classLoader; this.sourceFileName = f.SourceFileAttribute; ! this.baseTypeWrapper = f.IsInterface ? null : LoadTypeWrapper(classLoader, pd, f.SuperClass); ! if (BaseTypeWrapper != null) { if (!BaseTypeWrapper.IsAccessibleFrom(this)) { --- 118,139 ---- this.classLoader = classLoader; this.sourceFileName = f.SourceFileAttribute; ! if (f.IsInterface) { + // interfaces can't "override" final methods in object + foreach (ClassFile.Method method in f.Methods) + { + MethodWrapper mw; + if (method.IsVirtual + && (mw = CoreClasses.java.lang.Object.Wrapper.GetMethodWrapper(method.Name, method.Signature, false)) != null + && mw.IsVirtual + && mw.IsFinal) + { + throw new VerifyError("class " + f.Name + " overrides final method " + method.Name + "." + method.Signature); + } + } + } + else + { + this.baseTypeWrapper = LoadTypeWrapper(classLoader, pd, f.SuperClass); if (!BaseTypeWrapper.IsAccessibleFrom(this)) { |
|
From: Jeroen F. <jfr...@us...> - 2014-06-23 15:09:46
|
Update of /cvsroot/ikvm/ikvm/runtime/openjdk In directory sfp-cvs-1.v30.ch3.sourceforge.com:/tmp/cvs-serv25837 Modified Files: java.lang.cs Log Message: Bug fix. Array classes get the system protection domain, not the element type's. Index: java.lang.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/openjdk/java.lang.cs,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** java.lang.cs 10 Jun 2014 13:23:29 -0000 1.16 --- java.lang.cs 23 Jun 2014 15:09:43 -0000 1.17 *************** *** 338,344 **** #else TypeWrapper wrapper = TypeWrapper.FromClass(thisClass); ! while (wrapper.IsArray) { ! wrapper = wrapper.ElementTypeWrapper; } java.security.ProtectionDomain pd = wrapper.ClassObject.pd; --- 338,344 ---- #else TypeWrapper wrapper = TypeWrapper.FromClass(thisClass); ! if (wrapper.IsArray) { ! return null; } java.security.ProtectionDomain pd = wrapper.ClassObject.pd; |