Beispiel #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;
 }
Beispiel #2
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);
	}
		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;
		}
		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);
			}
		}
Beispiel #5
0
 private static bool Double_longBitsToDouble(DynamicTypeWrapper.FinishContext context, CodeEmitter ilgen, MethodWrapper method, MethodAnalyzer ma, int opcodeIndex, MethodWrapper caller, ClassFile classFile, Instruction[] code, InstructionFlags[] flags)
 {
     EmitConversion(ilgen, typeofDoubleConverter, "ToDouble");
     return(true);
 }
		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);
			}
		}
		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);
			}
		}
		protected override void NewobjImpl(CodeEmitter ilgen)
		{
			ilgen.Emit(OpCodes.Newobj, (ConstructorInfo)GetMethod());
		}
		internal void EmitSet(CodeEmitter ilgen)
		{
			AssertLinked();
			EmitSetImpl(ilgen);
		}
Beispiel #10
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);
 }
Beispiel #11
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);
        }
Beispiel #12
0
 private static bool Reflection_getCallerClass(DynamicTypeWrapper.FinishContext context, CodeEmitter ilgen, MethodWrapper method, MethodAnalyzer ma, int opcodeIndex, MethodWrapper caller, ClassFile classFile, Instruction[] code, InstructionFlags[] flags)
 {
     if (caller.HasCallerID &&
         opcodeIndex > 0 &&
         (flags[opcodeIndex - 1] & InstructionFlags.BranchTarget) == 0 &&
         code[opcodeIndex - 1].NormalizedOpCode == NormalizedByteCode.__iconst &&
         code[opcodeIndex - 1].Arg1 == 2)
     {
         ilgen.LazyEmitPop();
         int arg = caller.GetParametersForDefineMethod().Length - 1;
         if (!caller.IsStatic)
         {
             arg++;
         }
         ilgen.Emit(OpCodes.Ldarg, (short)arg);
         MethodWrapper mw = [email protected]("getCallerClass", "()Ljava.lang.Class;", false);
         mw.Link();
         mw.EmitCallvirt(ilgen);
         return(true);
     }
     return(false);
 }
Beispiel #13
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);
 }
Beispiel #14
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);
        }
Beispiel #15
0
 private static bool AtomicReferenceFieldUpdater_newUpdater(DynamicTypeWrapper.FinishContext context, CodeEmitter ilgen, MethodWrapper method, MethodAnalyzer ma, int opcodeIndex, MethodWrapper caller, ClassFile classFile, Instruction[] code, InstructionFlags[] flags)
 {
     return(AtomicReferenceFieldUpdaterEmitter.Emit(context, caller.DeclaringType, ilgen, classFile, opcodeIndex, code, flags));
 }
Beispiel #16
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);
            }
        }
		protected virtual void NewobjImpl(CodeEmitter ilgen)
		{
			throw new InvalidOperationException();
		}
Beispiel #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);
        }
		protected override void CallvirtImpl(CodeEmitter ilgen)
		{
			ilgen.Emit(SimpleOpCodeToOpCode(callvirt), (MethodInfo)GetMethod());
		}
Beispiel #20
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);
        }
		protected override void CallImpl(CodeEmitter ilgen)
		{
			ilgen.Emit(OpCodes.Call, stub);
		}
Beispiel #22
0
 internal static void EmitUnbox(CodeEmitter ilgen, TypeWrapper tw, bool cast)
 {
     if (tw == PrimitiveTypeWrapper.BYTE)
     {
         if (cast)
         {
             javaLangByte.EmitCheckcast(ilgen);
         }
         byteValue.EmitCall(ilgen);
     }
     else if (tw == PrimitiveTypeWrapper.BOOLEAN)
     {
         if (cast)
         {
             javaLangBoolean.EmitCheckcast(ilgen);
         }
         booleanValue.EmitCall(ilgen);
     }
     else if (tw == PrimitiveTypeWrapper.SHORT)
     {
         if (cast)
         {
             javaLangShort.EmitCheckcast(ilgen);
         }
         shortValue.EmitCall(ilgen);
     }
     else if (tw == PrimitiveTypeWrapper.CHAR)
     {
         if (cast)
         {
             javaLangCharacter.EmitCheckcast(ilgen);
         }
         charValue.EmitCall(ilgen);
     }
     else if (tw == PrimitiveTypeWrapper.INT)
     {
         if (cast)
         {
             javaLangInteger.EmitCheckcast(ilgen);
         }
         intValue.EmitCall(ilgen);
     }
     else if (tw == PrimitiveTypeWrapper.FLOAT)
     {
         if (cast)
         {
             javaLangFloat.EmitCheckcast(ilgen);
         }
         floatValue.EmitCall(ilgen);
     }
     else if (tw == PrimitiveTypeWrapper.LONG)
     {
         if (cast)
         {
             javaLangLong.EmitCheckcast(ilgen);
         }
         longValue.EmitCall(ilgen);
     }
     else if (tw == PrimitiveTypeWrapper.DOUBLE)
     {
         if (cast)
         {
             javaLangDouble.EmitCheckcast(ilgen);
         }
         doubleValue.EmitCall(ilgen);
     }
     else
     {
         throw new InvalidOperationException();
     }
 }
		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());
		}
Beispiel #24
0
        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);
        }
		protected override void EmitGetImpl(CodeEmitter ilgen)
		{
			if(getter == null)
			{
				EmitThrowNoSuchMethodErrorForGetter(ilgen, this.FieldTypeWrapper, this.IsStatic);
			}
			else if(getter.IsStatic)
			{
				getter.EmitCall(ilgen);
			}
			else
			{
				getter.EmitCallvirt(ilgen);
			}
		}
Beispiel #26
0
        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);
        }
		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);
			}
		}
Beispiel #28
0
        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();
        }
		protected override void EmitSetImpl(CodeEmitter ilgen)
		{
			ilgen.Emit(OpCodes.Call, setter);
		}
Beispiel #30
0
        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);
        }
Beispiel #31
0
        private static void CreateMethod(CompilerClassLoader loader, TypeBuilder tb, ProxyMethod pm)
        {
            MethodBuilder mb         = pm.mw.GetDefineMethodHelper().DefineMethod(loader.GetTypeWrapperFactory(), tb, pm.mw.Name, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final);
            List <string> exceptions = new List <string>();

            foreach (TypeWrapper tw in pm.exceptions)
            {
                exceptions.Add(tw.Name);
            }
            AttributeHelper.SetThrowsAttribute(mb, exceptions.ToArray());
            CodeEmitter ilgen = CodeEmitter.Create(mb);

            ilgen.BeginExceptionBlock();
            ilgen.Emit(OpCodes.Ldarg_0);
            invocationHandlerField.EmitGet(ilgen);
            ilgen.Emit(OpCodes.Ldarg_0);
            ilgen.Emit(OpCodes.Ldsfld, pm.fb);
            TypeWrapper[] parameters = pm.mw.GetParameters();
            if (parameters.Length == 0)
            {
                ilgen.Emit(OpCodes.Ldnull);
            }
            else
            {
                ilgen.EmitLdc_I4(parameters.Length);
                ilgen.Emit(OpCodes.Newarr, Types.Object);
                for (int i = 0; i < parameters.Length; i++)
                {
                    ilgen.Emit(OpCodes.Dup);
                    ilgen.EmitLdc_I4(i);
                    ilgen.EmitLdarg(i);
                    if (parameters[i].IsNonPrimitiveValueType)
                    {
                        parameters[i].EmitBox(ilgen);
                    }
                    else if (parameters[i].IsPrimitive)
                    {
                        Boxer.EmitBox(ilgen, parameters[i]);
                    }
                    ilgen.Emit(OpCodes.Stelem_Ref);
                }
            }
            invokeMethod.EmitCallvirt(ilgen);
            TypeWrapper      returnType  = pm.mw.ReturnType;
            CodeEmitterLocal returnValue = null;

            if (returnType != PrimitiveTypeWrapper.VOID)
            {
                returnValue = ilgen.DeclareLocal(returnType.TypeAsSignatureType);
                if (returnType.IsNonPrimitiveValueType)
                {
                    returnType.EmitUnbox(ilgen);
                }
                else if (returnType.IsPrimitive)
                {
                    Boxer.EmitUnbox(ilgen, returnType);
                }
                else if (returnType != CoreClasses.java.lang.Object.Wrapper)
                {
                    ilgen.EmitCastclass(returnType.TypeAsSignatureType);
                }
                ilgen.Emit(OpCodes.Stloc, returnValue);
            }
            CodeEmitterLabel returnLabel = ilgen.DefineLabel();

            ilgen.EmitLeave(returnLabel);
            // TODO consider using a filter here (but we would need to add filter support to CodeEmitter)
            ilgen.BeginCatchBlock(Types.Exception);
            ilgen.EmitLdc_I4(0);
            ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.mapException.MakeGenericMethod(Types.Exception));
            CodeEmitterLocal exception = ilgen.DeclareLocal(Types.Exception);

            ilgen.Emit(OpCodes.Stloc, exception);
            CodeEmitterLabel rethrow = ilgen.DefineLabel();

            ilgen.Emit(OpCodes.Ldloc, exception);
            errorClass.EmitInstanceOf(ilgen);
            ilgen.EmitBrtrue(rethrow);
            ilgen.Emit(OpCodes.Ldloc, exception);
            runtimeExceptionClass.EmitInstanceOf(ilgen);
            ilgen.EmitBrtrue(rethrow);
            foreach (TypeWrapper tw in pm.exceptions)
            {
                ilgen.Emit(OpCodes.Ldloc, exception);
                tw.EmitInstanceOf(ilgen);
                ilgen.EmitBrtrue(rethrow);
            }
            ilgen.Emit(OpCodes.Ldloc, exception);
            undeclaredThrowableExceptionConstructor.EmitNewobj(ilgen);
            ilgen.Emit(OpCodes.Throw);
            ilgen.MarkLabel(rethrow);
            ilgen.Emit(OpCodes.Rethrow);
            ilgen.EndExceptionBlock();
            ilgen.MarkLabel(returnLabel);
            if (returnValue != null)
            {
                ilgen.Emit(OpCodes.Ldloc, returnValue);
            }
            ilgen.Emit(OpCodes.Ret);
            ilgen.DoEmit();
        }
Beispiel #32
0
 internal abstract void Emit(CodeEmitter ilgen);
		internal sealed override void EmitNewobj(CodeEmitter ilgen)
		{
			AssertLinked();
			PreEmit(ilgen);
			NewobjImpl(ilgen);
			if(DeclaringType.IsNonPrimitiveValueType)
			{
				DeclaringType.EmitBox(ilgen);
			}
		}
Beispiel #34
0
 internal override void Emit(CodeEmitter ilgen)
 {
     base.Emit(ilgen);
     ilgen.Emit(OpCodes.Ldobj, Type);
 }
		internal override void EmitCallvirt(CodeEmitter ilgen)
		{
			ilgen.Emit(SimpleOpCodeToOpCode(callvirt), (MethodInfo)GetMethod());
		}
Beispiel #36
0
 internal override void Emit(CodeEmitter ilgen)
 {
     ilgen.Emit(OpCodes.Ldnull);
 }
		protected override void CallImpl(CodeEmitter ilgen)
		{
			ilgen.Emit(OpCodes.Call, (ConstructorInfo)GetMethod());
		}
Beispiel #38
0
            internal override void Emit(CodeEmitter ilgen)
            {
                switch (l)
                {
                case -1:
                    ilgen.Emit(OpCodes.Ldc_I4_M1);
                    ilgen.Emit(OpCodes.Conv_I8);
                    break;

                case 0:
                    ilgen.Emit(OpCodes.Ldc_I4_0);
                    ilgen.Emit(OpCodes.Conv_I8);
                    break;

                case 1:
                    ilgen.Emit(OpCodes.Ldc_I4_1);
                    ilgen.Emit(OpCodes.Conv_I8);
                    break;

                case 2:
                    ilgen.Emit(OpCodes.Ldc_I4_2);
                    ilgen.Emit(OpCodes.Conv_I8);
                    break;

                case 3:
                    ilgen.Emit(OpCodes.Ldc_I4_3);
                    ilgen.Emit(OpCodes.Conv_I8);
                    break;

                case 4:
                    ilgen.Emit(OpCodes.Ldc_I4_4);
                    ilgen.Emit(OpCodes.Conv_I8);
                    break;

                case 5:
                    ilgen.Emit(OpCodes.Ldc_I4_5);
                    ilgen.Emit(OpCodes.Conv_I8);
                    break;

                case 6:
                    ilgen.Emit(OpCodes.Ldc_I4_6);
                    ilgen.Emit(OpCodes.Conv_I8);
                    break;

                case 7:
                    ilgen.Emit(OpCodes.Ldc_I4_7);
                    ilgen.Emit(OpCodes.Conv_I8);
                    break;

                case 8:
                    ilgen.Emit(OpCodes.Ldc_I4_8);
                    ilgen.Emit(OpCodes.Conv_I8);
                    break;

                default:
                    if (l >= -2147483648L && l <= 4294967295L)
                    {
                        if (l >= -128 && l <= 127)
                        {
                            ilgen.Emit(OpCodes.Ldc_I4_S, (sbyte)l);
                        }
                        else
                        {
                            ilgen.Emit(OpCodes.Ldc_I4, (int)l);
                        }
                        if (l < 0)
                        {
                            ilgen.Emit(OpCodes.Conv_I8);
                        }
                        else
                        {
                            ilgen.Emit(OpCodes.Conv_U8);
                        }
                    }
                    else
                    {
                        ilgen.Emit(OpCodes.Ldc_I8, l);
                    }
                    break;
                }
            }
		protected override void CallvirtImpl(CodeEmitter ilgen)
		{
			ilgen.Emit(OpCodes.Callvirt, stubVirtual);
		}
Beispiel #40
0
 internal override void Emit(CodeEmitter ilgen)
 {
     ilgen.Emit(OpCodes.Ldstr, str);
 }
		protected override void NewobjImpl(CodeEmitter ilgen)
		{
			ilgen.Emit(OpCodes.Newobj, stub);
		}
Beispiel #42
0
 internal override void Emit(CodeEmitter ilgen)
 {
     ilgen.Emit(OpCodes.Isinst, this.Type);
     ilgen.Emit(OpCodes.Ldnull);
     ilgen.Emit(OpCodes.Cgt_Un);
 }
		protected abstract void EmitSetImpl(CodeEmitter ilgen);
Beispiel #44
0
 internal abstract void EmitBcc(CodeEmitter ilgen, Comparison comp, CodeEmitterLabel label);
		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();
			}
		}
Beispiel #46
0
 internal sealed override void EmitBcc(CodeEmitter ilgen, Comparison comp, CodeEmitterLabel label)
 {
     ilgen.EmitBcc(comp, label);
 }
		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);
			}
		}
Beispiel #48
0
 internal override void Emit(CodeEmitter ilgen)
 {
     Type.EmitClassLiteral(ilgen);
 }
		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));
		}
Beispiel #50
0
 internal override void Emit(CodeEmitter ilgen)
 {
     ilgen.Emit(OpCodes.Ldelem_I1);
 }
		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);
			}
		}
Beispiel #52
0
 internal override void Emit(CodeEmitter ilgen)
 {
     base.Emit(ilgen);
     ilgen.Emit(OpCodes.Conv_I8);
 }
		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);
			}
		}
		internal virtual void EmitNewobj(CodeEmitter ilgen)
		{
			throw new InvalidOperationException();
		}
		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);
		}
Beispiel #56
0
        private static bool Class_desiredAssertionStatus(DynamicTypeWrapper.FinishContext context, CodeEmitter ilgen, MethodWrapper method, MethodAnalyzer ma, int opcodeIndex, MethodWrapper caller, ClassFile classFile, Instruction[] code, InstructionFlags[] flags)
        {
            TypeWrapper classLiteral = ilgen.PeekLazyClassLiteral();

            if (classLiteral != null && classLiteral.GetClassLoader().RemoveAsserts)
            {
                ilgen.LazyEmitPop();
                ilgen.LazyEmitLdc_I4(0);
                return(true);
            }
            else
            {
                return(false);
            }
        }
		internal virtual void EmitCallvirtReflect(CodeEmitter ilgen)
		{
			EmitCallvirt(ilgen);
		}
Beispiel #58
0
 private static bool Float_floatToRawIntBits(DynamicTypeWrapper.FinishContext context, CodeEmitter ilgen, MethodWrapper method, MethodAnalyzer ma, int opcodeIndex, MethodWrapper caller, ClassFile classFile, Instruction[] code, InstructionFlags[] flags)
 {
     EmitConversion(ilgen, typeofFloatConverter, "ToInt");
     return(true);
 }
			protected override void CallvirtImpl(CodeEmitter ilgen)
			{
				ResolveGhostMethod();
				ilgen.Emit(OpCodes.Call, ghostMethod);
			}
Beispiel #60
0
 internal EmitIntrinsicContext(MethodWrapper method, DynamicTypeWrapper.FinishContext context, CodeEmitter ilgen, CodeInfo ma, int opcodeIndex, MethodWrapper caller, ClassFile classFile, Instruction[] code, InstructionFlags[] flags)
 {
     this.Method      = method;
     this.Context     = context;
     this.Emitter     = ilgen;
     this.ma          = ma;
     this.OpcodeIndex = opcodeIndex;
     this.Caller      = caller;
     this.ClassFile   = classFile;
     this.Code        = code;
     this.Flags       = flags;
 }