~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to external/ikvm/runtime/openjdk/java.lang.invoke.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
  Copyright (C) 2011 Jeroen Frijters
 
3
 
 
4
  This software is provided 'as-is', without any express or implied
 
5
  warranty.  In no event will the authors be held liable for any damages
 
6
  arising from the use of this software.
 
7
 
 
8
  Permission is granted to anyone to use this software for any purpose,
 
9
  including commercial applications, and to alter it and redistribute it
 
10
  freely, subject to the following restrictions:
 
11
 
 
12
  1. The origin of this software must not be misrepresented; you must not
 
13
     claim that you wrote the original software. If you use this software
 
14
     in a product, an acknowledgment in the product documentation would be
 
15
     appreciated but is not required.
 
16
  2. Altered source versions must be plainly marked as such, and must not be
 
17
     misrepresented as being the original software.
 
18
  3. This notice may not be removed or altered from any source distribution.
 
19
 
 
20
  Jeroen Frijters
 
21
  jeroen@frijters.net
 
22
  
 
23
*/
 
24
 
 
25
using System;
 
26
using System.Reflection;
 
27
using System.Reflection.Emit;
 
28
using IKVM.Internal;
 
29
using java.lang.invoke;
 
30
using jlClass = java.lang.Class;
 
31
 
 
32
static class Java_java_lang_invoke_BoundMethodHandle
 
33
{
 
34
        public static object createDelegate(MethodType newType, MethodHandle mh, int argnum, object argument)
 
35
        {
 
36
#if FIRST_PASS
 
37
                return null;
 
38
#else
 
39
                Delegate del = (Delegate)mh.vmtarget;
 
40
                if (argnum == 0
 
41
                        && del.Target == null
 
42
                        // we don't have to check for instance methods on a Value Type, because DirectMethodHandle can't use a direct delegate for that anyway
 
43
                        && (!del.Method.IsStatic || !del.Method.GetParameters()[0].ParameterType.IsValueType)
 
44
                        && !ReflectUtil.IsDynamicMethod(del.Method))
 
45
                {
 
46
                        return Delegate.CreateDelegate(MethodHandleUtil.CreateDelegateType(newType), argument, del.Method);
 
47
                }
 
48
                else
 
49
                {
 
50
                        // slow path where we're generating a DynamicMethod
 
51
                        if (mh.type().parameterType(argnum).isPrimitive())
 
52
                        {
 
53
                                argument = JVM.Unbox(argument);
 
54
                        }
 
55
                        MethodHandleUtil.DynamicMethodBuilder dm = new MethodHandleUtil.DynamicMethodBuilder("BoundMethodHandle", newType, mh, argument);
 
56
                        for (int i = 0, count = mh.type().parameterCount(), pos = 0; i < count; i++)
 
57
                        {
 
58
                                if (i == argnum)
 
59
                                {
 
60
                                        dm.LoadValue();
 
61
                                }
 
62
                                else
 
63
                                {
 
64
                                        dm.Ldarg(pos++);
 
65
                                }
 
66
                        }
 
67
                        dm.CallTarget();
 
68
                        dm.Ret();
 
69
                        return dm.CreateDelegate();
 
70
                }
 
71
#endif
 
72
        }
 
73
}
 
74
 
 
75
static class Java_java_lang_invoke_CallSite
 
76
{
 
77
        public static object createIndyCallSite(object target)
 
78
        {
 
79
                return Activator.CreateInstance(typeof(IKVM.Runtime.IndyCallSite<>).MakeGenericType(target.GetType()), true);
 
80
        }
 
81
}
 
82
 
 
83
static class Java_java_lang_invoke_DirectMethodHandle
 
84
{
 
85
        // TODO what is lookupClass for?
 
86
    public static object createDelegate(MethodType type, MemberName m, bool doDispatch, jlClass lookupClass)
 
87
        {
 
88
#if FIRST_PASS
 
89
                return null;
 
90
#else
 
91
                int index = m.getVMIndex();
 
92
                if (index == Int32.MaxValue)
 
93
                {
 
94
                        bool invokeExact = m.getName() == "invokeExact";
 
95
                        Type targetDelegateType = MethodHandleUtil.CreateDelegateType(invokeExact ? type.dropParameterTypes(0, 1) : type);
 
96
                        MethodHandleUtil.DynamicMethodBuilder dm = new MethodHandleUtil.DynamicMethodBuilder("DirectMethodHandle." + m.getName(), type, typeof(IKVM.Runtime.InvokeCache<>).MakeGenericType(targetDelegateType));
 
97
                        dm.Ldarg(0);
 
98
                        if (invokeExact)
 
99
                        {
 
100
                                dm.Call(ByteCodeHelperMethods.GetDelegateForInvokeExact.MakeGenericMethod(targetDelegateType));
 
101
                        }
 
102
                        else
 
103
                        {
 
104
                                dm.LoadValueAddress();
 
105
                                dm.Call(ByteCodeHelperMethods.GetDelegateForInvoke.MakeGenericMethod(targetDelegateType));
 
106
                                dm.Ldarg(0);
 
107
                        }
 
108
                        for (int i = 1, count = type.parameterCount(); i < count; i++)
 
109
                        {
 
110
                                dm.Ldarg(i);
 
111
                        }
 
112
                        dm.CallDelegate(targetDelegateType);
 
113
                        dm.Ret();
 
114
                        return dm.CreateDelegate();
 
115
                }
 
116
                else
 
117
                {
 
118
                        TypeWrapper tw = (TypeWrapper)typeof(MemberName).GetField("vmtarget", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(m);
 
119
                        tw.Finish();
 
120
                        MethodWrapper mw = tw.GetMethods()[index];
 
121
                        mw.ResolveMethod();
 
122
                        MethodInfo mi = mw.GetMethod() as MethodInfo;
 
123
                        if (mi != null
 
124
                                && !tw.IsRemapped
 
125
                                && !tw.IsGhost
 
126
                                && !tw.IsNonPrimitiveValueType
 
127
                                && type.parameterCount() <= MethodHandleUtil.MaxArity
 
128
                                // FXBUG we should be able to use a normal (unbound) delegate for virtual methods
 
129
                                // (when doDispatch is set), but the x64 CLR crashes when doing a virtual method dispatch on
 
130
                                // a null reference
 
131
                                && (!mi.IsVirtual || (doDispatch && IntPtr.Size == 4))
 
132
                                && (doDispatch || !mi.IsVirtual))
 
133
                        {
 
134
                                return Delegate.CreateDelegate(MethodHandleUtil.CreateDelegateType(tw, mw), mi);
 
135
                        }
 
136
                        else
 
137
                        {
 
138
                                // slow path where we emit a DynamicMethod
 
139
                                MethodHandleUtil.DynamicMethodBuilder dm = new MethodHandleUtil.DynamicMethodBuilder(mw.DeclaringType.TypeAsBaseType, "DirectMethodHandle:" + mw.Name, type);
 
140
                                for (int i = 0, count = type.parameterCount(); i < count; i++)
 
141
                                {
 
142
                                        if (i == 0 && !mw.IsStatic && (tw.IsGhost || tw.IsNonPrimitiveValueType))
 
143
                                        {
 
144
                                                dm.LoadFirstArgAddress();
 
145
                                        }
 
146
                                        else
 
147
                                        {
 
148
                                                dm.Ldarg(i);
 
149
                                        }
 
150
                                }
 
151
                                if (doDispatch && !mw.IsStatic)
 
152
                                {
 
153
                                        dm.Callvirt(mw);
 
154
                                }
 
155
                                else
 
156
                                {
 
157
                                        dm.Call(mw);
 
158
                                }
 
159
                                dm.Ret();
 
160
                                return dm.CreateDelegate();
 
161
                        }
 
162
                }
 
163
#endif
 
164
        }
 
165
}
 
166
 
 
167
static class Java_java_lang_invoke_MethodHandle
 
168
{
 
169
        private static IKVM.Runtime.InvokeCache<IKVM.Runtime.MH<MethodHandle, object[], object>> cache;
 
170
 
 
171
        public static object invokeExact(MethodHandle mh, object[] args)
 
172
        {
 
173
#if FIRST_PASS
 
174
                return null;
 
175
#else
 
176
                return IKVM.Runtime.ByteCodeHelper.GetDelegateForInvokeExact<IKVM.Runtime.MH<object[], object>>(mh)(args);
 
177
#endif
 
178
        }
 
179
 
 
180
        public static object invoke(MethodHandle mh, object[] args)
 
181
        {
 
182
#if FIRST_PASS
 
183
                return null;
 
184
#else
 
185
                MethodType type = mh.type();
 
186
                if (mh.isVarargsCollector())
 
187
                {
 
188
                        java.lang.Class varargType = type.parameterType(type.parameterCount() - 1);
 
189
                        if (type.parameterCount() == args.Length)
 
190
                        {
 
191
                                if (!varargType.isInstance(args[args.Length - 1]))
 
192
                                {
 
193
                                        Array arr = (Array)java.lang.reflect.Array.newInstance(varargType.getComponentType(), 1);
 
194
                                        arr.SetValue(args[args.Length - 1], 0);
 
195
                                        args[args.Length - 1] = arr;
 
196
                                }
 
197
                        }
 
198
                        else if (type.parameterCount() - 1 > args.Length)
 
199
                        {
 
200
                                throw new WrongMethodTypeException();
 
201
                        }
 
202
                        else
 
203
                        {
 
204
                                object[] newArgs = new object[type.parameterCount()];
 
205
                                Array.Copy(args, newArgs, newArgs.Length - 1);
 
206
                                Array varargs = (Array)java.lang.reflect.Array.newInstance(varargType.getComponentType(), args.Length - (newArgs.Length - 1));
 
207
                                Array.Copy(args, newArgs.Length - 1, varargs, 0, varargs.Length);
 
208
                                newArgs[newArgs.Length - 1] = varargs;
 
209
                                args = newArgs;
 
210
                        }
 
211
                }
 
212
                if (mh.type().parameterCount() != args.Length)
 
213
                {
 
214
                        throw new WrongMethodTypeException();
 
215
                }
 
216
                mh = mh.asSpreader(typeof(object[]), args.Length);
 
217
                return IKVM.Runtime.ByteCodeHelper.GetDelegateForInvoke<IKVM.Runtime.MH<MethodHandle, object[], object>>(mh, ref cache)(mh, args);
 
218
#endif
 
219
        }
 
220
}
 
221
 
 
222
static partial class MethodHandleUtil
 
223
{
 
224
        internal static Type CreateDelegateType(MethodType type)
 
225
        {
 
226
#if FIRST_PASS
 
227
                return null;
 
228
#else
 
229
                TypeWrapper[] args = new TypeWrapper[type.parameterCount()];
 
230
                for (int i = 0; i < args.Length; i++)
 
231
                {
 
232
                        args[i] = TypeWrapper.FromClass(type.parameterType(i));
 
233
                        args[i].Finish();
 
234
                }
 
235
                TypeWrapper ret = TypeWrapper.FromClass(type.returnType());
 
236
                ret.Finish();
 
237
                return CreateDelegateType(args, ret);
 
238
#endif
 
239
        }
 
240
 
 
241
#if !FIRST_PASS
 
242
        private static Type[] GetParameterTypes(MethodBase mb)
 
243
        {
 
244
                ParameterInfo[] pi = mb.GetParameters();
 
245
                Type[] args = new Type[pi.Length];
 
246
                for (int i = 0; i < args.Length; i++)
 
247
                {
 
248
                        args[i] = pi[i].ParameterType;
 
249
                }
 
250
                return args;
 
251
        }
 
252
 
 
253
        private static Type[] GetParameterTypes(Type thisType, MethodBase mb)
 
254
        {
 
255
                ParameterInfo[] pi = mb.GetParameters();
 
256
                Type[] args = new Type[pi.Length + 1];
 
257
                args[0] = thisType;
 
258
                for (int i = 1; i < args.Length; i++)
 
259
                {
 
260
                        args[i] = pi[i - 1].ParameterType;
 
261
                }
 
262
                return args;
 
263
        }
 
264
 
 
265
        internal static MethodType GetDelegateMethodType(Type type)
 
266
        {
 
267
                java.lang.Class[] types;
 
268
                MethodInfo mi = GetDelegateInvokeMethod(type);
 
269
                ParameterInfo[] pi = mi.GetParameters();
 
270
                if (pi.Length > 0 && IsPackedArgsContainer(pi[pi.Length - 1].ParameterType))
 
271
                {
 
272
                        System.Collections.Generic.List<java.lang.Class> list = new System.Collections.Generic.List<java.lang.Class>();
 
273
                        for (int i = 0; i < pi.Length - 1; i++)
 
274
                        {
 
275
                                list.Add(ClassLoaderWrapper.GetWrapperFromType(pi[i].ParameterType).ClassObject);
 
276
                        }
 
277
                        Type[] args = pi[pi.Length - 1].ParameterType.GetGenericArguments();
 
278
                        while (IsPackedArgsContainer(args[args.Length - 1]))
 
279
                        {
 
280
                                for (int i = 0; i < args.Length - 1; i++)
 
281
                                {
 
282
                                        list.Add(ClassLoaderWrapper.GetWrapperFromType(args[i]).ClassObject);
 
283
                                }
 
284
                                args = args[args.Length - 1].GetGenericArguments();
 
285
                        }
 
286
                        for (int i = 0; i < args.Length; i++)
 
287
                        {
 
288
                                list.Add(ClassLoaderWrapper.GetWrapperFromType(args[i]).ClassObject);
 
289
                        }
 
290
                        types = list.ToArray();
 
291
                }
 
292
                else
 
293
                {
 
294
                        types = new java.lang.Class[pi.Length];
 
295
                        for (int i = 0; i < types.Length; i++)
 
296
                        {
 
297
                                types[i] = ClassLoaderWrapper.GetWrapperFromType(pi[i].ParameterType).ClassObject;
 
298
                        }
 
299
                }
 
300
                return MethodType.methodType(ClassLoaderWrapper.GetWrapperFromType(mi.ReturnType).ClassObject, types);
 
301
        }
 
302
 
 
303
        internal sealed class DynamicMethodBuilder
 
304
        {
 
305
                private readonly MethodType type;
 
306
                private readonly int firstArg;
 
307
                private readonly Type delegateType;
 
308
                private readonly object target;
 
309
                private readonly object value;
 
310
                private readonly Type container;
 
311
                private readonly DynamicMethod dm;
 
312
                private readonly CodeEmitter ilgen;
 
313
                private readonly Type packedArgType;
 
314
                private readonly int packedArgPos;
 
315
 
 
316
                sealed class Container<T1, T2>
 
317
                {
 
318
                        public T1 target;
 
319
                        public T2 value;
 
320
 
 
321
                        public Container(T1 target, T2 value)
 
322
                        {
 
323
                                this.target = target;
 
324
                                this.value = value;
 
325
                        }
 
326
                }
 
327
 
 
328
                private DynamicMethodBuilder(string name, MethodType type, Type container, object target, object value, Type owner)
 
329
                {
 
330
                        this.type = type;
 
331
                        this.delegateType = CreateDelegateType(type);
 
332
                        this.target = target;
 
333
                        this.value = value;
 
334
                        this.container = container;
 
335
                        MethodInfo mi = GetDelegateInvokeMethod(delegateType);
 
336
                        Type[] paramTypes;
 
337
                        if (container != null)
 
338
                        {
 
339
                                this.firstArg = 1;
 
340
                                paramTypes = GetParameterTypes(container, mi);
 
341
                        }
 
342
                        else if (target != null)
 
343
                        {
 
344
                                this.firstArg = 1;
 
345
                                paramTypes = GetParameterTypes(target.GetType(), mi);
 
346
                        }
 
347
                        else
 
348
                        {
 
349
                                paramTypes = GetParameterTypes(mi);
 
350
                        }
 
351
                        if (!ReflectUtil.CanOwnDynamicMethod(owner))
 
352
                        {
 
353
                                owner = typeof(DynamicMethodBuilder);
 
354
                        }
 
355
                        this.dm = new DynamicMethod(name, mi.ReturnType, paramTypes, owner, true);
 
356
                        this.ilgen = CodeEmitter.Create(dm);
 
357
 
 
358
                        if (type.parameterCount() > MaxArity)
 
359
                        {
 
360
                                ParameterInfo[] pi = mi.GetParameters();
 
361
                                this.packedArgType = pi[pi.Length - 1].ParameterType;
 
362
                                this.packedArgPos = pi.Length - 1 + firstArg;
 
363
                        }
 
364
                        else
 
365
                        {
 
366
                                this.packedArgPos = Int32.MaxValue;
 
367
                        }
 
368
                }
 
369
 
 
370
                internal DynamicMethodBuilder(Type owner, string name, MethodType type)
 
371
                        : this(name, type, null, null, null, owner)
 
372
                {
 
373
                }
 
374
 
 
375
                internal DynamicMethodBuilder(string name, MethodType type, MethodHandle target)
 
376
                        : this(name, type, null, target.vmtarget, null, null)
 
377
                {
 
378
                        ilgen.Emit(OpCodes.Ldarg_0);
 
379
                }
 
380
 
 
381
                internal DynamicMethodBuilder(string name, MethodType type, MethodHandle target, object value)
 
382
                        : this(name, type, typeof(Container<,>).MakeGenericType(target.vmtarget.GetType(), value.GetType()), target.vmtarget, value, null)
 
383
                {
 
384
                        ilgen.Emit(OpCodes.Ldarg_0);
 
385
                        ilgen.Emit(OpCodes.Ldfld, container.GetField("target"));
 
386
                }
 
387
 
 
388
                internal DynamicMethodBuilder(string name, MethodType type, Type valueType)
 
389
                        : this(name, type, typeof(Container<,>).MakeGenericType(typeof(object), valueType), null, null, null)
 
390
                {
 
391
                }
 
392
 
 
393
                internal void Call(MethodInfo method)
 
394
                {
 
395
                        ilgen.Emit(OpCodes.Call, method);
 
396
                }
 
397
 
 
398
                internal void Callvirt(MethodInfo method)
 
399
                {
 
400
                        ilgen.Emit(OpCodes.Callvirt, method);
 
401
                }
 
402
 
 
403
                internal void Call(MethodWrapper mw)
 
404
                {
 
405
                        mw.EmitCall(ilgen);
 
406
                }
 
407
 
 
408
                internal void Callvirt(MethodWrapper mw)
 
409
                {
 
410
                        mw.EmitCallvirt(ilgen);
 
411
                }
 
412
 
 
413
                internal void CallDelegate(Type delegateType)
 
414
                {
 
415
                        EmitCallDelegateInvokeMethod(ilgen, delegateType);
 
416
                }
 
417
 
 
418
                internal void LoadFirstArgAddress()
 
419
                {
 
420
                        ilgen.EmitLdarga(firstArg);
 
421
                }
 
422
 
 
423
                internal void Ldarg(int i)
 
424
                {
 
425
                        i += firstArg;
 
426
                        if (i >= packedArgPos)
 
427
                        {
 
428
                                ilgen.EmitLdarga(packedArgPos);
 
429
                                int fieldPos = i - packedArgPos;
 
430
                                Type type = packedArgType;
 
431
                                while (fieldPos >= MaxArity || (fieldPos == MaxArity - 1 && IsPackedArgsContainer(type.GetField("t8").FieldType)))
 
432
                                {
 
433
                                        FieldInfo field = type.GetField("t8");
 
434
                                        type = field.FieldType;
 
435
                                        ilgen.Emit(OpCodes.Ldflda, field);
 
436
                                        fieldPos -= MaxArity - 1;
 
437
                                }
 
438
                                ilgen.Emit(OpCodes.Ldfld, type.GetField("t" + (1 + fieldPos)));
 
439
                        }
 
440
                        else
 
441
                        {
 
442
                                ilgen.EmitLdarg(i);
 
443
                        }
 
444
                }
 
445
 
 
446
                internal void LoadArrayElement(int index, TypeWrapper tw)
 
447
                {
 
448
                        ilgen.EmitLdc_I4(index);
 
449
                        if (tw.IsNonPrimitiveValueType)
 
450
                        {
 
451
                                ilgen.Emit(OpCodes.Ldelema, tw.TypeAsArrayType);
 
452
                                ilgen.Emit(OpCodes.Ldobj, tw.TypeAsArrayType);
 
453
                        }
 
454
                        else if (tw == PrimitiveTypeWrapper.BYTE
 
455
                                || tw == PrimitiveTypeWrapper.BOOLEAN)
 
456
                        {
 
457
                                ilgen.Emit(OpCodes.Ldelem_I1);
 
458
                        }
 
459
                        else if (tw == PrimitiveTypeWrapper.SHORT)
 
460
                        {
 
461
                                ilgen.Emit(OpCodes.Ldelem_I2);
 
462
                        }
 
463
                        else if (tw == PrimitiveTypeWrapper.CHAR)
 
464
                        {
 
465
                                ilgen.Emit(OpCodes.Ldelem_U2);
 
466
                        }
 
467
                        else if (tw == PrimitiveTypeWrapper.INT)
 
468
                        {
 
469
                                ilgen.Emit(OpCodes.Ldelem_I4);
 
470
                        }
 
471
                        else if (tw == PrimitiveTypeWrapper.LONG)
 
472
                        {
 
473
                                ilgen.Emit(OpCodes.Ldelem_I8);
 
474
                        }
 
475
                        else if (tw == PrimitiveTypeWrapper.FLOAT)
 
476
                        {
 
477
                                ilgen.Emit(OpCodes.Ldelem_R4);
 
478
                        }
 
479
                        else if (tw == PrimitiveTypeWrapper.DOUBLE)
 
480
                        {
 
481
                                ilgen.Emit(OpCodes.Ldelem_R8);
 
482
                        }
 
483
                        else
 
484
                        {
 
485
                                ilgen.Emit(OpCodes.Ldelem_Ref);
 
486
                                if (tw.IsGhost)
 
487
                                {
 
488
                                        tw.EmitConvStackTypeToSignatureType(ilgen, null);
 
489
                                }
 
490
                        }
 
491
                }
 
492
 
 
493
                internal void Convert(java.lang.Class srcType, java.lang.Class dstType, int level)
 
494
                {
 
495
                        EmitConvert(ilgen, srcType, dstType, level);
 
496
                }
 
497
 
 
498
                internal void CallTarget()
 
499
                {
 
500
                        EmitCallDelegateInvokeMethod(ilgen, target.GetType());
 
501
                }
 
502
 
 
503
                internal void LoadValueAddress()
 
504
                {
 
505
                        ilgen.Emit(OpCodes.Ldarg_0);
 
506
                        ilgen.Emit(OpCodes.Ldflda, container.GetField("value"));
 
507
                }
 
508
 
 
509
                internal void LoadValue()
 
510
                {
 
511
                        ilgen.Emit(OpCodes.Ldarg_0);
 
512
                        ilgen.Emit(OpCodes.Ldfld, container.GetField("value"));
 
513
                }
 
514
 
 
515
                internal void CallValue()
 
516
                {
 
517
                        EmitCallDelegateInvokeMethod(ilgen, value.GetType());
 
518
                }
 
519
 
 
520
                internal void Ret()
 
521
                {
 
522
                        ilgen.Emit(OpCodes.Ret);
 
523
                }
 
524
 
 
525
                internal Delegate CreateDelegate()
 
526
                {
 
527
                        ilgen.DoEmit();
 
528
                        return ValidateDelegate(firstArg == 0
 
529
                                ? dm.CreateDelegate(delegateType)
 
530
                                : dm.CreateDelegate(delegateType, container == null ? target : Activator.CreateInstance(container, target, value)));
 
531
                }
 
532
 
 
533
                internal AdapterMethodHandle CreateAdapter()
 
534
                {
 
535
                        return new AdapterMethodHandle(type, CreateDelegate());
 
536
                }
 
537
        }
 
538
 
 
539
#if DEBUG
 
540
        [System.Security.SecuritySafeCritical]
 
541
#endif
 
542
        private static Delegate ValidateDelegate(Delegate d)
 
543
        {
 
544
#if DEBUG
 
545
                try
 
546
                {
 
547
                        System.Runtime.CompilerServices.RuntimeHelpers.PrepareDelegate(d);
 
548
                }
 
549
                catch (Exception x)
 
550
                {
 
551
                        JVM.CriticalFailure("Delegate failed to JIT", x);
 
552
                }
 
553
#endif
 
554
                return d;
 
555
        }
 
556
 
 
557
        private struct BoxUtil
 
558
        {
 
559
                private static readonly BoxUtil[] boxers = new BoxUtil[] {
 
560
                        BoxUtil.Create<java.lang.Boolean, bool>(java.lang.Boolean.TYPE, "boolean", "Boolean"),
 
561
                        BoxUtil.Create<java.lang.Byte, byte>(java.lang.Byte.TYPE, "byte", "Byte"),
 
562
                        BoxUtil.Create<java.lang.Character, char>(java.lang.Character.TYPE, "char", "Character"),
 
563
                        BoxUtil.Create<java.lang.Short, short>(java.lang.Short.TYPE, "short", "Short"),
 
564
                        BoxUtil.Create<java.lang.Integer, int>(java.lang.Integer.TYPE, "int", "Integer"),
 
565
                        BoxUtil.Create<java.lang.Long, int>(java.lang.Long.TYPE, "long", "Long"),
 
566
                        BoxUtil.Create<java.lang.Float, float>(java.lang.Float.TYPE, "float", "Float"),
 
567
                        BoxUtil.Create<java.lang.Double, double>(java.lang.Double.TYPE, "double", "Double"),
 
568
                };
 
569
                private readonly jlClass clazz;
 
570
                private readonly jlClass type;
 
571
                private readonly MethodInfo box;
 
572
                private readonly MethodInfo unbox;
 
573
                private readonly MethodInfo unboxObject;
 
574
 
 
575
                private BoxUtil(jlClass clazz, jlClass type, MethodInfo box, MethodInfo unbox, MethodInfo unboxObject)
 
576
                {
 
577
                        this.clazz = clazz;
 
578
                        this.type = type;
 
579
                        this.box = box;
 
580
                        this.unbox = unbox;
 
581
                        this.unboxObject = unboxObject;
 
582
                }
 
583
 
 
584
                private static BoxUtil Create<T, P>(jlClass type, string name, string longName)
 
585
                {
 
586
                        return new BoxUtil(ikvm.@internal.ClassLiteral<T>.Value, type,
 
587
                                typeof(T).GetMethod("valueOf", new Type[] { typeof(P) }),
 
588
                                typeof(T).GetMethod(name + "Value", Type.EmptyTypes),
 
589
                                typeof(sun.invoke.util.ValueConversions).GetMethod("unbox" + longName, BindingFlags.Static | BindingFlags.NonPublic));
 
590
                }
 
591
 
 
592
                internal static void Box(CodeEmitter ilgen, jlClass srcClass, jlClass dstClass, int level)
 
593
                {
 
594
                        for (int i = 0; i < boxers.Length; i++)
 
595
                        {
 
596
                                if (boxers[i].type == srcClass)
 
597
                                {
 
598
                                        ilgen.Emit(OpCodes.Call, boxers[i].box);
 
599
                                        EmitConvert(ilgen, boxers[i].clazz, dstClass, level);
 
600
                                        return;
 
601
                                }
 
602
                        }
 
603
                        throw new InvalidOperationException();
 
604
                }
 
605
 
 
606
                internal static void Unbox(CodeEmitter ilgen, jlClass srcClass, jlClass dstClass, int level)
 
607
                {
 
608
                        for (int i = 0; i < boxers.Length; i++)
 
609
                        {
 
610
                                if (boxers[i].clazz == srcClass)
 
611
                                {
 
612
                                        // typed unboxing
 
613
                                        ilgen.Emit(OpCodes.Call, boxers[i].unbox);
 
614
                                        EmitConvert(ilgen, boxers[i].type, dstClass, level);
 
615
                                        return;
 
616
                                }
 
617
                        }
 
618
                        for (int i = 0; i < boxers.Length; i++)
 
619
                        {
 
620
                                if (boxers[i].type == dstClass)
 
621
                                {
 
622
                                        // untyped unboxing
 
623
                                        ilgen.EmitLdc_I4(level > 1 ? 1 : 0);
 
624
                                        ilgen.Emit(OpCodes.Call, boxers[i].unboxObject);
 
625
                                        return;
 
626
                                }
 
627
                        }
 
628
                        throw new InvalidOperationException();
 
629
                }
 
630
        }
 
631
 
 
632
        private static void EmitConvert(CodeEmitter ilgen, java.lang.Class srcClass, java.lang.Class dstClass, int level)
 
633
        {
 
634
                if (srcClass != dstClass)
 
635
                {
 
636
                        TypeWrapper src = TypeWrapper.FromClass(srcClass);
 
637
                        TypeWrapper dst = TypeWrapper.FromClass(dstClass);
 
638
                        src.Finish();
 
639
                        dst.Finish();
 
640
                        if (src.IsNonPrimitiveValueType)
 
641
                        {
 
642
                                src.EmitBox(ilgen);
 
643
                        }
 
644
                        if (dst == PrimitiveTypeWrapper.VOID)
 
645
                        {
 
646
                                ilgen.Emit(OpCodes.Pop);
 
647
                        }
 
648
                        else if (src.IsPrimitive)
 
649
                        {
 
650
                                if (dst.IsPrimitive)
 
651
                                {
 
652
                                        if (src == PrimitiveTypeWrapper.BYTE)
 
653
                                        {
 
654
                                                ilgen.Emit(OpCodes.Conv_I1);
 
655
                                        }
 
656
                                        if (dst == PrimitiveTypeWrapper.FLOAT)
 
657
                                        {
 
658
                                                ilgen.Emit(OpCodes.Conv_R4);
 
659
                                        }
 
660
                                        else if (dst == PrimitiveTypeWrapper.DOUBLE)
 
661
                                        {
 
662
                                                ilgen.Emit(OpCodes.Conv_R8);
 
663
                                        }
 
664
                                        else if (dst == PrimitiveTypeWrapper.LONG)
 
665
                                        {
 
666
                                                if (src == PrimitiveTypeWrapper.FLOAT)
 
667
                                                {
 
668
                                                        ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.f2l);
 
669
                                                }
 
670
                                                else if (src == PrimitiveTypeWrapper.DOUBLE)
 
671
                                                {
 
672
                                                        ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.d2l);
 
673
                                                }
 
674
                                                else
 
675
                                                {
 
676
                                                        ilgen.Emit(OpCodes.Conv_I8);
 
677
                                                }
 
678
                                        }
 
679
                                        else if (dst == PrimitiveTypeWrapper.BOOLEAN)
 
680
                                        {
 
681
                                                if (src == PrimitiveTypeWrapper.FLOAT)
 
682
                                                {
 
683
                                                        ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.f2i);
 
684
                                                }
 
685
                                                else if (src == PrimitiveTypeWrapper.DOUBLE)
 
686
                                                {
 
687
                                                        ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.d2i);
 
688
                                                }
 
689
                                                else
 
690
                                                {
 
691
                                                        ilgen.Emit(OpCodes.Conv_I4);
 
692
                                                }
 
693
                                                ilgen.Emit(OpCodes.Ldc_I4_1);
 
694
                                                ilgen.Emit(OpCodes.And);
 
695
                                        }
 
696
                                        else if (src == PrimitiveTypeWrapper.LONG)
 
697
                                        {
 
698
                                                ilgen.Emit(OpCodes.Conv_I4);
 
699
                                        }
 
700
                                        else if (src == PrimitiveTypeWrapper.FLOAT)
 
701
                                        {
 
702
                                                ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.f2i);
 
703
                                        }
 
704
                                        else if (src == PrimitiveTypeWrapper.DOUBLE)
 
705
                                        {
 
706
                                                ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.d2i);
 
707
                                        }
 
708
                                }
 
709
                                else
 
710
                                {
 
711
                                        BoxUtil.Box(ilgen, srcClass, dstClass, level);
 
712
                                }
 
713
                        }
 
714
                        else if (src.IsGhost)
 
715
                        {
 
716
                                src.EmitConvSignatureTypeToStackType(ilgen);
 
717
                                EmitConvert(ilgen, ikvm.@internal.ClassLiteral<java.lang.Object>.Value, dstClass, level);
 
718
                        }
 
719
                        else if (srcClass == ikvm.@internal.ClassLiteral<sun.invoke.empty.Empty>.Value)
 
720
                        {
 
721
                                ilgen.Emit(OpCodes.Pop);
 
722
                                ilgen.Emit(OpCodes.Ldloc, ilgen.DeclareLocal(dst.TypeAsSignatureType));
 
723
                        }
 
724
                        else if (dst.IsPrimitive)
 
725
                        {
 
726
                                BoxUtil.Unbox(ilgen, srcClass, dstClass, level);
 
727
                        }
 
728
                        else if (dst.IsGhost)
 
729
                        {
 
730
                                dst.EmitConvStackTypeToSignatureType(ilgen, null);
 
731
                        }
 
732
                        else if (dst.IsNonPrimitiveValueType)
 
733
                        {
 
734
                                dst.EmitUnbox(ilgen);
 
735
                        }
 
736
                        else
 
737
                        {
 
738
                                dst.EmitCheckcast(null, ilgen);
 
739
                        }
 
740
                }
 
741
        }
 
742
 
 
743
        internal static void Dump(MethodHandle mh)
 
744
        {
 
745
                Console.WriteLine("----");
 
746
                Dump((Delegate)mh.vmtarget, 0);
 
747
        }
 
748
 
 
749
        private static void WriteNest(int nest)
 
750
        {
 
751
                for (int i = 0; i < nest; i++)
 
752
                {
 
753
                        Console.Write("  ");
 
754
                }
 
755
        }
 
756
 
 
757
        private static void Dump(Delegate d, int nest)
 
758
        {
 
759
                if (nest > 0)
 
760
                {
 
761
                        WriteNest(nest - 1);
 
762
                        Console.Write("->");
 
763
                }
 
764
                Console.Write(d.Method.Name + "(");
 
765
                string sep = "";
 
766
                foreach (ParameterInfo pi in d.Method.GetParameters())
 
767
                {
 
768
                        Console.WriteLine(sep);
 
769
                        WriteNest(nest);
 
770
                        Console.Write("  {0}", TypeToString(pi.ParameterType));
 
771
                        sep = ",";
 
772
                }
 
773
                Console.WriteLine(")");
 
774
                WriteNest(nest);
 
775
                Console.WriteLine("  : {0}", TypeToString(d.Method.ReturnType));
 
776
                if (d.Target is Delegate)
 
777
                {
 
778
                        Dump((Delegate)d.Target, nest == 0 ? 1 : nest);
 
779
                }
 
780
                else if (d.Target != null)
 
781
                {
 
782
                        FieldInfo field = d.Target.GetType().GetField("value");
 
783
                        if (field != null && field.GetValue(d.Target) is Delegate)
 
784
                        {
 
785
                                WriteNest(nest + 1);
 
786
                                Console.WriteLine("Collector:");
 
787
                                Dump((Delegate)field.GetValue(d.Target), nest + 2);
 
788
                        }
 
789
                        field = d.Target.GetType().GetField("target");
 
790
                        if (field != null && field.GetValue(d.Target) != null)
 
791
                        {
 
792
                                Dump((Delegate)field.GetValue(d.Target), nest == 0 ? 1 : nest);
 
793
                        }
 
794
                }
 
795
        }
 
796
 
 
797
        private static string TypeToString(Type type)
 
798
        {
 
799
                if (type.IsGenericType
 
800
                        && type.Namespace == "IKVM.Runtime"
 
801
                        && (type.Name.StartsWith("MH`") || type.Name.StartsWith("MHV`")))
 
802
                {
 
803
                        return type.Name.Substring(0, type.Name.IndexOf('`')) + "<" + TypesToString(type.GetGenericArguments()) + ">";
 
804
                }
 
805
                else if (type.DeclaringType == typeof(DynamicMethodBuilder))
 
806
                {
 
807
                        return "C<" + TypesToString(type.GetGenericArguments()) + ">";
 
808
                }
 
809
                else if (ReflectUtil.IsVector(type))
 
810
                {
 
811
                        return TypeToString(type.GetElementType()) + "[]";
 
812
                }
 
813
                else if (type == typeof(object))
 
814
                {
 
815
                        return "object";
 
816
                }
 
817
                else if (type == typeof(string))
 
818
                {
 
819
                        return "string";
 
820
                }
 
821
                else if (type.IsPrimitive)
 
822
                {
 
823
                        return type.Name.ToLowerInvariant();
 
824
                }
 
825
                else
 
826
                {
 
827
                        return type.ToString();
 
828
                }
 
829
        }
 
830
 
 
831
        private static string TypesToString(Type[] types)
 
832
        {
 
833
                System.Text.StringBuilder sb = new System.Text.StringBuilder();
 
834
                foreach (Type type in types)
 
835
                {
 
836
                        if (sb.Length != 0)
 
837
                        {
 
838
                                sb.Append(", ");
 
839
                        }
 
840
                        sb.Append(TypeToString(type));
 
841
                }
 
842
                return sb.ToString();
 
843
        }
 
844
#endif
 
845
}
 
846
 
 
847
static class Java_java_lang_invoke_AdapterMethodHandle
 
848
{
 
849
        public static MethodHandle makePairwiseConvert(MethodType newType, MethodHandle target, int level)
 
850
        {
 
851
#if FIRST_PASS
 
852
                return null;
 
853
#else
 
854
                MethodType oldType = target.type();
 
855
                MethodHandleUtil.DynamicMethodBuilder dm = new MethodHandleUtil.DynamicMethodBuilder("AdapterMethodHandle.pairwiseConvert", newType, target);
 
856
                for (int i = 0, count = newType.parameterCount(); i < count; i++)
 
857
                {
 
858
                        dm.Ldarg(i);
 
859
                        dm.Convert(newType.parameterType(i), oldType.parameterType(i), level);
 
860
                }
 
861
                dm.CallTarget();
 
862
                dm.Convert(oldType.returnType(), newType.returnType(), level);
 
863
                dm.Ret();
 
864
                return dm.CreateAdapter();
 
865
#endif
 
866
        }
 
867
 
 
868
        public static MethodHandle makeRetype(MethodType newType, MethodHandle target, bool raw)
 
869
        {
 
870
#if FIRST_PASS
 
871
                return null;
 
872
#else
 
873
                MethodType oldType = target.type();
 
874
                if (oldType == newType)
 
875
                {
 
876
                        return target;
 
877
                }
 
878
                if (!AdapterMethodHandle.canRetype(newType, oldType, raw))
 
879
                {
 
880
                        return null;
 
881
                }
 
882
                // TODO does raw translate into a level?
 
883
                return makePairwiseConvert(newType, target, 0);
 
884
#endif
 
885
        }
 
886
 
 
887
        public static MethodHandle makeSpreadArguments(MethodType newType, MethodHandle target, java.lang.Class spreadArgType, int spreadArgPos, int spreadArgCount)
 
888
        {
 
889
#if FIRST_PASS
 
890
                return null;
 
891
#else
 
892
                TypeWrapper twComponent = TypeWrapper.FromClass(spreadArgType).ElementTypeWrapper;
 
893
                MethodHandleUtil.DynamicMethodBuilder dm = new MethodHandleUtil.DynamicMethodBuilder("AdapterMethodHandle.spreadArguments", newType, target);
 
894
                for (int i = 0, count = newType.parameterCount(); i < count; i++)
 
895
                {
 
896
                        if (i == spreadArgPos)
 
897
                        {
 
898
                                for (int j = 0; j < spreadArgCount; j++)
 
899
                                {
 
900
                                        dm.Ldarg(i);
 
901
                                        dm.LoadArrayElement(j, twComponent);
 
902
                                        dm.Convert(twComponent.ClassObject, target.type().parameterType(i + j), 0);
 
903
                                }
 
904
                        }
 
905
                        else
 
906
                        {
 
907
                                dm.Ldarg(i);
 
908
                        }
 
909
                }
 
910
                dm.CallTarget();
 
911
                dm.Ret();
 
912
                return dm.CreateAdapter();
 
913
#endif
 
914
        }
 
915
 
 
916
        public static MethodHandle makeCollectArguments(MethodHandle target, MethodHandle collector, int collectArgPos, bool retainOriginalArgs)
 
917
        {
 
918
#if FIRST_PASS
 
919
                return null;
 
920
#else
 
921
                MethodType targetType = target.type();
 
922
                MethodType collectorType = collector.type();
 
923
                bool isfilter = collectorType.returnType() == java.lang.Void.TYPE;
 
924
                MethodType newType = targetType.dropParameterTypes(collectArgPos, collectArgPos + (isfilter ? 0 : 1));
 
925
                if (!retainOriginalArgs)
 
926
                {
 
927
                        newType = newType.insertParameterTypes(collectArgPos, collectorType.parameterList());
 
928
                }
 
929
                MethodHandleUtil.DynamicMethodBuilder dm = new MethodHandleUtil.DynamicMethodBuilder("AdapterMethodHandle.collectArguments", newType, target, collector.vmtarget);
 
930
                for (int i = 0, count = newType.parameterCount(); i < count || i == collectArgPos; i++)
 
931
                {
 
932
                        if (i == collectArgPos)
 
933
                        {
 
934
                                dm.LoadValue();
 
935
                                for (int j = 0; j < collectorType.parameterCount(); j++)
 
936
                                {
 
937
                                        dm.Ldarg(i + j);
 
938
                                }
 
939
                                dm.CallValue();
 
940
 
 
941
                                collectArgPos = -1;
 
942
                                i--;
 
943
                                if (!retainOriginalArgs)
 
944
                                {
 
945
                                        i += collectorType.parameterCount();
 
946
                                }
 
947
                        }
 
948
                        else
 
949
                        {
 
950
                                dm.Ldarg(i);
 
951
                        }
 
952
                }
 
953
                dm.CallTarget();
 
954
                dm.Ret();
 
955
                return dm.CreateAdapter();
 
956
#endif
 
957
        }
 
958
}
 
959
 
 
960
static class Java_java_lang_invoke_MethodHandleImpl
 
961
{
 
962
        public static MethodHandle permuteArguments(MethodHandle target, MethodType newType, MethodType oldType, int[] permutationOrNull)
 
963
        {
 
964
#if FIRST_PASS
 
965
                return null;
 
966
#else
 
967
                // LAME why does OpenJDK name the parameter permutationOrNull while it is not allowed to be null?
 
968
                if (permutationOrNull.Length != oldType.parameterCount())
 
969
                {
 
970
                        throw new java.lang.IllegalArgumentException("wrong number of arguments in permutation");
 
971
                }
 
972
                MethodHandleUtil.DynamicMethodBuilder dm = new MethodHandleUtil.DynamicMethodBuilder("MethodHandleImpl.permuteArguments", newType, target);
 
973
                for (int i = 0, argCount = newType.parameterCount(); i < permutationOrNull.Length; i++)
 
974
                {
 
975
                        // make sure to only read each array element once, to avoid having to make a defensive copy of the array
 
976
                        int perm = permutationOrNull[i];
 
977
                        if (perm < 0 || perm >= argCount)
 
978
                        {
 
979
                                throw new java.lang.IllegalArgumentException("permutation argument out of range");
 
980
                        }
 
981
                        dm.Ldarg(perm);
 
982
                        dm.Convert(oldType.parameterType(i), newType.parameterType(perm), 0);
 
983
                }
 
984
                dm.CallTarget();
 
985
                dm.Convert(oldType.returnType(), newType.returnType(), 0);
 
986
                dm.Ret();
 
987
                return dm.CreateAdapter();
 
988
#endif
 
989
        }
 
990
}
 
991
 
 
992
static class Java_java_lang_invoke_MethodHandleNatives
 
993
{
 
994
        public static void init(MemberName self, object r)
 
995
        {
 
996
#if !FIRST_PASS
 
997
                if (r is java.lang.reflect.Method || r is java.lang.reflect.Constructor)
 
998
                {
 
999
                        MethodWrapper mw = MethodWrapper.FromMethodOrConstructor(r);
 
1000
                        int index = Array.IndexOf(mw.DeclaringType.GetMethods(), mw);
 
1001
                        if (index != -1)
 
1002
                        {
 
1003
                                // TODO self.setVMIndex(index);
 
1004
                                typeof(MemberName).GetField("vmindex", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(self, index);
 
1005
                                typeof(MemberName).GetField("vmtarget", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(self, mw.DeclaringType);
 
1006
                                int flags = (int)mw.Modifiers;
 
1007
                                if (r is java.lang.reflect.Method)
 
1008
                                {
 
1009
                                        flags |= MemberName.IS_METHOD;
 
1010
                                }
 
1011
                                else
 
1012
                                {
 
1013
                                        flags |= MemberName.IS_CONSTRUCTOR;
 
1014
                                }
 
1015
                                typeof(MemberName).GetField("flags", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(self, flags);
 
1016
                        }
 
1017
                }
 
1018
                else if (r is java.lang.reflect.Field)
 
1019
                {
 
1020
                        FieldWrapper fw = FieldWrapper.FromField(r);
 
1021
                        int index = Array.IndexOf(fw.DeclaringType.GetFields(), fw);
 
1022
                        if (index != -1)
 
1023
                        {
 
1024
                                // TODO self.setVMIndex(index);
 
1025
                                typeof(MemberName).GetField("vmindex", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(self, index);
 
1026
                                typeof(MemberName).GetField("flags", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(self, (int)fw.Modifiers | MemberName.IS_FIELD);
 
1027
                        }
 
1028
                }
 
1029
                else
 
1030
                {
 
1031
                        throw new InvalidOperationException();
 
1032
                }
 
1033
#endif
 
1034
        }
 
1035
 
 
1036
        public static void expand(MemberName self)
 
1037
        {
 
1038
                throw new NotImplementedException();
 
1039
        }
 
1040
 
 
1041
        public static void resolve(MemberName self, jlClass caller)
 
1042
        {
 
1043
#if !FIRST_PASS
 
1044
                if (self.isMethod() || self.isConstructor())
 
1045
                {
 
1046
                        TypeWrapper tw = TypeWrapper.FromClass(self.getDeclaringClass());
 
1047
                        if (tw == CoreClasses.java.lang.invoke.MethodHandle.Wrapper
 
1048
                                && (self.getName() == "invoke" || self.getName() == "invokeExact"))
 
1049
                        {
 
1050
                                typeof(MemberName).GetField("vmindex", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(self, Int32.MaxValue);
 
1051
                                return;
 
1052
                        }
 
1053
                        MethodWrapper mw = tw.GetMethodWrapper(self.getName(), self.getSignature().Replace('/', '.'), true);
 
1054
                        if (mw != null)
 
1055
                        {
 
1056
                                tw = mw.DeclaringType;
 
1057
                                int index = Array.IndexOf(tw.GetMethods(), mw);
 
1058
                                if (index != -1)
 
1059
                                {
 
1060
                                        // TODO self.setVMIndex(index);
 
1061
                                        typeof(MemberName).GetField("vmindex", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(self, index);
 
1062
                                        typeof(MemberName).GetField("vmtarget", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(self, tw);
 
1063
                                        int flags = (int)mw.Modifiers;
 
1064
                                        if (self.isMethod())
 
1065
                                        {
 
1066
                                                flags |= MemberName.IS_METHOD;
 
1067
                                        }
 
1068
                                        else
 
1069
                                        {
 
1070
                                                flags |= MemberName.IS_CONSTRUCTOR;
 
1071
                                        }
 
1072
                                        typeof(MemberName).GetField("flags", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(self, flags);
 
1073
                                }
 
1074
                        }
 
1075
                }
 
1076
                else if (self.isField())
 
1077
                {
 
1078
                        TypeWrapper tw = TypeWrapper.FromClass(self.getDeclaringClass());
 
1079
                        // TODO should we look in base classes?
 
1080
                        FieldWrapper fw = tw.GetFieldWrapper(self.getName(), self.getSignature().Replace('/', '.'));
 
1081
                        if (fw != null)
 
1082
                        {
 
1083
                                int index = Array.IndexOf(fw.DeclaringType.GetFields(), fw);
 
1084
                                if (index != -1)
 
1085
                                {
 
1086
                                        // TODO self.setVMIndex(index);
 
1087
                                        typeof(MemberName).GetField("vmindex", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(self, index);
 
1088
                                        typeof(MemberName).GetField("flags", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(self, (int)fw.Modifiers | MemberName.IS_FIELD);
 
1089
                                }
 
1090
                        }
 
1091
                }
 
1092
                else
 
1093
                {
 
1094
                        throw new InvalidOperationException();
 
1095
                }
 
1096
#endif
 
1097
        }
 
1098
 
 
1099
        public static int getMembers(jlClass defc, string matchName, string matchSig, int matchFlags, jlClass caller, int skip, object[] results)
 
1100
        {
 
1101
                return 1;
 
1102
        }
 
1103
}