Skip to content

Commit fef053d

Browse files
committed
android: Support ART w/o copied_methods_offset_
1 parent f72e61e commit fef053d

1 file changed

Lines changed: 72 additions & 15 deletions

File tree

lib/class-model.js

Lines changed: 72 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ struct _JavaFieldApi
8585
8686
struct _JavaApi
8787
{
88+
jvmtiEnv * jvmti;
8889
JavaClassApi clazz;
8990
JavaMethodApi method;
9091
JavaFieldApi field;
@@ -235,6 +236,7 @@ model_new (jclass class_handle,
235236
{
236237
Model * model;
237238
GHashTable * members;
239+
jvmtiEnv * jvmti = java_api.jvmti;
238240
gpointer * funcs = env->functions;
239241
jmethodID (* from_reflected_method) (JNIEnv *, jobject) = funcs[7];
240242
jfieldID (* from_reflected_field) (JNIEnv *, jobject) = funcs[8];
@@ -254,7 +256,52 @@ model_new (jclass class_handle,
254256
members = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
255257
model->members = members;
256258
257-
if (art_api.available)
259+
if (jvmti != NULL)
260+
{
261+
gpointer * jf = jvmti->functions - 1;
262+
jvmtiError (* deallocate) (jvmtiEnv *, void * mem) = jf[47];
263+
jvmtiError (* get_class_methods) (jvmtiEnv *, jclass, jint *, jmethodID **) = jf[52];
264+
jvmtiError (* get_class_fields) (jvmtiEnv *, jclass, jint *, jfieldID **) = jf[53];
265+
jvmtiError (* get_field_name) (jvmtiEnv *, jclass, jfieldID, char **, char **, char **) = jf[60];
266+
jvmtiError (* get_field_modifiers) (jvmtiEnv *, jclass, jfieldID, jint *) = jf[62];
267+
jvmtiError (* get_method_name) (jvmtiEnv *, jmethodID, char **, char **, char **) = jf[64];
268+
jvmtiError (* get_method_modifiers) (jvmtiEnv *, jmethodID, jint *) = jf[66];
269+
jint method_count;
270+
jmethodID * methods;
271+
jint field_count;
272+
jfieldID * fields;
273+
char * name;
274+
jint modifiers;
275+
276+
get_class_methods (jvmti, class_handle, &method_count, &methods);
277+
for (i = 0; i != method_count; i++)
278+
{
279+
jmethodID method = methods[i];
280+
281+
get_method_name (jvmti, method, &name, NULL, NULL);
282+
get_method_modifiers (jvmti, method, &modifiers);
283+
284+
model_add_method (model, name, method, modifiers);
285+
286+
deallocate (jvmti, name);
287+
}
288+
deallocate (jvmti, methods);
289+
290+
get_class_fields (jvmti, class_handle, &field_count, &fields);
291+
for (i = 0; i != field_count; i++)
292+
{
293+
jfieldID field = fields[i];
294+
295+
get_field_name (jvmti, class_handle, field, &name, NULL, NULL);
296+
get_field_modifiers (jvmti, class_handle, field, &modifiers);
297+
298+
model_add_field (model, name, field, modifiers);
299+
300+
deallocate (jvmti, name);
301+
}
302+
deallocate (jvmti, fields);
303+
}
304+
else if (art_api.available)
258305
{
259306
gpointer elements;
260307
guint n, i;
@@ -702,8 +749,7 @@ enumerate_methods_jvm (const gchar * class_query,
702749
jboolean include_signature,
703750
jboolean ignore_case,
704751
jboolean skip_system_classes,
705-
JNIEnv * env,
706-
jvmtiEnv * jvmti)
752+
JNIEnv * env)
707753
{
708754
gchar * result;
709755
GPatternSpec * class_pattern, * method_pattern;
@@ -712,6 +758,7 @@ enumerate_methods_jvm (const gchar * class_query,
712758
jobject (* new_global_ref) (JNIEnv *, jobject) = ef[21];
713759
void (* delete_local_ref) (JNIEnv *, jobject) = ef[23];
714760
jboolean (* is_same_object) (JNIEnv *, jobject, jobject) = ef[24];
761+
jvmtiEnv * jvmti = java_api.jvmti;
715762
gpointer * jf = jvmti->functions - 1;
716763
jvmtiError (* deallocate) (jvmtiEnv *, void * mem) = jf[47];
717764
jvmtiError (* get_class_signature) (jvmtiEnv *, jclass, char **, char **) = jf[48];
@@ -1207,10 +1254,10 @@ export default class Model {
12071254
}
12081255

12091256
let result;
1210-
if (api.flavor === 'jvm') {
1257+
if (api.jvmti !== null) {
12111258
const json = cm.enumerateMethodsJvm(classQuery, methodQuery,
12121259
boolToNative(includeSignature), boolToNative(ignoreCase), boolToNative(skipSystemClasses),
1213-
env, api.jvmti);
1260+
env);
12141261
try {
12151262
result = JSON.parse(json.readUtf8String())
12161263
.map(group => {
@@ -1273,11 +1320,14 @@ function ensureInitialized (env) {
12731320
}
12741321

12751322
function compileModule (env) {
1323+
const api = getApi();
1324+
const { jvmti } = api;
1325+
12761326
const { pointerSize } = Process;
12771327

12781328
const lockSize = 8;
12791329
const modelsSize = pointerSize;
1280-
const javaApiSize = 6 * pointerSize;
1330+
const javaApiSize = 7 * pointerSize;
12811331
const artApiSize = (10 * 4) + (5 * pointerSize);
12821332

12831333
const dataSize = lockSize + modelsSize + javaApiSize + artApiSize;
@@ -1293,6 +1343,7 @@ function compileModule (env) {
12931343
const field = env.javaLangReflectField();
12941344
let j = javaApi;
12951345
[
1346+
jvmti,
12961347
getDeclaredMethods, getDeclaredFields,
12971348
method.getName, method.getModifiers,
12981349
field.getName, field.getModifiers
@@ -1303,16 +1354,22 @@ function compileModule (env) {
13031354

13041355
const artApi = javaApi.add(javaApiSize);
13051356
const { vm } = env;
1306-
const artClass = getArtClassSpec(vm);
1307-
if (artClass !== null) {
1308-
const c = artClass.offset;
1357+
if (api.flavor === 'art') {
1358+
let artClassOffsets;
1359+
if (jvmti !== null) {
1360+
artClassOffsets = [0, 0, 0, 0];
1361+
} else {
1362+
const c = getArtClassSpec(vm).offset;
1363+
artClassOffsets = [c.ifields, c.methods, c.sfields, c.copiedMethodsOffset];
1364+
}
1365+
13091366
const m = getArtMethodSpec(vm);
13101367
const f = getArtFieldSpec(vm);
13111368

13121369
let s = artApi;
13131370
[
13141371
1,
1315-
c.ifields, c.methods, c.sfields, c.copiedMethodsOffset,
1372+
...artClassOffsets,
13161373
m.size, m.offset.accessFlags,
13171374
f.size, f.offset.accessFlags,
13181375
0xffffffff
@@ -1321,7 +1378,6 @@ function compileModule (env) {
13211378
s = s.writeUInt(value).add(4);
13221379
});
13231380

1324-
const api = getApi();
13251381
[
13261382
api.artClassLinker.address,
13271383
api['art::ClassLinker::VisitClasses'],
@@ -1349,25 +1405,26 @@ function compileModule (env) {
13491405

13501406
return {
13511407
handle: cm,
1352-
mode: (artClass !== null) ? 'full' : 'basic',
13531408
new: new NativeFunction(cm.model_new, 'pointer', ['pointer', 'pointer', 'pointer'], reentrantOptions),
13541409
has: new NativeFunction(cm.model_has, 'bool', ['pointer', 'pointer'], fastOptions),
13551410
find: new NativeFunction(cm.model_find, 'pointer', ['pointer', 'pointer'], fastOptions),
13561411
list: new NativeFunction(cm.model_list, 'pointer', ['pointer'], fastOptions),
13571412
enumerateMethodsArt: new NativeFunction(cm.enumerate_methods_art, 'pointer', ['pointer', 'pointer', 'bool', 'bool', 'bool'],
13581413
reentrantOptions),
13591414
enumerateMethodsJvm: new NativeFunction(cm.enumerate_methods_jvm, 'pointer', ['pointer', 'pointer', 'bool', 'bool', 'bool',
1360-
'pointer', 'pointer'], reentrantOptions),
1415+
'pointer'], reentrantOptions),
13611416
dealloc: new NativeFunction(cm.dealloc, 'void', ['pointer'], fastOptions)
13621417
};
13631418
}
13641419

13651420
function makeHandleUnwrapper (cm, vm) {
1366-
if (cm.mode === 'basic') {
1421+
const api = getApi();
1422+
1423+
if (api.flavor !== 'art') {
13671424
return nullUnwrap;
13681425
}
13691426

1370-
const decodeGlobal = getApi()['art::JavaVMExt::DecodeGlobal'];
1427+
const decodeGlobal = api['art::JavaVMExt::DecodeGlobal'];
13711428

13721429
return function (handle, env, fn) {
13731430
let result;

0 commit comments

Comments
 (0)