@@ -8,20 +8,25 @@ extern crate once_cell;
88extern crate prost;
99
1010use anyhow:: Result ;
11- use jni:: objects:: { JByteArray , JClass , JObject } ;
11+ use jni:: objects:: { GlobalRef , JByteArray , JClass , JObject , JString } ;
1212use jni:: sys:: jbyteArray;
1313use jni:: JNIEnv ;
14- use kclvm_api:: call;
14+ use jni:: JavaVM ;
15+ use kclvm_api:: call_with_plugin_agent;
1516use kclvm_api:: gpyrpc:: LoadPackageArgs ;
1617use kclvm_api:: service:: KclvmServiceImpl ;
1718use kclvm_parser:: KCLModuleCache ;
1819use kclvm_sema:: resolver:: scope:: KCLScopeCache ;
1920use lazy_static:: lazy_static;
2021use once_cell:: sync:: OnceCell ;
2122use prost:: Message ;
23+ use std:: ffi:: { CStr , CString } ;
24+ use std:: os:: raw:: c_char;
2225use std:: sync:: Mutex ;
2326
2427lazy_static ! {
28+ static ref JVM : Mutex <Option <JavaVM >> = Mutex :: new( None ) ;
29+ static ref CALLBACK_OBJ : Mutex <Option <GlobalRef >> = Mutex :: new( None ) ;
2530 static ref MODULE_CACHE : Mutex <OnceCell <KCLModuleCache >> = Mutex :: new( OnceCell :: new( ) ) ;
2631 static ref SCOPE_CACHE : Mutex <OnceCell <KCLScopeCache >> = Mutex :: new( OnceCell :: new( ) ) ;
2732}
@@ -33,12 +38,20 @@ pub extern "system" fn Java_com_kcl_api_API_callNative(
3338 name : JByteArray ,
3439 args : JByteArray ,
3540) -> jbyteArray {
36- intern_call_native ( & mut env, name, args) . unwrap_or_else ( |e| {
41+ intern_call_native_with_plugin ( & mut env, name, args) . unwrap_or_else ( |e| {
3742 let _ = throw ( & mut env, e) ;
3843 JObject :: default ( ) . into_raw ( )
3944 } )
4045}
4146
47+ #[ no_mangle]
48+ pub extern "system" fn Java_com_kcl_api_API_registerPluginContext ( env : JNIEnv , obj : JObject ) {
49+ let jvm = env. get_java_vm ( ) . unwrap ( ) ;
50+ * JVM . lock ( ) . unwrap ( ) = Some ( jvm) ;
51+ let global_ref = env. new_global_ref ( obj) . unwrap ( ) ;
52+ * CALLBACK_OBJ . lock ( ) . unwrap ( ) = Some ( global_ref) ;
53+ }
54+
4255#[ no_mangle]
4356pub extern "system" fn Java_com_kcl_api_API_loadPackageWithCache (
4457 mut env : JNIEnv ,
@@ -51,10 +64,14 @@ pub extern "system" fn Java_com_kcl_api_API_loadPackageWithCache(
5164 } )
5265}
5366
54- fn intern_call_native ( env : & mut JNIEnv , name : JByteArray , args : JByteArray ) -> Result < jbyteArray > {
67+ fn intern_call_native_with_plugin (
68+ env : & mut JNIEnv ,
69+ name : JByteArray ,
70+ args : JByteArray ,
71+ ) -> Result < jbyteArray > {
5572 let name = env. convert_byte_array ( name) ?;
5673 let args = env. convert_byte_array ( args) ?;
57- let result = call ( & name, & args) ?;
74+ let result = call_with_plugin_agent ( & name, & args, plugin_agent as u64 ) ?;
5875 let j_byte_array = env. byte_array_from_slice ( & result) ?;
5976 Ok ( j_byte_array. into_raw ( ) )
6077}
@@ -78,6 +95,47 @@ fn intern_load_package_with_cache(env: &mut JNIEnv, args: JByteArray) -> Result<
7895 Ok ( j_byte_array. into_raw ( ) )
7996}
8097
98+ #[ no_mangle]
99+ extern "C" fn plugin_agent (
100+ method : * const c_char ,
101+ args : * const c_char ,
102+ kwargs : * const c_char ,
103+ ) -> * const c_char {
104+ let jvm = JVM . lock ( ) . unwrap ( ) ;
105+ let jvm = jvm. as_ref ( ) . unwrap ( ) ;
106+ let mut env = jvm. attach_current_thread ( ) . unwrap ( ) ;
107+
108+ let callback_obj = CALLBACK_OBJ . lock ( ) . unwrap ( ) ;
109+ let callback_obj = callback_obj. as_ref ( ) . unwrap ( ) ;
110+
111+ let method = unsafe {
112+ env. new_string ( CStr :: from_ptr ( method) . to_string_lossy ( ) . into_owned ( ) )
113+ . expect ( "Failed to create Java string" )
114+ } ;
115+ let args = unsafe {
116+ env. new_string ( CStr :: from_ptr ( args) . to_string_lossy ( ) . into_owned ( ) )
117+ . expect ( "Failed to create Java string" )
118+ } ;
119+ let kwargs = unsafe {
120+ env. new_string ( CStr :: from_ptr ( kwargs) . to_string_lossy ( ) . into_owned ( ) )
121+ . expect ( "Failed to create Java string" )
122+ } ;
123+ let params = & [ ( & method) . into ( ) , ( & args) . into ( ) , ( & kwargs) . into ( ) ] ;
124+ let result = env
125+ . call_method (
126+ callback_obj,
127+ "callMethod" ,
128+ "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;" ,
129+ params,
130+ )
131+ . unwrap ( ) ;
132+ let result: JString = result. l ( ) . unwrap ( ) . into ( ) ;
133+ let result: String = env. get_string ( & result) . unwrap ( ) . into ( ) ;
134+ CString :: new ( result)
135+ . expect ( "Failed to create CString" )
136+ . into_raw ( )
137+ }
138+
81139fn throw ( env : & mut JNIEnv , error : anyhow:: Error ) -> jni:: errors:: Result < ( ) > {
82140 env. throw ( ( "java/lang/Exception" , error. to_string ( ) ) )
83141}
0 commit comments