Emit() private méthode

private Emit ( OpCode opcode ) : void
opcode OpCode
Résultat void
Exemple #1
0
        private static void EmitConversion(CodeEmitter ilgen, Type converterType, string method)
        {
            CodeEmitterLocal converter = ilgen.UnsafeAllocTempLocal(converterType);

            ilgen.Emit(OpCodes.Ldloca, converter);
            ilgen.Emit(OpCodes.Call, converterType.GetMethod(method));
        }
        internal static bool Emit(DynamicTypeWrapper.FinishContext context, ClassFile classFile, int constantPoolIndex, ClassFile.ConstantPoolItemInvokeDynamic cpi, CodeEmitter ilgen)
        {
#if !WINRT
            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);
#else
            throw new NotImplementedException();
#endif
        }
	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_nothrow
			&& 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
					ilgen.Emit(OpCodes.Pop);
					ilgen.Emit(OpCodes.Pop);
					ilgen.Emit(OpCodes.Pop);
					ilgen.Emit(OpCodes.Newobj, context.GetAtomicReferenceFieldUpdater(field));
					return true;
				}
			}
		}
		return false;
	}
Exemple #4
0
        private static ConstructorBuilder DefineThreadLocalType(DynamicTypeWrapper.FinishContext context, int opcodeIndex, MethodWrapper caller)
        {
            TypeWrapper  threadLocal = ClassLoaderWrapper.LoadClassCritical("ikvm.internal.IntrinsicThreadLocal");
            TypeBuilder  tb          = caller.DeclaringType.TypeAsBuilder.DefineNestedType("__<tls>_" + opcodeIndex, TypeAttributes.NestedPrivate | TypeAttributes.Sealed, threadLocal.TypeAsBaseType);
            FieldBuilder fb          = tb.DefineField("field", Types.Object, FieldAttributes.Private | FieldAttributes.Static);

            fb.SetCustomAttribute(new CustomAttributeBuilder(JVM.Import(typeof(ThreadStaticAttribute)).GetConstructor(Type.EmptyTypes), new object[0]));
            MethodBuilder mbGet = tb.DefineMethod("get", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final, Types.Object, Type.EmptyTypes);
            ILGenerator   ilgen = mbGet.GetILGenerator();

            ilgen.Emit(OpCodes.Ldsfld, fb);
            ilgen.Emit(OpCodes.Ret);
            MethodBuilder mbSet = tb.DefineMethod("set", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final, null, new Type[] { Types.Object });

            ilgen = mbSet.GetILGenerator();
            ilgen.Emit(OpCodes.Ldarg_1);
            ilgen.Emit(OpCodes.Stsfld, fb);
            ilgen.Emit(OpCodes.Ret);
            ConstructorBuilder cb        = tb.DefineConstructor(MethodAttributes.Assembly, CallingConventions.Standard, Type.EmptyTypes);
            CodeEmitter        ctorilgen = CodeEmitter.Create(cb);

            ctorilgen.Emit(OpCodes.Ldarg_0);
            MethodWrapper basector = threadLocal.GetMethodWrapper("<init>", "()V", false);

            basector.Link();
            basector.EmitCall(ctorilgen);
            ctorilgen.Emit(OpCodes.Ret);
            ctorilgen.DoEmit();
            context.RegisterPostFinishProc(delegate
            {
                threadLocal.Finish();
                tb.CreateType();
            });
            return(cb);
        }
Exemple #5
0
 private static bool Object_getClass(DynamicTypeWrapper.FinishContext context, CodeEmitter ilgen, MethodWrapper method, MethodAnalyzer ma, int opcodeIndex, MethodWrapper caller, ClassFile classFile, Instruction[] code, InstructionFlags[] flags)
 {
     // this is the null-check idiom that javac uses (both in its own source and in the code it generates)
     if (code[opcodeIndex + 1].NormalizedOpCode == NormalizedByteCode.__pop)
     {
         ilgen.Emit(OpCodes.Dup);
         ilgen.EmitNullCheck();
         return(true);
     }
     // this optimizes obj1.getClass() ==/!= obj2.getClass()
     else if (opcodeIndex + 3 < code.Length &&
              (flags[opcodeIndex + 1] & InstructionFlags.BranchTarget) == 0 &&
              (flags[opcodeIndex + 2] & InstructionFlags.BranchTarget) == 0 &&
              (flags[opcodeIndex + 3] & InstructionFlags.BranchTarget) == 0 &&
              code[opcodeIndex + 1].NormalizedOpCode == NormalizedByteCode.__aload &&
              code[opcodeIndex + 2].NormalizedOpCode == NormalizedByteCode.__invokevirtual &&
              (code[opcodeIndex + 3].NormalizedOpCode == NormalizedByteCode.__if_acmpeq || code[opcodeIndex + 3].NormalizedOpCode == NormalizedByteCode.__if_acmpne) &&
              (IsSafeForGetClassOptimization(ma.GetStackTypeWrapper(opcodeIndex, 0)) || IsSafeForGetClassOptimization(ma.GetStackTypeWrapper(opcodeIndex + 2, 0))))
     {
         ClassFile.ConstantPoolItemMI cpi = classFile.GetMethodref(code[opcodeIndex + 2].Arg1);
         if (cpi.Class == "java.lang.Object" && cpi.Name == "getClass" && cpi.Signature == "()Ljava.lang.Class;")
         {
             // we can't patch the current opcode, so we have to emit the first call to GetTypeHandle here
             ilgen.Emit(OpCodes.Callvirt, Compiler.getTypeMethod);
             code[opcodeIndex + 2].PatchOpCode(NormalizedByteCode.__intrinsic_gettype);
             return(true);
         }
     }
     return(false);
 }
Exemple #6
0
        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);
            AttributeHelper.HideFromJava(getObjectData);
            //TODO: We need to review this for .NET Core
            //getObjectData.AddDeclarativeSecurity(SecurityAction.Demand, psetSerializationFormatter);
            tb.DefineMethodOverride(getObjectData, JVM.Import(typeof(ISerializable)).GetMethod("GetObjectData"));
            CodeEmitter ilgen = CodeEmitter.Create(getObjectData);

            ilgen.Emit(OpCodes.Ldarg_0);
            ilgen.Emit(OpCodes.Ldarg_1);
            TypeWrapper   serializationHelper = ClassLoaderWrapper.LoadClassCritical("ikvm.internal.Serialization");
            MethodWrapper mw = serializationHelper.GetMethodWrapper("writeObject", "(Ljava.lang.Object;Lcli.System.Runtime.Serialization.SerializationInfo;)V", false);

            mw.Link();
            mw.EmitCall(ilgen);
            ilgen.Emit(OpCodes.Ret);
            ilgen.DoEmit();
        }
Exemple #7
0
        private static void CreateConstructor(TypeBuilder tb)
        {
            CodeEmitter ilgen = CodeEmitter.Create(ReflectUtil.DefineConstructor(tb, MethodAttributes.Public, new Type[] { invocationHandlerClass.TypeAsSignatureType }));

            ilgen.Emit(OpCodes.Ldarg_0);
            ilgen.Emit(OpCodes.Ldarg_1);
            proxyConstructor.EmitCall(ilgen);
            ilgen.Emit(OpCodes.Ret);
            ilgen.DoEmit();
        }
Exemple #8
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();
            }
        }
Exemple #9
0
        private static void CreateConstructor(TypeBuilder tb)
        {
            ConstructorBuilder cb    = tb.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new Type[] { invocationHandlerClass.TypeAsSignatureType });
            CodeEmitter        ilgen = CodeEmitter.Create(cb);

            ilgen.Emit(OpCodes.Ldarg_0);
            ilgen.Emit(OpCodes.Ldarg_1);
            proxyConstructor.EmitCall(ilgen);
            ilgen.Emit(OpCodes.Ret);
            ilgen.DoEmit();
        }
Exemple #10
0
            internal override void Emit(CodeEmitter ilgen)
            {
                base.Emit(ilgen);
                // unbox leaves a pointer to the value of the stack (instead of the value)
                // so we have to copy the value into a local variable and load the address
                // of the local onto the stack
                LocalBuilder local = ilgen.DeclareLocal(Type);

                ilgen.Emit(OpCodes.Stloc, local);
                ilgen.Emit(OpCodes.Ldloca, local);
            }
Exemple #11
0
        private static void RemoveReadResolve(TypeBuilder tb)
        {
            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);

            ilgen.Emit(OpCodes.Ldarg_0);
            ilgen.Emit(OpCodes.Ret);
            ilgen.DoEmit();
        }
Exemple #12
0
        private static bool ThreadLocal_new(DynamicTypeWrapper.FinishContext context, CodeEmitter ilgen, MethodWrapper method, MethodAnalyzer ma, int opcodeIndex, MethodWrapper caller, ClassFile classFile, Instruction[] code, InstructionFlags[] flags)
        {
            // it is only valid to replace a ThreadLocal instantiation by our ThreadStatic based version, if we can prove that the instantiation only happens once
            // (which is the case when we're in <clinit> and there aren't any branches that lead to the current position)
            if (caller.Name != StringConstants.CLINIT)
            {
                return(false);
            }
#if CLASSGC
            if (JVM.classUnloading)
            {
                // RunAndCollect assemblies do not support ThreadStaticAttribute
                return(false);
            }
#endif
            for (int i = 0; i <= opcodeIndex; i++)
            {
                if ((flags[i] & InstructionFlags.BranchTarget) != 0)
                {
                    return(false);
                }
            }
            ilgen.Emit(OpCodes.Newobj, DefineThreadLocalType(context, opcodeIndex, caller));
            return(true);
        }
        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();
                }
            }
        }
Exemple #14
0
        internal static void Finish(ClassLoaderWrapper loader)
        {
            TypeBuilder tb = (TypeBuilder)genericEnumEnumType;
            TypeWrapper enumTypeWrapper = loader.LoadClassByDottedName("java.lang.Enum");

            enumTypeWrapper.Finish();
            tb.SetParent(enumTypeWrapper.TypeAsBaseType);
            CodeEmitter ilgen = CodeEmitter.Create(ReflectUtil.DefineConstructor(tb, MethodAttributes.Private, new Type[] { Types.String, Types.Int32 }));

            ilgen.Emit(OpCodes.Ldarg_0);
            ilgen.Emit(OpCodes.Ldarg_1);
            ilgen.Emit(OpCodes.Ldarg_2);
            enumTypeWrapper.GetMethodWrapper("<init>", "(Ljava.lang.String;I)V", false).EmitCall(ilgen);
            ilgen.Emit(OpCodes.Ret);
            ilgen.DoEmit();
            genericEnumEnumType = tb.CreateType();
        }
        private static MethodBuilder AddConstructor(TypeBuilder tb, MethodWrapper defaultConstructor, MethodBase serializationConstructor, bool callReadObject)
        {
            MethodBuilder ctor = ReflectUtil.DefineConstructor(tb, MethodAttributes.Family, new Type[] { JVM.Import(typeof(SerializationInfo)), JVM.Import(typeof(StreamingContext)) });

            AttributeHelper.HideFromJava(ctor);
            CodeEmitter ilgen = CodeEmitter.Create(ctor);

            ilgen.Emit(OpCodes.Ldarg_0);
            if (defaultConstructor != null)
            {
                defaultConstructor.EmitCall(ilgen);
            }
            else
            {
                ilgen.Emit(OpCodes.Ldarg_1);
                ilgen.Emit(OpCodes.Ldarg_2);
                ilgen.Emit(OpCodes.Call, serializationConstructor);
            }
            if (callReadObject)
            {
                ilgen.Emit(OpCodes.Ldarg_0);
                ilgen.Emit(OpCodes.Ldarg_1);
                TypeWrapper   serializationHelper = ClassLoaderWrapper.LoadClassCritical("ikvm.internal.Serialization");
                MethodWrapper mw = serializationHelper.GetMethodWrapper("readObject", "(Ljava.lang.Object;Lcli.System.Runtime.Serialization.SerializationInfo;)V", false);
                mw.Link();
                mw.EmitCall(ilgen);
            }
            ilgen.Emit(OpCodes.Ret);
            ilgen.DoEmit();
            return(ctor);
        }
Exemple #16
0
        private static ConstructorInfo AddConstructor(TypeBuilder tb, MethodWrapper defaultConstructor, ConstructorInfo serializationConstructor, bool callReadObject)
        {
            ConstructorBuilder ctor = tb.DefineConstructor(MethodAttributes.Family, CallingConventions.Standard, new Type[] { JVM.Import(typeof(SerializationInfo)), JVM.Import(typeof(StreamingContext)) });

            AttributeHelper.HideFromJava(ctor);
            ctor.AddDeclarativeSecurity(SecurityAction.Demand, psetSerializationFormatter);
            CodeEmitter ilgen = CodeEmitter.Create(ctor);

            ilgen.Emit(OpCodes.Ldarg_0);
            if (defaultConstructor != null)
            {
                defaultConstructor.EmitCall(ilgen);
            }
            else
            {
                ilgen.Emit(OpCodes.Ldarg_1);
                ilgen.Emit(OpCodes.Ldarg_2);
                ilgen.Emit(OpCodes.Call, serializationConstructor);
            }
            if (callReadObject)
            {
                ilgen.Emit(OpCodes.Ldarg_0);
                ilgen.Emit(OpCodes.Ldarg_1);
                TypeWrapper   serializationHelper = ClassLoaderWrapper.LoadClassCritical("ikvm.internal.Serialization");
                MethodWrapper mw = serializationHelper.GetMethodWrapper("readObject", "(Ljava.lang.Object;Lcli.System.Runtime.Serialization.SerializationInfo;)V", false);
                mw.Link();
                mw.EmitCall(ilgen);
            }
            ilgen.Emit(OpCodes.Ret);
            ilgen.DoEmit();
            return(ctor);
        }
Exemple #17
0
        private static void CreateEnumEnum(ModuleBuilder modb, ClassLoaderWrapper loader)
        {
            TypeWrapper enumTypeWrapper = loader.LoadClassByDottedName("java.lang.Enum");

            enumTypeWrapper.Finish();
            TypeBuilder tb = modb.DefineType(DotNetTypeWrapper.GenericEnumEnumTypeName, TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.Public, enumTypeWrapper.TypeAsBaseType);
            GenericTypeParameterBuilder gtpb = tb.DefineGenericParameters("T")[0];

            gtpb.SetBaseTypeConstraint(Types.Enum);
            CodeEmitter ilgen = CodeEmitter.Create(tb.DefineConstructor(MethodAttributes.Private, CallingConventions.Standard, new Type[] { Types.String, Types.Int32 }));

            ilgen.Emit(OpCodes.Ldarg_0);
            ilgen.Emit(OpCodes.Ldarg_1);
            ilgen.Emit(OpCodes.Ldarg_2);
            enumTypeWrapper.GetMethodWrapper("<init>", "(Ljava.lang.String;I)V", false).EmitCall(ilgen);
            ilgen.Emit(OpCodes.Ret);
            genericEnumEnumType = tb.CreateType();
        }
Exemple #18
0
        private static bool Class_getPrimitiveClass(DynamicTypeWrapper.FinishContext context, CodeEmitter ilgen, MethodWrapper method, MethodAnalyzer ma, int opcodeIndex, MethodWrapper caller, ClassFile classFile, Instruction[] code, InstructionFlags[] flags)
        {
            ilgen.LazyEmitPop();
            ilgen.Emit(OpCodes.Ldnull);
            MethodWrapper mw = CoreClasses.java.lang.Class.Wrapper.GetMethodWrapper("<init>", "(Lcli.System.Type;)V", false);

            mw.Link();
            mw.EmitNewobj(ilgen);
            return(true);
        }
        private static void EmitClassLiteral(CompilerClassLoader ccl)
        {
            TypeBuilder tb = ccl.GetTypeWrapperFactory().ModuleBuilder.DefineType("ikvm.internal.ClassLiteral`1", TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.Abstract | TypeAttributes.Class | TypeAttributes.BeforeFieldInit);
            GenericTypeParameterBuilder typeParam = tb.DefineGenericParameters("T")[0];
            Type classType = CoreClasses.java.lang.Class.Wrapper.TypeAsSignatureType;

            classLiteralField = tb.DefineField("Value", classType, FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.InitOnly);
            CodeEmitter ilgen = CodeEmitter.Create(ReflectUtil.DefineTypeInitializer(tb));

            ilgen.Emit(OpCodes.Ldtoken, typeParam);
            ilgen.Emit(OpCodes.Call, Types.Type.GetMethod("GetTypeFromHandle", new Type[] { Types.RuntimeTypeHandle }));
            MethodWrapper mw = CoreClasses.java.lang.Class.Wrapper.GetMethodWrapper("<init>", "(Lcli.System.Type;)V", false);

            mw.Link();
            mw.EmitNewobj(ilgen);
            ilgen.Emit(OpCodes.Stsfld, classLiteralField);
            ilgen.Emit(OpCodes.Ret);
            ilgen.DoEmit();
            classLiteralType = tb.CreateType();
        }
Exemple #20
0
        private static bool Util_getInstanceTypeFromClass(DynamicTypeWrapper.FinishContext context, CodeEmitter ilgen, MethodWrapper method, MethodAnalyzer ma, int opcodeIndex, MethodWrapper caller, ClassFile classFile, Instruction[] code, InstructionFlags[] flags)
        {
            TypeWrapper tw = ilgen.PeekLazyClassLiteral();

            if (tw != null)
            {
                ilgen.LazyEmitPop();
                if (tw.IsRemapped && tw.IsFinal)
                {
                    ilgen.Emit(OpCodes.Ldtoken, tw.TypeAsTBD);
                }
                else
                {
                    ilgen.Emit(OpCodes.Ldtoken, tw.TypeAsBaseType);
                }
                ilgen.Emit(OpCodes.Call, Compiler.getTypeFromHandleMethod);
                return(true);
            }
            return(false);
        }
        private static void AddReadResolve(TypeWrapper wrapper)
        {
            MethodWrapper mw = wrapper.GetMethodWrapper("readResolve", "()Ljava.lang.Object;", false);

            if (mw != null && !wrapper.IsSubTypeOf(iobjectreference))
            {
                TypeBuilder tb = wrapper.TypeAsBuilder;
                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();
                ilgen.Emit(OpCodes.Ldarg_0);
                mw.EmitCall(ilgen);
                ilgen.Emit(OpCodes.Ret);
            }
        }
Exemple #22
0
            internal sealed override void Emit(CodeEmitter ilgen)
            {
                LocalBuilder value1 = ilgen.AllocTempLocal(FloatOrDouble());
                LocalBuilder value2 = ilgen.AllocTempLocal(FloatOrDouble());

                ilgen.Emit(OpCodes.Stloc, value2);
                ilgen.Emit(OpCodes.Stloc, value1);
                ilgen.Emit(OpCodes.Ldloc, value1);
                ilgen.Emit(OpCodes.Ldloc, value2);
                ilgen.Emit(OpCodes.Cgt_Un);
                ilgen.Emit(OpCodes.Ldloc, value1);
                ilgen.Emit(OpCodes.Ldloc, value2);
                ilgen.Emit(OpCodes.Clt);
                ilgen.Emit(OpCodes.Sub);
                ilgen.ReleaseTempLocal(value1);
                ilgen.ReleaseTempLocal(value2);
            }
Exemple #23
0
            internal sealed override void Emit(CodeEmitter ilgen)
            {
                LocalBuilder value1 = ilgen.AllocTempLocal(Types.Int64);
                LocalBuilder value2 = ilgen.AllocTempLocal(Types.Int64);

                ilgen.Emit(OpCodes.Stloc, value2);
                ilgen.Emit(OpCodes.Stloc, value1);
                ilgen.Emit(OpCodes.Ldloc, value1);
                ilgen.Emit(OpCodes.Ldloc, value2);
                ilgen.Emit(OpCodes.Cgt);
                ilgen.Emit(OpCodes.Ldloc, value1);
                ilgen.Emit(OpCodes.Ldloc, value2);
                ilgen.Emit(OpCodes.Clt);
                ilgen.Emit(OpCodes.Sub);
                ilgen.ReleaseTempLocal(value2);
                ilgen.ReleaseTempLocal(value1);
            }
Exemple #24
0
            internal sealed override void EmitBcc(CodeEmitter ilgen, Comparison comp, CodeEmitterLabel label)
            {
                switch (comp)
                {
                case Comparison.LessOrEqual:
                    ilgen.Emit(OpCodes.Ble, label);
                    break;

                case Comparison.LessThan:
                    ilgen.Emit(OpCodes.Blt, label);
                    break;

                case Comparison.GreaterOrEqual:
                    ilgen.Emit(OpCodes.Bge_Un, label);
                    break;

                case Comparison.GreaterThan:
                    ilgen.Emit(OpCodes.Bgt_Un, label);
                    break;
                }
            }
Exemple #25
0
        private static void CreateStaticInitializer(TypeBuilder tb, List <ProxyMethod> methods)
        {
            ConstructorBuilder cb         = tb.DefineConstructor(MethodAttributes.Static, CallingConventions.Standard, Type.EmptyTypes);
            CodeEmitter        ilgen      = CodeEmitter.Create(cb);
            CodeEmitterLocal   callerID   = ilgen.DeclareLocal([email protected]);
            TypeBuilder        tbCallerID = DynamicTypeWrapper.FinishContext.EmitCreateCallerID(tb, ilgen);

            ilgen.Emit(OpCodes.Stloc, callerID);
            // HACK we shouldn't create the nested type here (the outer type must be created first)
            tbCallerID.CreateType();
            ilgen.BeginExceptionBlock();
            foreach (ProxyMethod method in methods)
            {
                method.mw.DeclaringType.EmitClassLiteral(ilgen);
                ilgen.Emit(OpCodes.Ldstr, method.mw.Name);
                TypeWrapper[] parameters = method.mw.GetParameters();
                ilgen.EmitLdc_I4(parameters.Length);
                ilgen.Emit(OpCodes.Newarr, CoreClasses.java.lang.Class.Wrapper.TypeAsArrayType);
                for (int i = 0; i < parameters.Length; i++)
                {
                    ilgen.Emit(OpCodes.Dup);
                    ilgen.EmitLdc_I4(i);
                    parameters[i].EmitClassLiteral(ilgen);
                    ilgen.Emit(OpCodes.Stelem_Ref);
                }
                if (javaLangClass_getMethod.HasCallerID)
                {
                    ilgen.Emit(OpCodes.Ldloc, callerID);
                }
                javaLangClass_getMethod.EmitCallvirt(ilgen);
                ilgen.Emit(OpCodes.Stsfld, method.fb);
            }
            CodeEmitterLabel label = ilgen.DefineLabel();

            ilgen.EmitLeave(label);
            ilgen.BeginCatchBlock(javaLangNoSuchMethodException.TypeAsExceptionType);
            javaLangThrowable_getMessage.EmitCallvirt(ilgen);
            javaLangNoClassDefFoundErrorConstructor.EmitNewobj(ilgen);
            ilgen.Emit(OpCodes.Throw);
            ilgen.EndExceptionBlock();
            ilgen.MarkLabel(label);
            ilgen.Emit(OpCodes.Ret);
            ilgen.DoEmit();
        }
Exemple #26
0
        private static void EmitLoadCharArrayLiteral(CodeEmitter ilgen, string str, TypeWrapper tw)
        {
            ModuleBuilder mod = tw.GetClassLoader().GetTypeWrapperFactory().ModuleBuilder;
            // FXBUG on .NET 1.1 & 2.0 the value type that Ref.Emit automatically generates is public,
            // so we pre-create a non-public type with the right name here and it will "magically" use
            // that instead.
            // If we're running on Mono this isn't necessary, but for simplicitly we'll simply create
            // the type as well (it is useless, but all it does is waste a little space).
            int    length   = str.Length * 2;
            string typename = "$ArrayType$" + length;
            Type   type     = mod.GetType(typename, false, false);

            if (type == null)
            {
                if (tw.GetClassLoader().GetTypeWrapperFactory().ReserveName(typename))
                {
                    TypeBuilder tb = mod.DefineType(typename, TypeAttributes.Sealed | TypeAttributes.Class | TypeAttributes.ExplicitLayout | TypeAttributes.NotPublic, Types.ValueType, PackingSize.Size1, length);
                    AttributeHelper.HideFromJava(tb);
                    type = tb.CreateType();
                }
            }
            if (type == null ||
                !type.IsValueType ||
                type.StructLayoutAttribute.Pack != 1 || type.StructLayoutAttribute.Size != length)
            {
                // the type that we found doesn't match (must mean we've compiled a Java type with that name),
                // so we fall back to the string approach
                ilgen.Emit(OpCodes.Ldstr, str);
                ilgen.Emit(OpCodes.Call, Types.String.GetMethod("ToCharArray", Type.EmptyTypes));
                return;
            }
            ilgen.Emit(OpCodes.Ldc_I4, str.Length);
            ilgen.Emit(OpCodes.Newarr, Types.Char);
            ilgen.Emit(OpCodes.Dup);
            byte[] data = new byte[length];
            for (int j = 0; j < str.Length; j++)
            {
                data[j * 2 + 0] = (byte)(str[j] >> 0);
                data[j * 2 + 1] = (byte)(str[j] >> 8);
            }
            // NOTE we define a module field, because type fields on Mono don't use the global $ArrayType$<n> type.
            // NOTE this also means that this will only work during static compilation, because ModuleBuilder.CreateGlobalFunctions() must
            // be called before the field can be used.
            FieldBuilder fb = mod.DefineInitializedData("__<str>", data, FieldAttributes.Static | FieldAttributes.PrivateScope);

            // MONOBUG Type.Equals(Type) is broken on Mono. We have to use the virtual method that ends up in our implementation
            if (!fb.FieldType.Equals((object)type))
            {
                // this is actually relatively harmless, but I would like to know about it, so we abort and hope that users report this when they encounter it
                JVM.CriticalFailure("Unsupported runtime: ModuleBuilder.DefineInitializedData() field type mispredicted", null);
            }
            ilgen.Emit(OpCodes.Ldtoken, fb);
            ilgen.Emit(OpCodes.Call, JVM.Import(typeof(System.Runtime.CompilerServices.RuntimeHelpers)).GetMethod("InitializeArray", new Type[] { Types.Array, JVM.Import(typeof(RuntimeFieldHandle)) }));
        }
		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;
		}
        private static void AddGetObjectData(TypeWrapper wrapper)
        {
            TypeBuilder tb = wrapper.TypeAsBuilder;

            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);
            AttributeHelper.HideFromJava(getObjectData);
            getObjectData.AddDeclarativeSecurity(SecurityAction.Demand, psetSerializationFormatter);
            tb.DefineMethodOverride(getObjectData, JVM.Import(typeof(ISerializable)).GetMethod("GetObjectData"));
            CodeEmitter ilgen = CodeEmitter.Create(getObjectData);

            ilgen.Emit(OpCodes.Ldarg_0);
            ilgen.Emit(OpCodes.Ldarg_1);
            TypeWrapper   serializationHelper = ClassLoaderWrapper.LoadClassCritical("ikvm.internal.Serialization");
            MethodWrapper mw = serializationHelper.GetMethodWrapper("writeObject", "(Ljava.lang.Object;Lcli.System.Runtime.Serialization.SerializationInfo;)V", false);

            mw.Link();
            mw.EmitCall(ilgen);
            ilgen.Emit(OpCodes.Ret);
        }
Exemple #29
0
        private static bool System_arraycopy(DynamicTypeWrapper.FinishContext context, CodeEmitter ilgen, MethodWrapper method, MethodAnalyzer ma, int opcodeIndex, MethodWrapper caller, ClassFile classFile, Instruction[] code, InstructionFlags[] flags)
        {
            // if the array arguments on the stack are of a known array type, we can redirect to an optimized version of arraycopy.
            // Note that we also have to handle VMSystem.arraycopy, because on GNU Classpath StringBuffer directly calls
            // this method to avoid prematurely initialising System.
            TypeWrapper dst_type = ma.GetStackTypeWrapper(opcodeIndex, 2);
            TypeWrapper src_type = ma.GetStackTypeWrapper(opcodeIndex, 4);

            if (!dst_type.IsUnloadable && dst_type.IsArray && dst_type == src_type)
            {
                switch (dst_type.Name[1])
                {
                case 'J':
                case 'D':
                    ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.arraycopy_primitive_8);
                    break;

                case 'I':
                case 'F':
                    ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.arraycopy_primitive_4);
                    break;

                case 'S':
                case 'C':
                    ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.arraycopy_primitive_2);
                    break;

                case 'B':
                case 'Z':
                    ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.arraycopy_primitive_1);
                    break;

                default:
                    // TODO once the verifier tracks actual types (i.e. it knows that
                    // a particular reference is the result of a "new" opcode) we can
                    // use the fast version if the exact destination type is known
                    // (in that case the "dst_type == src_type" above should
                    // be changed to "src_type.IsAssignableTo(dst_type)".
                    TypeWrapper elemtw = dst_type.ElementTypeWrapper;
                    // note that IsFinal returns true for array types, so we have to be careful!
                    if (!elemtw.IsArray && elemtw.IsFinal)
                    {
                        ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.arraycopy_fast);
                    }
                    else
                    {
                        ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.arraycopy);
                    }
                    break;
                }
                return(true);
            }
            else
            {
                return(false);
            }
        }
Exemple #30
0
        private static bool String_toCharArray(DynamicTypeWrapper.FinishContext context, CodeEmitter ilgen, MethodWrapper method, MethodAnalyzer ma, int opcodeIndex, MethodWrapper caller, ClassFile classFile, Instruction[] code, InstructionFlags[] flags)
        {
            string str = ilgen.PopLazyLdstr();

            if (str != null)
            {
                // arbitrary length for "big" strings
                if (str.Length > 128)
                {
                    EmitLoadCharArrayLiteral(ilgen, str, caller.DeclaringType);
                    return(true);
                }
                ilgen.Emit(OpCodes.Ldstr, str);
            }
            return(false);
        }
Exemple #31
0
 private static bool ClassLoader_getCallerClassLoader(DynamicTypeWrapper.FinishContext context, CodeEmitter ilgen, MethodWrapper method, MethodAnalyzer ma, int opcodeIndex, MethodWrapper caller, ClassFile classFile, Instruction[] code, InstructionFlags[] flags)
 {
     if (caller.HasCallerID)
     {
         int arg = caller.GetParametersForDefineMethod().Length - 1;
         if (!caller.IsStatic)
         {
             arg++;
         }
         ilgen.Emit(OpCodes.Ldarg, (short)arg);
         MethodWrapper mw = [email protected]("getCallerClassLoader", "()Ljava.lang.ClassLoader;", false);
         mw.Link();
         mw.EmitCallvirt(ilgen);
         return(true);
     }
     return(false);
 }
Exemple #32
0
 private static bool CallerID_getCallerID(DynamicTypeWrapper.FinishContext context, CodeEmitter ilgen, MethodWrapper method, MethodAnalyzer ma, int opcodeIndex, MethodWrapper caller, ClassFile classFile, Instruction[] code, InstructionFlags[] flags)
 {
     if (caller.HasCallerID)
     {
         int arg = caller.GetParametersForDefineMethod().Length - 1;
         if (!caller.IsStatic)
         {
             arg++;
         }
         ilgen.Emit(OpCodes.Ldarg, (short)arg);
         return(true);
     }
     else
     {
         JVM.CriticalFailure("CallerID.getCallerID() requires a HasCallerID annotation", null);
     }
     return(false);
 }
		protected override void EmitGetImpl(CodeEmitter ilgen)
		{
			MethodInfo getter = property.GetGetMethod(true);
			if(getter == null)
			{
				DynamicPropertyFieldWrapper.EmitThrowNoSuchMethodErrorForGetter(ilgen, this.FieldTypeWrapper, this.IsStatic);
			}
			else if(getter.IsStatic)
			{
				ilgen.Emit(OpCodes.Call, getter);
			}
			else
			{
				ilgen.Emit(OpCodes.Callvirt, getter);
			}
		}
		protected override void CallvirtImpl(CodeEmitter ilgen)
		{
			ilgen.Emit(OpCodes.Callvirt, stubVirtual);
		}
		protected override void NewobjImpl(CodeEmitter ilgen)
		{
			ilgen.Emit(OpCodes.Newobj, stub);
		}
		protected override void EmitSetImpl(CodeEmitter ilgen)
		{
			FieldInfo fi = GetField();
			if(!IsStatic && DeclaringType.IsNonPrimitiveValueType)
			{
				CodeEmitterLocal temp = ilgen.DeclareLocal(FieldTypeWrapper.TypeAsSignatureType);
				ilgen.Emit(OpCodes.Stloc, temp);
				ilgen.Emit(OpCodes.Unbox, DeclaringType.TypeAsTBD);
				ilgen.Emit(OpCodes.Ldloc, temp);
			}
			if(IsVolatile)
			{
				ilgen.Emit(OpCodes.Volatile);
			}
			ilgen.Emit(IsStatic ? OpCodes.Stsfld : OpCodes.Stfld, fi);
			if(IsVolatile)
			{
				ilgen.EmitMemoryBarrier();
			}
		}
		protected override void EmitSetImpl(CodeEmitter ilgen)
		{
			FieldInfo fi = GetField();
			CodeEmitterLocal temp = ilgen.DeclareLocal(FieldTypeWrapper.TypeAsSignatureType);
			ilgen.Emit(OpCodes.Stloc, temp);
			if(fi.IsStatic)
			{
				ilgen.Emit(OpCodes.Ldsflda, fi);
			}
			else
			{
				if(DeclaringType.IsNonPrimitiveValueType)
				{
					ilgen.Emit(OpCodes.Unbox, DeclaringType.TypeAsTBD);
				}
				ilgen.Emit(OpCodes.Ldflda, fi);
			}
			ilgen.Emit(OpCodes.Ldloc, temp);
			if(FieldTypeWrapper == PrimitiveTypeWrapper.DOUBLE)
			{
				ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.volatileWriteDouble);
			}
			else
			{
				Debug.Assert(FieldTypeWrapper == PrimitiveTypeWrapper.LONG);
				ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.volatileWriteLong);
			}
		}
		protected override void EmitSetImpl(CodeEmitter ilgen)
		{
			if(setter == null)
			{
				if(this.IsFinal)
				{
					ilgen.Emit(OpCodes.Pop);
					if(!this.IsStatic)
					{
						ilgen.Emit(OpCodes.Pop);
					}
				}
				else
				{
					EmitThrowNoSuchMethodErrorForSetter(ilgen, this.IsStatic);
				}
			}
			else if(setter.IsStatic)
			{
				setter.EmitCall(ilgen);
			}
			else
			{
				setter.EmitCallvirt(ilgen);
			}
		}
		internal override void EmitCallvirt(CodeEmitter ilgen)
		{
			ilgen.Emit(SimpleOpCodeToOpCode(callvirt), (MethodInfo)GetMethod());
		}
		protected override void CallImpl(CodeEmitter ilgen)
		{
			ilgen.Emit(OpCodes.Call, (ConstructorInfo)GetMethod());
		}
		protected override void CallvirtImpl(CodeEmitter ilgen)
		{
			ilgen.Emit(SimpleOpCodeToOpCode(callvirt), (MethodInfo)GetMethod());
		}
		protected override void EmitGetImpl(CodeEmitter ilgen)
		{
			// Reading a field should trigger the cctor, but since we're inlining the value
			// we have to trigger it explicitly
			DeclaringType.EmitRunClassConstructor(ilgen);

			// NOTE even though you're not supposed to access a constant static final (the compiler is supposed
			// to inline them), we have to support it (because it does happen, e.g. if the field becomes final
			// after the referencing class was compiled, or when we're accessing an unsigned primitive .NET field)
			object v = GetConstantValue();
			if(v == null)
			{
				ilgen.Emit(OpCodes.Ldnull);
			}
			else if(constant is int || 
				constant is short ||
				constant is ushort ||
				constant is byte ||
				constant is sbyte ||
				constant is char ||
				constant is bool)
			{
				ilgen.Emit(OpCodes.Ldc_I4, ((IConvertible)constant).ToInt32(null));
			}
			else if(constant is string)
			{
				ilgen.Emit(OpCodes.Ldstr, (string)constant);
			}
			else if(constant is float)
			{
				ilgen.Emit(OpCodes.Ldc_R4, (float)constant);
			}
			else if(constant is double)
			{
				ilgen.Emit(OpCodes.Ldc_R8, (double)constant);
			}
			else if(constant is long)
			{
				ilgen.Emit(OpCodes.Ldc_I8, (long)constant);
			}
			else if(constant is uint)
			{
				ilgen.Emit(OpCodes.Ldc_I4, unchecked((int)((IConvertible)constant).ToUInt32(null)));
			}
			else if(constant is ulong)
			{
				ilgen.Emit(OpCodes.Ldc_I8, unchecked((long)(ulong)constant));
			}
			else
			{
				throw new InvalidOperationException(constant.GetType().FullName);
			}
		}
		protected override void NewobjImpl(CodeEmitter ilgen)
		{
			ilgen.Emit(OpCodes.Newobj, (ConstructorInfo)GetMethod());
		}
		protected override void EmitSetImpl(CodeEmitter ilgen)
		{
			ilgen.Emit(OpCodes.Call, setter);
		}
		protected override void CallImpl(CodeEmitter ilgen)
		{
			ilgen.Emit(OpCodes.Call, stub);
		}
Exemple #46
0
 internal override void EmitCheckcast(CodeEmitter ilgen)
 {
     if(IsGhost)
     {
         ilgen.Emit(OpCodes.Dup);
         ilgen.Emit(OpCodes.Call, ghostCastMethod);
         ilgen.Emit(OpCodes.Pop);
     }
     else if(IsGhostArray)
     {
         ilgen.Emit(OpCodes.Dup);
         TypeWrapper tw = this;
         int rank = 0;
         while(tw.IsArray)
         {
             rank++;
             tw = tw.ElementTypeWrapper;
         }
         ilgen.EmitLdc_I4(rank);
         ilgen.Emit(OpCodes.Call, ghostCastArrayMethod);
         ilgen.Emit(OpCodes.Castclass, ArrayTypeWrapper.MakeArrayType(Types.Object, rank));
     }
     else
     {
         base.EmitCheckcast(ilgen);
     }
 }
		protected override void EmitGetImpl(CodeEmitter ilgen)
		{
			if(!IsStatic && DeclaringType.IsNonPrimitiveValueType)
			{
				ilgen.Emit(OpCodes.Unbox, DeclaringType.TypeAsTBD);
			}
			if(IsVolatile)
			{
				ilgen.Emit(OpCodes.Volatile);
			}
			ilgen.Emit(IsStatic ? OpCodes.Ldsfld : OpCodes.Ldfld, GetField());
		}
Exemple #48
0
 internal override void EmitInstanceOf(CodeEmitter ilgen)
 {
     if(IsGhost)
     {
         ilgen.Emit(OpCodes.Call, ghostIsInstanceMethod);
     }
     else if(IsGhostArray)
     {
         ilgen.Emit(OpCodes.Call, ghostIsInstanceArrayMethod);
     }
     else
     {
         base.EmitInstanceOf(ilgen);
     }
 }
		protected override void EmitGetImpl(CodeEmitter ilgen)
		{
			FieldInfo fi = GetField();
			if(fi.IsStatic)
			{
				ilgen.Emit(OpCodes.Ldsflda, fi);
			}
			else
			{
				if(DeclaringType.IsNonPrimitiveValueType)
				{
					ilgen.Emit(OpCodes.Unbox, DeclaringType.TypeAsTBD);
				}
				ilgen.Emit(OpCodes.Ldflda, fi);
			}
			if(FieldTypeWrapper == PrimitiveTypeWrapper.DOUBLE)
			{
				ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.volatileReadDouble);
			}
			else
			{
				Debug.Assert(FieldTypeWrapper == PrimitiveTypeWrapper.LONG);
				ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.volatileReadLong);
			}
		}
				internal override void EmitCall(CodeEmitter ilgen)
				{
					ilgen.Emit(OpCodes.Call, (ConstructorInfo)GetMethod());
				}
		internal static void EmitThrowNoSuchMethodErrorForGetter(CodeEmitter ilgen, TypeWrapper type, bool isStatic)
		{
			// HACK the branch around the throw is to keep the verifier happy
			CodeEmitterLabel label = ilgen.DefineLabel();
			ilgen.Emit(OpCodes.Ldc_I4_0);
			ilgen.Emit(OpCodes.Brtrue_S, label);
			ilgen.EmitThrow("java.lang.NoSuchMethodError");
			ilgen.MarkLabel(label);
			if (!isStatic)
			{
				ilgen.Emit(OpCodes.Pop);
			}
			ilgen.Emit(OpCodes.Ldloc, ilgen.DeclareLocal(type.TypeAsLocalOrStackType));
		}
				internal override void EmitNewobj(CodeEmitter ilgen)
				{
					if(mbHelper != null)
					{
						ilgen.Emit(OpCodes.Call, mbHelper);
					}
					else
					{
						ilgen.Emit(OpCodes.Newobj, (ConstructorInfo)GetMethod());
					}
				}
		internal static void EmitThrowNoSuchMethodErrorForSetter(CodeEmitter ilgen, bool isStatic)
		{
			// HACK the branch around the throw is to keep the verifier happy
			CodeEmitterLabel label = ilgen.DefineLabel();
			ilgen.Emit(OpCodes.Ldc_I4_0);
			ilgen.Emit(OpCodes.Brtrue_S, label);
			ilgen.EmitThrow("java.lang.NoSuchMethodError");
			ilgen.MarkLabel(label);
			ilgen.Emit(OpCodes.Pop);
			if (!isStatic)
			{
				ilgen.Emit(OpCodes.Pop);
			}
		}
				internal override void EmitCall(CodeEmitter ilgen)
				{
					if(!IsStatic && IsFinal)
					{
						// When calling a final instance method on a remapped type from a class derived from a .NET class (i.e. a cli.System.Object or cli.System.Exception derived base class)
						// then we can't call the java.lang.Object or java.lang.Throwable methods and we have to go through the instancehelper_ method. Note that since the method
						// is final, this won't affect the semantics.
						EmitCallvirt(ilgen);
					}
					else
					{
						ilgen.Emit(OpCodes.Call, (MethodInfo)GetMethod());
					}
				}
		protected override void EmitSetImpl(CodeEmitter ilgen)
		{
			MethodInfo setter = property.GetSetMethod(true);
			if (setter == null)
			{
				if(this.IsFinal)
				{
					ilgen.Emit(OpCodes.Pop);
					if(!this.IsStatic)
					{
						ilgen.Emit(OpCodes.Pop);
					}
				}
				else
				{
					DynamicPropertyFieldWrapper.EmitThrowNoSuchMethodErrorForSetter(ilgen, this.IsStatic);
				}
			}
			else if(setter.IsStatic)
			{
				ilgen.Emit(OpCodes.Call, setter);
			}
			else
			{
				ilgen.Emit(OpCodes.Callvirt, setter);
			}
		}
				private void EmitCallvirtImpl(CodeEmitter ilgen, bool cloneOrFinalizeHack)
				{
					if(mbHelper != null && !cloneOrFinalizeHack)
					{
						ilgen.Emit(OpCodes.Call, mbHelper);
					}
					else
					{
						ilgen.Emit(OpCodes.Callvirt, (MethodInfo)GetMethod());
					}
				}
		protected override void EmitSetImpl(CodeEmitter ilgen)
		{
			// when constant static final fields are updated, the JIT normally doesn't see that (because the
			// constant value is inlined), so we emulate that behavior by emitting a Pop
			ilgen.Emit(OpCodes.Pop);
		}
				private void EmitRedirect(Type baseType, CodeEmitter ilgen)
				{
					string redirName = m.redirect.Name;
					string redirSig = m.redirect.Sig;
					if(redirName == null)
					{
						redirName = m.Name;
					}
					if(redirSig == null)
					{
						redirSig = m.Sig;
					}
					ClassLoaderWrapper classLoader = DeclaringType.GetClassLoader();
					// HACK if the class name contains a comma, we assume it is a .NET type
					if(m.redirect.Class == null || m.redirect.Class.IndexOf(',') >= 0)
					{
						// TODO better error handling
						Type type = m.redirect.Class == null ? baseType : StaticCompiler.Universe.GetType(m.redirect.Class, true);
						Type[] redirParamTypes = classLoader.ArgTypeListFromSig(redirSig);
						MethodInfo mi = type.GetMethod(m.redirect.Name, redirParamTypes);
						if(mi == null)
						{
							throw new InvalidOperationException();
						}
						ilgen.Emit(OpCodes.Call, mi);
					}
					else
					{
						TypeWrapper tw = classLoader.LoadClassByDottedName(m.redirect.Class);
						MethodWrapper mw = tw.GetMethodWrapper(redirName, redirSig, false);
						if(mw == null)
						{
							throw new InvalidOperationException("Missing redirect method: " + tw.Name + "." + redirName + redirSig);
						}
						mw.Link();
						mw.EmitCall(ilgen);
					}
				}
			protected override void CallvirtImpl(CodeEmitter ilgen)
			{
				ResolveGhostMethod();
				ilgen.Emit(OpCodes.Call, ghostMethod);
			}
			internal void Emit(IKVM.Internal.MapXml.CodeGenContext context, CodeEmitter ilgen)
			{
				MethodWrapper mwSuppressFillInStackTrace = CoreClasses.java.lang.Throwable.Wrapper.GetMethodWrapper("__<suppressFillInStackTrace>", "()V", false);
				mwSuppressFillInStackTrace.Link();
				ilgen.Emit(OpCodes.Ldarg_0);
				ilgen.Emit(OpCodes.Callvirt, Compiler.getTypeMethod);
				for(int i = 0; i < map.Length; i++)
				{
					ilgen.Emit(OpCodes.Dup);
					ilgen.Emit(OpCodes.Ldtoken, StaticCompiler.Universe.GetType(map[i].src, true));
					ilgen.Emit(OpCodes.Call, Compiler.getTypeFromHandleMethod);
					ilgen.Emit(OpCodes.Ceq);
					CodeEmitterLabel label = ilgen.DefineLabel();
					ilgen.Emit(OpCodes.Brfalse_S, label);
					ilgen.Emit(OpCodes.Pop);
					if(map[i].code != null)
					{
						ilgen.Emit(OpCodes.Ldarg_0);
						if(map[i].code.invoke != null)
						{
							foreach(MapXml.Instruction instr in map[i].code.invoke)
							{
								MapXml.NewObj newobj = instr as MapXml.NewObj;
								if(newobj != null
									&& newobj.Class != null
									&& context.ClassLoader.LoadClassByDottedName(newobj.Class).IsSubTypeOf(CoreClasses.java.lang.Throwable.Wrapper))
								{
									mwSuppressFillInStackTrace.EmitCall(ilgen);
								}
								instr.Generate(context, ilgen);
							}
						}
						ilgen.Emit(OpCodes.Ret);
					}
					else
					{
						TypeWrapper tw = context.ClassLoader.LoadClassByDottedName(map[i].dst);
						MethodWrapper mw = tw.GetMethodWrapper("<init>", "()V", false);
						mw.Link();
						mwSuppressFillInStackTrace.EmitCall(ilgen);
						mw.EmitNewobj(ilgen);
						ilgen.Emit(OpCodes.Ret);
					}
					ilgen.MarkLabel(label);
				}
				ilgen.Emit(OpCodes.Pop);
				ilgen.Emit(OpCodes.Ldarg_0);
				ilgen.Emit(OpCodes.Ret);
			}