Skip to content
Draft
Changes from all 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
87 changes: 72 additions & 15 deletions lib/class-model.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ struct _JavaFieldApi

struct _JavaApi
{
jvmtiEnv * jvmti;
JavaClassApi clazz;
JavaMethodApi method;
JavaFieldApi field;
Expand Down Expand Up @@ -235,6 +236,7 @@ model_new (jclass class_handle,
{
Model * model;
GHashTable * members;
jvmtiEnv * jvmti = java_api.jvmti;
gpointer * funcs = env->functions;
jmethodID (* from_reflected_method) (JNIEnv *, jobject) = funcs[7];
jfieldID (* from_reflected_field) (JNIEnv *, jobject) = funcs[8];
Expand All @@ -254,7 +256,52 @@ model_new (jclass class_handle,
members = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
model->members = members;

if (art_api.available)
if (jvmti != NULL)
{
gpointer * jf = jvmti->functions - 1;
jvmtiError (* deallocate) (jvmtiEnv *, void * mem) = jf[47];
jvmtiError (* get_class_methods) (jvmtiEnv *, jclass, jint *, jmethodID **) = jf[52];
jvmtiError (* get_class_fields) (jvmtiEnv *, jclass, jint *, jfieldID **) = jf[53];
jvmtiError (* get_field_name) (jvmtiEnv *, jclass, jfieldID, char **, char **, char **) = jf[60];
jvmtiError (* get_field_modifiers) (jvmtiEnv *, jclass, jfieldID, jint *) = jf[62];
jvmtiError (* get_method_name) (jvmtiEnv *, jmethodID, char **, char **, char **) = jf[64];
jvmtiError (* get_method_modifiers) (jvmtiEnv *, jmethodID, jint *) = jf[66];
jint method_count;
jmethodID * methods;
jint field_count;
jfieldID * fields;
char * name;
jint modifiers;

get_class_methods (jvmti, class_handle, &method_count, &methods);
for (i = 0; i != method_count; i++)
{
jmethodID method = methods[i];

get_method_name (jvmti, method, &name, NULL, NULL);
get_method_modifiers (jvmti, method, &modifiers);

model_add_method (model, name, method, modifiers);

deallocate (jvmti, name);
}
deallocate (jvmti, methods);

get_class_fields (jvmti, class_handle, &field_count, &fields);
for (i = 0; i != field_count; i++)
{
jfieldID field = fields[i];

get_field_name (jvmti, class_handle, field, &name, NULL, NULL);
get_field_modifiers (jvmti, class_handle, field, &modifiers);

model_add_field (model, name, field, modifiers);

deallocate (jvmti, name);
}
deallocate (jvmti, fields);
}
else if (art_api.available)
{
gpointer elements;
guint n, i;
Expand Down Expand Up @@ -702,8 +749,7 @@ enumerate_methods_jvm (const gchar * class_query,
jboolean include_signature,
jboolean ignore_case,
jboolean skip_system_classes,
JNIEnv * env,
jvmtiEnv * jvmti)
JNIEnv * env)
{
gchar * result;
GPatternSpec * class_pattern, * method_pattern;
Expand All @@ -712,6 +758,7 @@ enumerate_methods_jvm (const gchar * class_query,
jobject (* new_global_ref) (JNIEnv *, jobject) = ef[21];
void (* delete_local_ref) (JNIEnv *, jobject) = ef[23];
jboolean (* is_same_object) (JNIEnv *, jobject, jobject) = ef[24];
jvmtiEnv * jvmti = java_api.jvmti;
gpointer * jf = jvmti->functions - 1;
jvmtiError (* deallocate) (jvmtiEnv *, void * mem) = jf[47];
jvmtiError (* get_class_signature) (jvmtiEnv *, jclass, char **, char **) = jf[48];
Expand Down Expand Up @@ -1207,10 +1254,10 @@ export default class Model {
}

let result;
if (api.flavor === 'jvm') {
if (api.jvmti !== null) {
const json = cm.enumerateMethodsJvm(classQuery, methodQuery,
boolToNative(includeSignature), boolToNative(ignoreCase), boolToNative(skipSystemClasses),
env, api.jvmti);
env);
try {
result = JSON.parse(json.readUtf8String())
.map(group => {
Expand Down Expand Up @@ -1273,11 +1320,14 @@ function ensureInitialized (env) {
}

function compileModule (env) {
const api = getApi();
const { jvmti } = api;

const { pointerSize } = Process;

const lockSize = 8;
const modelsSize = pointerSize;
const javaApiSize = 6 * pointerSize;
const javaApiSize = 7 * pointerSize;
const artApiSize = (10 * 4) + (5 * pointerSize);

const dataSize = lockSize + modelsSize + javaApiSize + artApiSize;
Expand All @@ -1293,6 +1343,7 @@ function compileModule (env) {
const field = env.javaLangReflectField();
let j = javaApi;
[
jvmti,
getDeclaredMethods, getDeclaredFields,
method.getName, method.getModifiers,
field.getName, field.getModifiers
Expand All @@ -1303,16 +1354,22 @@ function compileModule (env) {

const artApi = javaApi.add(javaApiSize);
const { vm } = env;
const artClass = getArtClassSpec(vm);
if (artClass !== null) {
const c = artClass.offset;
if (api.flavor === 'art') {
let artClassOffsets;
if (jvmti !== null) {
artClassOffsets = [0, 0, 0, 0];
} else {
const c = getArtClassSpec(vm).offset;
artClassOffsets = [c.ifields, c.methods, c.sfields, c.copiedMethodsOffset];
}

const m = getArtMethodSpec(vm);
const f = getArtFieldSpec(vm);

let s = artApi;
[
1,
c.ifields, c.methods, c.sfields, c.copiedMethodsOffset,
...artClassOffsets,
m.size, m.offset.accessFlags,
f.size, f.offset.accessFlags,
0xffffffff
Expand All @@ -1321,7 +1378,6 @@ function compileModule (env) {
s = s.writeUInt(value).add(4);
});

const api = getApi();
[
api.artClassLinker.address,
api['art::ClassLinker::VisitClasses'],
Expand Down Expand Up @@ -1349,25 +1405,26 @@ function compileModule (env) {

return {
handle: cm,
mode: (artClass !== null) ? 'full' : 'basic',
new: new NativeFunction(cm.model_new, 'pointer', ['pointer', 'pointer', 'pointer'], reentrantOptions),
has: new NativeFunction(cm.model_has, 'bool', ['pointer', 'pointer'], fastOptions),
find: new NativeFunction(cm.model_find, 'pointer', ['pointer', 'pointer'], fastOptions),
list: new NativeFunction(cm.model_list, 'pointer', ['pointer'], fastOptions),
enumerateMethodsArt: new NativeFunction(cm.enumerate_methods_art, 'pointer', ['pointer', 'pointer', 'bool', 'bool', 'bool'],
reentrantOptions),
enumerateMethodsJvm: new NativeFunction(cm.enumerate_methods_jvm, 'pointer', ['pointer', 'pointer', 'bool', 'bool', 'bool',
'pointer', 'pointer'], reentrantOptions),
'pointer'], reentrantOptions),
dealloc: new NativeFunction(cm.dealloc, 'void', ['pointer'], fastOptions)
};
}

function makeHandleUnwrapper (cm, vm) {
if (cm.mode === 'basic') {
const api = getApi();

if (api.flavor !== 'art') {
return nullUnwrap;
}

const decodeGlobal = getApi()['art::JavaVMExt::DecodeGlobal'];
const decodeGlobal = api['art::JavaVMExt::DecodeGlobal'];

return function (handle, env, fn) {
let result;
Expand Down
Loading