aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe-php-rpc/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/shirabe-php-rpc/src/lib.rs')
-rw-r--r--crates/shirabe-php-rpc/src/lib.rs24
1 files changed, 20 insertions, 4 deletions
diff --git a/crates/shirabe-php-rpc/src/lib.rs b/crates/shirabe-php-rpc/src/lib.rs
index b2bc2c28..dfd8fa67 100644
--- a/crates/shirabe-php-rpc/src/lib.rs
+++ b/crates/shirabe-php-rpc/src/lib.rs
@@ -643,6 +643,12 @@ impl std::error::Error for PhpThrow {}
/// Handles `CallRustMethod` requests arriving while a Rust-initiated call is waiting for its
/// `Return` (the cooperative reentrancy loop). A handler may itself issue nested RPC calls.
+///
+/// `out_param_positions` names the by-ref parameters of the called method, as the calling stub
+/// declared them. A handler that assigns to one writes the resulting value into `out_params` under
+/// the same position, and the stub copies it back into the caller's variable; leaving a position
+/// out means the method never assigned to it, which is what PHP does with an untouched by-ref
+/// parameter.
pub trait RustMethodDispatcher {
fn dispatch(
&mut self,
@@ -650,6 +656,7 @@ pub trait RustMethodDispatcher {
method_name: &str,
args: Vec<PluginValue>,
out_param_positions: &[u32],
+ out_params: &mut IndexMap<u32, PluginValue>,
) -> Result<PluginValue, PhpThrow>;
}
@@ -812,10 +819,15 @@ fn rpc_call(
args,
out_param_positions,
} => {
+ let mut out_params = IndexMap::new();
let outcome = match dispatcher.as_deref_mut() {
- Some(dispatcher) => {
- dispatcher.dispatch(rhandle, &method_name, args, &out_param_positions)
- }
+ Some(dispatcher) => dispatcher.dispatch(
+ rhandle,
+ &method_name,
+ args,
+ &out_param_positions,
+ &mut out_params,
+ ),
// Never fall back to a silent null: an unroutable callback is reported as an
// explicit error on the PHP side.
None => Err(PhpThrow::runtime(format!(
@@ -827,7 +839,7 @@ fn rpc_call(
Ok(value) => Frame::Return {
corr_id,
value,
- out_params: IndexMap::new(),
+ out_params,
},
Err(throw) => Frame::Throw {
corr_id,
@@ -1011,6 +1023,10 @@ const STUB_FILES: &[(&str, &str)] = &[
"Composer/Util/Filesystem.php",
include_str!("../php/stubs/Composer/Util/Filesystem.php"),
),
+ (
+ "Composer/Util/ProcessExecutor.php",
+ include_str!("../php/stubs/Composer/Util/ProcessExecutor.php"),
+ ),
];
/// Hand-written worker-side classes (two-world implementations with behavior of their own, not