package com.oracle.svm.jni.functions;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Executable;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.util.Arrays;
import org.graalvm.compiler.serviceprovider.GraalUnsafeAccess;
import org.graalvm.nativeimage.ImageSingletons;
import org.graalvm.nativeimage.IsolateThread;
import org.graalvm.nativeimage.LogHandler;
import org.graalvm.nativeimage.StackValue;
import org.graalvm.nativeimage.c.function.CEntryPoint;
import org.graalvm.nativeimage.c.function.CFunctionPointer;
import org.graalvm.nativeimage.c.function.InvokeCFunctionPointer;
import org.graalvm.nativeimage.c.struct.SizeOf;
import org.graalvm.nativeimage.c.type.CCharPointer;
import org.graalvm.nativeimage.c.type.CLongPointer;
import org.graalvm.nativeimage.c.type.CShortPointer;
import org.graalvm.nativeimage.c.type.CTypeConversion;
import org.graalvm.nativeimage.c.type.WordPointer;
import org.graalvm.word.Pointer;
import org.graalvm.word.WordBase;
import org.graalvm.word.WordFactory;
import com.oracle.svm.core.SubstrateUtil;
import com.oracle.svm.core.annotate.Alias;
import com.oracle.svm.core.annotate.NeverInline;
import com.oracle.svm.core.annotate.TargetClass;
import com.oracle.svm.core.annotate.Uninterruptible;
import com.oracle.svm.core.c.CGlobalData;
import com.oracle.svm.core.c.CGlobalDataFactory;
import com.oracle.svm.core.c.function.CEntryPointActions;
import com.oracle.svm.core.c.function.CEntryPointErrors;
import com.oracle.svm.core.c.function.CEntryPointOptions;
import com.oracle.svm.core.c.function.CEntryPointOptions.Publish;
import com.oracle.svm.core.hub.DynamicHub;
import com.oracle.svm.core.log.Log;
import com.oracle.svm.core.monitor.MonitorSupport;
import com.oracle.svm.core.snippets.KnownIntrinsics;
import com.oracle.svm.core.thread.VMThreads;
import com.oracle.svm.core.util.Utf8;
import com.oracle.svm.core.util.VMError;
import com.oracle.svm.jni.JNIObjectHandles;
import com.oracle.svm.jni.JNIThreadLocalPendingException;
import com.oracle.svm.jni.JNIThreadLocalPinnedObjects;
import com.oracle.svm.jni.JNIThreadOwnedMonitors;
import com.oracle.svm.jni.access.JNIAccessFeature;
import com.oracle.svm.jni.access.JNIAccessibleMethod;
import com.oracle.svm.jni.access.JNIAccessibleMethodDescriptor;
import com.oracle.svm.jni.access.JNINativeLinkage;
import com.oracle.svm.jni.access.JNIReflectionDictionary;
import com.oracle.svm.jni.functions.JNIFunctions.Support.JNIEnvEnterFatalOnFailurePrologue;
import com.oracle.svm.jni.functions.JNIFunctions.Support.JNIEnvEnterReturnEDetachedOnFailurePrologue;
import com.oracle.svm.jni.functions.JNIFunctions.Support.JNIEnvEnterReturnMinusOneOnFailurePrologue;
import com.oracle.svm.jni.functions.JNIFunctions.Support.JNIEnvEnterReturnNullHandleOnFailurePrologue;
import com.oracle.svm.jni.functions.JNIFunctions.Support.JNIEnvEnterReturnNullWordOnFailurePrologue;
import com.oracle.svm.jni.functions.JNIFunctions.Support.JNIExceptionHandlerReturnFalse;
import com.oracle.svm.jni.functions.JNIFunctions.Support.JNIExceptionHandlerReturnJniErr;
import com.oracle.svm.jni.functions.JNIFunctions.Support.JNIExceptionHandlerReturnMinusOne;
import com.oracle.svm.jni.functions.JNIFunctions.Support.JNIExceptionHandlerReturnNullHandle;
import com.oracle.svm.jni.functions.JNIFunctions.Support.JNIExceptionHandlerReturnNullWord;
import com.oracle.svm.jni.functions.JNIFunctions.Support.JNIExceptionHandlerReturnZero;
import com.oracle.svm.jni.functions.JNIFunctions.Support.JNIExceptionHandlerVoid;
import com.oracle.svm.jni.nativeapi.JNIEnvironment;
import com.oracle.svm.jni.nativeapi.JNIErrors;
import com.oracle.svm.jni.nativeapi.JNIFieldId;
import com.oracle.svm.jni.nativeapi.JNIJavaVM;
import com.oracle.svm.jni.nativeapi.JNIJavaVMPointer;
import com.oracle.svm.jni.nativeapi.JNIMethodId;
import com.oracle.svm.jni.nativeapi.JNINativeMethod;
import com.oracle.svm.jni.nativeapi.JNIObjectHandle;
import com.oracle.svm.jni.nativeapi.JNIObjectRefType;
import com.oracle.svm.jni.nativeapi.JNIVersion;
import jdk.vm.ci.meta.MetaUtil;
import sun.misc.Unsafe;
@SuppressWarnings("unused")
final class JNIFunctions {
private static final Unsafe UNSAFE = GraalUnsafeAccess.getUnsafe();
@CEntryPoint
@CEntryPointOptions(prologue = CEntryPointOptions.NoPrologue.class, epilogue = CEntryPointOptions.NoEpilogue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
@Uninterruptible(reason = "No need to enter the isolate and also no way to report errors if unable to.")
static int GetVersion(JNIEnvironment env) {
return JNIVersion.JNI_VERSION_1_8();
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnNullHandle.class)
@CEntryPointOptions(prologue = JNIEnvEnterReturnNullHandleOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static JNIObjectHandle NewLocalRef(JNIEnvironment env, JNIObjectHandle ref) {
return JNIObjectHandles.newLocalRef(ref);
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerVoid.class)
@CEntryPointOptions(prologue = JNIEnvEnterFatalOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static void DeleteLocalRef(JNIEnvironment env, JNIObjectHandle localRef) {
JNIObjectHandles.deleteLocalRef(localRef);
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnJniErr.class)
@CEntryPointOptions(prologue = JNIEnvEnterReturnEDetachedOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static int EnsureLocalCapacity(JNIEnvironment env, int capacity) {
if (capacity < 0) {
return JNIErrors.JNI_ERR();
}
JNIObjectHandles.ensureLocalCapacity(capacity);
return 0;
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnJniErr.class)
@CEntryPointOptions(prologue = JNIEnvEnterReturnEDetachedOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static int PushLocalFrame(JNIEnvironment env, int capacity) {
if (capacity < 0) {
return JNIErrors.JNI_ERR();
}
JNIObjectHandles.pushLocalFrame(capacity);
return 0;
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnNullHandle.class)
@CEntryPointOptions(prologue = JNIEnvEnterReturnNullHandleOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static JNIObjectHandle PopLocalFrame(JNIEnvironment env, JNIObjectHandle handle) {
Object obj = JNIObjectHandles.getObject(handle);
JNIObjectHandles.popLocalFrame();
return JNIObjectHandles.createLocal(obj);
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnFalse.class)
@CEntryPointOptions(prologue = JNIEnvEnterFatalOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static boolean IsSameObject(JNIEnvironment env, JNIObjectHandle ref1, JNIObjectHandle ref2) {
Object obj1 = JNIObjectHandles.getObject(ref1);
Object obj2 = JNIObjectHandles.getObject(ref2);
return obj1 == obj2;
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnFalse.class)
@CEntryPointOptions(prologue = JNIEnvEnterFatalOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static boolean IsInstanceOf(JNIEnvironment env, JNIObjectHandle obj, JNIObjectHandle clazz) {
Object o = JNIObjectHandles.getObject(obj);
if (o == null) {
return true;
}
Class<?> c = JNIObjectHandles.getObject(clazz);
return c.isInstance(o);
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnNullHandle.class)
@CEntryPointOptions(prologue = JNIEnvEnterReturnNullHandleOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static JNIObjectHandle GetObjectClass(JNIEnvironment env, JNIObjectHandle handle) {
Object obj = JNIObjectHandles.getObject(handle);
Class<?> clazz = obj.getClass();
return JNIObjectHandles.createLocal(clazz);
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnNullHandle.class)
@CEntryPointOptions(prologue = JNIEnvEnterReturnNullHandleOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static JNIObjectHandle GetSuperclass(JNIEnvironment env, JNIObjectHandle handle) {
Class<?> clazz = JNIObjectHandles.getObject(handle);
return JNIObjectHandles.createLocal(clazz.getSuperclass());
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnFalse.class)
@CEntryPointOptions(prologue = JNIEnvEnterFatalOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static boolean IsAssignableFrom(JNIEnvironment env, JNIObjectHandle handle1, JNIObjectHandle handle2) {
Class<?> clazz1 = JNIObjectHandles.getObject(handle1);
Class<?> clazz2 = JNIObjectHandles.getObject(handle2);
return clazz2.isAssignableFrom(clazz1);
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnNullHandle.class)
@CEntryPointOptions(prologue = JNIEnvEnterFatalOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static JNIObjectHandle NewGlobalRef(JNIEnvironment env, JNIObjectHandle handle) {
return JNIObjectHandles.newGlobalRef(handle);
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerVoid.class)
@CEntryPointOptions(prologue = JNIEnvEnterFatalOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static void DeleteGlobalRef(JNIEnvironment env, JNIObjectHandle globalRef) {
JNIObjectHandles.deleteGlobalRef(globalRef);
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnNullHandle.class)
@CEntryPointOptions(prologue = JNIEnvEnterReturnNullHandleOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static JNIObjectHandle NewWeakGlobalRef(JNIEnvironment env, JNIObjectHandle handle) {
return JNIObjectHandles.newWeakGlobalRef(handle);
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerVoid.class)
@CEntryPointOptions(prologue = JNIEnvEnterFatalOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static void DeleteWeakGlobalRef(JNIEnvironment env, JNIObjectHandle weak) {
JNIObjectHandles.deleteWeakGlobalRef(weak);
}
@CEntryPoint
@CEntryPointOptions(prologue = JNIEnvEnterFatalOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static JNIObjectRefType GetObjectRefType(JNIEnvironment env, JNIObjectHandle handle) {
try {
return JNIObjectHandles.getHandleType(handle);
} catch (Throwable t) {
return JNIObjectRefType.Invalid;
}
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnNullHandle.class)
@CEntryPointOptions(prologue = JNIEnvEnterReturnNullHandleOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static JNIObjectHandle FindClass(JNIEnvironment env, CCharPointer cname) {
String name = Utf8.utf8ToString(cname);
if (!name.startsWith("[")) {
name = "L" + name + ";";
}
Class<?> clazz = JNIReflectionDictionary.singleton().getClassObjectByName(name);
if (clazz == null) {
throw new NoClassDefFoundError(name);
}
DynamicHub.fromClass(clazz).ensureInitialized();
return JNIObjectHandles.createLocal(clazz);
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnJniErr.class)
@CEntryPointOptions(prologue = JNIEnvEnterReturnEDetachedOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static int RegisterNatives(JNIEnvironment env, JNIObjectHandle hclazz, JNINativeMethod methods, int nmethods) {
Class<?> clazz = JNIObjectHandles.getObject(hclazz);
Pointer p = (Pointer) methods;
for (int i = 0; i < nmethods; i++) {
JNINativeMethod entry = (JNINativeMethod) p;
String name = Utf8.utf8ToString(entry.name());
String signature = Utf8.utf8ToString(entry.signature());
CFunctionPointer fnPtr = entry.fnPtr();
String declaringClass = MetaUtil.toInternalName(clazz.getName());
JNINativeLinkage linkage = JNIReflectionDictionary.singleton().getLinkage(declaringClass, name, signature);
if (linkage != null) {
linkage.setEntryPoint(fnPtr);
} else {
String message = clazz.getName() + '.' + name + signature;
JNINativeLinkage l = JNIReflectionDictionary.singleton().getClosestLinkage(declaringClass, name, signature);
if (l != null) {
message += " (found closely matching JNI-accessible method: " +
MetaUtil.internalNameToJava(l.getDeclaringClassName(), true, false) +
"." + l.getName() + l.getDescriptor() + ")";
}
throw new NoSuchMethodError(message);
}
p = p.add(SizeOf.get(JNINativeMethod.class));
}
return JNIErrors.JNI_OK();
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnJniErr.class)
@CEntryPointOptions(prologue = JNIEnvEnterReturnEDetachedOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static int UnregisterNatives(JNIEnvironment env, JNIObjectHandle hclazz) {
Class<?> clazz = JNIObjectHandles.getObject(hclazz);
String internalName = MetaUtil.toInternalName(clazz.getName());
JNIReflectionDictionary.singleton().unsetEntryPoints(internalName);
return JNIErrors.JNI_OK();
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnNullWord.class)
@CEntryPointOptions(prologue = JNIEnvEnterReturnNullWordOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static JNIMethodId GetMethodID(JNIEnvironment env, JNIObjectHandle hclazz, CCharPointer cname, CCharPointer csig) {
return Support.getMethodID(hclazz, cname, csig, false);
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnNullWord.class)
@CEntryPointOptions(prologue = JNIEnvEnterReturnNullWordOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static JNIMethodId GetStaticMethodID(JNIEnvironment env, JNIObjectHandle hclazz, CCharPointer cname, CCharPointer csig) {
return Support.getMethodID(hclazz, cname, csig, true);
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnNullWord.class)
@CEntryPointOptions(prologue = JNIEnvEnterReturnNullWordOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static JNIFieldId GetFieldID(JNIEnvironment env, JNIObjectHandle hclazz, CCharPointer cname, CCharPointer csig) {
return Support.getFieldID(hclazz, cname, csig, false);
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnNullWord.class)
@CEntryPointOptions(prologue = JNIEnvEnterReturnNullWordOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static JNIFieldId GetStaticFieldID(JNIEnvironment env, JNIObjectHandle hclazz, CCharPointer cname, CCharPointer csig) {
return Support.getFieldID(hclazz, cname, csig, true);
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnNullHandle.class)
@CEntryPointOptions(prologue = JNIEnvEnterReturnNullHandleOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static JNIObjectHandle AllocObject(JNIEnvironment env, JNIObjectHandle classHandle) {
Class<?> clazz = JNIObjectHandles.getObject(classHandle);
Object instance;
try {
instance = UNSAFE.allocateInstance(clazz);
} catch (InstantiationException e) {
instance = null;
}
return JNIObjectHandles.createLocal(instance);
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnNullHandle.class)
@CEntryPointOptions(prologue = JNIEnvEnterReturnNullHandleOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static JNIObjectHandle NewString(JNIEnvironment env, CShortPointer unicode, int len) {
String str;
char[] chars = new char[len];
for (int i = 0; i < chars.length; i++) {
int value = Short.toUnsignedInt(unicode.read(i));
chars[i] = (char) value;
}
str = new String(chars);
return JNIObjectHandles.createLocal(str);
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnNullHandle.class)
@CEntryPointOptions(prologue = JNIEnvEnterReturnNullHandleOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static JNIObjectHandle NewStringUTF(JNIEnvironment env, CCharPointer bytes) {
return JNIObjectHandles.createLocal(Utf8.utf8ToString(bytes));
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnMinusOne.class)
@CEntryPointOptions(prologue = JNIEnvEnterReturnMinusOneOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static int GetStringLength(JNIEnvironment env, JNIObjectHandle hstr) {
String str = JNIObjectHandles.getObject(hstr);
return (str != null) ? str.length() : 0;
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnMinusOne.class)
@CEntryPointOptions(prologue = JNIEnvEnterReturnMinusOneOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static int GetStringUTFLength(JNIEnvironment env, JNIObjectHandle hstr) {
String str = JNIObjectHandles.getObject(hstr);
return Utf8.utf8Length(str);
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnNullWord.class)
@CEntryPointOptions(prologue = JNIEnvEnterReturnNullWordOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static CShortPointer GetStringChars(JNIEnvironment env, JNIObjectHandle hstr, CCharPointer isCopy) {
return Support.getNulTerminatedStringCharsAndPin(hstr, isCopy);
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerVoid.class)
@CEntryPointOptions(prologue = JNIEnvEnterFatalOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static void ReleaseStringChars(JNIEnvironment env, JNIObjectHandle hstr, CShortPointer chars) {
Support.unpinString(chars);
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnNullWord.class)
@CEntryPointOptions(prologue = JNIEnvEnterReturnNullWordOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static CCharPointer GetStringUTFChars(JNIEnvironment env, JNIObjectHandle hstr, CCharPointer isCopy) {
String str = JNIObjectHandles.getObject(hstr);
if (str == null) {
return WordFactory.nullPointer();
}
if (isCopy.isNonNull()) {
isCopy.write((byte) 1);
}
byte[] utf = Utf8.stringToUtf8(str, true);
return JNIThreadLocalPinnedObjects.pinArrayAndGetAddress(utf);
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerVoid.class)
@CEntryPointOptions(prologue = JNIEnvEnterFatalOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static void ReleaseStringUTFChars(JNIEnvironment env, JNIObjectHandle hstr, CCharPointer chars) {
JNIThreadLocalPinnedObjects.unpinArrayByAddress(chars);
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnNullWord.class)
@CEntryPointOptions(prologue = JNIEnvEnterReturnNullWordOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static CShortPointer GetStringCritical(JNIEnvironment env, JNIObjectHandle hstr, CCharPointer isCopy) {
return Support.getNulTerminatedStringCharsAndPin(hstr, isCopy);
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerVoid.class)
@CEntryPointOptions(prologue = JNIEnvEnterFatalOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static void ReleaseStringCritical(JNIEnvironment env, JNIObjectHandle hstr, CShortPointer carray) {
Support.unpinString(carray);
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerVoid.class)
@CEntryPointOptions(prologue = JNIEnvEnterFatalOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static void GetStringRegion(JNIEnvironment env, JNIObjectHandle hstr, int start, int len, CShortPointer buf) {
String str = JNIObjectHandles.getObject(hstr);
if (start < 0) {
throw new StringIndexOutOfBoundsException(start);
}
if (start + len > str.length()) {
throw new StringIndexOutOfBoundsException(start + len);
}
if (len < 0) {
throw new StringIndexOutOfBoundsException(len);
}
for (int i = 0; i < len; i++) {
char c = str.charAt(start + i);
buf.write(i, (short) c);
}
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerVoid.class)
@CEntryPointOptions(prologue = JNIEnvEnterFatalOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static void GetStringUTFRegion(JNIEnvironment env, JNIObjectHandle hstr, int start, int len, CCharPointer buf) {
String str = JNIObjectHandles.getObject(hstr);
if (start < 0) {
throw new StringIndexOutOfBoundsException(start);
}
if (start + len > str.length()) {
throw new StringIndexOutOfBoundsException(start + len);
}
if (len < 0) {
throw new StringIndexOutOfBoundsException(len);
}
int capacity = Utf8.maxUtf8ByteLength(len, true);
ByteBuffer buffer = CTypeConversion.asByteBuffer(buf, capacity);
Utf8.substringToUtf8(buffer, str, start, start + len, true);
}
@TargetClass(className = "java.nio.DirectByteBuffer")
static final class Target_java_nio_DirectByteBuffer {
@Alias
Target_java_nio_DirectByteBuffer(long addr, int cap) {
}
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnNullHandle.class)
@CEntryPointOptions(prologue = JNIEnvEnterReturnNullHandleOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static JNIObjectHandle NewDirectByteBuffer(JNIEnvironment env, WordPointer address, long capacity) {
Target_java_nio_DirectByteBuffer bb = new Target_java_nio_DirectByteBuffer(address.rawValue(), (int) capacity);
return JNIObjectHandles.createLocal(bb);
}
@TargetClass(java.nio.Buffer.class)
static final class Target_java_nio_Buffer {
@Alias long address;
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnNullWord.class)
@CEntryPointOptions(prologue = JNIEnvEnterReturnNullWordOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static WordPointer GetDirectBufferAddress(JNIEnvironment env, JNIObjectHandle handle) {
WordPointer address = WordFactory.nullPointer();
Object obj = JNIObjectHandles.getObject(handle);
if (obj instanceof Target_java_nio_Buffer) {
Target_java_nio_Buffer buf = (Target_java_nio_Buffer) obj;
address = WordFactory.pointer(buf.address);
}
return address;
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnMinusOne.class)
@CEntryPointOptions(prologue = JNIEnvEnterReturnMinusOneOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static long GetDirectBufferCapacity(JNIEnvironment env, JNIObjectHandle hbuf) {
Buffer buffer = JNIObjectHandles.getObject(hbuf);
return buffer.capacity();
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnNullHandle.class)
@CEntryPointOptions(prologue = JNIEnvEnterReturnNullHandleOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static JNIObjectHandle NewObjectArray(JNIEnvironment env, int length, JNIObjectHandle hElementClass, JNIObjectHandle hInitialElement) {
if (length < 0) {
return JNIObjectHandles.nullHandle();
}
Class<?> elementClass = JNIObjectHandles.getObject(hElementClass);
Object[] array = null;
if (elementClass != null) {
Object initialElement = JNIObjectHandles.getObject(hInitialElement);
array = (Object[]) Array.newInstance(elementClass, length);
Arrays.fill(array, initialElement);
}
return JNIObjectHandles.createLocal(array);
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnNullHandle.class)
@CEntryPointOptions(prologue = JNIEnvEnterReturnNullHandleOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static JNIObjectHandle GetObjectArrayElement(JNIEnvironment env, JNIObjectHandle harray, int index) {
Object[] array = JNIObjectHandles.getObject(harray);
Object value = array[index];
return JNIObjectHandles.createLocal(value);
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerVoid.class)
@CEntryPointOptions(prologue = JNIEnvEnterFatalOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static void SetObjectArrayElement(JNIEnvironment env, JNIObjectHandle harray, int index, JNIObjectHandle hvalue) {
Object[] array = JNIObjectHandles.getObject(harray);
Object value = JNIObjectHandles.getObject(hvalue);
array[index] = value;
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnNullWord.class)
@CEntryPointOptions(prologue = JNIEnvEnterReturnNullWordOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static WordPointer GetPrimitiveArrayCritical(JNIEnvironment env, JNIObjectHandle harray, CCharPointer isCopy) {
Object array = JNIObjectHandles.getObject(harray);
if (array == null) {
return WordFactory.nullPointer();
}
if (isCopy.isNonNull()) {
isCopy.write((byte) 0);
}
return JNIThreadLocalPinnedObjects.pinArrayAndGetAddress(array);
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerVoid.class)
@CEntryPointOptions(prologue = JNIEnvEnterFatalOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static void ReleasePrimitiveArrayCritical(JNIEnvironment env, JNIObjectHandle harray, WordPointer carray, int mode) {
JNIThreadLocalPinnedObjects.unpinArrayByAddress(carray);
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnMinusOne.class)
@CEntryPointOptions(prologue = JNIEnvEnterReturnMinusOneOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static int GetArrayLength(JNIEnvironment env, JNIObjectHandle harray) {
return Array.getLength(JNIObjectHandles.getObject(harray));
}
@CEntryPoint
@CEntryPointOptions(prologue = JNIEnvEnterFatalOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static boolean ExceptionCheck(JNIEnvironment env) {
return JNIThreadLocalPendingException.get() != null;
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnNullHandle.class)
@CEntryPointOptions(prologue = JNIEnvEnterReturnNullHandleOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static JNIObjectHandle ExceptionOccurred(JNIEnvironment env) {
return JNIObjectHandles.createLocal(JNIThreadLocalPendingException.get());
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerVoid.class)
@CEntryPointOptions(prologue = JNIEnvEnterFatalOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static void ExceptionClear(JNIEnvironment env) {
JNIThreadLocalPendingException.clear();
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerVoid.class)
@CEntryPointOptions(prologue = JNIEnvEnterFatalOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static void ExceptionDescribe(JNIEnvironment env) {
Throwable t = JNIThreadLocalPendingException.get();
JNIThreadLocalPendingException.clear();
if (t != null) {
if (t instanceof ThreadDeath) {
} else {
System.err.println("Exception in thread \"" + Thread.currentThread().getName() + "\": " + t.getClass().getCanonicalName());
try {
t.printStackTrace();
} catch (Throwable ignored) {
}
System.err.flush();
}
}
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnZero.class)
@CEntryPointOptions(prologue = JNIEnvEnterReturnEDetachedOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static int Throw(JNIEnvironment env, JNIObjectHandle handle) throws Throwable {
throw (Throwable) JNIObjectHandles.getObject(handle);
}
interface NewObjectWithObjectArrayArgFunctionPointer extends CFunctionPointer {
@InvokeCFunctionPointer
JNIObjectHandle invoke(JNIEnvironment env, JNIObjectHandle clazz, JNIMethodId ctor, CLongPointer array);
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnZero.class)
@CEntryPointOptions(prologue = JNIEnvEnterReturnEDetachedOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static int ThrowNew(JNIEnvironment env, JNIObjectHandle clazzHandle, CCharPointer message) throws Throwable {
Class<?> clazz = JNIObjectHandles.getObject(clazzHandle);
JNIMethodId ctor = Support.getMethodID(clazz, "<init>", "(Ljava/lang/String;)V", false);
JNIObjectHandle messageHandle = NewStringUTF(env, message);
NewObjectWithObjectArrayArgFunctionPointer newObjectA = (NewObjectWithObjectArrayArgFunctionPointer) env.getFunctions().getNewObjectA();
CLongPointer array = StackValue.get(Long.BYTES);
array.write(messageHandle.rawValue());
JNIObjectHandle exception = newObjectA.invoke(env, clazzHandle, ctor, array);
throw (Throwable) JNIObjectHandles.getObject(exception);
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerVoid.class)
@CEntryPointOptions(prologue = JNIEnvEnterFatalOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
@NeverInline("Access of caller frame.")
static void FatalError(JNIEnvironment env, CCharPointer message) {
Log log = Log.log().autoflush(true);
log.string("Fatal error reported via JNI: ").string(message).newline();
VMThreads.StatusSupport.setStatusIgnoreSafepoints();
SubstrateUtil.printDiagnostics(log, KnownIntrinsics.readCallerStackPointer(), KnownIntrinsics.readReturnAddress());
ImageSingletons.lookup(LogHandler.class).fatalError();
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnJniErr.class)
@CEntryPointOptions(prologue = JNIEnvEnterReturnEDetachedOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static int GetJavaVM(JNIEnvironment env, JNIJavaVMPointer vm) {
vm.write(JNIFunctionTables.singleton().getGlobalJavaVM());
return JNIErrors.JNI_OK();
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnNullWord.class)
@CEntryPointOptions(prologue = JNIEnvEnterReturnNullWordOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static JNIFieldId FromReflectedField(JNIEnvironment env, JNIObjectHandle fieldHandle) {
JNIFieldId fieldId = WordFactory.zero();
if (JNIAccessFeature.singleton().haveJavaRuntimeReflectionSupport()) {
Field obj = JNIObjectHandles.getObject(fieldHandle);
if (obj != null) {
boolean isStatic = Modifier.isStatic(obj.getModifiers());
fieldId = JNIReflectionDictionary.singleton().getDeclaredFieldID(obj.getDeclaringClass(), obj.getName(), isStatic);
}
}
return fieldId;
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnNullHandle.class)
@CEntryPointOptions(prologue = JNIEnvEnterReturnNullHandleOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static JNIObjectHandle ToReflectedField(JNIEnvironment env, JNIObjectHandle classHandle, JNIFieldId fieldId) {
Field field = null;
if (JNIAccessFeature.singleton().haveJavaRuntimeReflectionSupport()) {
Class<?> clazz = JNIObjectHandles.getObject(classHandle);
if (clazz != null) {
String name = JNIReflectionDictionary.singleton().getFieldNameByID(clazz, fieldId);
if (name != null) {
try {
field = clazz.getDeclaredField(name);
} catch (NoSuchFieldException ignored) {
}
}
}
}
return JNIObjectHandles.createLocal(field);
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnNullWord.class)
@CEntryPointOptions(prologue = JNIEnvEnterReturnNullWordOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static JNIMethodId FromReflectedMethod(JNIEnvironment env, JNIObjectHandle methodHandle) {
JNIMethodId methodId = WordFactory.nullPointer();
if (JNIAccessFeature.singleton().haveJavaRuntimeReflectionSupport()) {
Executable method = JNIObjectHandles.getObject(methodHandle);
if (method != null) {
boolean isStatic = Modifier.isStatic(method.getModifiers());
JNIAccessibleMethodDescriptor descriptor = JNIAccessibleMethodDescriptor.of(method);
methodId = JNIReflectionDictionary.singleton().getDeclaredMethodID(method.getDeclaringClass(), descriptor, isStatic);
}
}
return methodId;
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnNullHandle.class)
@CEntryPointOptions(prologue = JNIEnvEnterReturnNullHandleOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static JNIObjectHandle ToReflectedMethod(JNIEnvironment env, JNIObjectHandle classHandle, JNIMethodId methodId, boolean isStatic) {
Executable result = null;
if (JNIAccessFeature.singleton().haveJavaRuntimeReflectionSupport()) {
JNIAccessibleMethod jniMethod = JNIReflectionDictionary.getMethodByID(methodId);
JNIAccessibleMethodDescriptor descriptor = JNIReflectionDictionary.getMethodDescriptor(jniMethod);
if (descriptor != null) {
Class<?> clazz = jniMethod.getDeclaringClass().getClassObject();
if (descriptor.isConstructor()) {
for (Constructor<?> ctor : clazz.getDeclaredConstructors()) {
if (descriptor.equals(JNIAccessibleMethodDescriptor.of(ctor))) {
result = ctor;
break;
}
}
} else {
for (Method method : clazz.getDeclaredMethods()) {
if (descriptor.getName().equals(method.getName())) {
if (descriptor.equals(JNIAccessibleMethodDescriptor.of(method))) {
result = method;
break;
}
}
}
}
}
}
return JNIObjectHandles.createLocal(result);
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnJniErr.class)
@CEntryPointOptions(prologue = JNIEnvEnterReturnEDetachedOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static int MonitorEnter(JNIEnvironment env, JNIObjectHandle handle) {
Object obj = JNIObjectHandles.getObject(handle);
if (obj == null) {
throw new NullPointerException();
}
MonitorSupport.singleton().monitorEnter(obj);
assert Thread.holdsLock(obj);
JNIThreadOwnedMonitors.entered(obj);
return JNIErrors.JNI_OK();
}
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnJniErr.class)
@CEntryPointOptions(prologue = JNIEnvEnterReturnEDetachedOnFailurePrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static int MonitorExit(JNIEnvironment env, JNIObjectHandle handle) {
Object obj = JNIObjectHandles.getObject(handle);
if (obj == null) {
throw new NullPointerException();
}
if (!Thread.holdsLock(obj)) {
throw new IllegalMonitorStateException();
}
MonitorSupport.singleton().monitorExit(obj);
JNIThreadOwnedMonitors.exited(obj);
return JNIErrors.JNI_OK();
}
static class Support {
static class JNIEnvEnterReturnEDetachedOnFailurePrologue {
public static void enter(JNIEnvironment env) {
int error = CEntryPointActions.enter((IsolateThread) env);
if (error != CEntryPointErrors.NO_ERROR) {
CEntryPointActions.bailoutInPrologue(JNIErrors.JNI_EDETACHED());
}
}
}
static class JNIEnvEnterReturnNullWordOnFailurePrologue {
public static void enter(JNIEnvironment env) {
int error = CEntryPointActions.enter((IsolateThread) env);
if (error != CEntryPointErrors.NO_ERROR) {
CEntryPointActions.bailoutInPrologue(WordFactory.nullPointer());
}
}
}
static class JNIEnvEnterReturnNullHandleOnFailurePrologue {
public static void enter(JNIEnvironment env) {
int error = CEntryPointActions.enter((IsolateThread) env);
if (error != CEntryPointErrors.NO_ERROR) {
CEntryPointActions.bailoutInPrologue(JNIObjectHandles.nullHandle());
}
}
}
static class JNIEnvEnterReturnMinusOneOnFailurePrologue {
public static void enter(JNIEnvironment env) {
int error = CEntryPointActions.enter((IsolateThread) env);
if (error != CEntryPointErrors.NO_ERROR) {
CEntryPointActions.bailoutInPrologue(-1);
}
}
}
static final CGlobalData<CCharPointer> JNIENV_ENTER_FAIL_FATALLY_MESSAGE = CGlobalDataFactory.createCString(
"A JNI call failed to enter the isolate via its JNI environment argument. The environment might be invalid or no longer exists.");
static class JNIEnvEnterFatalOnFailurePrologue {
public static void enter(JNIEnvironment env) {
int error = CEntryPointActions.enter((IsolateThread) env);
if (error != 0) {
CEntryPointActions.failFatally(error, JNIENV_ENTER_FAIL_FATALLY_MESSAGE.get());
}
}
}
static class JNIJavaVMEnterAttachThreadEnsureJavaThreadPrologue {
static void enter(JNIJavaVM vm) {
if (CEntryPointActions.enterAttachThread(vm.getFunctions().getIsolate(), true) != CEntryPointErrors.NO_ERROR) {
CEntryPointActions.bailoutInPrologue(JNIErrors.JNI_ERR());
}
}
}
static class JNIJavaVMEnterAttachThreadManualJavaThreadPrologue {
static void enter(JNIJavaVM vm) {
if (CEntryPointActions.enterAttachThread(vm.getFunctions().getIsolate(), false) != CEntryPointErrors.NO_ERROR) {
CEntryPointActions.bailoutInPrologue(JNIErrors.JNI_ERR());
}
}
}
static class JNIExceptionHandlerVoid {
static void handle(Throwable t) {
Support.handleException(t);
}
}
static class JNIExceptionHandlerReturnNullHandle {
static JNIObjectHandle handle(Throwable t) {
Support.handleException(t);
return JNIObjectHandles.nullHandle();
}
}
static class JNIExceptionHandlerReturnNullWord {
static WordBase handle(Throwable t) {
Support.handleException(t);
return WordFactory.nullPointer();
}
}
static class JNIExceptionHandlerReturnFalse {
static boolean handle(Throwable t) {
Support.handleException(t);
return false;
}
}
static class JNIExceptionHandlerReturnMinusOne {
static int handle(Throwable t) {
Support.handleException(t);
return -1;
}
}
static class JNIExceptionHandlerReturnZero {
static int handle(Throwable t) {
Support.handleException(t);
return 0;
}
}
static class JNIExceptionHandlerReturnJniErr {
static int handle(Throwable t) {
Support.handleException(t);
return JNIErrors.JNI_ERR();
}
}
static JNIMethodId getMethodID(JNIObjectHandle hclazz, CCharPointer cname, CCharPointer csig, boolean isStatic) {
Class<?> clazz = JNIObjectHandles.getObject(hclazz);
DynamicHub.fromClass(clazz).ensureInitialized();
String name = Utf8.utf8ToString(cname);
String signature = Utf8.utf8ToString(csig);
return getMethodID(clazz, name, signature, isStatic);
}
private static JNIMethodId getMethodID(Class<?> clazz, String name, String signature, boolean isStatic) {
JNIMethodId methodID = JNIReflectionDictionary.singleton().getMethodID(clazz, name, signature, isStatic);
if (methodID.isNull()) {
String message = clazz.getName() + "." + name + signature;
JNIMethodId candidate = JNIReflectionDictionary.singleton().getMethodID(clazz, name, signature, !isStatic);
if (candidate.isNonNull()) {
if (isStatic) {
message += " (found matching non-static method that would be returned by GetMethodID)";
} else {
message += " (found matching static method that would be returned by GetStaticMethodID)";
}
}
throw new NoSuchMethodError(message);
}
return methodID;
}
static JNIFieldId getFieldID(JNIObjectHandle hclazz, CCharPointer cname, CCharPointer csig, boolean isStatic) {
Class<?> clazz = JNIObjectHandles.getObject(hclazz);
DynamicHub.fromClass(clazz).ensureInitialized();
String name = Utf8.utf8ToString(cname);
JNIFieldId fieldID = JNIReflectionDictionary.singleton().getFieldID(clazz, name, isStatic);
if (fieldID.isNull()) {
throw new NoSuchFieldError(clazz.getName() + '.' + name);
}
return fieldID;
}
static CShortPointer getNulTerminatedStringCharsAndPin(JNIObjectHandle hstr, CCharPointer isCopy) {
String str = JNIObjectHandles.getObject(hstr);
if (str == null) {
return WordFactory.nullPointer();
}
if (isCopy.isNonNull()) {
isCopy.write((byte) 1);
}
char[] chars = new char[str.length() + 1];
str.getChars(0, str.length(), chars, 0);
return JNIThreadLocalPinnedObjects.pinArrayAndGetAddress(chars);
}
static void unpinString(CShortPointer cstr) {
JNIThreadLocalPinnedObjects.unpinArrayByAddress(cstr);
}
static void handleException(Throwable t) {
JNIThreadLocalPendingException.set(t);
}
}
static final CGlobalData<CCharPointer> UNIMPLEMENTED_UNATTACHED_ERROR_MESSAGE = CGlobalDataFactory.createCString(
"An unimplemented JNI function was called in a way or at a time when no error reporting could be performed.");
static class JNIEnvUnimplementedPrologue {
static void enter(JNIEnvironment env) {
int error = CEntryPointActions.enter((IsolateThread) env);
if (error != CEntryPointErrors.NO_ERROR) {
CEntryPointActions.failFatally(error, UNIMPLEMENTED_UNATTACHED_ERROR_MESSAGE.get());
}
}
}
static class UnimplementedWithJNIEnvArgument {
@CEntryPoint
@CEntryPointOptions(prologue = JNIEnvUnimplementedPrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static int unimplemented(JNIEnvironment env) {
throw VMError.shouldNotReachHere("An unimplemented JNI function was called. Please refer to the stack trace.");
}
}
static class JNIJavaVMUnimplementedPrologue {
static void enter(JNIJavaVM vm) {
int error = CEntryPointActions.enterAttachThread(vm.getFunctions().getIsolate(), true);
if (error != CEntryPointErrors.NO_ERROR) {
CEntryPointActions.failFatally(error, UNIMPLEMENTED_UNATTACHED_ERROR_MESSAGE.get());
}
}
}
static class UnimplementedWithJavaVMArgument {
@CEntryPoint
@CEntryPointOptions(prologue = JNIJavaVMUnimplementedPrologue.class, publishAs = Publish.NotPublished, include = CEntryPointOptions.NotIncludedAutomatically.class)
static int unimplemented(JNIJavaVM vm) {
throw VMError.shouldNotReachHere("An unimplemented JNI function was called. Please refer to the stack trace.");
}
}
}