IKVM11  11
Java SE 11 Virtual Machine for .NET
Loading...
Searching...
No Matches
JNIEnv.cs
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2014 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*/
24using System;
25using System.Collections.Generic;
26using System.Diagnostics;
27using System.Reflection;
29using System.Runtime.ExceptionServices;
30using System.Runtime.InteropServices;
31using System.Runtime.Serialization;
32
33using IKVM.ByteCode.Text;
36
37namespace IKVM.Runtime.JNI
38{
39
40 using jboolean = System.SByte;
41 using jbyte = System.SByte;
42 using jchar = System.UInt16;
43 using jdouble = System.Double;
44 using jfloat = System.Single;
45 using jint = System.Int32;
46 using jlong = System.Int64;
47 using jshort = System.Int16;
48 using jsize = System.Int32;
49
50#if FIRST_PASS == false && IMPORTER == false && EXPORTER == false
51
52 [StructLayout(LayoutKind.Sequential)]
53 unsafe partial struct JNIEnv
54 {
55
56 internal const string METHOD_PTR_FIELD_PREFIX = "__<jniptr>";
57
58 internal const int JNI_OK = 0;
59 internal const int JNI_ERR = -1;
60 internal const int JNI_EDETACHED = -2;
61 internal const int JNI_EVERSION = -3;
62 internal const int JNI_COMMIT = 1;
63 internal const int JNI_ABORT = 2;
64 internal const int JNI_VERSION_1_1 = 0x00010001;
65 internal const int JNI_VERSION_1_2 = 0x00010002;
66 internal const int JNI_VERSION_1_4 = 0x00010004;
67 internal const int JNI_VERSION_1_6 = 0x00010006;
68 internal const int JNI_VERSION_1_8 = 0x00010008;
69 internal const int JNIInvalidRefType = 0;
70 internal const int JNILocalRefType = 1;
71 internal const int JNIGlobalRefType = 2;
72 internal const int JNIWeakGlobalRefType = 3;
73 internal const jboolean JNI_TRUE = 1;
74 internal const jboolean JNI_FALSE = 0;
75
76 static readonly MUTF8Encoding MUTF8 = MUTF8Encoding.GetMUTF8(52);
77
78 internal void* vtable;
79 internal GCHandle context;
80 internal GCHandle* pinHandles;
81 internal int pinHandleMaxCount;
82 internal int pinHandleInUseCount;
83
88 internal JNIEnvContext GetContext()
89 {
90 return (JNIEnvContext)context.Target;
91 }
92
98 internal static JNIEnv* CreateJNIEnv(RuntimeContext context)
99 {
100 var env = JNIEnvContext.Current = new JNIEnvContext(context);
101 var jniEnvPtr = env.pJNIEnv;
102 jniEnvPtr->vtable = JNINativeInterface.Handle;
103 jniEnvPtr->context = GCHandle.Alloc(env, GCHandleType.WeakTrackResurrection);
104 jniEnvPtr->pinHandles = null;
105 jniEnvPtr->pinHandleMaxCount = 0;
106 jniEnvPtr->pinHandleInUseCount = 0;
107 return jniEnvPtr;
108 }
109
113 internal static void FreeJNIEnv()
114 {
115 JNIEnvContext.Current = null;
116 }
117
125 internal static string DecodeMUTF8Argument(byte* psz, string arg)
126 {
127 if (psz is null)
128 return null;
129
131 if (l < 0)
132 throw new java.lang.IllegalArgumentException(arg);
133
134 var v = MUTF8.GetString(psz, l);
135 return v;
136 }
137
144 internal static string DecodeMUTF8(byte* psz)
145 {
146 if (psz is null)
147 return null;
148
150 if (l < 0)
151 throw new java.lang.IllegalArgumentException();
152
153 var v = MUTF8.GetString(psz, l);
154 return v;
155 }
156
164 internal static int GetMethodArgs(JNIEnv* pEnv, nint methodID, byte* sig)
165 {
166 var args = RuntimeJavaMethod.FromCookie(methodID).GetParameters();
167 for (var i = 0; i < args.Length; i++)
168 sig[i] = args[i].IsPrimitive ? (byte)args[i].SigName[0] : (byte)'L';
169
170 return args.Length;
171 }
172
173 internal static int GetVersion(JNIEnv* pEnv)
174 {
175 return JNI_VERSION_1_8;
176 }
177
178 internal static nint DefineClass(JNIEnv* pEnv, byte* name, nint loader, jbyte* pbuf, jint length)
179 {
180 try
181 {
182 var buf = new byte[length];
183 Marshal.Copy((nint)(void*)pbuf, buf, 0, length);
184 // TODO what should the protection domain be?
185 // NOTE I'm assuming name is platform encoded (as opposed to UTF-8), but the Sun JVM only seems to work for ASCII.
186 var classLoader = (java.lang.ClassLoader)pEnv->UnwrapRef(loader);
187 return pEnv->MakeLocalRef(IKVM.Java.Externs.java.lang.ClassLoader.defineClass0(classLoader, name != null ? DecodeMUTF8Argument(name, nameof(name)) : null, buf, 0, buf.Length, null));
188 }
189 catch (Exception e)
190 {
191 JVM.SetPendingException(e);
192 return 0;
193 }
194 }
195
197 {
198 var env = pEnv->GetContext();
199 if (env.callerID != null)
200 return RuntimeClassLoader.FromCallerID(env.callerID);
201 else if (env.classLoader != null)
202 return env.classLoader;
203 else
204 return env.context.ClassLoaderFactory.GetClassLoaderWrapper(java.lang.ClassLoader.getSystemClassLoader());
205 }
206
207 internal static nint FindClass(JNIEnv* pEnv, byte* name)
208 {
209 try
210 {
211 try
212 {
213 var n = DecodeMUTF8Argument(name, nameof(name));
214
215 // don't allow dotted names!
216 if (n.Contains("."))
217 throw new java.lang.NoClassDefFoundError(n);
218
219 // spec doesn't say it, but Sun allows signature format class names (but not for primitives)
220 if (n.StartsWith("L") && n.EndsWith(";"))
221 n = n.Substring(1, n.Length - 2);
222
223 var w = FindNativeMethodClassLoader(pEnv).TryLoadClassByName(n.Replace('/', '.'));
224 if (w == null)
225 throw new java.lang.NoClassDefFoundError(n);
226
227 w.Finish();
228 w.RunClassInit(); // spec doesn't say it, but Sun runs the static initializer
229 return pEnv->MakeLocalRef(w.ClassObject);
230 }
232 {
233 ExceptionDispatchInfo.Capture(e.ToJava()).Throw();
234 throw null;
235 }
236 }
237 catch (Exception e)
238 {
239 JVM.SetPendingException(e);
240 return 0;
241 }
242 }
243
244 internal static nint FromReflectedMethod(JNIEnv* pEnv, nint method)
245 {
246 try
247 {
248 return RuntimeJavaMethod.FromExecutable((java.lang.reflect.Executable)pEnv->UnwrapRef(method)).Cookie;
249 }
250 catch (Exception e)
251 {
252 JVM.SetPendingException(e);
253 return 0;
254 }
255 }
256
257 internal static nint FromReflectedField(JNIEnv* pEnv, nint field)
258 {
259 try
260 {
261 return RuntimeJavaField.FromField((java.lang.reflect.Field)pEnv->UnwrapRef(field)).Cookie;
262 }
263 catch (Exception e)
264 {
265 JVM.SetPendingException(e);
266 return 0;
267 }
268 }
269
270 internal static nint ToReflectedMethod(JNIEnv* pEnv, nint clazz_ignored, nint method, sbyte isStatic)
271 {
272 try
273 {
274 return pEnv->MakeLocalRef(RuntimeJavaMethod.FromCookie(method).ToMethodOrConstructor(true));
275 }
276 catch (Exception e)
277 {
278 JVM.SetPendingException(e);
279 return 0;
280 }
281 }
282
283 internal static nint GetSuperclass(JNIEnv* pEnv, nint sub)
284 {
285 try
286 {
287 var wrapper = RuntimeJavaType.FromClass((java.lang.Class)pEnv->UnwrapRef(sub)).BaseTypeWrapper;
288 return pEnv->MakeLocalRef(wrapper == null ? null : wrapper.ClassObject);
289 }
290 catch (Exception e)
291 {
292 JVM.SetPendingException(e);
293 return 0;
294 }
295 }
296
297 internal static sbyte IsAssignableFrom(JNIEnv* pEnv, nint sub, nint super)
298 {
299 try
300 {
301 var w1 = RuntimeJavaType.FromClass((java.lang.Class)pEnv->UnwrapRef(sub));
302 var w2 = RuntimeJavaType.FromClass((java.lang.Class)pEnv->UnwrapRef(super));
303 return w1.IsAssignableTo(w2) ? JNI_TRUE : JNI_FALSE;
304 }
305 catch (Exception e)
306 {
307 JVM.SetPendingException(e);
308 return 0;
309 }
310 }
311
312 internal static nint ToReflectedField(JNIEnv* pEnv, nint clazz_ignored, nint field, jboolean isStatic)
313 {
314 try
315 {
316 return pEnv->MakeLocalRef(RuntimeJavaField.FromCookie(field).ToField(true));
317 }
318 catch (Exception e)
319 {
320 JVM.SetPendingException(e);
321 return 0;
322 }
323 }
324
325 internal static jint Throw(JNIEnv* pEnv, nint throwable)
326 {
327 try
328 {
329 var env = pEnv->GetContext();
330 var e = UnwrapRef(env, throwable) as Exception;
331 if (e != null)
332 JVM.SetPendingException(e);
333
334 return JNI_OK;
335 }
336 catch (Exception e)
337 {
338 JVM.SetPendingException(e);
339 return JNI_ERR;
340 }
341 }
342
343 internal static jint ThrowNew(JNIEnv* pEnv, nint clazz, byte* msg)
344 {
345 try
346 {
347 var env = pEnv->GetContext();
348 var wrapper = RuntimeJavaType.FromClass((java.lang.Class)UnwrapRef(env, clazz));
349 var mw = wrapper.GetMethod("<init>", msg == null ? "()V" : "(Ljava.lang.String;)V", false);
350 if (mw != null)
351 {
352 try
353 {
354 wrapper.Finish();
355 var cons = (java.lang.reflect.Constructor)mw.ToMethodOrConstructor(false);
356 JVM.SetPendingException((Exception)cons.newInstance(msg == null ? new object[0] : new object[] { DecodeMUTF8Argument(msg, nameof(msg)) }, env.callerID));
357 return JNI_OK;
358 }
360 {
361 ExceptionDispatchInfo.Capture(x.ToJava()).Throw();
362 throw null;
363 }
364 }
365 else
366 {
367 throw new java.lang.NoSuchMethodError("<init>(Ljava.lang.String;)V");
368 }
369 }
370 catch (Exception e)
371 {
372 JVM.SetPendingException(e);
373 return JNI_ERR;
374 }
375 }
376
382 internal static nint ExceptionOccurred(JNIEnv* pEnv)
383 {
384 try
385 {
386 return pEnv->MakeLocalRef(JVM.GetPendingException());
387 }
388 catch (Exception e)
389 {
390 JVM.SetPendingException(e);
391 return 0;
392 }
393 }
394
399 internal static void ExceptionDescribe(JNIEnv* pEnv)
400 {
401 try
402 {
403 var x = JVM.GetPendingException();
404 if (x != null)
405 {
406 JVM.SetPendingException(null);
407
408 try
409 {
410 ikvm.extensions.ExtensionMethods.printStackTrace(x);
411 }
412 catch (Exception ex)
413 {
414 Debug.Assert(false, ex.ToString());
415 }
416 }
417 }
418 catch (Exception e)
419 {
420 JVM.SetPendingException(e);
421 }
422 }
423
428 internal static void ExceptionClear(JNIEnv* pEnv)
429 {
430 try
431 {
432 JVM.SetPendingException(null);
433 }
434 catch (Exception e)
435 {
436 JVM.SetPendingException(e);
437 }
438 }
439
445 internal static void FatalError(JNIEnv* pEnv, byte* msg)
446 {
447 Console.Error.WriteLine("FATAL ERROR in native method: {0}", msg == null ? "(null)" : DecodeMUTF8Argument(msg, nameof(msg)));
448 Console.Error.WriteLine(new StackTrace(1, true));
449 System.Environment.Exit(1);
450 }
451
458 internal static jint PushLocalFrame(JNIEnv* pEnv, jint capacity)
459 {
460 try
461 {
462 return pEnv->GetContext().PushLocalFrame(capacity);
463 }
464 catch (Exception e)
465 {
466 JVM.SetPendingException(e);
467 return 0;
468 }
469 }
470
477 internal static nint PopLocalFrame(JNIEnv* pEnv, nint result)
478 {
479 try
480 {
481 var env = pEnv->GetContext();
482 return env.PopLocalFrame(UnwrapRef(env, result));
483 }
484 catch (Exception e)
485 {
486 JVM.SetPendingException(e);
487 return 0;
488 }
489 }
490
497 internal static nint NewGlobalRef(JNIEnv* pEnv, nint obj)
498 {
499 try
500 {
501 var o = pEnv->UnwrapRef(obj);
502 return o == null ? 0 : JNIGlobalRefTable.AddGlobalRef(o);
503 }
504 catch (Exception e)
505 {
506 JVM.SetPendingException(e);
507 return 0;
508 }
509 }
510
516 internal static void DeleteGlobalRef(JNIEnv* pEnv, nint obj)
517 {
518 try
519 {
520 if (IsGlobalRef(obj))
521 {
523 return;
524 }
525
526 if (IsLocalRef(obj))
527 Debug.Assert(false, "Local ref passed to DeleteGlobalRef");
528 }
529 catch (Exception e)
530 {
531 JVM.SetPendingException(e);
532 }
533 }
534
540 internal static void DeleteLocalRef(JNIEnv* pEnv, nint obj)
541 {
542 try
543 {
544 pEnv->GetContext().DeleteLocalRef(obj);
545 }
546 catch (Exception e)
547 {
548 JVM.SetPendingException(e);
549 }
550 }
551
559 internal static jboolean IsSameObject(JNIEnv* pEnv, nint obj1, nint obj2)
560 {
561 try
562 {
563 return pEnv->UnwrapRef(obj1) == pEnv->UnwrapRef(obj2) ? JNI_TRUE : JNI_FALSE;
564 }
565 catch (Exception e)
566 {
567 JVM.SetPendingException(e);
568 return 0;
569 }
570 }
571
578 internal static nint NewLocalRef(JNIEnv* pEnv, nint obj)
579 {
580 try
581 {
582 return pEnv->MakeLocalRef(pEnv->UnwrapRef(obj));
583 }
584 catch (Exception e)
585 {
586 JVM.SetPendingException(e);
587 return 0;
588 }
589 }
590
597 internal static jint EnsureLocalCapacity(JNIEnv* pEnv, jint capacity)
598 {
599 // since we can dynamically grow the local ref table, we'll just return success for any number
600 return JNI_OK;
601 }
602
609 internal static nint AllocObject(JNIEnv* pEnv, nint clazz)
610 {
611 try
612 {
613 return AllocObjectImpl(pEnv, RuntimeJavaType.FromClass((java.lang.Class)pEnv->UnwrapRef(clazz)));
614 }
615 catch (Exception e)
616 {
617 JVM.SetPendingException(e);
618 return 0;
619 }
620 }
621
622 static nint AllocObjectImpl(JNIEnv* pEnv, RuntimeJavaType wrapper)
623 {
624 try
625 {
626 if (wrapper.IsAbstract)
627 throw new java.lang.InstantiationException(wrapper.Name);
628
629 wrapper.Finish();
630#if NETFRAMEWORK
631 return pEnv->MakeLocalRef(FormatterServices.GetUninitializedObject(wrapper.TypeAsBaseType));
632#else
633 return pEnv->MakeLocalRef(RuntimeHelpers.GetUninitializedObject(wrapper.TypeAsBaseType));
634#endif
635 }
637 {
638 ExceptionDispatchInfo.Capture(e.ToJava()).Throw();
639 throw null;
640 }
641 }
642
652 static object InvokeHelper(JNIEnv* pEnv, nint objHandle, nint methodID, JValue* pArgs, bool nonVirtual)
653 {
654 // resolve object who's method is being invoked
655 var env = pEnv->GetContext();
656 var obj = UnwrapRef(env, objHandle);
657
658 // resolve the method being invoked on the object
659 var mw = RuntimeJavaMethod.FromCookie(methodID);
660 mw.Link();
661 mw.ResolveMethod();
662
663 // assemble arguments into array
664 var argTypes = mw.GetParameters();
665 var args = new object[argTypes.Length + (mw.HasCallerID ? 1 : 0)];
666 for (int i = 0; i < argTypes.Length; i++)
667 {
668 var type = argTypes[i];
669 if (type == env.context.PrimitiveJavaTypeFactory.BOOLEAN)
670 args[i] = pArgs[i].z != JNI_FALSE;
671 else if (type == env.context.PrimitiveJavaTypeFactory.BYTE)
672 args[i] = (byte)pArgs[i].b;
673 else if (type == env.context.PrimitiveJavaTypeFactory.CHAR)
674 args[i] = (char)pArgs[i].c;
675 else if (type == env.context.PrimitiveJavaTypeFactory.SHORT)
676 args[i] = pArgs[i].s;
677 else if (type == env.context.PrimitiveJavaTypeFactory.INT)
678 args[i] = pArgs[i].i;
679 else if (type == env.context.PrimitiveJavaTypeFactory.LONG)
680 args[i] = pArgs[i].j;
681 else if (type == env.context.PrimitiveJavaTypeFactory.FLOAT)
682 args[i] = pArgs[i].f;
683 else if (type == env.context.PrimitiveJavaTypeFactory.DOUBLE)
684 args[i] = pArgs[i].d;
685 else
686 args[i] = argTypes[i].GhostWrap(UnwrapRef(env, pArgs[i].l));
687 }
688
689 // method requires caller
690 if (mw.HasCallerID)
691 args[args.Length - 1] = env.callerID;
692
693 if (nonVirtual && mw.RequiresNonVirtualDispatcher)
694 return InvokeNonVirtual(env, mw, obj, args);
695
696 if (mw.IsConstructor)
697 {
698 if (obj == null)
699 {
700 return mw.CreateInstance(args);
701 }
702 else
703 {
704 var mb = mw.GetMethod();
705 if (mb.IsStatic)
706 {
707 // we're dealing with a constructor on a remapped type, if obj is supplied, it means
708 // that we should call the constructor on an already existing instance, but that isn't
709 // possible with remapped types
710 throw new NotSupportedException($"Remapped type {mw.DeclaringType.Name} doesn't support constructor invocation on an existing instance");
711 }
712 else if (!mb.DeclaringType.IsInstanceOfType(obj))
713 {
714 // we're trying to initialize an existing instance of a remapped type
715 throw new NotSupportedException($"Unable to partially construct object of type {obj.GetType().FullName} to type {mb.DeclaringType.FullName}");
716 }
717 }
718 }
719
720 return mw.Invoke(obj, args);
721 }
722
732 static object InvokeNonVirtual(JNIEnvContext env, RuntimeJavaMethod mw, object obj, object[] argarray)
733 {
734 if (mw.HasCallerID || mw.IsDynamicOnly)
735 throw new NotSupportedException();
736
737 if (mw.DeclaringType.IsRemapped && !mw.DeclaringType.TypeAsBaseType.IsInstanceOfType(obj))
738 return mw.InvokeNonvirtualRemapped(obj, argarray);
739
740 var del = (Delegate)Activator.CreateInstance(mw.GetDelegateType(), new object[] { obj, mw.GetMethod().MethodHandle.GetFunctionPointer() });
741 try
742 {
743 return del.DynamicInvoke(argarray);
744 }
745 catch (TargetInvocationException e)
746 {
747 ExceptionDispatchInfo.Capture(ikvm.runtime.Util.mapException(e.InnerException)).Throw();
748 throw null;
749 }
750 }
751
752 public static nint NewObjectA(JNIEnv* pEnv, nint clazz, nint methodID, JValue* args)
753 {
754 try
755 {
756 var wrapper = RuntimeJavaType.FromClass((java.lang.Class)pEnv->UnwrapRef(clazz));
757 if (wrapper.IsAbstract == false && wrapper.TypeAsBaseType.IsAbstract)
758 return pEnv->MakeLocalRef(InvokeHelper(pEnv, IntPtr.Zero, methodID, args, false)); // static newinstance helper method
759
760 var obj = AllocObjectImpl(pEnv, wrapper);
761 if (obj != IntPtr.Zero)
762 {
763 InvokeHelper(pEnv, obj, methodID, args, false);
764
765 if (ExceptionCheck(pEnv) == JNI_TRUE)
766 {
767 DeleteLocalRef(pEnv, obj);
768 obj = IntPtr.Zero;
769 }
770 }
771
772 return obj;
773 }
774 catch (Exception e)
775 {
776 JVM.SetPendingException(e);
777 return 0;
778 }
779 }
780
781 internal static nint GetObjectClass(JNIEnv* pEnv, nint obj)
782 {
783 try
784 {
785 return pEnv->MakeLocalRef(IKVM.Java.Externs.ikvm.runtime.Util.getClassFromObject(pEnv->UnwrapRef(obj)));
786 }
787 catch (Exception e)
788 {
789 JVM.SetPendingException(e);
790 return 0;
791 }
792 }
793
794 internal static jboolean IsInstanceOf(JNIEnv* pEnv, nint obj, nint clazz)
795 {
796 try
797 {
798 // NOTE if clazz is an interface, this is still the right thing to do
799 // (i.e. if the object implements the interface, we return true)
800 var objClass = IKVM.Java.Externs.ikvm.runtime.Util.getClassFromObject(pEnv->UnwrapRef(obj));
801 var w1 = RuntimeJavaType.FromClass((java.lang.Class)pEnv->UnwrapRef(clazz));
802 var w2 = RuntimeJavaType.FromClass(objClass);
803 return w2.IsAssignableTo(w1) ? JNI_TRUE : JNI_FALSE;
804 }
805 catch (Exception e)
806 {
807 JVM.SetPendingException(e);
808 return 0;
809 }
810 }
811
812 static RuntimeJavaMethod GetMethodImpl(RuntimeJavaType tw, string name, string sig)
813 {
814 for (; ; )
815 {
816 var mw = tw.GetMethod(name, sig, true);
817 if (mw == null || !mw.IsHideFromReflection)
818 return mw;
819
820 tw = mw.DeclaringType.BaseTypeWrapper;
821 if (tw == null)
822 return null;
823 }
824 }
825
826 static void AppendInterfaces(List<RuntimeJavaType> list, IList<RuntimeJavaType> add)
827 {
828 foreach (var iface in add)
829 if (list.Contains(iface) == false)
830 list.Add(iface);
831 }
832
833 static List<RuntimeJavaType> TransitiveInterfaces(RuntimeJavaType tw)
834 {
835 var list = new List<RuntimeJavaType>();
836
837 // append interfaces from base type
838 if (tw.BaseTypeWrapper != null)
839 AppendInterfaces(list, TransitiveInterfaces(tw.BaseTypeWrapper));
840
841 // append transitive interfaces of current type
842 foreach (RuntimeJavaType iface in tw.Interfaces)
844
845 // append interfaces of current type
846 AppendInterfaces(list, tw.Interfaces);
847
848 return list;
849 }
850
851 static RuntimeJavaMethod GetInterfaceMethodImpl(RuntimeJavaType tw, string name, string sig)
852 {
853 foreach (var iface in TransitiveInterfaces(tw))
854 {
855 var mw = iface.GetMethod(name, sig, false);
856 if (mw != null && !mw.IsHideFromReflection)
857 return mw;
858 }
859
860 return null;
861 }
862
863 static nint FindMethodID(JNIEnv* pEnv, nint clazz, byte* name, byte* sig, bool isStatic)
864 {
865 try
866 {
867 var tw = RuntimeJavaType.FromClass((java.lang.Class)pEnv->UnwrapRef(clazz));
868 tw.Finish();
869
870 // if name == NULL, the JDK returns the constructor
871 var methodname = (IntPtr)name == IntPtr.Zero ? "<init>" : DecodeMUTF8Argument(name, nameof(name));
872 var methodsig = DecodeMUTF8Argument(sig, nameof(sig));
873
874 RuntimeJavaMethod mw = null;
875
876 // don't allow dotted names!
877 if (methodsig.IndexOf('.') < 0)
878 {
879 methodsig = methodsig.Replace('/', '.');
880 if (methodname == "<init>" || methodname == "<clinit>")
881 mw = tw.GetMethod(methodname, methodsig, false);
882 else
883 mw = GetMethodImpl(tw, methodname, methodsig) ?? GetInterfaceMethodImpl(tw, methodname, methodsig);
884 }
885 if (mw != null && mw.IsStatic == isStatic)
886 {
887 mw.Link();
888 return mw.Cookie;
889 }
890
891 throw new java.lang.NoSuchMethodError($"{methodname}{methodsig}");
892 }
894 {
895 ExceptionDispatchInfo.Capture(e.ToJava()).Throw();
896 throw null;
897 }
898 }
899
900 internal static nint GetMethodID(JNIEnv* pEnv, nint clazz, byte* name, byte* sig)
901 {
902 try
903 {
904 return FindMethodID(pEnv, clazz, name, sig, false);
905 }
906 catch (Exception e)
907 {
908 JVM.SetPendingException(e);
909 return 0;
910 }
911 }
912
913 internal static nint CallObjectMethodA(JNIEnv* pEnv, nint obj, nint methodID, JValue* args)
914 {
915 try
916 {
917 return pEnv->MakeLocalRef(InvokeHelper(pEnv, obj, methodID, args, false));
918 }
919 catch (Exception e)
920 {
921 JVM.SetPendingException(e);
922 return 0;
923 }
924 }
925
926 internal static jboolean CallBooleanMethodA(JNIEnv* pEnv, nint obj, nint methodID, JValue* args)
927 {
928 try
929 {
930 var o = InvokeHelper(pEnv, obj, methodID, args, false);
931 if (o != null)
932 return ((bool)o) ? JNI_TRUE : JNI_FALSE;
933
934 return JNI_FALSE;
935 }
936 catch (Exception e)
937 {
938 JVM.SetPendingException(e);
939 return 0;
940 }
941 }
942
943 internal static jbyte CallByteMethodA(JNIEnv* pEnv, nint obj, nint methodID, JValue* args)
944 {
945 try
946 {
947 var o = InvokeHelper(pEnv, obj, methodID, args, false);
948 if (o != null)
949 return (jbyte)(byte)o;
950
951 return 0;
952 }
953 catch (Exception e)
954 {
955 JVM.SetPendingException(e);
956 return 0;
957 }
958 }
959
960 internal static jchar CallCharMethodA(JNIEnv* pEnv, nint obj, nint methodID, JValue* args)
961 {
962 try
963 {
964 var o = InvokeHelper(pEnv, obj, methodID, args, false);
965 if (o != null)
966 return (jchar)(char)o;
967
968 return 0;
969 }
970 catch (Exception e)
971 {
972 JVM.SetPendingException(e);
973 return 0;
974 }
975 }
976
977 internal static jshort CallShortMethodA(JNIEnv* pEnv, nint obj, nint methodID, JValue* args)
978 {
979 try
980 {
981 var o = InvokeHelper(pEnv, obj, methodID, args, false);
982 if (o != null)
983 return (jshort)(short)o;
984
985 return 0;
986 }
987 catch (Exception e)
988 {
989 JVM.SetPendingException(e);
990 return 0;
991 }
992 }
993
994 internal static jint CallIntMethodA(JNIEnv* pEnv, nint obj, nint methodID, JValue* args)
995 {
996 try
997 {
998 var o = InvokeHelper(pEnv, obj, methodID, args, false);
999 if (o != null)
1000 return (jint)(int)o;
1001
1002 return 0;
1003 }
1004 catch (Exception e)
1005 {
1006 JVM.SetPendingException(e);
1007 return 0;
1008 }
1009 }
1010
1011 internal static jlong CallLongMethodA(JNIEnv* pEnv, nint obj, nint methodID, JValue* args)
1012 {
1013 try
1014 {
1015 var o = InvokeHelper(pEnv, obj, methodID, args, false);
1016 if (o != null)
1017 return (jlong)(long)o;
1018
1019 return 0;
1020 }
1021 catch (Exception e)
1022 {
1023 JVM.SetPendingException(e);
1024 return 0;
1025 }
1026 }
1027
1028 internal static jfloat CallFloatMethodA(JNIEnv* pEnv, nint obj, nint methodID, JValue* args)
1029 {
1030 try
1031 {
1032 var o = InvokeHelper(pEnv, obj, methodID, args, false);
1033 if (o != null)
1034 return (jfloat)(float)o;
1035
1036 return 0;
1037 }
1038 catch (Exception e)
1039 {
1040 JVM.SetPendingException(e);
1041 return 0;
1042 }
1043 }
1044
1045 internal static jdouble CallDoubleMethodA(JNIEnv* pEnv, nint obj, nint methodID, JValue* args)
1046 {
1047 try
1048 {
1049 var o = InvokeHelper(pEnv, obj, methodID, args, false);
1050 if (o != null)
1051 return (jdouble)(double)o;
1052
1053 return 0;
1054 }
1055 catch (Exception e)
1056 {
1057 JVM.SetPendingException(e);
1058 return 0;
1059 }
1060 }
1061
1062 internal static void CallVoidMethodA(JNIEnv* pEnv, nint obj, nint methodID, JValue* args)
1063 {
1064 try
1065 {
1066 InvokeHelper(pEnv, obj, methodID, args, false);
1067 }
1068 catch (Exception e)
1069 {
1070 JVM.SetPendingException(e);
1071 }
1072 }
1073
1074 internal static nint CallNonvirtualObjectMethodA(JNIEnv* pEnv, nint obj, nint clazz, nint methodID, JValue* args)
1075 {
1076 try
1077 {
1078 return pEnv->MakeLocalRef(InvokeHelper(pEnv, obj, methodID, args, true));
1079 }
1080 catch (Exception e)
1081 {
1082 JVM.SetPendingException(e);
1083 return 0;
1084 }
1085 }
1086
1087 internal static jboolean CallNonvirtualBooleanMethodA(JNIEnv* pEnv, nint obj, nint clazz, nint methodID, JValue* args)
1088 {
1089 try
1090 {
1091 var o = InvokeHelper(pEnv, obj, methodID, args, true);
1092 if (o != null)
1093 return ((bool)o) ? JNI_TRUE : JNI_FALSE;
1094
1095 return JNI_FALSE;
1096 }
1097 catch (Exception e)
1098 {
1099 JVM.SetPendingException(e);
1100 return 0;
1101 }
1102 }
1103
1104 internal static jbyte CallNonvirtualByteMethodA(JNIEnv* pEnv, nint obj, nint clazz, nint methodID, JValue* args)
1105 {
1106 try
1107 {
1108 var o = InvokeHelper(pEnv, obj, methodID, args, true);
1109 if (o != null)
1110 return (jbyte)(byte)o;
1111
1112 return 0;
1113 }
1114 catch (Exception e)
1115 {
1116 JVM.SetPendingException(e);
1117 return 0;
1118 }
1119 }
1120
1121 internal static jchar CallNonvirtualCharMethodA(JNIEnv* pEnv, nint obj, nint clazz, nint methodID, JValue* args)
1122 {
1123 try
1124 {
1125 var o = InvokeHelper(pEnv, obj, methodID, args, true);
1126 if (o != null)
1127 return (jchar)(char)o;
1128
1129 return 0;
1130 }
1131 catch (Exception e)
1132 {
1133 JVM.SetPendingException(e);
1134 return 0;
1135 }
1136 }
1137
1138 internal static jshort CallNonvirtualShortMethodA(JNIEnv* pEnv, nint obj, nint clazz, nint methodID, JValue* args)
1139 {
1140 try
1141 {
1142 var o = InvokeHelper(pEnv, obj, methodID, args, true);
1143 if (o != null)
1144 return (jshort)(short)o;
1145
1146 return 0;
1147 }
1148 catch (Exception e)
1149 {
1150 JVM.SetPendingException(e);
1151 return 0;
1152 }
1153 }
1154
1155 internal static jint CallNonvirtualIntMethodA(JNIEnv* pEnv, nint obj, nint clazz, nint methodID, JValue* args)
1156 {
1157 try
1158 {
1159 var o = InvokeHelper(pEnv, obj, methodID, args, true);
1160 if (o != null)
1161 return (jint)(int)o;
1162
1163 return 0;
1164 }
1165 catch (Exception e)
1166 {
1167 JVM.SetPendingException(e);
1168 return 0;
1169 }
1170 }
1171
1172 internal static jlong CallNonvirtualLongMethodA(JNIEnv* pEnv, nint obj, nint clazz, nint methodID, JValue* args)
1173 {
1174 try
1175 {
1176 var o = InvokeHelper(pEnv, obj, methodID, args, true);
1177 if (o != null)
1178 return (jlong)(long)o;
1179
1180 return 0;
1181 }
1182 catch (Exception e)
1183 {
1184 JVM.SetPendingException(e);
1185 return 0;
1186 }
1187 }
1188
1189 internal static jfloat CallNonvirtualFloatMethodA(JNIEnv* pEnv, nint obj, nint clazz, nint methodID, JValue* args)
1190 {
1191 try
1192 {
1193 var o = InvokeHelper(pEnv, obj, methodID, args, true);
1194 if (o != null)
1195 return (jfloat)(float)o;
1196
1197 return 0;
1198 }
1199 catch (Exception e)
1200 {
1201 JVM.SetPendingException(e);
1202 return 0;
1203 }
1204 }
1205
1206 internal static jdouble CallNonvirtualDoubleMethodA(JNIEnv* pEnv, nint obj, nint clazz, nint methodID, JValue* args)
1207 {
1208 try
1209 {
1210 var o = InvokeHelper(pEnv, obj, methodID, args, true);
1211 if (o != null)
1212 return (jdouble)(double)o;
1213
1214 return 0;
1215 }
1216 catch (Exception e)
1217 {
1218 JVM.SetPendingException(e);
1219 return 0;
1220 }
1221 }
1222
1223 internal static void CallNonvirtualVoidMethodA(JNIEnv* pEnv, nint obj, nint clazz, nint methodID, JValue* args)
1224 {
1225 try
1226 {
1227 InvokeHelper(pEnv, obj, methodID, args, true);
1228 }
1229 catch (Exception e)
1230 {
1231 JVM.SetPendingException(e);
1232 }
1233 }
1234
1235 static RuntimeJavaField GetFieldImpl(RuntimeJavaType tw, string name, string sig)
1236 {
1237 for (; ; )
1238 {
1239 var fw = tw.GetFieldWrapper(name, sig);
1240 if (fw == null || !fw.IsHideFromReflection)
1241 return fw;
1242
1243 tw = fw.DeclaringType.BaseTypeWrapper;
1244 if (tw == null)
1245 return null;
1246 }
1247 }
1248
1249 static nint FindFieldID(JNIEnv* pEnv, nint clazz, byte* name, byte* sig, bool isStatic)
1250 {
1251 try
1252 {
1253 var n = DecodeMUTF8Argument(name, nameof(name));
1254 var s = DecodeMUTF8Argument(sig, nameof(sig));
1255
1256 var tw = RuntimeJavaType.FromClass((java.lang.Class)pEnv->UnwrapRef(clazz));
1257 tw.Finish();
1258
1259 // don't allow dotted names!
1260 if (s.IndexOf('.') < 0)
1261 {
1262 var fw = GetFieldImpl(tw, n, s.Replace('/', '.'));
1263 if (fw != null)
1264 if (fw.IsStatic == isStatic)
1265 return fw.Cookie;
1266 }
1267
1268 throw new java.lang.NoSuchFieldError($"{(isStatic ? "Static" : "Instance")} field '{n}' with signature '{s}' not found in class '{tw.Name}'");
1269 }
1271 {
1272 ExceptionDispatchInfo.Capture(x.ToJava()).Throw();
1273 throw null;
1274 }
1275 }
1276
1277 internal static nint GetFieldID(JNIEnv* pEnv, nint clazz, byte* name, byte* sig)
1278 {
1279 try
1280 {
1281 return FindFieldID(pEnv, clazz, name, sig, false);
1282 }
1283 catch (Exception e)
1284 {
1285 JVM.SetPendingException(e);
1286 return 0;
1287 }
1288 }
1289
1291 {
1292 return RuntimeJavaField.FromCookie(cookie);
1293 }
1294
1295 internal static nint GetObjectField(JNIEnv* pEnv, nint obj, nint fieldID)
1296 {
1297#if FIRST_PASS
1298 throw new NotImplementedException();
1299#else
1300 try
1301 {
1302 return pEnv->MakeLocalRef(GetFieldWrapper(fieldID).UnsafeGetValue<object>(pEnv->UnwrapRef(obj)));
1303 }
1304 catch (Exception e)
1305 {
1306 JVM.SetPendingException(e);
1307 return 0;
1308 }
1309#endif
1310 }
1311
1312 internal static jboolean GetBooleanField(JNIEnv* pEnv, nint obj, nint fieldID)
1313 {
1314#if FIRST_PASS
1315 throw new NotImplementedException();
1316#else
1317 try
1318 {
1319 return GetFieldWrapper(fieldID).UnsafeGetValue<bool>(pEnv->UnwrapRef(obj)) ? JNI_TRUE : JNI_FALSE;
1320 }
1321 catch (Exception e)
1322 {
1323 JVM.SetPendingException(e);
1324 return 0;
1325 }
1326#endif
1327 }
1328
1329 internal static jbyte GetByteField(JNIEnv* pEnv, nint obj, nint fieldID)
1330 {
1331#if FIRST_PASS
1332 throw new NotImplementedException();
1333#else
1334 try
1335 {
1336 return (jbyte)GetFieldWrapper(fieldID).UnsafeGetValue<byte>(pEnv->UnwrapRef(obj));
1337 }
1338 catch (Exception e)
1339 {
1340 JVM.SetPendingException(e);
1341 return 0;
1342 }
1343#endif
1344 }
1345
1346 internal static jchar GetCharField(JNIEnv* pEnv, nint obj, nint fieldID)
1347 {
1348#if FIRST_PASS
1349 throw new NotImplementedException();
1350#else
1351 try
1352 {
1353 return GetFieldWrapper(fieldID).UnsafeGetValue<char>(pEnv->UnwrapRef(obj));
1354 }
1355 catch (Exception e)
1356 {
1357 JVM.SetPendingException(e);
1358 return 0;
1359 }
1360#endif
1361 }
1362
1363 internal static jshort GetShortField(JNIEnv* pEnv, nint obj, nint fieldID)
1364 {
1365#if FIRST_PASS
1366 throw new NotImplementedException();
1367#else
1368 try
1369 {
1370 return GetFieldWrapper(fieldID).UnsafeGetValue<short>(pEnv->UnwrapRef(obj));
1371 }
1372 catch (Exception e)
1373 {
1374 JVM.SetPendingException(e);
1375 return 0;
1376 }
1377#endif
1378 }
1379
1380 internal static jint GetIntField(JNIEnv* pEnv, nint obj, nint fieldID)
1381 {
1382#if FIRST_PASS
1383 throw new NotImplementedException();
1384#else
1385 try
1386 {
1387 return GetFieldWrapper(fieldID).UnsafeGetValue<int>(pEnv->UnwrapRef(obj));
1388 }
1389 catch (Exception e)
1390 {
1391 JVM.SetPendingException(e);
1392 return 0;
1393 }
1394#endif
1395 }
1396
1397 internal static jlong GetLongField(JNIEnv* pEnv, nint obj, nint fieldID)
1398 {
1399#if FIRST_PASS
1400 throw new NotImplementedException();
1401#else
1402 try
1403 {
1404 return GetFieldWrapper(fieldID).UnsafeGetValue<long>(pEnv->UnwrapRef(obj));
1405 }
1406 catch (Exception e)
1407 {
1408 JVM.SetPendingException(e);
1409 return 0;
1410 }
1411#endif
1412 }
1413
1414 internal static jfloat GetFloatField(JNIEnv* pEnv, nint obj, nint fieldID)
1415 {
1416#if FIRST_PASS
1417 throw new NotImplementedException();
1418#else
1419 try
1420 {
1421 return GetFieldWrapper(fieldID).UnsafeGetValue<float>(pEnv->UnwrapRef(obj));
1422 }
1423 catch (Exception e)
1424 {
1425 JVM.SetPendingException(e);
1426 return 0;
1427 }
1428#endif
1429 }
1430
1431 internal static jdouble GetDoubleField(JNIEnv* pEnv, nint obj, nint fieldID)
1432 {
1433#if FIRST_PASS
1434 throw new NotImplementedException();
1435#else
1436 try
1437 {
1438 return GetFieldWrapper(fieldID).UnsafeGetValue<double>(pEnv->UnwrapRef(obj));
1439 }
1440 catch (Exception e)
1441 {
1442 JVM.SetPendingException(e);
1443 return 0;
1444 }
1445#endif
1446 }
1447
1448 internal static void SetObjectField(JNIEnv* pEnv, nint obj, nint fieldID, nint val)
1449 {
1450#if FIRST_PASS
1451 throw new NotImplementedException();
1452#else
1453 try
1454 {
1455 GetFieldWrapper(fieldID).UnsafeSetValue<object>(pEnv->UnwrapRef(obj), pEnv->UnwrapRef(val));
1456 }
1457 catch (Exception e)
1458 {
1459 JVM.SetPendingException(e);
1460 }
1461#endif
1462 }
1463
1464 internal static void SetBooleanField(JNIEnv* pEnv, nint obj, nint fieldID, jboolean val)
1465 {
1466#if FIRST_PASS
1467 throw new NotImplementedException();
1468#else
1469 try
1470 {
1471 GetFieldWrapper(fieldID).UnsafeSetValue<bool>(pEnv->UnwrapRef(obj), val != JNI_FALSE);
1472 }
1473 catch (Exception e)
1474 {
1475 JVM.SetPendingException(e);
1476 }
1477#endif
1478 }
1479
1480 internal static void SetByteField(JNIEnv* pEnv, nint obj, nint fieldID, jbyte val)
1481 {
1482#if FIRST_PASS
1483 throw new NotImplementedException();
1484#else
1485 try
1486 {
1487 GetFieldWrapper(fieldID).UnsafeSetValue<byte>(pEnv->UnwrapRef(obj), (byte)val);
1488 }
1489 catch (Exception e)
1490 {
1491 JVM.SetPendingException(e);
1492 }
1493#endif
1494 }
1495
1496 internal static void SetCharField(JNIEnv* pEnv, nint obj, nint fieldID, jchar val)
1497 {
1498#if FIRST_PASS
1499 throw new NotImplementedException();
1500#else
1501 try
1502 {
1503 GetFieldWrapper(fieldID).UnsafeSetValue<char>(pEnv->UnwrapRef(obj), (char)val);
1504 }
1505 catch (Exception e)
1506 {
1507 JVM.SetPendingException(e);
1508 }
1509#endif
1510 }
1511
1512 internal static void SetShortField(JNIEnv* pEnv, nint obj, nint fieldID, jshort val)
1513 {
1514#if FIRST_PASS
1515 throw new NotImplementedException();
1516#else
1517 try
1518 {
1519 GetFieldWrapper(fieldID).UnsafeSetValue<short>(pEnv->UnwrapRef(obj), val);
1520 }
1521 catch (Exception e)
1522 {
1523 JVM.SetPendingException(e);
1524 }
1525#endif
1526 }
1527
1528 internal static void SetIntField(JNIEnv* pEnv, nint obj, nint fieldID, jint val)
1529 {
1530#if FIRST_PASS
1531 throw new NotImplementedException();
1532#else
1533 try
1534 {
1535 GetFieldWrapper(fieldID).UnsafeSetValue<int>(pEnv->UnwrapRef(obj), val);
1536 }
1537 catch (Exception e)
1538 {
1539 JVM.SetPendingException(e);
1540 }
1541#endif
1542 }
1543
1544 internal static void SetLongField(JNIEnv* pEnv, nint obj, nint fieldID, jlong val)
1545 {
1546#if FIRST_PASS
1547 throw new NotImplementedException();
1548#else
1549 try
1550 {
1551 GetFieldWrapper(fieldID).UnsafeSetValue<long>(pEnv->UnwrapRef(obj), val);
1552 }
1553 catch (Exception e)
1554 {
1555 JVM.SetPendingException(e);
1556 }
1557#endif
1558 }
1559
1560 internal static void SetFloatField(JNIEnv* pEnv, nint obj, nint fieldID, jfloat val)
1561 {
1562#if FIRST_PASS
1563 throw new NotImplementedException();
1564#else
1565 try
1566 {
1567 GetFieldWrapper(fieldID).UnsafeSetValue<float>(pEnv->UnwrapRef(obj), val);
1568 }
1569 catch (Exception e)
1570 {
1571 JVM.SetPendingException(e);
1572 }
1573#endif
1574 }
1575
1576 internal static void SetDoubleField(JNIEnv* pEnv, nint obj, nint fieldID, jdouble val)
1577 {
1578#if FIRST_PASS
1579 throw new NotImplementedException();
1580#else
1581 try
1582 {
1583 GetFieldWrapper(fieldID).UnsafeSetValue<double>(pEnv->UnwrapRef(obj), val);
1584 }
1585 catch (Exception e)
1586 {
1587 JVM.SetPendingException(e);
1588 }
1589#endif
1590 }
1591
1592 internal static nint GetStaticMethodID(JNIEnv* pEnv, nint clazz, byte* name, byte* sig)
1593 {
1594 return FindMethodID(pEnv, clazz, name, sig, true);
1595 }
1596
1597 internal static nint CallStaticObjectMethodA(JNIEnv* pEnv, nint clazz, nint methodID, JValue* args)
1598 {
1599 try
1600 {
1601 return pEnv->MakeLocalRef(InvokeHelper(pEnv, IntPtr.Zero, methodID, args, false));
1602 }
1603 catch (Exception e)
1604 {
1605 JVM.SetPendingException(e);
1606 return 0;
1607 }
1608 }
1609
1610 internal static jboolean CallStaticBooleanMethodA(JNIEnv* pEnv, nint clazz, nint methodID, JValue* args)
1611 {
1612 try
1613 {
1614 var o = InvokeHelper(pEnv, IntPtr.Zero, methodID, args, false);
1615 return o != null ? ((bool)o) ? JNI_TRUE : JNI_FALSE : JNI_FALSE;
1616 }
1617 catch (Exception e)
1618 {
1619 JVM.SetPendingException(e);
1620 return 0;
1621 }
1622 }
1623
1624 internal static jbyte CallStaticByteMethodA(JNIEnv* pEnv, nint clazz, nint methodID, JValue* args)
1625 {
1626 try
1627 {
1628 var o = InvokeHelper(pEnv, IntPtr.Zero, methodID, args, false);
1629 return o != null ? (jbyte)(byte)o : (sbyte)0;
1630 }
1631 catch (Exception e)
1632 {
1633 JVM.SetPendingException(e);
1634 return 0;
1635 }
1636 }
1637
1638 internal static jchar CallStaticCharMethodA(JNIEnv* pEnv, nint clazz, nint methodID, JValue* args)
1639 {
1640 try
1641 {
1642 var o = InvokeHelper(pEnv, IntPtr.Zero, methodID, args, false);
1643 return o != null ? (jchar)(char)o : (ushort)0;
1644 }
1645 catch (Exception e)
1646 {
1647 JVM.SetPendingException(e);
1648 return 0;
1649 }
1650 }
1651
1652 internal static jshort CallStaticShortMethodA(JNIEnv* pEnv, nint clazz, nint methodID, JValue* args)
1653 {
1654 try
1655 {
1656 var o = InvokeHelper(pEnv, IntPtr.Zero, methodID, args, false);
1657 return o != null ? (jshort)(short)o : (short)0;
1658 }
1659 catch (Exception e)
1660 {
1661 JVM.SetPendingException(e);
1662 return 0;
1663 }
1664 }
1665
1666 internal static jint CallStaticIntMethodA(JNIEnv* pEnv, nint clazz, nint methodID, JValue* args)
1667 {
1668 try
1669 {
1670 var o = InvokeHelper(pEnv, IntPtr.Zero, methodID, args, false);
1671 return o != null ? (jint)(int)o : 0;
1672 }
1673 catch (Exception e)
1674 {
1675 JVM.SetPendingException(e);
1676 return 0;
1677 }
1678 }
1679
1680 internal static jlong CallStaticLongMethodA(JNIEnv* pEnv, nint clazz, nint methodID, JValue* args)
1681 {
1682 try
1683 {
1684 var o = InvokeHelper(pEnv, IntPtr.Zero, methodID, args, false);
1685 return o != null ? (jlong)(long)o : 0;
1686 }
1687 catch (Exception e)
1688 {
1689 JVM.SetPendingException(e);
1690 return 0;
1691 }
1692 }
1693
1694 internal static jfloat CallStaticFloatMethodA(JNIEnv* pEnv, nint clazz, nint methodID, JValue* args)
1695 {
1696 try
1697 {
1698 var o = InvokeHelper(pEnv, IntPtr.Zero, methodID, args, false);
1699 return o != null ? (jfloat)(float)o : 0;
1700 }
1701 catch (Exception e)
1702 {
1703 JVM.SetPendingException(e);
1704 return 0;
1705 }
1706 }
1707
1708 internal static jdouble CallStaticDoubleMethodA(JNIEnv* pEnv, nint clazz, nint methodID, JValue* args)
1709 {
1710 try
1711 {
1712 var o = InvokeHelper(pEnv, IntPtr.Zero, methodID, args, false);
1713 return o != null ? (jdouble)(double)o : 0;
1714 }
1715 catch (Exception e)
1716 {
1717 JVM.SetPendingException(e);
1718 return 0;
1719 }
1720 }
1721
1722 internal static void CallStaticVoidMethodA(JNIEnv* pEnv, nint cls, nint methodID, JValue* args)
1723 {
1724 try
1725 {
1726 InvokeHelper(pEnv, IntPtr.Zero, methodID, args, false);
1727 }
1728 catch (Exception e)
1729 {
1730 JVM.SetPendingException(e);
1731 }
1732 }
1733
1734 internal static nint GetStaticFieldID(JNIEnv* pEnv, nint clazz, byte* name, byte* sig)
1735 {
1736 try
1737 {
1738 return FindFieldID(pEnv, clazz, name, sig, true);
1739 }
1740 catch (Exception e)
1741 {
1742 JVM.SetPendingException(e);
1743 return 0;
1744 }
1745 }
1746
1747 internal static nint GetStaticObjectField(JNIEnv* pEnv, nint clazz, nint fieldID)
1748 {
1749#if FIRST_PASS
1750 throw new NotImplementedException();
1751#else
1752 try
1753 {
1754 return pEnv->MakeLocalRef(GetFieldWrapper(fieldID).UnsafeGetValue<object>(null));
1755 }
1756 catch (Exception e)
1757 {
1758 JVM.SetPendingException(e);
1759 return 0;
1760 }
1761#endif
1762 }
1763
1764 internal static jboolean GetStaticBooleanField(JNIEnv* pEnv, nint clazz, nint fieldID)
1765 {
1766#if FIRST_PASS
1767 throw new NotImplementedException();
1768#else
1769 try
1770 {
1771 return GetFieldWrapper(fieldID).UnsafeGetValue<bool>(null) ? JNI_TRUE : JNI_FALSE;
1772 }
1773 catch (Exception e)
1774 {
1775 JVM.SetPendingException(e);
1776 return 0;
1777 }
1778#endif
1779 }
1780
1781 internal static jbyte GetStaticByteField(JNIEnv* pEnv, nint clazz, nint fieldID)
1782 {
1783#if FIRST_PASS
1784 throw new NotImplementedException();
1785#else
1786 try
1787 {
1788 return (jbyte)GetFieldWrapper(fieldID).UnsafeGetValue<byte>(null);
1789 }
1790 catch (Exception e)
1791 {
1792 JVM.SetPendingException(e);
1793 return 0;
1794 }
1795#endif
1796 }
1797
1798 internal static jchar GetStaticCharField(JNIEnv* pEnv, nint clazz, nint fieldID)
1799 {
1800#if FIRST_PASS
1801 throw new NotImplementedException();
1802#else
1803 try
1804 {
1805 return GetFieldWrapper(fieldID).UnsafeGetValue<char>(null);
1806 }
1807 catch (Exception e)
1808 {
1809 JVM.SetPendingException(e);
1810 return 0;
1811 }
1812#endif
1813 }
1814
1815 internal static jshort GetStaticShortField(JNIEnv* pEnv, nint clazz, nint fieldID)
1816 {
1817#if FIRST_PASS
1818 throw new NotImplementedException();
1819#else
1820 try
1821 {
1822 return GetFieldWrapper(fieldID).UnsafeGetValue<short>(null);
1823 }
1824 catch (Exception e)
1825 {
1826 JVM.SetPendingException(e);
1827 return 0;
1828 }
1829#endif
1830 }
1831
1832 internal static jint GetStaticIntField(JNIEnv* pEnv, nint clazz, nint fieldID)
1833 {
1834#if FIRST_PASS
1835 throw new NotImplementedException();
1836#else
1837 try
1838 {
1839 return GetFieldWrapper(fieldID).UnsafeGetValue<int>(null);
1840 }
1841 catch (Exception e)
1842 {
1843 JVM.SetPendingException(e);
1844 return 0;
1845 }
1846#endif
1847 }
1848
1849 internal static jlong GetStaticLongField(JNIEnv* pEnv, nint clazz, nint fieldID)
1850 {
1851#if FIRST_PASS
1852 throw new NotImplementedException();
1853#else
1854 try
1855 {
1856 return GetFieldWrapper(fieldID).UnsafeGetValue<long>(null);
1857 }
1858 catch (Exception e)
1859 {
1860 JVM.SetPendingException(e);
1861 return 0;
1862 }
1863#endif
1864 }
1865
1866 internal static jfloat GetStaticFloatField(JNIEnv* pEnv, nint clazz, nint fieldID)
1867 {
1868#if FIRST_PASS
1869 throw new NotImplementedException();
1870#else
1871 try
1872 {
1873 return GetFieldWrapper(fieldID).UnsafeGetValue<float>(null);
1874 }
1875 catch (Exception e)
1876 {
1877 JVM.SetPendingException(e);
1878 return 0;
1879 }
1880#endif
1881 }
1882
1883 internal static jdouble GetStaticDoubleField(JNIEnv* pEnv, nint clazz, nint fieldID)
1884 {
1885#if FIRST_PASS
1886 throw new NotImplementedException();
1887#else
1888 try
1889 {
1890 return GetFieldWrapper(fieldID).UnsafeGetValue<double>(null);
1891 }
1892 catch (Exception e)
1893 {
1894 JVM.SetPendingException(e);
1895 return 0;
1896 }
1897#endif
1898 }
1899
1900 internal static void SetStaticObjectField(JNIEnv* pEnv, nint clazz, nint fieldID, nint val)
1901 {
1902#if FIRST_PASS
1903 throw new NotImplementedException();
1904#else
1905 try
1906 {
1907 GetFieldWrapper(fieldID).UnsafeSetValue<object>(null, pEnv->UnwrapRef(val));
1908 }
1909 catch (Exception e)
1910 {
1911 JVM.SetPendingException(e);
1912 }
1913#endif
1914 }
1915
1916 internal static void SetStaticBooleanField(JNIEnv* pEnv, nint clazz, nint fieldID, jboolean val)
1917 {
1918#if FIRST_PASS
1919 throw new NotImplementedException();
1920#else
1921 try
1922 {
1923 GetFieldWrapper(fieldID).UnsafeSetValue<bool>(null, val != JNI_TRUE);
1924 }
1925 catch (Exception e)
1926 {
1927 JVM.SetPendingException(e);
1928 }
1929#endif
1930 }
1931
1932 internal static void SetStaticByteField(JNIEnv* pEnv, nint clazz, nint fieldID, jbyte val)
1933 {
1934#if FIRST_PASS
1935 throw new NotImplementedException();
1936#else
1937 try
1938 {
1939 GetFieldWrapper(fieldID).UnsafeSetValue<byte>(null, (byte)val);
1940 }
1941 catch (Exception e)
1942 {
1943 JVM.SetPendingException(e);
1944 }
1945#endif
1946 }
1947
1948 internal static void SetStaticCharField(JNIEnv* pEnv, nint clazz, nint fieldID, jchar val)
1949 {
1950#if FIRST_PASS
1951 throw new NotImplementedException();
1952#else
1953 try
1954 {
1955 GetFieldWrapper(fieldID).UnsafeSetValue<char>(null, (char)val);
1956 }
1957 catch (Exception e)
1958 {
1959 JVM.SetPendingException(e);
1960 }
1961#endif
1962 }
1963
1964 internal static void SetStaticShortField(JNIEnv* pEnv, nint clazz, nint fieldID, jshort val)
1965 {
1966#if FIRST_PASS
1967 throw new NotImplementedException();
1968#else
1969 try
1970 {
1971 GetFieldWrapper(fieldID).UnsafeSetValue<short>(null, val);
1972 }
1973 catch (Exception e)
1974 {
1975 JVM.SetPendingException(e);
1976 }
1977#endif
1978 }
1979
1980 internal static void SetStaticIntField(JNIEnv* pEnv, nint clazz, nint fieldID, jint val)
1981 {
1982#if FIRST_PASS
1983 throw new NotImplementedException();
1984#else
1985 try
1986 {
1987 GetFieldWrapper(fieldID).UnsafeSetValue<int>(null, val);
1988 }
1989 catch (Exception e)
1990 {
1991 JVM.SetPendingException(e);
1992 }
1993#endif
1994 }
1995
1996 internal static void SetStaticLongField(JNIEnv* pEnv, nint clazz, nint fieldID, jlong val)
1997 {
1998#if FIRST_PASS
1999 throw new NotImplementedException();
2000#else
2001 try
2002 {
2003 GetFieldWrapper(fieldID).UnsafeSetValue<long>(null, val);
2004 }
2005 catch (Exception e)
2006 {
2007 JVM.SetPendingException(e);
2008 }
2009#endif
2010 }
2011
2012 internal static void SetStaticFloatField(JNIEnv* pEnv, nint clazz, nint fieldID, jfloat val)
2013 {
2014#if FIRST_PASS
2015 throw new NotImplementedException();
2016#else
2017 try
2018 {
2019 GetFieldWrapper(fieldID).UnsafeSetValue<float>(null, val);
2020 }
2021 catch (Exception e)
2022 {
2023 JVM.SetPendingException(e);
2024 }
2025#endif
2026 }
2027
2028 internal static void SetStaticDoubleField(JNIEnv* pEnv, nint clazz, nint fieldID, jdouble val)
2029 {
2030#if FIRST_PASS
2031 throw new NotImplementedException();
2032#else
2033 GetFieldWrapper(fieldID).UnsafeSetValue<double>(null, val);
2034#endif
2035 }
2036
2037 internal static nint NewString(JNIEnv* pEnv, jchar* unicode, int len)
2038 {
2039 return pEnv->MakeLocalRef(new String((char*)unicode, 0, len));
2040 }
2041
2042 internal static jint GetStringLength(JNIEnv* pEnv, nint str)
2043 {
2044 return ((string)pEnv->UnwrapRef(str)).Length;
2045 }
2046
2047 internal static jchar* GetStringChars(JNIEnv* pEnv, nint str, jboolean* isCopy)
2048 {
2049 try
2050 {
2051 var s = (string)pEnv->UnwrapRef(str);
2052 if (isCopy != null)
2053 *isCopy = JNI_TRUE;
2054
2055 return (jchar*)(void*)Marshal.StringToHGlobalUni(s);
2056 }
2057 catch (Exception e)
2058 {
2059 JVM.SetPendingException(e);
2060 return null;
2061 }
2062 }
2063
2064 internal static void ReleaseStringChars(JNIEnv* pEnv, nint str, jchar* chars)
2065 {
2066 try
2067 {
2068 Marshal.FreeHGlobal((IntPtr)(void*)chars);
2069 }
2070 catch (Exception e)
2071 {
2072 JVM.SetPendingException(e);
2073 return;
2074 }
2075 }
2076
2077 internal static nint NewStringUTF(JNIEnv* pEnv, byte* bytes)
2078 {
2079 try
2080 {
2081 return bytes == null ? IntPtr.Zero : pEnv->MakeLocalRef(DecodeMUTF8Argument(bytes, nameof(bytes)));
2082 }
2083 catch (Exception e)
2084 {
2085 JVM.SetPendingException(e);
2086 return -1;
2087 }
2088 }
2089
2090 internal static jint GetStringUTFLength(JNIEnv* pEnv, nint str)
2091 {
2092 try
2093 {
2094 return MUTF8.GetByteCount((string)pEnv->UnwrapRef(str));
2095 }
2096 catch (Exception e)
2097 {
2098 JVM.SetPendingException(e);
2099 return -1;
2100 }
2101 }
2102
2103 internal static byte* GetStringUTFChars(JNIEnv* pEnv, nint @string, jboolean* isCopy)
2104 {
2105 try
2106 {
2107 var s = (string)pEnv->UnwrapRef(@string);
2108 var buf = (byte*)JNIMemory.Alloc(MUTF8.GetByteCount(s) + 1);
2109 int j = 0;
2110
2111 for (int i = 0; i < s.Length; i++)
2112 {
2113 var ch = s[i];
2114 if ((ch != 0) && (ch <= 0x7F))
2115 {
2116 buf[j++] = (byte)ch;
2117 }
2118 else if (ch <= 0x7FF)
2119 {
2120 buf[j++] = (byte)((ch >> 6) | 0xC0);
2121 buf[j++] = (byte)((ch & 0x3F) | 0x80);
2122 }
2123 else
2124 {
2125 buf[j++] = (byte)((ch >> 12) | 0xE0);
2126 buf[j++] = (byte)(((ch >> 6) & 0x3F) | 0x80);
2127 buf[j++] = (byte)((ch & 0x3F) | 0x80);
2128 }
2129 }
2130
2131 buf[j] = 0;
2132
2133 if (isCopy != null)
2134 *isCopy = JNI_TRUE;
2135
2136 return buf;
2137 }
2138 catch (Exception e)
2139 {
2140 JVM.SetPendingException(e);
2141 return null;
2142 }
2143 }
2144
2145 internal static void ReleaseStringUTFChars(JNIEnv* pEnv, nint @string, byte* utf)
2146 {
2147 JNIMemory.Free((IntPtr)(void*)utf);
2148 }
2149
2150 internal static jsize GetArrayLength(JNIEnv* pEnv, nint array)
2151 {
2152 return ((Array)pEnv->UnwrapRef(array)).Length;
2153 }
2154
2155 internal static nint NewObjectArray(JNIEnv* pEnv, jsize len, nint clazz, nint init)
2156 {
2157 try
2158 {
2159 // we want to support (non-primitive) value types so we can't cast to object[]
2160 var a = Array.CreateInstance(RuntimeJavaType.FromClass((java.lang.Class)pEnv->UnwrapRef(clazz)).TypeAsArrayType, len);
2161 var o = pEnv->UnwrapRef(init);
2162 if (o != null)
2163 for (int i = 0; i < a.Length; i++)
2164 a.SetValue(o, i);
2165
2166 return pEnv->MakeLocalRef(a);
2167 }
2168 catch (ArgumentOutOfRangeException)
2169 {
2170 JVM.SetPendingException(new java.lang.NegativeArraySizeException());
2171 return IntPtr.Zero;
2172 }
2173 catch (Exception e)
2174 {
2175 JVM.SetPendingException(e);
2176 return IntPtr.Zero;
2177 }
2178 }
2179
2180 internal static nint GetObjectArrayElement(JNIEnv* pEnv, nint array, jsize index)
2181 {
2182 try
2183 {
2184 // we want to support (non-primitive) value types so we can't cast to object[]
2185 return pEnv->MakeLocalRef(((Array)pEnv->UnwrapRef(array)).GetValue(index));
2186 }
2187 catch (IndexOutOfRangeException)
2188 {
2189 JVM.SetPendingException(new java.lang.ArrayIndexOutOfBoundsException());
2190 return IntPtr.Zero;
2191 }
2192 }
2193
2194 internal static void SetObjectArrayElement(JNIEnv* pEnv, nint array, jsize index, nint val)
2195 {
2196 try
2197 {
2198 // we want to support (non-primitive) value types so we can't cast to object[]
2199 ((Array)pEnv->UnwrapRef(array)).SetValue(pEnv->UnwrapRef(val), index);
2200 }
2201 catch (NullReferenceException)
2202 {
2203 JVM.SetPendingException(new java.lang.NullPointerException());
2204 }
2205 catch (InvalidCastException)
2206 {
2207 JVM.SetPendingException(new java.lang.ArrayStoreException());
2208 }
2209 catch (IndexOutOfRangeException)
2210 {
2211 JVM.SetPendingException(new java.lang.ArrayIndexOutOfBoundsException());
2212 }
2213 catch (Exception e)
2214 {
2215 JVM.SetPendingException(e);
2216 }
2217 }
2218
2219 internal static nint NewBooleanArray(JNIEnv* pEnv, jsize len)
2220 {
2221 try
2222 {
2223 return pEnv->MakeLocalRef(new bool[len]);
2224 }
2225 catch (Exception x)
2226 {
2227 JVM.SetPendingException(x);
2228 return IntPtr.Zero;
2229 }
2230 }
2231
2232 internal static nint NewByteArray(JNIEnv* pEnv, jsize len)
2233 {
2234 try
2235 {
2236 return pEnv->MakeLocalRef(new byte[len]);
2237 }
2238 catch (Exception x)
2239 {
2240 JVM.SetPendingException(x);
2241 return IntPtr.Zero;
2242 }
2243 }
2244
2245 internal static nint NewCharArray(JNIEnv* pEnv, jsize len)
2246 {
2247 try
2248 {
2249 return pEnv->MakeLocalRef(new char[len]);
2250 }
2251 catch (Exception x)
2252 {
2253 JVM.SetPendingException(x);
2254 return IntPtr.Zero;
2255 }
2256 }
2257
2258 internal static nint NewShortArray(JNIEnv* pEnv, jsize len)
2259 {
2260 try
2261 {
2262 return pEnv->MakeLocalRef(new short[len]);
2263 }
2264 catch (Exception x)
2265 {
2266 JVM.SetPendingException(x);
2267 return IntPtr.Zero;
2268 }
2269 }
2270
2271 internal static nint NewIntArray(JNIEnv* pEnv, jsize len)
2272 {
2273 try
2274 {
2275 return pEnv->MakeLocalRef(new int[len]);
2276 }
2277 catch (Exception x)
2278 {
2279 JVM.SetPendingException(x);
2280 return IntPtr.Zero;
2281 }
2282 }
2283
2284 internal static nint NewLongArray(JNIEnv* pEnv, jsize len)
2285 {
2286 try
2287 {
2288 return pEnv->MakeLocalRef(new long[len]);
2289 }
2290 catch (Exception x)
2291 {
2292 JVM.SetPendingException(x);
2293 return IntPtr.Zero;
2294 }
2295 }
2296
2297 internal static nint NewFloatArray(JNIEnv* pEnv, jsize len)
2298 {
2299 try
2300 {
2301 return pEnv->MakeLocalRef(new float[len]);
2302 }
2303 catch (Exception x)
2304 {
2305 JVM.SetPendingException(x);
2306 return IntPtr.Zero;
2307 }
2308 }
2309
2310 internal static nint NewDoubleArray(JNIEnv* pEnv, jsize len)
2311 {
2312 try
2313 {
2314 return pEnv->MakeLocalRef(new double[len]);
2315 }
2316 catch (Exception x)
2317 {
2318 JVM.SetPendingException(x);
2319 return IntPtr.Zero;
2320 }
2321 }
2322
2323 internal static jboolean* GetBooleanArrayElements(JNIEnv* pEnv, nint array, jboolean* isCopy)
2324 {
2325 var b = (bool[])pEnv->UnwrapRef(array);
2326 var p = (jboolean*)(void*)JNIMemory.Alloc(b.Length * 1);
2327 for (int i = 0; i < b.Length; i++)
2328 p[i] = b[i] ? JNI_TRUE : JNI_FALSE;
2329
2330 if (isCopy != null)
2331 *isCopy = JNI_TRUE;
2332
2333 return p;
2334 }
2335
2336 internal static jbyte* GetByteArrayElements(JNIEnv* pEnv, nint array, jboolean* isCopy)
2337 {
2338 byte[] b = (byte[])pEnv->UnwrapRef(array);
2339 jbyte* p = (jbyte*)(void*)JNIMemory.Alloc(b.Length * 1);
2340 for (int i = 0; i < b.Length; i++)
2341 p[i] = (jbyte)b[i];
2342
2343 if (isCopy != null)
2344 *isCopy = JNI_TRUE;
2345
2346 return p;
2347 }
2348
2349 internal static jchar* GetCharArrayElements(JNIEnv* pEnv, nint array, jboolean* isCopy)
2350 {
2351 char[] b = (char[])pEnv->UnwrapRef(array);
2352 IntPtr buf = JNIMemory.Alloc(b.Length * 2);
2353 Marshal.Copy(b, 0, buf, b.Length);
2354 if (isCopy != null)
2355 {
2356 *isCopy = JNI_TRUE;
2357 }
2358 return (jchar*)(void*)buf;
2359 }
2360
2361 internal static jshort* GetShortArrayElements(JNIEnv* pEnv, nint array, jboolean* isCopy)
2362 {
2363 short[] b = (short[])pEnv->UnwrapRef(array);
2364 IntPtr buf = JNIMemory.Alloc(b.Length * 2);
2365 Marshal.Copy(b, 0, buf, b.Length);
2366 if (isCopy != null)
2367 {
2368 *isCopy = JNI_TRUE;
2369 }
2370 return (jshort*)(void*)buf;
2371 }
2372
2373 internal static jint* GetIntArrayElements(JNIEnv* pEnv, nint array, jboolean* isCopy)
2374 {
2375 int[] b = (int[])pEnv->UnwrapRef(array);
2376 IntPtr buf = JNIMemory.Alloc(b.Length * 4);
2377 Marshal.Copy(b, 0, buf, b.Length);
2378 if (isCopy != null)
2379 {
2380 *isCopy = JNI_TRUE;
2381 }
2382 return (jint*)(void*)buf;
2383 }
2384
2385 internal static jlong* GetLongArrayElements(JNIEnv* pEnv, nint array, jboolean* isCopy)
2386 {
2387 long[] b = (long[])pEnv->UnwrapRef(array);
2388 IntPtr buf = JNIMemory.Alloc(b.Length * 8);
2389 Marshal.Copy(b, 0, buf, b.Length);
2390 if (isCopy != null)
2391 {
2392 *isCopy = JNI_TRUE;
2393 }
2394 return (jlong*)(void*)buf;
2395 }
2396
2397 internal static jfloat* GetFloatArrayElements(JNIEnv* pEnv, nint array, jboolean* isCopy)
2398 {
2399 float[] b = (float[])pEnv->UnwrapRef(array);
2400 IntPtr buf = JNIMemory.Alloc(b.Length * 4);
2401 Marshal.Copy(b, 0, buf, b.Length);
2402 if (isCopy != null)
2403 {
2404 *isCopy = JNI_TRUE;
2405 }
2406 return (jfloat*)(void*)buf;
2407 }
2408
2409 internal static jdouble* GetDoubleArrayElements(JNIEnv* pEnv, nint array, jboolean* isCopy)
2410 {
2411 double[] b = (double[])pEnv->UnwrapRef(array);
2412 IntPtr buf = JNIMemory.Alloc(b.Length * 8);
2413 Marshal.Copy(b, 0, buf, b.Length);
2414 if (isCopy != null)
2415 {
2416 *isCopy = JNI_TRUE;
2417 }
2418 return (jdouble*)(void*)buf;
2419 }
2420
2421 internal static void ReleaseBooleanArrayElements(JNIEnv* pEnv, nint array, jboolean* elems, jint mode)
2422 {
2423 if (mode == 0 || mode == JNI_COMMIT)
2424 {
2425 bool[] b = (bool[])pEnv->UnwrapRef(array);
2426 for (int i = 0; i < b.Length; i++)
2427 {
2428 b[i] = elems[i] != JNI_FALSE;
2429 }
2430 }
2431 if (mode == 0 || mode == JNI_ABORT)
2432 {
2433 JNIMemory.Free((IntPtr)(void*)elems);
2434 }
2435 }
2436
2437 internal static void ReleaseByteArrayElements(JNIEnv* pEnv, nint array, jbyte* elems, jint mode)
2438 {
2439 if (mode == 0 || mode == JNI_COMMIT)
2440 {
2441 byte[] b = (byte[])pEnv->UnwrapRef(array);
2442 for (int i = 0; i < b.Length; i++)
2443 {
2444 b[i] = (byte)elems[i];
2445 }
2446 }
2447 if (mode == 0 || mode == JNI_ABORT)
2448 {
2449 JNIMemory.Free((IntPtr)(void*)elems);
2450 }
2451 }
2452
2453 internal static void ReleaseCharArrayElements(JNIEnv* pEnv, nint array, jchar* elems, jint mode)
2454 {
2455 if (mode == 0 || mode == JNI_COMMIT)
2456 {
2457 char[] b = (char[])pEnv->UnwrapRef(array);
2458 Marshal.Copy((IntPtr)(void*)elems, b, 0, b.Length);
2459 }
2460 if (mode == 0 || mode == JNI_ABORT)
2461 {
2462 JNIMemory.Free((IntPtr)(void*)elems);
2463 }
2464 }
2465
2466 internal static void ReleaseShortArrayElements(JNIEnv* pEnv, nint array, jshort* elems, jint mode)
2467 {
2468 if (mode == 0 || mode == JNI_COMMIT)
2469 {
2470 short[] b = (short[])pEnv->UnwrapRef(array);
2471 Marshal.Copy((IntPtr)(void*)elems, b, 0, b.Length);
2472 }
2473 if (mode == 0 || mode == JNI_ABORT)
2474 {
2475 JNIMemory.Free((IntPtr)(void*)elems);
2476 }
2477 }
2478
2479 internal static void ReleaseIntArrayElements(JNIEnv* pEnv, nint array, jint* elems, jint mode)
2480 {
2481 if (mode == 0 || mode == JNI_COMMIT)
2482 {
2483 int[] b = (int[])pEnv->UnwrapRef(array);
2484 Marshal.Copy((IntPtr)(void*)elems, b, 0, b.Length);
2485 }
2486 if (mode == 0 || mode == JNI_ABORT)
2487 {
2488 JNIMemory.Free((IntPtr)(void*)elems);
2489 }
2490 }
2491
2492 internal static void ReleaseLongArrayElements(JNIEnv* pEnv, nint array, jlong* elems, jint mode)
2493 {
2494 if (mode == 0 || mode == JNI_COMMIT)
2495 {
2496 long[] b = (long[])pEnv->UnwrapRef(array);
2497 Marshal.Copy((IntPtr)(void*)elems, b, 0, b.Length);
2498 }
2499 if (mode == 0 || mode == JNI_ABORT)
2500 {
2501 JNIMemory.Free((IntPtr)(void*)elems);
2502 }
2503 }
2504
2505 internal static void ReleaseFloatArrayElements(JNIEnv* pEnv, nint array, jfloat* elems, jint mode)
2506 {
2507 if (mode == 0 || mode == JNI_COMMIT)
2508 {
2509 float[] b = (float[])pEnv->UnwrapRef(array);
2510 Marshal.Copy((IntPtr)(void*)elems, b, 0, b.Length);
2511 }
2512 if (mode == 0 || mode == JNI_ABORT)
2513 {
2514 JNIMemory.Free((IntPtr)(void*)elems);
2515 }
2516 }
2517
2518 internal static void ReleaseDoubleArrayElements(JNIEnv* pEnv, nint array, jdouble* elems, jint mode)
2519 {
2520 if (mode == 0 || mode == JNI_COMMIT)
2521 {
2522 double[] b = (double[])pEnv->UnwrapRef(array);
2523 Marshal.Copy((IntPtr)(void*)elems, b, 0, b.Length);
2524 }
2525 if (mode == 0 || mode == JNI_ABORT)
2526 {
2527 JNIMemory.Free((IntPtr)(void*)elems);
2528 }
2529 }
2530
2531 internal static void GetBooleanArrayRegion(JNIEnv* pEnv, nint array, int start, int len, jboolean* buf)
2532 {
2533 try
2534 {
2535 bool[] b = (bool[])pEnv->UnwrapRef(array);
2536 sbyte* p = (sbyte*)(void*)buf;
2537 for (int i = 0; i < len; i++)
2538 {
2539 *p++ = b[start + i] ? JNI_TRUE : JNI_FALSE;
2540 }
2541 }
2542 catch (IndexOutOfRangeException)
2543 {
2544 JVM.SetPendingException(new java.lang.ArrayIndexOutOfBoundsException());
2545 }
2546 }
2547
2548 internal static void GetByteArrayRegion(JNIEnv* pEnv, nint array, int start, int len, jbyte* buf)
2549 {
2550 try
2551 {
2552 byte[] b = (byte[])pEnv->UnwrapRef(array);
2553 byte* p = (byte*)(void*)buf;
2554 for (int i = 0; i < len; i++)
2555 {
2556 *p++ = b[start + i];
2557 }
2558 }
2559 catch (IndexOutOfRangeException)
2560 {
2561 JVM.SetPendingException(new java.lang.ArrayIndexOutOfBoundsException());
2562 }
2563 }
2564
2565 internal static void GetCharArrayRegion(JNIEnv* pEnv, nint array, int start, int len, jchar* buf)
2566 {
2567 try
2568 {
2569 char[] b = (char[])pEnv->UnwrapRef(array);
2570 Marshal.Copy(b, start, (IntPtr)buf, len);
2571 }
2572 catch (ArgumentOutOfRangeException)
2573 {
2574 JVM.SetPendingException(new java.lang.ArrayIndexOutOfBoundsException());
2575 }
2576 }
2577
2578 internal static void GetShortArrayRegion(JNIEnv* pEnv, nint array, int start, int len, jshort* buf)
2579 {
2580 try
2581 {
2582 short[] b = (short[])pEnv->UnwrapRef(array);
2583 Marshal.Copy(b, start, (IntPtr)buf, len);
2584 }
2585 catch (ArgumentOutOfRangeException)
2586 {
2587 JVM.SetPendingException(new java.lang.ArrayIndexOutOfBoundsException());
2588 }
2589 }
2590
2591 internal static void GetIntArrayRegion(JNIEnv* pEnv, nint array, int start, int len, jint* buf)
2592 {
2593 try
2594 {
2595 int[] b = (int[])pEnv->UnwrapRef(array);
2596 Marshal.Copy(b, start, (IntPtr)buf, len);
2597 }
2598 catch (ArgumentOutOfRangeException)
2599 {
2600 JVM.SetPendingException(new java.lang.ArrayIndexOutOfBoundsException());
2601 }
2602 }
2603
2604 internal static void GetLongArrayRegion(JNIEnv* pEnv, nint array, int start, int len, jlong* buf)
2605 {
2606 try
2607 {
2608 long[] b = (long[])pEnv->UnwrapRef(array);
2609 Marshal.Copy(b, start, (IntPtr)buf, len);
2610 }
2611 catch (ArgumentOutOfRangeException)
2612 {
2613 JVM.SetPendingException(new java.lang.ArrayIndexOutOfBoundsException());
2614 }
2615 }
2616
2617 internal static void GetFloatArrayRegion(JNIEnv* pEnv, nint array, int start, int len, jfloat* buf)
2618 {
2619 try
2620 {
2621 float[] b = (float[])pEnv->UnwrapRef(array);
2622 Marshal.Copy(b, start, (IntPtr)buf, len);
2623 }
2624 catch (ArgumentOutOfRangeException)
2625 {
2626 JVM.SetPendingException(new java.lang.ArrayIndexOutOfBoundsException());
2627 }
2628 }
2629
2630 internal static void GetDoubleArrayRegion(JNIEnv* pEnv, nint array, int start, int len, jdouble* buf)
2631 {
2632 try
2633 {
2634 double[] b = (double[])pEnv->UnwrapRef(array);
2635 Marshal.Copy(b, start, (IntPtr)buf, len);
2636 }
2637 catch (ArgumentOutOfRangeException)
2638 {
2639 JVM.SetPendingException(new java.lang.ArrayIndexOutOfBoundsException());
2640 }
2641 }
2642
2643 internal static void SetBooleanArrayRegion(JNIEnv* pEnv, nint array, int start, int len, jboolean* buf)
2644 {
2645 try
2646 {
2647 bool[] b = (bool[])pEnv->UnwrapRef(array);
2648 sbyte* p = (sbyte*)(void*)buf;
2649 for (int i = 0; i < len; i++)
2650 {
2651 b[start + i] = *p++ != JNI_FALSE;
2652 }
2653 }
2654 catch (IndexOutOfRangeException)
2655 {
2656 JVM.SetPendingException(new java.lang.ArrayIndexOutOfBoundsException());
2657 }
2658 }
2659
2660 internal static void SetByteArrayRegion(JNIEnv* pEnv, nint array, int start, int len, jbyte* buf)
2661 {
2662 try
2663 {
2664 byte[] b = (byte[])pEnv->UnwrapRef(array);
2665 byte* p = (byte*)(void*)buf;
2666 for (int i = 0; i < len; i++)
2667 {
2668 b[start + i] = *p++;
2669 }
2670 }
2671 catch (IndexOutOfRangeException)
2672 {
2673 JVM.SetPendingException(new java.lang.ArrayIndexOutOfBoundsException());
2674 }
2675 }
2676
2677 internal static void SetCharArrayRegion(JNIEnv* pEnv, nint array, int start, int len, jchar* buf)
2678 {
2679 try
2680 {
2681 char[] b = (char[])pEnv->UnwrapRef(array);
2682 Marshal.Copy((IntPtr)buf, b, start, len);
2683 }
2684 catch (ArgumentOutOfRangeException)
2685 {
2686 JVM.SetPendingException(new java.lang.ArrayIndexOutOfBoundsException());
2687 }
2688 }
2689
2690 internal static void SetShortArrayRegion(JNIEnv* pEnv, nint array, int start, int len, jshort* buf)
2691 {
2692 try
2693 {
2694 short[] b = (short[])pEnv->UnwrapRef(array);
2695 Marshal.Copy((IntPtr)buf, b, start, len);
2696 }
2697 catch (ArgumentOutOfRangeException)
2698 {
2699 JVM.SetPendingException(new java.lang.ArrayIndexOutOfBoundsException());
2700 }
2701 }
2702
2703 internal static void SetIntArrayRegion(JNIEnv* pEnv, nint array, int start, int len, jint* buf)
2704 {
2705 try
2706 {
2707 int[] b = (int[])pEnv->UnwrapRef(array);
2708 Marshal.Copy((IntPtr)buf, b, start, len);
2709 }
2710 catch (ArgumentOutOfRangeException)
2711 {
2712 JVM.SetPendingException(new java.lang.ArrayIndexOutOfBoundsException());
2713 }
2714 }
2715
2716 internal static void SetLongArrayRegion(JNIEnv* pEnv, nint array, int start, int len, jlong* buf)
2717 {
2718 try
2719 {
2720 long[] b = (long[])pEnv->UnwrapRef(array);
2721 Marshal.Copy((IntPtr)buf, b, start, len);
2722 }
2723 catch (ArgumentOutOfRangeException)
2724 {
2725 JVM.SetPendingException(new java.lang.ArrayIndexOutOfBoundsException());
2726 }
2727 }
2728
2729 internal static void SetFloatArrayRegion(JNIEnv* pEnv, nint array, int start, int len, jfloat* buf)
2730 {
2731 try
2732 {
2733 float[] b = (float[])pEnv->UnwrapRef(array);
2734 Marshal.Copy((IntPtr)buf, b, start, len);
2735 }
2736 catch (ArgumentOutOfRangeException)
2737 {
2738 JVM.SetPendingException(new java.lang.ArrayIndexOutOfBoundsException());
2739 }
2740 }
2741
2742 internal static void SetDoubleArrayRegion(JNIEnv* pEnv, nint array, int start, int len, jdouble* buf)
2743 {
2744 try
2745 {
2746 double[] b = (double[])pEnv->UnwrapRef(array);
2747 Marshal.Copy((IntPtr)buf, b, start, len);
2748 }
2749 catch (ArgumentOutOfRangeException)
2750 {
2751 JVM.SetPendingException(new java.lang.ArrayIndexOutOfBoundsException());
2752 }
2753 }
2754
2755 [StructLayout(LayoutKind.Sequential)]
2756 unsafe internal struct JNINativeMethod
2757 {
2758 public byte* name;
2759 public byte* signature;
2760 public void* fnPtr;
2761 }
2762
2763 internal static jint RegisterNatives(JNIEnv* pEnv, nint clazz, JNINativeMethod* methods, jint nMethods)
2764 {
2765 try
2766 {
2767 var wrapper = RuntimeJavaType.FromClass((java.lang.Class)pEnv->UnwrapRef(clazz));
2768 wrapper.Finish();
2769 for (int i = 0; i < nMethods; i++)
2770 {
2771 var methodName = DecodeMUTF8(methods[i].name);
2772 var methodSig = DecodeMUTF8(methods[i].signature);
2773
2774 JVM.Context.Diagnostics.GenericJniInfo($"Registering native method: {wrapper.Name}.{methodName}{methodSig}, fnPtr = 0x{((IntPtr)methods[i].fnPtr).ToInt64():X}");
2775 FieldInfo fi = null;
2776
2777 // don't allow dotted names!
2778 if (methodSig.IndexOf('.') < 0)
2779 fi = wrapper.TypeAsTBD.GetField(METHOD_PTR_FIELD_PREFIX + methodName + methodSig, BindingFlags.Static | BindingFlags.NonPublic);
2780
2781 if (fi == null)
2782 {
2783 JVM.Context.Diagnostics.GenericJniError($"Failed to register native method: {wrapper.Name}.{methodName}{methodSig}");
2784 throw new java.lang.NoSuchMethodError(methodName);
2785 }
2786
2787 fi.SetValue(null, (IntPtr)methods[i].fnPtr);
2788 }
2789 return JNI_OK;
2790 }
2792 {
2793 JVM.SetPendingException(e.ToJava());
2794 return JNI_ERR;
2795 }
2796 catch (Exception e)
2797 {
2798 JVM.SetPendingException(e);
2799 return JNI_ERR;
2800 }
2801 }
2802
2803 internal static jint UnregisterNatives(JNIEnv* pEnv, nint clazz)
2804 {
2805 try
2806 {
2807 RuntimeJavaType wrapper = RuntimeJavaType.FromClass((java.lang.Class)pEnv->UnwrapRef(clazz));
2808 wrapper.Finish();
2809 // TODO this won't work when we're putting the JNI methods in jniproxy.dll
2810 foreach (FieldInfo fi in wrapper.TypeAsTBD.GetFields(BindingFlags.Static | BindingFlags.NonPublic))
2811 {
2812 string name = fi.Name;
2813 if (name.StartsWith(METHOD_PTR_FIELD_PREFIX))
2814 {
2815 JVM.Context.Diagnostics.GenericJniInfo($"Unregistering native method: {wrapper.Name}.{name.Substring(METHOD_PTR_FIELD_PREFIX.Length)}");
2816 fi.SetValue(null, IntPtr.Zero);
2817 }
2818 }
2819 return JNI_OK;
2820 }
2822 {
2823 JVM.SetPendingException(x.ToJava());
2824 return JNI_ERR;
2825 }
2826 catch (Exception x)
2827 {
2828 JVM.SetPendingException(x);
2829 return JNI_ERR;
2830 }
2831 }
2832
2833 internal static jint MonitorEnter(JNIEnv* pEnv, nint obj)
2834 {
2835 try
2836 {
2837 // on .NET 4.0 Monitor.Enter has been marked obsolete,
2838 // but in this case the alternative adds no value
2839#pragma warning disable 618
2840 System.Threading.Monitor.Enter(pEnv->UnwrapRef(obj));
2841#pragma warning restore 618
2842 return JNI_OK;
2843 }
2844 catch (Exception x)
2845 {
2846 JVM.SetPendingException(x);
2847 return JNI_ERR;
2848 }
2849 }
2850
2851 internal static jint MonitorExit(JNIEnv* pEnv, nint obj)
2852 {
2853 try
2854 {
2855 System.Threading.Monitor.Exit(pEnv->UnwrapRef(obj));
2856 return JNI_OK;
2857 }
2858 catch (Exception x)
2859 {
2860 JVM.SetPendingException(x);
2861 return JNI_ERR;
2862 }
2863 }
2864
2865 internal static jint GetJavaVM(JNIEnv* pEnv, JavaVM** ppJavaVM)
2866 {
2867 *ppJavaVM = JavaVM.pJavaVM;
2868 return JNI_OK;
2869 }
2870
2871 internal static void GetStringRegion(JNIEnv* pEnv, nint str, jsize start, jsize len, jchar* buf)
2872 {
2873 string s = (string)pEnv->UnwrapRef(str);
2874 if (s != null)
2875 {
2876 if (start < 0 || start > s.Length || s.Length - start < len)
2877 {
2878 JVM.SetPendingException(new java.lang.StringIndexOutOfBoundsException());
2879 return;
2880 }
2881 else
2882 {
2883 char* p = (char*)(void*)buf;
2884 // TODO isn't there a managed memcpy?
2885 for (int i = 0; i < len; i++)
2886 {
2887 *p++ = s[start + i];
2888 }
2889 return;
2890 }
2891 }
2892 else
2893 {
2894 JVM.SetPendingException(new java.lang.NullPointerException());
2895 }
2896 }
2897
2898 internal static void GetStringUTFRegion(JNIEnv* pEnv, nint str, jsize start, jsize len, byte* buf)
2899 {
2900 string s = (string)pEnv->UnwrapRef(str);
2901 if (s != null)
2902 {
2903 if (start < 0 || start > s.Length || s.Length - start < len)
2904 {
2905 JVM.SetPendingException(new java.lang.StringIndexOutOfBoundsException());
2906 return;
2907 }
2908 else
2909 {
2910 byte* p = (byte*)(void*)buf;
2911 for (int i = 0; i < len; i++)
2912 {
2913 char ch = s[start + i];
2914 if ((ch != 0) && (ch <= 0x7F))
2915 {
2916 *p++ = (byte)ch;
2917 }
2918 else if (ch <= 0x7FF)
2919 {
2920 *p++ = (byte)((ch >> 6) | 0xC0);
2921 *p++ = (byte)((ch & 0x3F) | 0x80);
2922 }
2923 else
2924 {
2925 *p++ = (byte)((ch >> 12) | 0xE0);
2926 *p++ = (byte)(((ch >> 6) & 0x3F) | 0x80);
2927 *p++ = (byte)((ch & 0x3F) | 0x80);
2928 }
2929 }
2930 return;
2931 }
2932 }
2933 else
2934 {
2935 JVM.SetPendingException(new java.lang.NullPointerException());
2936 }
2937 }
2938
2939 void* PinObject(object obj)
2940 {
2941 if (pinHandleInUseCount == pinHandleMaxCount)
2942 {
2943 var newCount = pinHandleMaxCount + 32;
2944 var pNew = (GCHandle*)JNIMemory.Alloc(sizeof(GCHandle) * newCount);
2945 for (int i = 0; i < pinHandleMaxCount; i++)
2946 pNew[i] = pinHandles[i];
2947
2948 for (int i = pinHandleMaxCount; i < newCount; i++)
2949 pNew[i] = new GCHandle();
2950
2951 JNIMemory.Free((nint)pinHandles);
2952 pinHandles = pNew;
2953 pinHandleMaxCount = newCount;
2954 }
2955
2956 var index = pinHandleInUseCount++;
2957 if (pinHandles[index].IsAllocated == false)
2958 pinHandles[index] = GCHandle.Alloc(null, GCHandleType.Pinned);
2959
2960 pinHandles[index].Target = obj;
2961 return (void*)pinHandles[index].AddrOfPinnedObject();
2962 }
2963
2964 void UnpinObject(object obj)
2965 {
2966 for (int i = 0; i < pinHandleInUseCount; i++)
2967 {
2968 if (pinHandles[i].Target == obj)
2969 {
2970 pinHandles[i].Target = pinHandles[--pinHandleInUseCount].Target;
2971 pinHandles[pinHandleInUseCount].Target = null;
2972 return;
2973 }
2974 }
2975 }
2976
2977 internal static void* GetPrimitiveArrayCritical(JNIEnv* pEnv, nint array, jboolean* isCopy)
2978 {
2979 if (isCopy != null)
2980 *isCopy = JNI_FALSE;
2981
2982 return pEnv->PinObject(pEnv->UnwrapRef(array));
2983 }
2984
2985 internal static void ReleasePrimitiveArrayCritical(JNIEnv* pEnv, nint array, void* carray, jint mode)
2986 {
2987 pEnv->UnpinObject(pEnv->UnwrapRef(array));
2988 }
2989
2997 internal static jchar* GetStringCritical(JNIEnv* pEnv, nint str, jboolean* isCopy)
2998 {
2999 if (isCopy != null)
3000 *isCopy = JNI_FALSE;
3001
3002 return (jchar*)pEnv->PinObject(pEnv->UnwrapRef(str));
3003 }
3004
3011 internal static void ReleaseStringCritical(JNIEnv* pEnv, nint str, jchar* cstring)
3012 {
3013 pEnv->UnpinObject(pEnv->UnwrapRef(str));
3014 }
3015
3022 internal static nint NewWeakGlobalRef(JNIEnv* pEnv, nint obj)
3023 {
3024 var o = pEnv->UnwrapRef(obj);
3025 return o == null ? IntPtr.Zero : JNIGlobalRefTable.AddWeakGlobalRef(o);
3026 }
3027
3033 internal static void DeleteWeakGlobalRef(JNIEnv* pEnv, nint obj)
3034 {
3035 if (IsGlobalRef(obj))
3036 {
3038 return;
3039 }
3040
3041 if (IsLocalRef(obj))
3042 Debug.Assert(false, "Local ref passed to DeleteWeakGlobalRef");
3043 }
3044
3050 internal static jboolean ExceptionCheck(JNIEnv* pEnv)
3051 {
3052 return JVM.GetPendingException() != null ? JNI_TRUE : JNI_FALSE;
3053 }
3054
3055 internal static nint NewDirectByteBuffer(JNIEnv* pEnv, IntPtr address, jlong capacity)
3056 {
3057#if FIRST_PASS
3058 throw new NotImplementedException();
3059#else
3060 try
3061 {
3062 if (capacity < 0 || capacity > int.MaxValue)
3063 {
3064 JVM.SetPendingException(new java.lang.IllegalArgumentException("capacity"));
3065 return IntPtr.Zero;
3066 }
3067
3068 return pEnv->MakeLocalRef(global::java.nio.DirectByteBuffer.__new(address.ToInt64(), (int)capacity));
3069 }
3070 catch (Exception x)
3071 {
3072 JVM.SetPendingException(x);
3073 return IntPtr.Zero;
3074 }
3075#endif
3076 }
3077
3078 internal static void* GetDirectBufferAddress(JNIEnv* pEnv, nint buf)
3079 {
3080 try
3081 {
3082 return (void*)(IntPtr)((sun.nio.ch.DirectBuffer)pEnv->UnwrapRef(buf)).address();
3083 }
3084 catch (Exception x)
3085 {
3086 JVM.SetPendingException(x);
3087 return (void*)IntPtr.Zero;
3088 }
3089 }
3090
3091 internal static jlong GetDirectBufferCapacity(JNIEnv* pEnv, nint buf)
3092 {
3093 try
3094 {
3095 return (jlong)(long)((java.nio.Buffer)pEnv->UnwrapRef(buf)).capacity();
3096 }
3097 catch (Exception x)
3098 {
3099 JVM.SetPendingException(x);
3100 return 0;
3101 }
3102 }
3103
3104 internal static JObjectRefType GetObjectRefType(JNIEnv* pEnv, nint obj)
3105 {
3106 int i = ((IntPtr)obj).ToInt32();
3107 if (i >= 0)
3108 return JObjectRefType.JNILocalRefType;
3109
3110 i = -i;
3111 if ((i & (1 << 30)) != 0)
3112 return JObjectRefType.JNIWeakGlobalRefType;
3113 else
3114 return JObjectRefType.JNIGlobalRefType;
3115 }
3116
3117 internal nint MakeLocalRef(object obj)
3118 {
3119 return GetContext().MakeLocalRef(obj);
3120 }
3121
3122 internal object UnwrapRef(nint o)
3123 {
3124 if (IsLocalRef(o))
3125 return GetContext().UnwrapLocalRef(o);
3126 else if (IsGlobalRef(o))
3127 return JNIGlobalRefTable.Unwrap(o);
3128 return null;
3129 }
3130
3131 internal static object UnwrapRef(JNIEnvContext env, nint o)
3132 {
3133 if (IsLocalRef(o))
3134 return env.UnwrapLocalRef(o);
3135 else if (IsGlobalRef(o))
3136 return JNIGlobalRefTable.Unwrap(o);
3137 else
3138 return null;
3139 }
3140
3141 static bool IsLocalRef(nint o)
3142 {
3143 return o > 0;
3144 }
3145
3146 static bool IsGlobalRef(nint o)
3147 {
3148 return o < 0;
3149 }
3150
3151 }
3152
3153#endif
3154
3155}
IKVM.Reflection.FieldInfo FieldInfo
static global::java.lang.Class getClassFromObject(object o)
Definition Util.cs:35
static global::java.lang.Class defineClass0(global::java.lang.ClassLoader self, string name, byte[] b, int off, int len, global::java.security.ProtectionDomain pd)
Implements the native method 'defineClass0'.
static unsafe int GetIndexOfNull(byte *ptr, int max=int.MaxValue)
Gets the length of a pointer to a C string.
Maintains a set of global refereces to instances.
static void DeleteGlobalRef(nint o)
Deletes a global ref from the table.
static nint AddWeakGlobalRef(object o)
Adds a new global ref to the table.
static void DeleteWeakGlobalRef(nint o)
Deletes a weak global ref from the table.
static nint AddGlobalRef(object o)
Adds a new global ref to the table.
Provides methods to assist in allocating memory for JNI.
Definition JNIMemory.cs:33
static nint Alloc(int cb)
static void Free(nint p)
Main state of the running JVM.
.NET exception that corresponds to a Java exception.
Runtime support for a class loader.
Maintains services relevant to an instane of the IKVM runtime.
IDiagnosticHandler Diagnostics
Gets the IDiagnosticHandler where events should be sent.
RuntimeClassLoaderFactory ClassLoaderFactory
Gets the RuntimeClassLoaderFactory associated with this instance of the runtime.
void GenericJniError(string arg0)
The 'GenericJniError' diagnostic.
void GenericJniInfo(string arg0)
The 'GenericJniInfo' diagnostic.
System.Int16 jshort
Definition JNIEnv.cs:47
System.Single jfloat
Definition JNIEnv.cs:44
System.Double jdouble
Definition JNIEnv.cs:43
System.SByte jboolean
System.SByte jbyte
Definition JNIEnv.cs:41
System.Int32 jint
Definition JavaVM.cs:35
System.UInt16 jchar
Definition JNIEnv.cs:42
System.Int64 jlong
Definition JNIEnv.cs:46
System.Int32 jsize
Definition JNIEnv.cs:48
static nint FindMethodID(JNIEnv *pEnv, nint clazz, byte *name, byte *sig, bool isStatic)
Definition JNIEnv.cs:863
static bool IsLocalRef(nint o)
Definition JNIEnv.cs:3141
static nint FindFieldID(JNIEnv *pEnv, nint clazz, byte *name, byte *sig, bool isStatic)
Definition JNIEnv.cs:1249
static bool IsGlobalRef(nint o)
Definition JNIEnv.cs:3146
static RuntimeJavaField GetFieldWrapper(nint cookie)
Definition JNIEnv.cs:1290
static RuntimeJavaMethod GetInterfaceMethodImpl(RuntimeJavaType tw, string name, string sig)
Definition JNIEnv.cs:851
static RuntimeJavaField GetFieldImpl(RuntimeJavaType tw, string name, string sig)
Definition JNIEnv.cs:1235
static readonly MUTF8Encoding MUTF8
Definition JNIEnv.cs:76
void UnpinObject(object obj)
Definition JNIEnv.cs:2964
static object InvokeNonVirtual(JNIEnvContext env, RuntimeJavaMethod mw, object obj, object[] argarray)
Invokes the given non-virtual method, by ID, on the given object handle. Accepts a pointer to a JValu...
Definition JNIEnv.cs:732
static void AppendInterfaces(List< RuntimeJavaType > list, IList< RuntimeJavaType > add)
Definition JNIEnv.cs:826
static RuntimeClassLoader FindNativeMethodClassLoader(JNIEnv *pEnv)
Definition JNIEnv.cs:196
void * PinObject(object obj)
Definition JNIEnv.cs:2939
static RuntimeJavaMethod GetMethodImpl(RuntimeJavaType tw, string name, string sig)
Definition JNIEnv.cs:812
static List< RuntimeJavaType > TransitiveInterfaces(RuntimeJavaType tw)
Definition JNIEnv.cs:833
static nint NewObjectA(JNIEnv *pEnv, nint clazz, nint methodID, JValue *args)
Definition JNIEnv.cs:752
static nint AllocObjectImpl(JNIEnv *pEnv, RuntimeJavaType wrapper)
Definition JNIEnv.cs:622
static object InvokeHelper(JNIEnv *pEnv, nint objHandle, nint methodID, JValue *pArgs, bool nonVirtual)
Invokes the given method, by ID, on the given object handle. Accepts a pointer to a JValue array of a...
Definition JNIEnv.cs:652
Manged implementation of the JNINativeInterface structure.
static JNINativeInterface * Handle
Gets a pointer to the JNINativeInterface table.
Union type that represents 'jvalue'.
Definition jvalue.cs:21