package erjang;
import java.util.HashMap;
import kilim.Pausable;
public class NIF {
static {
System.loadLibrary("jnif");
}
/** pointer to struct jnif_module */
private long module_ptr;
private String module_name;
private HashMap<FunID, Integer> nif_funs = new HashMap<FunID, Integer>();
private NIF(final long ptr) {
module_ptr = ptr;
init();
}
void init() {
final long ptr = module_ptr;
module_name = jni_module_name(ptr);
int count = jni_fun_count(ptr);
for (int i = 0; i < count; i++) {
final String name = jni_fun_name(ptr, i);
final int arity = jni_fun_arity(ptr, i);
final FunID fid = new FunID(module_name, name, arity);
nif_funs.put(fid, i);
// System.err.println("loaded " + fid + " => " + i );
final int idx = i;
EFunHandler nif_handler = new EFunHandler() {
@Override
public EObject invoke(EProc proc, EObject[] args)
throws Pausable {
return NIF.this.jni_invoke(proc, ptr, idx, args);
}
@Override
public String toString() {
return "#NIF<" + fid + ">";
}
};
try {
EModuleManager.bind_nif(fid, nif_handler);
} catch (Exception e) {
throw new RuntimeException("unable to bind "+fid, e);
}
}
}
/** call NIF function number <code>index</code>, with <code>args</code>. */
private native EObject jni_invoke(EProc proc, long module_ptr, int index, EObject[] args);
/** load NIF */
private static native long jni_load(String path, EObject info);
private static native String jni_module_name(long ptr);
private static native int jni_fun_count(long ptr);
private static native String jni_fun_name(long ptr, int idx);
private static native int jni_fun_arity(long ptr, int idx);
public static NIF load(String path, EObject info)
{
long ptr = jni_load(path, info);
if (ptr != 0L) {
return new NIF(ptr);
}
return null;
}
public static NIF load(String path)
{
return load(path, ERT.am_undefined);
}
//
// Static methods used by the NIF infrastructure
//
public static String get_erts_version() {
String erts_version = ERT.runtime_info.erts_version;
// remove prefix
String prefix = "erts-";
if (erts_version.startsWith(prefix)) {
erts_version = erts_version.substring(prefix.length());
}
return erts_version;
}
public static String get_otp_release() {
return ERT.runtime_info.otp_version;
}
public static int get_num_async_threads() {
return ERT.asyncThreadPoolSize();
}
public static int get_num_scheduler_threads() {
return ERT.threadPoolSize();
}
public static void send(EPID target, EObject msg) {
target.sendb(msg);
}
}