Esempio n. 1
0
 internal static bool Emit(DynamicTypeWrapper.FinishContext context, TypeWrapper wrapper, CodeEmitter ilgen, ClassFile classFile, int i, ClassFile.Method.Instruction[] code, InstructionFlags[] flags)
 {
     if (i >= 3
         && (flags[i - 0] & InstructionFlags.BranchTarget) == 0
         && (flags[i - 1] & InstructionFlags.BranchTarget) == 0
         && (flags[i - 2] & InstructionFlags.BranchTarget) == 0
         && (flags[i - 3] & InstructionFlags.BranchTarget) == 0
         && code[i - 1].NormalizedOpCode == NormalizedByteCode.__ldc
         && code[i - 2].NormalizedOpCode == NormalizedByteCode.__ldc
         && code[i - 3].NormalizedOpCode == NormalizedByteCode.__ldc)
     {
         // we now have a structural match, now we need to make sure that the argument values are what we expect
         TypeWrapper tclass = classFile.GetConstantPoolClassType(code[i - 3].Arg1);
         TypeWrapper vclass = classFile.GetConstantPoolClassType(code[i - 2].Arg1);
         string fieldName = classFile.GetConstantPoolConstantString(code[i - 1].Arg1);
         if (tclass == wrapper && !vclass.IsUnloadable && !vclass.IsPrimitive && !vclass.IsNonPrimitiveValueType)
         {
             FieldWrapper field = wrapper.GetFieldWrapper(fieldName, vclass.SigName);
             if (field != null && !field.IsStatic && field.IsVolatile && field.DeclaringType == wrapper && field.FieldTypeWrapper == vclass)
             {
                 // everything matches up, now call the actual emitter
                 DoEmit(context, wrapper, ilgen, field);
                 return true;
             }
         }
     }
     return false;
 }
Esempio n. 2
0
 internal override string AllocMangledName(DynamicTypeWrapper tw)
 {
     lock (dynamicTypes)
     {
         return(TypeNameMangleImpl(dynamicTypes, tw.Name, tw));
     }
 }
		internal static ConstructorInfo AddAutomagicSerialization(DynamicTypeWrapper wrapper, TypeBuilder typeBuilder)
		{
			ConstructorInfo serializationCtor = null;
			if (wrapper.GetClassLoader().NoAutomagicSerialization)
			{
				// do nothing
			}
			else if ((wrapper.Modifiers & IKVM.Attributes.Modifiers.Enum) != 0)
			{
				MarkSerializable(typeBuilder);
			}
			else if (wrapper.IsSubTypeOf(serializable) && IsSafeForAutomagicSerialization(wrapper))
			{
				if (wrapper.IsSubTypeOf(externalizable))
				{
					MethodWrapper ctor = wrapper.GetMethodWrapper("<init>", "()V", false);
					if (ctor != null && ctor.IsPublic)
					{
						MarkSerializable(typeBuilder);
						ctor.Link();
						serializationCtor = AddConstructor(typeBuilder, ctor, null, true);
						if (!wrapper.BaseTypeWrapper.IsSubTypeOf(serializable))
						{
							AddGetObjectData(typeBuilder);
						}
						if (wrapper.BaseTypeWrapper.GetMethodWrapper("readResolve", "()Ljava.lang.Object;", true) != null)
						{
							RemoveReadResolve(typeBuilder);
						}
					}
				}
				else if (wrapper.BaseTypeWrapper.IsSubTypeOf(serializable))
				{
					ConstructorInfo baseCtor = wrapper.GetBaseSerializationConstructor();
					if (baseCtor != null && (baseCtor.IsFamily || baseCtor.IsFamilyOrAssembly))
					{
						MarkSerializable(typeBuilder);
						serializationCtor = AddConstructor(typeBuilder, null, baseCtor, false);
						AddReadResolve(wrapper, typeBuilder);
					}
				}
				else
				{
					MethodWrapper baseCtor = wrapper.BaseTypeWrapper.GetMethodWrapper("<init>", "()V", false);
					if (baseCtor != null && baseCtor.IsAccessibleFrom(wrapper.BaseTypeWrapper, wrapper, wrapper))
					{
						MarkSerializable(typeBuilder);
						AddGetObjectData(typeBuilder);
#if STATIC_COMPILER
						// because the base type can be a __WorkaroundBaseClass__, we may need to replace the constructor
						baseCtor = ((AotTypeWrapper)wrapper).ReplaceMethodWrapper(baseCtor);
#endif
						baseCtor.Link();
						serializationCtor = AddConstructor(typeBuilder, baseCtor, null, true);
						AddReadResolve(wrapper, typeBuilder);
					}
				}
			}
			return serializationCtor;
		}
Esempio n. 4
0
 private static bool Reflection_getCallerClass(EmitIntrinsicContext eic)
 {
     if (eic.Caller.HasCallerID)
     {
         int arg = eic.Caller.GetParametersForDefineMethod().Length - 1;
         if (!eic.Caller.IsStatic)
         {
             arg++;
         }
         eic.Emitter.EmitLdarg(arg);
         MethodWrapper mw;
         if (MatchInvokeStatic(eic, 1, "java.lang.ClassLoader", "getClassLoader", "(Ljava.lang.Class;)Ljava.lang.ClassLoader;"))
         {
             eic.PatchOpCode(1, NormalizedByteCode.__nop);
             mw = [email protected]("getCallerClassLoader", "()Ljava.lang.ClassLoader;", false);
         }
         else
         {
             mw = [email protected]("getCallerClass", "()Ljava.lang.Class;", false);
         }
         mw.Link();
         mw.EmitCallvirt(eic.Emitter);
         return(true);
     }
     else if (!DynamicTypeWrapper.RequiresDynamicReflectionCallerClass(eic.ClassFile.Name, eic.Caller.Name, eic.Caller.Signature))
     {
         StaticCompiler.IssueMessage(Message.ReflectionCallerClassRequiresCallerID, eic.ClassFile.Name, eic.Caller.Name, eic.Caller.Signature);
     }
     return(false);
 }
Esempio n. 5
0
        private static void AddReadResolve(DynamicTypeWrapper wrapper, TypeBuilder tb)
        {
            MethodWrapper mw = wrapper.GetMethodWrapper("readResolve", "()Ljava.lang.Object;", false);

            if (mw != null && !wrapper.IsSubTypeOf(iobjectreference))
            {
                tb.AddInterfaceImplementation(JVM.Import(typeof(IObjectReference)));
                MethodBuilder getRealObject = tb.DefineMethod("IObjectReference.GetRealObject", MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final,
                                                              Types.Object, new Type[] { JVM.Import(typeof(StreamingContext)) });
                getRealObject.SetCustomAttribute(securityCriticalAttribute);
                AttributeHelper.HideFromJava(getRealObject);
                tb.DefineMethodOverride(getRealObject, JVM.Import(typeof(IObjectReference)).GetMethod("GetRealObject"));
                CodeEmitter ilgen = CodeEmitter.Create(getRealObject);
                mw.Link();
                if (!wrapper.IsFinal)
                {
                    // readResolve is only applicable if it exists on the actual type of the object, so if we're a subclass don't call it
                    ilgen.Emit(OpCodes.Ldarg_0);
                    ilgen.Emit(OpCodes.Callvirt, Compiler.getTypeMethod);
                    ilgen.Emit(OpCodes.Ldtoken, wrapper.TypeAsBaseType);
                    ilgen.Emit(OpCodes.Call, Compiler.getTypeFromHandleMethod);
                    CodeEmitterLabel label = ilgen.DefineLabel();
                    ilgen.Emit(OpCodes.Beq_S, label);
                    ilgen.Emit(OpCodes.Ldarg_0);
                    ilgen.Emit(OpCodes.Ret);
                    ilgen.MarkLabel(label);
                }
                ilgen.Emit(OpCodes.Ldarg_0);
                mw.EmitCall(ilgen);
                ilgen.Emit(OpCodes.Ret);
                ilgen.DoEmit();
            }
        }
Esempio n. 6
0
    private static void InitMethodImpl(MemberName self, MethodWrapper mw, bool wantSpecial)
    {
#if !FIRST_PASS
        int flags = (int)mw.Modifiers;
        flags |= mw.IsConstructor ? MethodHandleNatives.Constants.MN_IS_CONSTRUCTOR : MethodHandleNatives.Constants.MN_IS_METHOD;
        if (mw.IsStatic)
        {
            flags |= MethodHandleNatives.Constants.REF_invokeStatic << MethodHandleNatives.Constants.MN_REFERENCE_KIND_SHIFT;
        }
        else if (mw.IsPrivate || mw.IsFinal || mw.IsConstructor || wantSpecial)
        {
            flags |= MethodHandleNatives.Constants.REF_invokeSpecial << MethodHandleNatives.Constants.MN_REFERENCE_KIND_SHIFT;
        }
        else if (mw.DeclaringType.IsInterface)
        {
            flags |= MethodHandleNatives.Constants.REF_invokeInterface << MethodHandleNatives.Constants.MN_REFERENCE_KIND_SHIFT;
        }
        else
        {
            flags |= MethodHandleNatives.Constants.REF_invokeVirtual << MethodHandleNatives.Constants.MN_REFERENCE_KIND_SHIFT;
        }
        if (mw.HasCallerID || DynamicTypeWrapper.RequiresDynamicReflectionCallerClass(mw.DeclaringType.Name, mw.Name, mw.Signature))
        {
            flags |= MemberName.CALLER_SENSITIVE;
        }
        if (mw.IsConstructor && mw.DeclaringType == CoreClasses.java.lang.String.Wrapper)
        {
            java.lang.Class[] parameters1 = new java.lang.Class[mw.GetParameters().Length];
            for (int i = 0; i < mw.GetParameters().Length; i++)
            {
                parameters1[i] = mw.GetParameters()[i].ClassObject;
            }
            MethodType mt = MethodType.methodType(typeof(string), parameters1);
            typeof(MemberName).GetField("type", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(self, mt);
            self.vmtarget = CreateMemberNameDelegate(mw, null, false, mt);
            flags        -= MethodHandleNatives.Constants.REF_invokeSpecial << MethodHandleNatives.Constants.MN_REFERENCE_KIND_SHIFT;
            flags        += MethodHandleNatives.Constants.REF_invokeStatic << MethodHandleNatives.Constants.MN_REFERENCE_KIND_SHIFT;
            flags        -= MethodHandleNatives.Constants.MN_IS_CONSTRUCTOR;
            flags        += MethodHandleNatives.Constants.MN_IS_METHOD;
            flags        += MethodHandleNatives.Constants.ACC_STATIC;
            self._flags(flags);
            self._clazz(mw.DeclaringType.ClassObject);
            return;
        }
        self._flags(flags);
        self._clazz(mw.DeclaringType.ClassObject);
        int firstParam = mw.IsStatic ? 0 : 1;
        java.lang.Class[] parameters = new java.lang.Class[mw.GetParameters().Length + firstParam];
        for (int i = 0; i < mw.GetParameters().Length; i++)
        {
            parameters[i + firstParam] = mw.GetParameters()[i].ClassObject;
        }
        if (!mw.IsStatic)
        {
            parameters[0] = mw.DeclaringType.ClassObject;
        }
        self.vmtarget = CreateMemberNameDelegate(mw, mw.ReturnType.ClassObject, !wantSpecial, MethodType.methodType(mw.ReturnType.ClassObject, parameters));
#endif
    }
Esempio n. 7
0
        internal static MethodBuilder AddAutomagicSerialization(DynamicTypeWrapper wrapper, TypeBuilder typeBuilder)
        {
            MethodBuilder serializationCtor = null;

            if ((wrapper.Modifiers & IKVM.Attributes.Modifiers.Enum) != 0)
            {
                MarkSerializable(typeBuilder);
            }
            else if (wrapper.IsSubTypeOf(CoreClasses.java.io.Serializable.Wrapper) && IsSafeForAutomagicSerialization(wrapper))
            {
                if (wrapper.IsSubTypeOf(externalizable))
                {
                    MethodWrapper ctor = wrapper.GetMethodWrapper("<init>", "()V", false);
                    if (ctor != null && ctor.IsPublic)
                    {
                        MarkSerializable(typeBuilder);
                        ctor.Link();
                        serializationCtor = AddConstructor(typeBuilder, ctor, null, true);
                        if (!wrapper.BaseTypeWrapper.IsSubTypeOf(CoreClasses.java.io.Serializable.Wrapper))
                        {
                            AddGetObjectData(typeBuilder);
                        }
                        if (wrapper.BaseTypeWrapper.GetMethodWrapper("readResolve", "()Ljava.lang.Object;", true) != null)
                        {
                            RemoveReadResolve(typeBuilder);
                        }
                    }
                }
                else if (wrapper.BaseTypeWrapper.IsSubTypeOf(CoreClasses.java.io.Serializable.Wrapper))
                {
                    MethodBase baseCtor = wrapper.GetBaseSerializationConstructor();
                    if (baseCtor != null && (baseCtor.IsFamily || baseCtor.IsFamilyOrAssembly))
                    {
                        MarkSerializable(typeBuilder);
                        serializationCtor = AddConstructor(typeBuilder, null, baseCtor, false);
                        AddReadResolve(wrapper, typeBuilder);
                    }
                }
                else
                {
                    MethodWrapper baseCtor = wrapper.BaseTypeWrapper.GetMethodWrapper("<init>", "()V", false);
                    if (baseCtor != null && baseCtor.IsAccessibleFrom(wrapper.BaseTypeWrapper, wrapper, wrapper))
                    {
                        MarkSerializable(typeBuilder);
                        AddGetObjectData(typeBuilder);
#if STATIC_COMPILER
                        // because the base type can be a __WorkaroundBaseClass__, we may need to replace the constructor
                        baseCtor = ((AotTypeWrapper)wrapper).ReplaceMethodWrapper(baseCtor);
#endif
                        baseCtor.Link();
                        serializationCtor = AddConstructor(typeBuilder, baseCtor, null, true);
                        AddReadResolve(wrapper, typeBuilder);
                    }
                }
            }
            return(serializationCtor);
        }
Esempio n. 8
0
        public void CanSetProperty()
        {
            var expectedValue = "TestValue";
            var propName      = "TestProp";
            var wrapper       = new DynamicTypeWrapper();

            wrapper.SetPropertyValue(propName, expectedValue);

            var actual = wrapper.GetPropertyValue(propName);

            Assert.Equal(expectedValue, actual);
        }
Esempio n. 9
0
        internal sealed override TypeWrapper DefineClassImpl(Dictionary <string, TypeWrapper> types, ClassFile f, ClassLoaderWrapper classLoader, object protectionDomain)
        {
            DynamicTypeWrapper type;

#if STATIC_COMPILER
            type = new AotTypeWrapper(f, (CompilerClassLoader)classLoader);
#else
            type = new DynamicTypeWrapper(f, classLoader);
#endif
            // this step can throw a retargettable exception, if the class is incorrect
            bool hasclinit;
            type.CreateStep1(out hasclinit);
            // now we can allocate the mangledTypeName, because the next step cannot fail
            string mangledTypeName = AllocMangledName(f.Name);
            // This step actually creates the TypeBuilder. It is not allowed to throw any exceptions,
            // if an exception does occur, it is due to a programming error in the IKVM or CLR runtime
            // and will cause a CriticalFailure and exit the process.
            type.CreateStep2NoFail(hasclinit, mangledTypeName);
            lock (types)
            {
                // in very extreme conditions another thread may have beaten us to it
                // and loaded (not defined) a class with the same name, in that case
                // we'll leak the the Reflection.Emit defined type. Also see the comment
                // in ClassLoaderWrapper.RegisterInitiatingLoader().
                TypeWrapper race;
                types.TryGetValue(f.Name, out race);
                if (race == null)
                {
                    lock (dynamicTypes)
                    {
                        Debug.Assert(dynamicTypes.ContainsKey(mangledTypeName) && dynamicTypes[mangledTypeName] == null);
                        dynamicTypes[mangledTypeName] = type;
                    }
                    types[f.Name] = type;
#if !STATIC_COMPILER && !FIRST_PASS
                    java.lang.Class clazz = new java.lang.Class(null);
#if __MonoCS__
                    TypeWrapper.SetTypeWrapperHack(clazz, type);
#else
                    clazz.typeWrapper = type;
#endif
                    clazz.pd = (java.security.ProtectionDomain)protectionDomain;
                    type.SetClassObject(clazz);
#endif
                }
                else
                {
                    throw new LinkageError("duplicate class definition: " + f.Name);
                }
            }
            return(type);
        }
Esempio n. 10
0
        public void GetHashCodeEqualForEqualWrappers()
        {
            var expectedValue = "TestValue";
            var propName      = "TestProp";
            var wrapper       = new DynamicTypeWrapper();

            wrapper.SetPropertyValue(propName, expectedValue);

            var wrapper2 = new DynamicTypeWrapper();

            wrapper2.SetPropertyValue(propName, expectedValue);

            Assert.Equal(wrapper.GetHashCode(), wrapper2.GetHashCode());
        }
Esempio n. 11
0
        public void CanEqualWrappers()
        {
            var expectedValue = "TestValue";
            var propName      = "TestProp";
            var wrapper       = new DynamicTypeWrapper();

            wrapper.SetPropertyValue(propName, expectedValue);

            var wrapper2 = new DynamicTypeWrapper();

            wrapper2.SetPropertyValue(propName, expectedValue);

            Assert.Equal(wrapper, wrapper2);
        }
Esempio n. 12
0
        public void CanTryGetProperty()
        {
            var expectedValue = "TestValue";
            var propName      = "TestProp";
            var wrapper       = new DynamicTypeWrapper();

            wrapper.SetPropertyValue(propName, expectedValue);

            object actual;

            Assert.True(wrapper.TryGetPropertyValue(propName, out actual));

            Assert.Equal(expectedValue, actual);
        }
Esempio n. 13
0
        /// <summary>
        /// Writes the JSON representation of the object.
        /// </summary>
        /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
        /// <param name="value">The value.</param>
        /// <param name="serializer">The calling serializer.</param>
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            if (serializer is null)
            {
                throw new ArgumentNullException(nameof(serializer));
            }

            DynamicTypeWrapper dynamicTypeWrapper = value as DynamicTypeWrapper;

            if (dynamicTypeWrapper != null)
            {
                serializer.Serialize(writer, dynamicTypeWrapper.Values);
            }
        }
        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);
        }
Esempio n. 15
0
        private object GetValue(DynamicTypeWrapper wrapper, string path)
        {
            var parts = path.Split('/');

            foreach (var part in parts)
            {
                object value;
                wrapper.TryGetPropertyValue(part, out value);
                wrapper = value as DynamicTypeWrapper;
                if (wrapper == null)
                {
                    return(value);
                }
            }

            Assert.False(true, "Property " + path + " not found");
            return(null);
        }
Esempio n. 16
0
        internal sealed override TypeWrapper DefineClassImpl(Dictionary <string, TypeWrapper> types, TypeWrapper host, ClassFile f, ClassLoaderWrapper classLoader, ProtectionDomain protectionDomain)
        {
#if STATIC_COMPILER
            AotTypeWrapper type = new AotTypeWrapper(f, (CompilerClassLoader)classLoader);
            type.CreateStep1();
            types[f.Name] = type;
            return(type);
#elif FIRST_PASS
            return(null);
#else
            // this step can throw a retargettable exception, if the class is incorrect
            DynamicTypeWrapper type = new DynamicTypeWrapper(host, f, classLoader, protectionDomain);
            // This step actually creates the TypeBuilder. It is not allowed to throw any exceptions,
            // if an exception does occur, it is due to a programming error in the IKVM or CLR runtime
            // and will cause a CriticalFailure and exit the process.
            type.CreateStep1();
            type.CreateStep2();
            if (types == null)
            {
                // we're defining an anonymous class, so we don't need any locking
                TieClassAndWrapper(type, protectionDomain);
                return(type);
            }
            lock (types)
            {
                // in very extreme conditions another thread may have beaten us to it
                // and loaded (not defined) a class with the same name, in that case
                // we'll leak the the Reflection.Emit defined type. Also see the comment
                // in ClassLoaderWrapper.RegisterInitiatingLoader().
                TypeWrapper race;
                types.TryGetValue(f.Name, out race);
                if (race == null)
                {
                    types[f.Name] = type;
                    TieClassAndWrapper(type, protectionDomain);
                }
                else
                {
                    throw new LinkageError("duplicate class definition: " + f.Name);
                }
            }
            return(type);
#endif // STATIC_COMPILER
        }
Esempio n. 17
0
        public NodeInStream(INodeIn nodeIn, IConnectionHandler handler, T defaultValue = default(T))
        {
            handler = handler ?? new DefaultConnectionHandler(null, typeof(T));
            FNodeIn = nodeIn;
            object inputInterface;

            if (typeof(T).UsesDynamicAssembly())
            {
                inputInterface = new DynamicTypeWrapper(this);
            }
            else
            {
                inputInterface = this;
            }
            FNodeIn.SetConnectionHandler(handler, inputInterface);
            FAutoValidate   = nodeIn.AutoValidate;
            FDefaultValue   = defaultValue;
            FUpstreamStream = FNullStream;
        }
Esempio n. 18
0
	private static void DoEmit(DynamicTypeWrapper.FinishContext context, TypeWrapper wrapper, CodeEmitter ilgen, FieldWrapper field)
	{
		ConstructorBuilder cb;
		bool exists;
		lock (map)
		{
			exists = map.TryGetValue(field, out cb);
		}
		if (!exists)
		{
			// note that we don't need to lock here, because we're running as part of FinishCore, which is already protected by a lock
			TypeWrapper arfuTypeWrapper = ClassLoaderWrapper.LoadClassCritical("ikvm.internal.IntrinsicAtomicReferenceFieldUpdater");
			TypeBuilder tb = wrapper.TypeAsBuilder.DefineNestedType("__<ARFU>_" + field.Name + field.Signature.Replace('.', '/'), TypeAttributes.NestedPrivate | TypeAttributes.Sealed, arfuTypeWrapper.TypeAsBaseType);
			EmitCompareAndSet("compareAndSet", tb, field.GetField());
			EmitGet(tb, field.GetField());
			EmitSet("set", tb, field.GetField());

			cb = tb.DefineConstructor(MethodAttributes.Assembly, CallingConventions.Standard, Type.EmptyTypes);
			lock (map)
			{
				map.Add(field, cb);
			}
			CodeEmitter ctorilgen = CodeEmitter.Create(cb);
			ctorilgen.Emit(OpCodes.Ldarg_0);
			MethodWrapper basector = arfuTypeWrapper.GetMethodWrapper("<init>", "()V", false);
			basector.Link();
			basector.EmitCall(ctorilgen);
			ctorilgen.Emit(OpCodes.Ret);
			context.RegisterPostFinishProc(delegate
			{
				arfuTypeWrapper.Finish();
				tb.CreateType();
			});
		}
		ilgen.LazyEmitPop();
		ilgen.LazyEmitPop();
		ilgen.LazyEmitPop();
		ilgen.Emit(OpCodes.Newobj, cb);
	}
Esempio n. 19
0
 private static bool Reflection_getCallerClass(EmitIntrinsicContext eic)
 {
     if (eic.Caller.HasCallerID)
     {
         int arg = eic.Caller.GetParametersForDefineMethod().Length - 1;
         if (!eic.Caller.IsStatic)
         {
             arg++;
         }
         eic.Emitter.EmitLdarg(arg);
         MethodWrapper mw;
         if (MatchInvokeStatic(eic, 1, "java.lang.ClassLoader", "getClassLoader", "(Ljava.lang.Class;)Ljava.lang.ClassLoader;"))
         {
             eic.PatchOpCode(1, NormalizedByteCode.__nop);
             mw = [email protected]("getCallerClassLoader", "()Ljava.lang.ClassLoader;", false);
         }
         else
         {
             mw = [email protected]("getCallerClass", "()Ljava.lang.Class;", false);
         }
         mw.Link();
         mw.EmitCallvirt(eic.Emitter);
         return(true);
     }
     else if (DynamicTypeWrapper.RequiresDynamicReflectionCallerClass(eic.ClassFile.Name, eic.Caller.Name, eic.Caller.Signature))
     {
         // since the non-intrinsic version of Reflection.getCallerClass() always throws an exception, we have to redirect to the dynamic version
         MethodWrapper getCallerClass = ClassLoaderWrapper.LoadClassCritical("sun.reflect.Reflection").GetMethodWrapper("getCallerClass", "(I)Ljava.lang.Class;", false);
         getCallerClass.Link();
         eic.Emitter.EmitLdc_I4(2);
         getCallerClass.EmitCall(eic.Emitter);
         return(true);
     }
     else
     {
         StaticCompiler.IssueMessage(Message.ReflectionCallerClassRequiresCallerID, eic.ClassFile.Name, eic.Caller.Name, eic.Caller.Signature);
     }
     return(false);
 }
		internal static bool Emit(DynamicTypeWrapper.FinishContext context, ClassFile classFile, int constantPoolIndex, ClassFile.ConstantPoolItemInvokeDynamic cpi, CodeEmitter ilgen)
		{
			ClassFile.BootstrapMethod bsm = classFile.GetBootstrapMethod(cpi.BootstrapMethod);
			if (!IsLambdaMetafactory(classFile, bsm) && !IsLambdaAltMetafactory(classFile, bsm))
			{
				return false;
			}
			LambdaMetafactory lmf = context.GetValue<LambdaMetafactory>(constantPoolIndex);
			if (lmf.ctor == null && !lmf.EmitImpl(context, classFile, cpi, bsm, ilgen))
			{
#if STATIC_COMPILER
				if (context.TypeWrapper.GetClassLoader().DisableDynamicBinding)
				{
					StaticCompiler.IssueMessage(Message.UnableToCreateLambdaFactory);
				}
#endif
				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;
		}
Esempio n. 21
0
    private static void ResolveMethod(MemberName self, JlClass caller)
    {
        bool          invokeSpecial     = self.getReferenceKind() == MethodHandleNatives.Constants.REF_invokeSpecial;
        bool          newInvokeSpecial  = self.getReferenceKind() == MethodHandleNatives.Constants.REF_newInvokeSpecial;
        bool          searchBaseClasses = !newInvokeSpecial;
        MethodWrapper mw = TypeWrapper.FromClass(self.getDeclaringClass()).GetMethodWrapper(self.getName(), self.getSignature().Replace('/', '.'), searchBaseClasses);

        if (mw == null)
        {
            if (self.getReferenceKind() == MethodHandleNatives.Constants.REF_invokeInterface)
            {
                mw = TypeWrapper.FromClass(self.getDeclaringClass()).GetInterfaceMethod(self.getName(), self.getSignature().Replace('/', '.'));
                if (mw == null)
                {
                    mw = CoreClasses.java.lang.Object.Wrapper.GetMethodWrapper(self.getName(), self.getSignature().Replace('/', '.'), false);
                }
                if (mw != null && mw.IsConstructor)
                {
                    throw new java.lang.IncompatibleClassChangeError("Found interface " + self.getDeclaringClass().getName() + ", but class was expected");
                }
            }
            if (mw == null)
            {
                string msg = String.Format(invokeSpecial ? "{0}: method {1}{2} not found" : "{0}.{1}{2}", self.getDeclaringClass().getName(), self.getName(), self.getSignature());
                throw new java.lang.NoSuchMethodError(msg);
            }
        }
        if (mw.IsStatic != IsReferenceKindStatic(self.getReferenceKind()))
        {
            string msg = String.Format(mw.IsStatic ? "Expecting non-static method {0}.{1}{2}" : "Expected static method {0}.{1}{2}", mw.DeclaringType.Name, self.getName(), self.getSignature());
            throw new java.lang.IncompatibleClassChangeError(msg);
        }
        if (self.getReferenceKind() == MethodHandleNatives.Constants.REF_invokeVirtual && mw.DeclaringType.IsInterface)
        {
            throw new java.lang.IncompatibleClassChangeError("Found interface " + mw.DeclaringType.Name + ", but class was expected");
        }
        if (!mw.IsPublic && self.getReferenceKind() == MethodHandleNatives.Constants.REF_invokeInterface)
        {
            throw new java.lang.IncompatibleClassChangeError("private interface method requires invokespecial, not invokeinterface: method " + self.getDeclaringClass().getName() + "." + self.getName() + self.getSignature());
        }
        if (mw.IsConstructor && mw.DeclaringType == CoreClasses.java.lang.String.Wrapper)
        {
            self.vmtarget = CreateMemberNameDelegate(mw, caller, false, self.getMethodType().changeReturnType(CoreClasses.java.lang.String.Wrapper.ClassObject));
        }
        else if (!mw.IsConstructor || invokeSpecial || newInvokeSpecial)
        {
            MethodType methodType = self.getMethodType();
            if (!mw.IsStatic)
            {
                methodType = methodType.insertParameterTypes(0, mw.DeclaringType.ClassObject);
                if (newInvokeSpecial)
                {
                    methodType = methodType.changeReturnType(java.lang.Void.TYPE);
                }
            }
            self.vmtarget = CreateMemberNameDelegate(mw, caller, self.hasReceiverTypeDispatch(), methodType);
        }
        SetModifiers(self, mw);
        self._flags(self._flags() | (mw.IsConstructor ? MethodHandleNatives.Constants.MN_IS_CONSTRUCTOR : MethodHandleNatives.Constants.MN_IS_METHOD));
        if (self.getReferenceKind() == MethodHandleNatives.Constants.REF_invokeVirtual && (mw.IsPrivate || mw.IsFinal || mw.IsConstructor))
        {
            int flags = self._flags();
            flags -= MethodHandleNatives.Constants.REF_invokeVirtual << MethodHandleNatives.Constants.MN_REFERENCE_KIND_SHIFT;
            flags += MethodHandleNatives.Constants.REF_invokeSpecial << MethodHandleNatives.Constants.MN_REFERENCE_KIND_SHIFT;
            self._flags(flags);
        }
        if (mw.HasCallerID || DynamicTypeWrapper.RequiresDynamicReflectionCallerClass(mw.DeclaringType.Name, mw.Name, mw.Signature))
        {
            self._flags(self._flags() | MemberName.CALLER_SENSITIVE);
        }
    }
		internal override string AllocMangledName(DynamicTypeWrapper tw)
		{
			lock(dynamicTypes)
			{
				return TypeNameMangleImpl(dynamicTypes, tw.Name, tw);
			}
		}
		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)
			{
				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++)
					{
						ilgen.EmitLdarg(i);
					}
					CoreClasses.java.lang.Object.Wrapper.GetMethodWrapper(mw.Name, mw.Signature, false).EmitCallvirt(ilgen);
					ilgen.Emit(OpCodes.Ret);
					ilgen.DoEmit();
				}
			}
		}
		private bool EmitImpl(DynamicTypeWrapper.FinishContext context, ClassFile classFile, ClassFile.ConstantPoolItemInvokeDynamic cpi, ClassFile.BootstrapMethod bsm, CodeEmitter ilgen)
		{
			if (HasUnloadable(cpi))
			{
				Fail("cpi has unloadable");
				return false;
			}
			bool serializable = false;
			TypeWrapper[] markers = TypeWrapper.EmptyArray;
			ClassFile.ConstantPoolItemMethodType[] bridges = null;
			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)
				{
					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;
						}
					}
				}
			}
			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 (!CheckSupportedInterfaces(context.TypeWrapper, interfaceType, markers, bridges, out methodList))
			{
				Fail("unsupported interface");
				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))
			{
				Fail("implMethod " + implMethod.MemberConstantPoolItem.Class + "::" + implMethod.MemberConstantPoolItem.Name + implMethod.MemberConstantPoolItem.Signature);
				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;
					}
				}
			}
			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");
					return false;
				}
			}
			MethodWrapper interfaceMethod = null;
			List<MethodWrapper> methods = new List<MethodWrapper>();
			foreach (MethodWrapper mw in methodList)
			{
				if (mw.Name == cpi.Name && mw.Signature == samMethodType.Signature)
				{
					interfaceMethod = mw;
					methods.Add(mw);
				}
				else if (mw.IsAbstract && !IsObjectMethod(mw))
				{
					methods.Add(mw);
				}
			}
			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);
			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, tb, methods, implParameters, samMethodType, implMethod, instantiatedMethodType, serializable);
			AddDefaultInterfaceMethods(context, methodList, tb);
			return true;
		}
		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.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++)
			{
				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 = interfaceMethod.GetParameters()[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();
		}
		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];
			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("arg$" + (i + 1), 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 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();

				if (!context.TypeWrapper.GetClassLoader().NoAutomagicSerialization)
				{
					// add .NET serialization interop support
					Serialization.MarkSerializable(tb);
					Serialization.AddGetObjectData(tb);
				}
			}

			return ctor;
		}
Esempio n. 27
0
 private static void AddReadResolve(DynamicTypeWrapper wrapper, TypeBuilder tb)
 {
     MethodWrapper mw = wrapper.GetMethodWrapper("readResolve", "()Ljava.lang.Object;", false);
     if (mw != null && !wrapper.IsSubTypeOf(iobjectreference))
     {
         tb.AddInterfaceImplementation(JVM.Import(typeof(IObjectReference)));
         MethodBuilder getRealObject = tb.DefineMethod("IObjectReference.GetRealObject", MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final,
             Types.Object, new Type[] { JVM.Import(typeof(StreamingContext)) });
         getRealObject.SetCustomAttribute(securityCriticalAttribute);
         AttributeHelper.HideFromJava(getRealObject);
         tb.DefineMethodOverride(getRealObject, JVM.Import(typeof(IObjectReference)).GetMethod("GetRealObject"));
         CodeEmitter ilgen = CodeEmitter.Create(getRealObject);
         mw.Link();
         if (!wrapper.IsFinal)
         {
             // readResolve is only applicable if it exists on the actual type of the object, so if we're a subclass don't call it
             ilgen.Emit(OpCodes.Ldarg_0);
             ilgen.Emit(OpCodes.Callvirt, Compiler.getTypeMethod);
             ilgen.Emit(OpCodes.Ldtoken, wrapper.TypeAsBaseType);
             ilgen.Emit(OpCodes.Call, Compiler.getTypeFromHandleMethod);
             CodeEmitterLabel label = ilgen.DefineLabel();
             ilgen.EmitBeq(label);
             ilgen.Emit(OpCodes.Ldarg_0);
             ilgen.Emit(OpCodes.Ret);
             ilgen.MarkLabel(label);
         }
         ilgen.Emit(OpCodes.Ldarg_0);
         mw.EmitCall(ilgen);
         ilgen.Emit(OpCodes.Ret);
         ilgen.DoEmit();
     }
 }
 internal override sealed TypeWrapper DefineClassImpl(Dictionary<string, TypeWrapper> types, ClassFile f, ClassLoaderWrapper classLoader, object protectionDomain)
 {
     DynamicTypeWrapper type;
     #if STATIC_COMPILER
     type = new AotTypeWrapper(f, (CompilerClassLoader)classLoader);
     #else
     type = new DynamicTypeWrapper(f, classLoader);
     #endif
     // this step can throw a retargettable exception, if the class is incorrect
     bool hasclinit;
     type.CreateStep1(out hasclinit);
     // now we can allocate the mangledTypeName, because the next step cannot fail
     string mangledTypeName = AllocMangledName(f.Name);
     // This step actually creates the TypeBuilder. It is not allowed to throw any exceptions,
     // if an exception does occur, it is due to a programming error in the IKVM or CLR runtime
     // and will cause a CriticalFailure and exit the process.
     type.CreateStep2NoFail(hasclinit, mangledTypeName);
     lock(types)
     {
         // in very extreme conditions another thread may have beaten us to it
         // and loaded (not defined) a class with the same name, in that case
         // we'll leak the the Reflection.Emit defined type. Also see the comment
         // in ClassLoaderWrapper.RegisterInitiatingLoader().
         TypeWrapper race;
         types.TryGetValue(f.Name, out race);
         if(race == null)
         {
             lock(dynamicTypes)
             {
                 Debug.Assert(dynamicTypes.ContainsKey(mangledTypeName) && dynamicTypes[mangledTypeName] == null);
                 dynamicTypes[mangledTypeName] = type;
             }
             types[f.Name] = type;
     #if !STATIC_COMPILER && !FIRST_PASS
             java.lang.Class clazz = new java.lang.Class(null);
     #if __MonoCS__
             TypeWrapper.SetTypeWrapperHack(clazz, type);
     #else
             clazz.typeWrapper = type;
     #endif
             clazz.pd = (java.security.ProtectionDomain)protectionDomain;
             type.SetClassObject(clazz);
     #endif
         }
         else
         {
             throw new LinkageError("duplicate class definition: " + f.Name);
         }
     }
     return type;
 }