Skip to content
This repository has been archived by the owner on Mar 8, 2020. It is now read-only.

Node.load() implementation #91

Merged
merged 4 commits into from
Jul 4, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 0 additions & 11 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,10 @@ stages:
- name: release
if: tag IS present


jobs:
include:
- name: 'All tests'
stage: test
if: tag IS present # TODO(bzz): enable on PRs as soon as migrated to V2
install: &test_setup_anchor
- docker run --privileged -d -p 9432:9432 --name bblfsh bblfsh/bblfshd
- docker exec -it bblfsh bblfshctl driver install --recommended
Expand All @@ -34,15 +32,6 @@ jobs:
after_failure: &failure_logs_anchor
- docker logs bblfsh

- name: 'V2: passing tests' # TODO(#83): remove, after both tests sets converge
install: *test_setup_anchor
script:
- sudo apt-get install -y binutils
- ./sbt assembly
- ./sbt "testOnly *Close* *ClientVersion* *SupportedLanguages* *BblfshClientParseTest"

after_failure: *failure_logs_anchor

- name: 'Cross-compile, release & publish to Sonatype'
stage: release
before_install:
Expand Down
131 changes: 111 additions & 20 deletions src/main/native/jni_utils.cc
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
#include "jni_utils.h"
#include <string>

// Class fully qualified names
const char *CLS_NODE = "org/bblfsh/client/v2/Node";
const char *CLS_CTX = "org/bblfsh/client/v2/Context";

extern JavaVM *jvm; // FIXME(bzz): double-check and document
// TODO(bzz): double-check and document. Suggestion and more context at
// https://github.com/bblfsh/client-scala/pull/84#discussion_r288347756
extern JavaVM *jvm;

JNIEnv *getJNIEnv() {
JNIEnv *pEnv = NULL;
Expand All @@ -21,38 +20,130 @@ JNIEnv *getJNIEnv() {
return pEnv;
}

// Class fully qualified names
const char *CLS_NODE = "org/bblfsh/client/v2/Node";
bzz marked this conversation as resolved.
Show resolved Hide resolved
const char *CLS_CTX = "org/bblfsh/client/v2/Context";
const char *CLS_OBJ = "java/lang/Object";
const char *CLS_RE = "java/lang/RuntimeException";

const char *CLS_JNODE = "org/bblfsh/client/v2/JNode";
const char *CLS_JNULL = "org/bblfsh/client/v2/JNull";
const char *CLS_JSTR = "org/bblfsh/client/v2/JString";
const char *CLS_JINT = "org/bblfsh/client/v2/JInt";
const char *CLS_JFLT = "org/bblfsh/client/v2/JFloat";
const char *CLS_JBOL = "org/bblfsh/client/v2/JBool";
bzz marked this conversation as resolved.
Show resolved Hide resolved
const char *CLS_JUINT = "org/bblfsh/client/v2/JUint";
const char *CLS_JARR = "org/bblfsh/client/v2/JArray";
const char *CLS_JOBJ = "org/bblfsh/client/v2/JObject";

// Method signatures
const char *METHOD_JNODE_KEY_AT = "(I)Ljava/lang/String;";
const char *METHOD_JNODE_VALUE_AT = "(I)Lorg/bblfsh/client/v2/JNode;";
const char *METHOD_JOBJ_ADD =
"(Ljava/lang/String;Lorg/bblfsh/client/v2/JNode;)Lscala/collection/"
"mutable/Buffer;";
const char *METHOD_JARR_ADD =
"(Lorg/bblfsh/client/v2/JNode;)Lscala/collection/mutable/Buffer;";

const char *METHOD_OBJ_TO_STR = "()Ljava/lang/String;";

void checkJvmException(std::string msg) {
bzz marked this conversation as resolved.
Show resolved Hide resolved
JNIEnv *env = getJNIEnv();
if (env->ExceptionCheck()) {
// env->ExceptionDescribe(); // prints to stdout, un-comment for debuging
bzz marked this conversation as resolved.
Show resolved Hide resolved
auto err = env->ExceptionOccurred();

jmethodID toString = env->GetMethodID(env->FindClass(CLS_OBJ), "toString",
METHOD_OBJ_TO_STR);
jstring s = (jstring)env->CallObjectMethod(err, toString);
const char *utf = env->GetStringUTFChars(s, 0);
env->ReleaseStringUTFChars(s, utf);

env->ExceptionClear();

auto exception = env->FindClass(CLS_RE);
env->ThrowNew(exception, msg.append(": ").append(utf).data());
}
}

jobject NewJavaObject(JNIEnv *env, const char *className, const char *initSign,
...) {
jclass cls = env->FindClass(className);
if (env->ExceptionOccurred() || !cls) {
return NULL;
}
checkJvmException(std::string("failed to find a class ").append(className));

jmethodID initId = env->GetMethodID(cls, "<init>", initSign);
if (env->ExceptionOccurred() || !initId) {
return NULL;
}
checkJvmException(
std::string("failed to call <inti> constructor for ").append(className));
bzz marked this conversation as resolved.
Show resolved Hide resolved

va_list varargs;
va_start(varargs, initSign);
jobject instance = env->NewObjectV(cls, initId, varargs);
va_end(varargs);
if (env->ExceptionOccurred() || !instance) {
return NULL;
}
checkJvmException(
std::string("failed get varargs for constructor of ").append(className));

return instance;
}

jfieldID getField(JNIEnv *env, jobject obj, const char *name) {
jclass cls = env->GetObjectClass(obj);
if (env->ExceptionOccurred() || !cls) {
return nullptr;
}
checkJvmException("failed get an object class");
bzz marked this conversation as resolved.
Show resolved Hide resolved

jfieldID jfid = env->GetFieldID(cls, name, "J");
if (env->ExceptionOccurred() || !jfid) {
return nullptr;
}
checkJvmException(std::string("failed get a field ").append(name));

return jfid;
}

static jmethodID MethodID(JNIEnv *env, const char *method,
const char *signature, const char *className) {
jclass cls = env->FindClass(className);
checkJvmException(std::string("failed to find a class ").append(className));

jmethodID mId = env->GetMethodID(cls, method, signature);
checkJvmException(std::string("failed get a method ")
.append(className)
.append(".")
.append(method));

return mId;
}

jint IntMethod(JNIEnv *env, const char *method, const char *signature,
const char *className, const jobject *object) {
jmethodID mId = MethodID(env, method, signature, className);
checkJvmException(std::string("failed get a method ")
bzz marked this conversation as resolved.
Show resolved Hide resolved
.append(className)
.append(".")
.append(method));

jint res = env->CallIntMethod(*object, mId);
checkJvmException(std::string("failed call a method ")
bzz marked this conversation as resolved.
Show resolved Hide resolved
.append(className)
.append(".")
.append(method)
.append(" using signature ")
.append(signature));

return res;
}

jobject ObjectMethod(JNIEnv *env, const char *method, const char *signature,
const char *className, const jobject *object, ...) {
jmethodID mId = MethodID(env, method, signature, className);
checkJvmException(std::string("failed get a method ")
.append(className)
.append(".")
.append(method));

va_list varargs;
va_start(varargs, object);
jobject res = env->CallObjectMethodV(*object, mId, varargs);
va_end(varargs);
checkJvmException(std::string("failed get varargs for ")
.append(className)
.append(".")
.append(method));

return res;
}
28 changes: 28 additions & 0 deletions src/main/native/jni_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,40 @@
#define _Included_org_bblfsh_client_libuast_Libuast_jni_utils

#include <jni.h>
#include <string>

extern const char *CLS_NODE;
extern const char *CLS_CTX;
extern const char *CLS_OBJ;
bzz marked this conversation as resolved.
Show resolved Hide resolved
extern const char *CLS_RE;

extern const char *CLS_JNODE;
extern const char *CLS_JNULL;
extern const char *CLS_JSTR;
extern const char *CLS_JINT;
extern const char *CLS_JFLT;
extern const char *CLS_JBOL;
extern const char *CLS_JUINT;
extern const char *CLS_JARR;
extern const char *CLS_JOBJ;

extern const char *METHOD_JNODE_KEY_AT;
extern const char *METHOD_JNODE_VALUE_AT;
extern const char *METHOD_JOBJ_ADD;
extern const char *METHOD_JARR_ADD;

extern const char *METHOD_OBJ_TO_STR;

void checkJvmException(std::string);

JNIEnv *getJNIEnv();
jobject NewJavaObject(JNIEnv *, const char *, const char *, ...);
jfieldID getField(JNIEnv *env, jobject obj, const char *name);

jint IntMethod(JNIEnv *, const char *, const char *, const char *,
const jobject *);

jobject ObjectMethod(JNIEnv *, const char *, const char *, const char *,
const jobject *, ...);

#endif
21 changes: 21 additions & 0 deletions src/main/native/org_bblfsh_client_v2_Context__.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading