@@ -85,6 +85,7 @@ struct _JavaFieldApi
8585
8686struct _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
12751322function 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
13651420function 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