aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe-php-rpc/php
diff options
context:
space:
mode:
Diffstat (limited to 'crates/shirabe-php-rpc/php')
-rw-r--r--crates/shirabe-php-rpc/php/stubs/Composer/EventDispatcher/EventDispatcher.php10
-rw-r--r--crates/shirabe-php-rpc/php/stubs/Composer/IO/BaseIO.php10
-rw-r--r--crates/shirabe-php-rpc/php/stubs/Composer/Installer/InstallationManager.php10
-rw-r--r--crates/shirabe-php-rpc/php/stubs/Composer/Package/BasePackage.php17
-rw-r--r--crates/shirabe-php-rpc/php/stubs/Composer/PartialComposer.php10
-rw-r--r--crates/shirabe-php-rpc/php/stubs/Composer/Repository/ArrayRepository.php10
-rw-r--r--crates/shirabe-php-rpc/php/stubs/Composer/Repository/RepositoryManager.php10
-rw-r--r--crates/shirabe-php-rpc/php/worker.php10
8 files changed, 80 insertions, 7 deletions
diff --git a/crates/shirabe-php-rpc/php/stubs/Composer/EventDispatcher/EventDispatcher.php b/crates/shirabe-php-rpc/php/stubs/Composer/EventDispatcher/EventDispatcher.php
index c0651081..30f8c0e8 100644
--- a/crates/shirabe-php-rpc/php/stubs/Composer/EventDispatcher/EventDispatcher.php
+++ b/crates/shirabe-php-rpc/php/stubs/Composer/EventDispatcher/EventDispatcher.php
@@ -44,6 +44,16 @@ class EventDispatcher implements \ShirabeRustStub
];
}
+ public function __clone()
+ {
+ // PHP has already shallow-copied this stub, so both copies would point at one
+ // entity and release it twice. The Rust side clones the entity instead, applying
+ // whatever __clone semantics the real class defines, and this copy rebinds to the
+ // fresh handle. Entities without clone semantics answer with an explicit error.
+ [$this->__rhandle, $this->__epoch] = \ShirabeRpcRuntime::callRust($this->__rhandle, '__shirabeClone', []);
+ \ShirabeRustObjectRegistry::adopt($this->__rhandle, $this);
+ }
+
public function setRunScripts(bool $runScripts = true): self
{
\ShirabeRpcRuntime::callRust($this->__rhandle, 'setRunScripts', [$runScripts]);
diff --git a/crates/shirabe-php-rpc/php/stubs/Composer/IO/BaseIO.php b/crates/shirabe-php-rpc/php/stubs/Composer/IO/BaseIO.php
index 55da6415..b3e0fb51 100644
--- a/crates/shirabe-php-rpc/php/stubs/Composer/IO/BaseIO.php
+++ b/crates/shirabe-php-rpc/php/stubs/Composer/IO/BaseIO.php
@@ -42,6 +42,16 @@ abstract class BaseIO implements IOInterface, \ShirabeRustStub
];
}
+ public function __clone()
+ {
+ // PHP has already shallow-copied this stub, so both copies would point at one
+ // entity and release it twice. The Rust side clones the entity instead, applying
+ // whatever __clone semantics the real class defines, and this copy rebinds to the
+ // fresh handle. Entities without clone semantics answer with an explicit error.
+ [$this->__rhandle, $this->__epoch] = \ShirabeRpcRuntime::callRust($this->__rhandle, '__shirabeClone', []);
+ \ShirabeRustObjectRegistry::adopt($this->__rhandle, $this);
+ }
+
public function isInteractive()
{
return \ShirabeRpcRuntime::callRust($this->__rhandle, 'isInteractive', []);
diff --git a/crates/shirabe-php-rpc/php/stubs/Composer/Installer/InstallationManager.php b/crates/shirabe-php-rpc/php/stubs/Composer/Installer/InstallationManager.php
index 35682561..d458d30b 100644
--- a/crates/shirabe-php-rpc/php/stubs/Composer/Installer/InstallationManager.php
+++ b/crates/shirabe-php-rpc/php/stubs/Composer/Installer/InstallationManager.php
@@ -50,6 +50,16 @@ class InstallationManager implements \ShirabeRustStub
];
}
+ public function __clone()
+ {
+ // PHP has already shallow-copied this stub, so both copies would point at one
+ // entity and release it twice. The Rust side clones the entity instead, applying
+ // whatever __clone semantics the real class defines, and this copy rebinds to the
+ // fresh handle. Entities without clone semantics answer with an explicit error.
+ [$this->__rhandle, $this->__epoch] = \ShirabeRpcRuntime::callRust($this->__rhandle, '__shirabeClone', []);
+ \ShirabeRustObjectRegistry::adopt($this->__rhandle, $this);
+ }
+
public function reset(): void
{
\ShirabeRpcRuntime::callRust($this->__rhandle, 'reset', []);
diff --git a/crates/shirabe-php-rpc/php/stubs/Composer/Package/BasePackage.php b/crates/shirabe-php-rpc/php/stubs/Composer/Package/BasePackage.php
index e55c3fb5..de8037ca 100644
--- a/crates/shirabe-php-rpc/php/stubs/Composer/Package/BasePackage.php
+++ b/crates/shirabe-php-rpc/php/stubs/Composer/Package/BasePackage.php
@@ -42,6 +42,16 @@ abstract class BasePackage implements PackageInterface, \ShirabeRustStub
];
}
+ public function __clone()
+ {
+ // PHP has already shallow-copied this stub, so both copies would point at one
+ // entity and release it twice. The Rust side clones the entity instead, applying
+ // whatever __clone semantics the real class defines, and this copy rebinds to the
+ // fresh handle. Entities without clone semantics answer with an explicit error.
+ [$this->__rhandle, $this->__epoch] = \ShirabeRpcRuntime::callRust($this->__rhandle, '__shirabeClone', []);
+ \ShirabeRustObjectRegistry::adopt($this->__rhandle, $this);
+ }
+
public const STABILITY_STABLE = 0;
public const STABILITY_RC = 5;
public const STABILITY_BETA = 10;
@@ -75,13 +85,6 @@ abstract class BasePackage implements PackageInterface, \ShirabeRustStub
\ShirabeRpcRuntime::callRust($this->__rhandle, '__set', [$name, $value]);
}
- public function __clone()
- {
- // Cloning a proxy is an open design question; fail instead of silently sharing
- // the Rust-side entity between two stub instances.
- throw new \RuntimeException('Shirabe does not support cloning ' . static::class . ' inside the plugin process yet');
- }
-
public static function packageNameToRegexp(string $allowPattern, string $wrap = '{^%s$}i'): string
{
$cleanedAllowPattern = str_replace('\\*', '.*', preg_quote($allowPattern));
diff --git a/crates/shirabe-php-rpc/php/stubs/Composer/PartialComposer.php b/crates/shirabe-php-rpc/php/stubs/Composer/PartialComposer.php
index 588800dc..c60edbb2 100644
--- a/crates/shirabe-php-rpc/php/stubs/Composer/PartialComposer.php
+++ b/crates/shirabe-php-rpc/php/stubs/Composer/PartialComposer.php
@@ -46,6 +46,16 @@ class PartialComposer implements \ShirabeRustStub
];
}
+ public function __clone()
+ {
+ // PHP has already shallow-copied this stub, so both copies would point at one
+ // entity and release it twice. The Rust side clones the entity instead, applying
+ // whatever __clone semantics the real class defines, and this copy rebinds to the
+ // fresh handle. Entities without clone semantics answer with an explicit error.
+ [$this->__rhandle, $this->__epoch] = \ShirabeRpcRuntime::callRust($this->__rhandle, '__shirabeClone', []);
+ \ShirabeRustObjectRegistry::adopt($this->__rhandle, $this);
+ }
+
public function setPackage(RootPackageInterface $package): void
{
\ShirabeRpcRuntime::callRust($this->__rhandle, 'setPackage', [$package]);
diff --git a/crates/shirabe-php-rpc/php/stubs/Composer/Repository/ArrayRepository.php b/crates/shirabe-php-rpc/php/stubs/Composer/Repository/ArrayRepository.php
index 33454fa2..51e6a462 100644
--- a/crates/shirabe-php-rpc/php/stubs/Composer/Repository/ArrayRepository.php
+++ b/crates/shirabe-php-rpc/php/stubs/Composer/Repository/ArrayRepository.php
@@ -42,6 +42,16 @@ class ArrayRepository implements RepositoryInterface, \ShirabeRustStub
];
}
+ public function __clone()
+ {
+ // PHP has already shallow-copied this stub, so both copies would point at one
+ // entity and release it twice. The Rust side clones the entity instead, applying
+ // whatever __clone semantics the real class defines, and this copy rebinds to the
+ // fresh handle. Entities without clone semantics answer with an explicit error.
+ [$this->__rhandle, $this->__epoch] = \ShirabeRpcRuntime::callRust($this->__rhandle, '__shirabeClone', []);
+ \ShirabeRustObjectRegistry::adopt($this->__rhandle, $this);
+ }
+
public function hasPackage(PackageInterface $package)
{
return \ShirabeRpcRuntime::callRust($this->__rhandle, 'hasPackage', [$package]);
diff --git a/crates/shirabe-php-rpc/php/stubs/Composer/Repository/RepositoryManager.php b/crates/shirabe-php-rpc/php/stubs/Composer/Repository/RepositoryManager.php
index 252bab4d..5635c0dc 100644
--- a/crates/shirabe-php-rpc/php/stubs/Composer/Repository/RepositoryManager.php
+++ b/crates/shirabe-php-rpc/php/stubs/Composer/Repository/RepositoryManager.php
@@ -42,6 +42,16 @@ class RepositoryManager implements \ShirabeRustStub
];
}
+ public function __clone()
+ {
+ // PHP has already shallow-copied this stub, so both copies would point at one
+ // entity and release it twice. The Rust side clones the entity instead, applying
+ // whatever __clone semantics the real class defines, and this copy rebinds to the
+ // fresh handle. Entities without clone semantics answer with an explicit error.
+ [$this->__rhandle, $this->__epoch] = \ShirabeRpcRuntime::callRust($this->__rhandle, '__shirabeClone', []);
+ \ShirabeRustObjectRegistry::adopt($this->__rhandle, $this);
+ }
+
public function findPackage(string $name, $constraint): ?PackageInterface
{
return \ShirabeRpcRuntime::callRust($this->__rhandle, 'findPackage', [$name, $constraint]);
diff --git a/crates/shirabe-php-rpc/php/worker.php b/crates/shirabe-php-rpc/php/worker.php
index 241dad57..12297c83 100644
--- a/crates/shirabe-php-rpc/php/worker.php
+++ b/crates/shirabe-php-rpc/php/worker.php
@@ -51,6 +51,16 @@ final class ShirabeRustObjectRegistry
return $stub;
}
+ /**
+ * Interns a stub the registry did not build: a `__clone` forwarder rebinds the copy PHP
+ * made to a freshly cloned entity, and that pairing has to be visible to later crossings
+ * of the same handle.
+ */
+ public static function adopt(int $rhandle, object $stub): void
+ {
+ self::$internTable[$rhandle] = WeakReference::create($stub);
+ }
+
/** Invoked when an EpochBump frame arrives. No-op if the stub already died. */
public static function bumpEpoch(int $rhandle, int $epoch): void
{