Exemplo n.º 1
0
        internal void EmitThrow(string dottedClassName)
        {
            TypeWrapper   exception = ClassLoaderWrapper.GetBootstrapClassLoader().LoadClassByDottedName(dottedClassName);
            MethodWrapper mw        = exception.GetMethodWrapper("<init>", "()V", false);

            mw.Link();
            mw.EmitNewobj(this);
            Emit(OpCodes.Throw);
        }
Exemplo n.º 2
0
        private static bool Class_getPrimitiveClass(EmitIntrinsicContext eic)
        {
            eic.Emitter.Emit(OpCodes.Pop);
            eic.Emitter.Emit(OpCodes.Ldnull);
            MethodWrapper mw = CoreClasses.java.lang.Class.Wrapper.GetMethodWrapper("<init>", "(Lcli.System.Type;)V", false);

            mw.Link();
            mw.EmitNewobj(eic.Emitter);
            return(true);
        }
Exemplo n.º 3
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();
        }
Exemplo n.º 5
0
 internal sealed override void Generate(CodeGenContext context, CodeEmitter ilgen)
 {
     Debug.Assert(Name != null);
     if (Name == ".ctor")
     {
         Debug.Assert(Class == null && type != null);
         Type[]          argTypes = context.ClassLoader.ArgTypeListFromSig(Sig);
         ConstructorInfo ci       = StaticCompiler.GetTypeForMapXml(context.ClassLoader, type).GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, CallingConventions.Standard, argTypes, null);
         if (ci == null)
         {
             throw new InvalidOperationException("Missing .ctor: " + type + "..ctor" + Sig);
         }
         ilgen.Emit(opcode, ci);
     }
     else
     {
         Debug.Assert(Class == null ^ type == null);
         if (Class != null)
         {
             Debug.Assert(Sig != null);
             MethodWrapper method = context.ClassLoader.LoadClassByDottedName(Class).GetMethodWrapper(Name, Sig, false);
             if (method == null)
             {
                 throw new InvalidOperationException("method not found: " + Class + "." + Name + Sig);
             }
             method.Link();
             // TODO this code is part of what Compiler.CastInterfaceArgs (in compiler.cs) does,
             // it would be nice if we could avoid this duplication...
             TypeWrapper[] argTypeWrappers = method.GetParameters();
             for (int i = 0; i < argTypeWrappers.Length; i++)
             {
                 if (argTypeWrappers[i].IsGhost)
                 {
                     CodeEmitterLocal[] temps = new CodeEmitterLocal[argTypeWrappers.Length + (method.IsStatic ? 0 : 1)];
                     for (int j = temps.Length - 1; j >= 0; j--)
                     {
                         TypeWrapper tw;
                         if (method.IsStatic)
                         {
                             tw = argTypeWrappers[j];
                         }
                         else
                         {
                             if (j == 0)
                             {
                                 tw = method.DeclaringType;
                             }
                             else
                             {
                                 tw = argTypeWrappers[j - 1];
                             }
                         }
                         if (tw.IsGhost)
                         {
                             tw.EmitConvStackTypeToSignatureType(ilgen, null);
                         }
                         temps[j] = ilgen.DeclareLocal(tw.TypeAsSignatureType);
                         ilgen.Emit(OpCodes.Stloc, temps[j]);
                     }
                     for (int j = 0; j < temps.Length; j++)
                     {
                         ilgen.Emit(OpCodes.Ldloc, temps[j]);
                     }
                     break;
                 }
             }
             if (opcode.Value == OpCodes.Call.Value)
             {
                 method.EmitCall(ilgen);
             }
             else if (opcode.Value == OpCodes.Callvirt.Value)
             {
                 method.EmitCallvirt(ilgen);
             }
             else if (opcode.Value == OpCodes.Newobj.Value)
             {
                 method.EmitNewobj(ilgen);
             }
             else
             {
                 // ldftn or ldvirtftn
                 ilgen.Emit(opcode, (MethodInfo)method.GetMethod());
             }
         }
         else
         {
             Type[] argTypes;
             if (Sig.StartsWith("("))
             {
                 argTypes = context.ClassLoader.ArgTypeListFromSig(Sig);
             }
             else if (Sig == "")
             {
                 argTypes = Type.EmptyTypes;
             }
             else
             {
                 string[] types = Sig.Split(';');
                 argTypes = new Type[types.Length];
                 for (int i = 0; i < types.Length; i++)
                 {
                     argTypes[i] = StaticCompiler.GetTypeForMapXml(context.ClassLoader, types[i]);
                 }
             }
             MethodInfo mi = StaticCompiler.GetTypeForMapXml(context.ClassLoader, type).GetMethod(Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static, null, argTypes, null);
             if (mi == null)
             {
                 throw new InvalidOperationException("Missing method: " + type + "." + Name + Sig);
             }
             ilgen.Emit(opcode, mi);
         }
     }
 }
        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);
        }