Permalink
Browse files

Complete the NIF API to 100%

With this batch of changes, all the enif_XXX
functions in the NIF API should be complete.
  • Loading branch information...
1 parent 6792e28 commit 6469ca8952fd4404725cfe6868a459f64fd99272 @krestenkrab krestenkrab committed Oct 24, 2013
Showing with 148 additions and 9 deletions.
  1. +65 −1 jnif/jnif.cc
  2. +16 −0 jnif/jnif_binary.cc
  3. +1 −1 jnif/jnif_dlopen.cc
  4. +58 −1 jnif/jnif_number.cc
  5. +4 −1 jnif/jnif_thread.cc
  6. +0 −5 src/main/java/erjang/EProc.java
  7. +4 −0 src/main/java/erjang/ERT.java
View
@@ -16,9 +16,12 @@ static JavaVM *jvm;
static jmethodID m_eobject__testReference;
static jmethodID m_eobject__testFunction;
static jmethodID m_eobject__testPort;
+static jmethodID m_eobject__equals;
+static jmethodID m_eobject__compare;
static jclass ERT_class;
static jmethodID m_ERT__badarg;
+static jmethodID m_ERT__make_ref;
void* enif_realloc(void* ptr, size_t size)
@@ -36,6 +39,62 @@ void enif_free(void *data)
free(data);
}
+int enif_fprintf(void/* FILE* */ *filep, const char *format, ...)
+{
+ va_list vl;
+ va_start(vl, format);
+ int result = vfprintf((FILE*) filep, format, vl);
+ va_end(vl);
+ return result;
+}
+
+int enif_consume_timeslice(ErlNifEnv* env, int percent)
+{
+ // TODO: Figure out if this is really needed.
+ // We can definitively do something reasonable, but need to understand what.
+ return 0;
+}
+
+int enif_is_identical(ERL_NIF_TERM term1, ERL_NIF_TERM term2)
+{
+ if (term1 == term2)
+ return NIF_TRUE;
+
+ jobject o1 = E2J(term1);
+ jobject o2 = E2J(term2);
+
+ JNIEnv *je;
+ if (jvm->AttachCurrentThreadAsDaemon((void**)&je, NULL) == JNI_OK) {
+ if (je->CallBooleanMethod(o1, m_eobject__equals, o2)) {
+ return NIF_TRUE;
+ } else {
+ return NIF_FALSE;
+ }
+ }
+
+ return NIF_FALSE;
+}
+
+int enif_compare(ERL_NIF_TERM term1, ERL_NIF_TERM term2)
+{
+ if (term1 == term2)
+ return 0;
+
+ jobject o1 = E2J(term1);
+ jobject o2 = E2J(term2);
+
+ JNIEnv *je;
+ if (jvm->AttachCurrentThreadAsDaemon((void**)&je, NULL) == JNI_OK) {
+ return je->CallIntMethod(o1, m_eobject__compare, o2);
+ }
+
+ abort();
+}
+
+ERL_NIF_TERM enif_make_ref(ErlNifEnv *ee) {
+ return jnif_retain( ee, ee->je->CallStaticObjectMethod(ERT_class, m_ERT__make_ref));
+}
+
int enif_is_ref(ErlNifEnv* ee, ERL_NIF_TERM term)
{
JNIEnv *je = ee->je;
@@ -247,10 +306,15 @@ static void init_jvm_data(JavaVM *vm, JNIEnv* je)
m_eobject__testReference = je->GetMethodID(eobject_class, "testReference", "()Lerjang/ERef;");
m_eobject__testFunction = je->GetMethodID(eobject_class, "testFunction", "()Lerjang/EFun;");
m_eobject__testPort = je->GetMethodID(eobject_class, "testPort", "()Lerjang/EPort;");
+ m_eobject__equals = je->GetMethodID(eobject_class, "equalsExactly", "(Lerjang/EObject;)Z");
+ m_eobject__compare = je->GetMethodID(eobject_class, "erlangCompareTo", "(Lerjang/EObject;)I");
+
+ jclass ERT_class = je->FindClass("erjang/ERT");
ERT_class = je->FindClass("erjang/ERT");
ERT_class = (jclass)je->NewGlobalRef(ERT_class);
- m_ERT__badarg = je->GetStaticMethodID(ERT_class, "badarg", "()Lerjang/ErlangError;");
+ m_ERT__badarg = je->GetStaticMethodID(ERT_class, "badarg", "()Lerjang/ErlangError;");
+ m_ERT__make_ref = je->GetStaticMethodID(ERT_class, "make_ref", "()Lerjang/ERef;");
}
View
@@ -12,6 +12,7 @@ static jclass ErlConvert_class;
static jclass ebinary_class;
static jmethodID m_ebinary__make;
static jmethodID m_ErlConvert__iolist_to_binary;
+static jmethodID m_ebitstring_substring;
void initialize_jnif_binary(JavaVM* vm, JNIEnv *je)
@@ -35,6 +36,11 @@ void initialize_jnif_binary(JavaVM* vm, JNIEnv *je)
je->GetStaticMethodID(ErlConvert_class,
"iolist_to_binary",
"(Lerjang/EObject;)Lerjang/EBitString;");
+
+ ebitstring_class = je->FindClass("erjang/EBitString");
+ m_ebitstring_substring = je->GetMethodID(ebitstring_class,
+ "substring",
+ "(JJ)Lerjang/EBitString;");
}
static void jnif_release_binary(struct jnif_bin_data *bd);
@@ -226,3 +232,13 @@ unsigned char *enif_make_new_binary(ErlNifEnv* ee,
return (unsigned char*) arr;
}
+
+ERL_NIF_TERM enif_make_sub_binary(ErlNifEnv* ee, ERL_NIF_TERM bin_term, size_t pos, size_t size)
+{
+ jobject binary = E2J(bin_term);
+ jobject sub_bin = ee->je->CallObjectMethod(binary,
+ m_ebitstring_substring,
+ (jlong)(pos*8),
+ (long)(size*8));
+ return jnif_retain(ee, sub_bin);
+}
View
@@ -7,7 +7,7 @@ typedef ErlNifEntry* (*nif_init_t)();
void* enif_dlopen(const char* lib,
void (*err_handler)(void*,const char*), void* err_arg)
{
- char buffer[NAME_MAX];
+ char buffer[strlen(lib)+4];
void *so_handle;
sprintf(buffer, "%s.so", lib);
View
@@ -1,8 +1,9 @@
#include "jnif.h"
-
+#include <limits>
static jmethodID m_eobject__testNumber;
+static jmethodID m_eobject__testInteger;
static jmethodID m_enumber__doubleValue;
static jmethodID m_enumber__intValue;
static jmethodID m_enumber__longValue;
@@ -24,6 +25,9 @@ void initialize_jnif_number(JavaVM* vm, JNIEnv *je)
m_eobject__testNumber = je->GetMethodID(eobject_class,
"testNumber",
"()Lerjang/ENumber;");
+ m_eobject__testInteger = je->GetMethodID(eobject_class,
+ "testInteger",
+ "()Lerjang/EInteger;");
jclass enumber_class = je->FindClass("erjang/ENumber");
m_enumber__doubleValue = je->GetMethodID(enumber_class,
@@ -87,6 +91,35 @@ int enif_get_int(ErlNifEnv* ee, ERL_NIF_TERM term, int* ip)
return NIF_TRUE;
}
+int enif_get_ulong(ErlNifEnv* ee, ERL_NIF_TERM term, unsigned long* ip)
+{
+ jobject o = ee->je->CallObjectMethod(E2J(term), m_eobject__testInteger);
+ if (o == NULL)
+ return NIF_FALSE;
+
+ *ip = ee->je->CallIntMethod(o, m_enumber__intValue);
+ return NIF_TRUE;
+}
+
+int enif_get_long(ErlNifEnv* ee, ERL_NIF_TERM term, long* ip)
+{
+ jobject o = ee->je->CallObjectMethod(E2J(term), m_eobject__testNumber);
+ if (o == NULL)
+ return NIF_FALSE;
+
+ if (sizeof(jint) == sizeof(long)) {
+ *ip = ee->je->CallIntMethod(o, m_enumber__intValue);
+ } else {
+ jlong val = ee->je->CallLongMethod(o, m_enumber__longValue);
+ if (val < std::numeric_limits<long>::min()
+ || val > std::numeric_limits<long>::max()) {
+ return NIF_FALSE;
+ }
+ *ip = val;
+ }
+ return NIF_TRUE;
+}
+
int enif_get_int64(ErlNifEnv* ee, ERL_NIF_TERM term, ErlNifSInt64* ip)
{
jobject o = ee->je->CallObjectMethod(E2J(term), m_eobject__testNumber);
@@ -97,6 +130,16 @@ int enif_get_int64(ErlNifEnv* ee, ERL_NIF_TERM term, ErlNifSInt64* ip)
return NIF_TRUE;
}
+int enif_get_uint64(ErlNifEnv* ee, ERL_NIF_TERM term, ErlNifUInt64* ip)
+{
+ jobject o = ee->je->CallObjectMethod(E2J(term), m_eobject__testInteger);
+ if (o == NULL)
+ return NIF_FALSE;
+
+ *ip = (jlong) ee->je->CallLongMethod(o, m_enumber__longValue);
+ return NIF_TRUE;
+}
+
int enif_get_uint(ErlNifEnv* ee, ERL_NIF_TERM term, unsigned* ip)
{
jobject o = ee->je->CallObjectMethod(E2J(term), m_eobject__testNumber);
@@ -183,6 +226,20 @@ extern ERL_NIF_TERM enif_make_uint64 (ErlNifEnv* ee, ErlNifUInt64 i)
return jnif_retain(ee, boxed);
}
+extern ERL_NIF_TERM enif_make_int64 (ErlNifEnv* ee, ErlNifSInt64 i)
+{
+ jobject boxed;
+ boxed = ee->je->CallStaticObjectMethod(ERT_class, m_ERT__box_long, (jlong) i);
+ return jnif_retain(ee, boxed);
+}
+
+extern ERL_NIF_TERM enif_make_long (ErlNifEnv* ee, long i)
+{
+ jobject boxed;
+ boxed = ee->je->CallStaticObjectMethod(ERT_class, m_ERT__box_long, (jlong) i);
+ return jnif_retain(ee, boxed);
+}
+
extern ERL_NIF_TERM enif_make_double(ErlNifEnv* ee, double d)
{
jobject boxed = ee->je->CallStaticObjectMethod(ERT_class, m_ERT__box_double, d);
View
@@ -32,7 +32,10 @@ static void* jnif_macos_start_routine(void* a)
#endif
-
+int enif_equal_tids(ErlNifTid tid1, ErlNifTid tid2)
+{
+ return pthread_equal((pthread_t)tid1, (pthread_t)tid2) ? NIF_TRUE : NIF_FALSE;
+}
int enif_thread_create(char *name,
ErlNifTid *tid,
@@ -179,11 +179,6 @@ protected void setTarget(EAtom m, EAtom f, ESeq a) {
case 0:
}
}
-
- // called from JNIF
- static EProc find(int key) {
- return all_tasks.get(key);
- }
private int key() {
int key = (self.serial() << 15) | (self.id() & 0x7fff);
@@ -1001,6 +1001,10 @@ public static EObject func_info(EAtom mod, EAtom fun, ESeq args) {
throw new ErlangError(am_function_clause, args);
}
+ public static ERef make_ref() {
+ return getLocalNode().createRef();
+ }
+
/**
* @param command
* @return

0 comments on commit 6469ca8

Please sign in to comment.