Skip to content

Commit

Permalink
Merge pull request #150 from sj-i/refactor-trace-reader
Browse files Browse the repository at this point in the history
Refactor trace reader
  • Loading branch information
sj-i committed Feb 1, 2022
2 parents 10c591a + f6efc93 commit 769e482
Show file tree
Hide file tree
Showing 27 changed files with 1,358 additions and 363 deletions.
5 changes: 5 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,5 +65,10 @@
"phpcs": [
"phpcs --standard=./phpcs.xml ./src ./tests"
]
},
"config": {
"allow-plugins": {
"composer/package-versions-deprecated": true
}
}
}
4 changes: 2 additions & 2 deletions src/Command/Inspector/GetCurrentFunctionNameCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
use PhpProfiler\Lib\Elf\Tls\TlsFinderException;
use PhpProfiler\Lib\PhpProcessReader\PhpGlobalsFinder;
use PhpProfiler\Lib\Process\MemoryReader\MemoryReaderException;
use PhpProfiler\Lib\PhpProcessReader\PhpMemoryReader\ExecutorGlobalsReader;
use PhpProfiler\Lib\PhpProcessReader\PhpMemoryReader\CallTraceReader;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
Expand All @@ -34,7 +34,7 @@ final class GetCurrentFunctionNameCommand extends Command
{
public function __construct(
private PhpGlobalsFinder $php_globals_finder,
private ExecutorGlobalsReader $executor_globals_reader,
private CallTraceReader $executor_globals_reader,
private TraceLoopProvider $loop_provider,
private TargetPhpSettingsFromConsoleInput $target_php_settings_from_console_input,
private TargetProcessSettingsFromConsoleInput $target_process_settings_from_console_input,
Expand Down
4 changes: 2 additions & 2 deletions src/Command/Inspector/GetTraceCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
use PhpProfiler\Lib\Elf\Tls\TlsFinderException;
use PhpProfiler\Lib\PhpProcessReader\PhpGlobalsFinder;
use PhpProfiler\Lib\Process\MemoryReader\MemoryReaderException;
use PhpProfiler\Lib\PhpProcessReader\PhpMemoryReader\ExecutorGlobalsReader;
use PhpProfiler\Lib\PhpProcessReader\PhpMemoryReader\CallTraceReader;
use PhpProfiler\Lib\Process\ProcessStopper\ProcessStopper;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
Expand All @@ -40,7 +40,7 @@ final class GetTraceCommand extends Command
{
public function __construct(
private PhpGlobalsFinder $php_globals_finder,
private ExecutorGlobalsReader $executor_globals_reader,
private CallTraceReader $executor_globals_reader,
private TraceLoopProvider $loop_provider,
private GetTraceSettingsFromConsoleInput $get_trace_settings_from_console_input,
private TargetPhpSettingsFromConsoleInput $target_php_settings_from_console_input,
Expand Down
4 changes: 2 additions & 2 deletions src/Inspector/Daemon/Reader/Worker/PhpReaderTraceLoop.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
use PhpProfiler\Inspector\Settings\TargetPhpSettings\TargetPhpSettings;
use PhpProfiler\Inspector\Settings\TraceLoopSettings\TraceLoopSettings;
use PhpProfiler\Lib\PhpProcessReader\PhpGlobalsFinder;
use PhpProfiler\Lib\PhpProcessReader\PhpMemoryReader\ExecutorGlobalsReader;
use PhpProfiler\Lib\PhpProcessReader\PhpMemoryReader\CallTraceReader;
use PhpProfiler\Lib\Process\ProcessSpecifier;
use PhpProfiler\Lib\Process\ProcessStopper\ProcessStopper;

Expand All @@ -30,7 +30,7 @@ final class PhpReaderTraceLoop implements PhpReaderTraceLoopInterface
{
public function __construct(
private PhpGlobalsFinder $php_globals_finder,
private ExecutorGlobalsReader $executor_globals_reader,
private CallTraceReader $executor_globals_reader,
private ReaderLoopProvider $reader_loop_provider,
private ProcessStopper $process_stopper,
) {
Expand Down
26 changes: 26 additions & 0 deletions src/Lib/FFI/CastedTypeProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

/**
* This file is part of the sj-i/php-profiler package.
*
* (c) sji <sji@sj-i.dev>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace PhpProfiler\Lib\FFI;

use FFI\CData;
use PhpProfiler\Lib\PhpInternals\CastedCData;

/**
* @template T
*/
interface CastedTypeProvider
{
/** @return CastedCData<CData> */
public function readAs(string $ctype_name, CData $buffer): CastedCData;
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,16 @@

use FFI\CData;

/** @template T */
final class ZendTypeCData
/** @template T of CData */
final class CastedCData
{
/** @param T $typed */
/**
* @param CData $raw
* @param T $casted
*/
public function __construct(
public CData $raw,
public CData $typed,
public object $raw,
public object $casted,
) {
}
}
62 changes: 62 additions & 0 deletions src/Lib/PhpInternals/Types/C/RawString.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

/**
* This file is part of the sj-i/php-profiler package.
*
* (c) sji <sji@sj-i.dev>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace PhpProfiler\Lib\PhpInternals\Types\C;

use FFI\CData;
use PhpProfiler\Lib\PhpInternals\CastedCData;
use PhpProfiler\Lib\Process\Pointer\Dereferencable;
use PhpProfiler\Lib\Process\Pointer\Pointer;

final class RawString implements Dereferencable
{
/** @psalm-suppress PropertyNotSetInConstructor */
public string $value;

/** @param CastedCData<CData> $cdata */
public function __construct(
private CastedCData $cdata,
private int $len,
) {
unset($this->value);
}

public function __toString(): string
{
return $this->value;
}

public function __get(string $field_name): string
{
return match ($field_name) {
'value' => $this->value = substr(
\FFI::string($this->cdata->casted),
0,
$this->len
),
};
}

public static function getCTypeName(): string
{
return 'char[0]';
}

/** @param CastedCData<CData> $casted_cdata */
public static function fromCastedCData(
CastedCData $casted_cdata,
Pointer $pointer
): static {
return new self($casted_cdata, $pointer->size);
}
}
33 changes: 33 additions & 0 deletions src/Lib/PhpInternals/Types/Zend/ZendCastedTypeProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

/**
* This file is part of the sj-i/php-profiler package.
*
* (c) sji <sji@sj-i.dev>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace PhpProfiler\Lib\PhpInternals\Types\Zend;

use FFI\CData;
use PhpProfiler\Lib\FFI\CastedTypeProvider;
use PhpProfiler\Lib\PhpInternals\CastedCData;
use PhpProfiler\Lib\PhpInternals\ZendTypeReader;

class ZendCastedTypeProvider implements CastedTypeProvider
{
public function __construct(
private ZendTypeReader $zend_type_reader,
) {
}

public function readAs(string $ctype_name, CData $buffer): CastedCData
{
/** @var CastedCData<CData> */
return $this->zend_type_reader->readAs($ctype_name, $buffer);
}
}
66 changes: 66 additions & 0 deletions src/Lib/PhpInternals/Types/Zend/ZendClassEntry.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

/**
* This file is part of the sj-i/php-profiler package.
*
* (c) sji <sji@sj-i.dev>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace PhpProfiler\Lib\PhpInternals\Types\Zend;

use FFI\PhpInternals\zend_class_entry;
use PhpProfiler\Lib\PhpInternals\CastedCData;
use PhpProfiler\Lib\Process\Pointer\Dereferencable;
use PhpProfiler\Lib\Process\Pointer\Dereferencer;
use PhpProfiler\Lib\Process\Pointer\Pointer;

final class ZendClassEntry implements Dereferencable
{
/**
* @psalm-suppress PropertyNotSetInConstructor
* @var Pointer<ZendString>
*/
public Pointer $name;

/** @param CastedCData<zend_class_entry> $casted_cdata */
public function __construct(
private CastedCData $casted_cdata,
) {
unset($this->name);
}

public function __get(string $field_name)
{
return match ($field_name) {
'name' => $this->name = Pointer::fromCData(
ZendString::class,
$this->casted_cdata->casted->name,
),
};
}

public static function getCTypeName(): string
{
return 'zend_class_entry';
}

public static function fromCastedCData(
CastedCData $casted_cdata,
Pointer $pointer
): static {
/** @var CastedCData<zend_class_entry> $casted_cdata */
return new self($casted_cdata);
}

public function getClassName(Dereferencer $dereferencer): string
{
$string = $dereferencer->deref($this->name);
$val = $string->getValuePointer($this->name);
return (string)$dereferencer->deref($val);
}
}
90 changes: 90 additions & 0 deletions src/Lib/PhpInternals/Types/Zend/ZendExecuteData.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<?php

/**
* This file is part of the sj-i/php-profiler package.
*
* (c) sji <sji@sj-i.dev>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace PhpProfiler\Lib\PhpInternals\Types\Zend;

use FFI\PhpInternals\zend_execute_data;
use PhpProfiler\Lib\PhpInternals\CastedCData;
use PhpProfiler\Lib\Process\Pointer\Dereferencable;
use PhpProfiler\Lib\Process\Pointer\Dereferencer;
use PhpProfiler\Lib\Process\Pointer\Pointer;

final class ZendExecuteData implements Dereferencable
{
/** @var Pointer<ZendFunction>|null */
public ?Pointer $func;

/** @var Pointer<ZendExecuteData>|null */
public ?Pointer $prev_execute_data;

/** @var Pointer<ZendOp>|null */
public ?Pointer $opline;

/** @param CastedCData<zend_execute_data> $casted_cdata */
public function __construct(
private CastedCData $casted_cdata,
) {
unset($this->func);
unset($this->prev_execute_data);
unset($this->opline);
}

public function __get(string $field_name): mixed
{
return match ($field_name) {
'func' => $this->casted_cdata->casted->func !== null
? Pointer::fromCData(
ZendFunction::class,
$this->casted_cdata->casted->func,
)
: null
,
'prev_execute_data' => $this->casted_cdata->casted->prev_execute_data !== null
? Pointer::fromCData(
ZendExecuteData::class,
$this->casted_cdata->casted->prev_execute_data,
)
: null
,
'opline' => $this->casted_cdata->casted->opline !== null
? Pointer::fromCData(
ZendOp::class,
$this->casted_cdata->casted->opline
)
: null
,
};
}

public static function getCTypeName(): string
{
return 'zend_execute_data';
}

public static function fromCastedCData(
CastedCData $casted_cdata,
Pointer $pointer
): static {
/** @var CastedCData<zend_execute_data> $casted_cdata */
return new self($casted_cdata);
}

public function getFunctionName(Dereferencer $dereferencer): ?string
{
if (is_null($this->func)) {
return null;
}
$func = $dereferencer->deref($this->func);
return $func->getFullyQualifiedFunctionName($dereferencer);
}
}
Loading

0 comments on commit 769e482

Please sign in to comment.