Skip to content

Commit 9417f4a

Browse files
[VarDumper] Sfdump JS ns and VarCloner replacing Ext+PhpCloner
1 parent 4a16e34 commit 9417f4a

File tree

6 files changed

+91
-261
lines changed

6 files changed

+91
-261
lines changed

Cloner/ExtCloner.php

Lines changed: 0 additions & 201 deletions
This file was deleted.

Cloner/PhpCloner.php renamed to Cloner/VarCloner.php

Lines changed: 67 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -14,29 +14,37 @@
1414
/**
1515
* @author Nicolas Grekas <[email protected]>
1616
*/
17-
class PhpCloner extends AbstractCloner
17+
class VarCloner extends AbstractCloner
1818
{
1919
/**
2020
* {@inheritdoc}
2121
*/
2222
protected function doClone($var)
2323
{
24+
$useExt = extension_loaded('symfony_debug');
2425
$i = 0; // Current iteration position in $queue
2526
$len = 1; // Length of $queue
2627
$pos = 0; // Number of cloned items past the first level
2728
$refs = 0; // Number of hard+soft references in $var
2829
$queue = array(array($var)); // This breadth-first queue is the return value
2930
$arrayRefs = array(); // Map of queue indexes to stub array objects
30-
$hardRefs = array(); // By-ref map of stub objects' hashes to original hard `&` references
31+
$hardRefs = array(); // Map of original zval hashes to stub objects
3132
$softRefs = array(); // Map of original object hashes to their stub object couterpart
3233
$values = array(); // Map of stub objects' hashes to original values
3334
$maxItems = $this->maxItems;
3435
$maxString = $this->maxString;
3536
$cookie = (object) array(); // Unique object used to detect hard references
36-
$isRef = false;
3737
$a = null; // Array cast for nested structures
3838
$stub = null; // Stub capturing the main properties of an original item value,
3939
// or null if the original value is used directly
40+
$zval = array( // Main properties of the current value
41+
'type' => null,
42+
'zval_isref' => null,
43+
'array_count' => null,
44+
'object_class' => null,
45+
'object_hash' => null,
46+
'resource_type' => null,
47+
);
4048

4149
for ($i = 0; $i < $len; ++$i) {
4250
$indexed = true; // Whether the currently iterated array is numerically indexed or not
@@ -48,20 +56,33 @@ protected function doClone($var)
4856
if ($indexed && $k !== ++$j) {
4957
$indexed = false;
5058
}
51-
$step[$k] = $cookie;
52-
if ($queue[$i][$k] === $cookie) {
53-
$queue[$i][$k] =& $stub; // Break hard references to make $queue completely
54-
unset($stub); // independent from the original structure
55-
if ($v instanceof Stub && isset($hardRefs[spl_object_hash($v)])) {
56-
$v->ref = ++$refs;
57-
$step[$k] = $queue[$i][$k] = $v;
58-
continue;
59+
if ($useExt) {
60+
$zval = symfony_zval_info($k, $step);
61+
if ($zval['zval_isref']) {
62+
$queue[$i][$k] =& $stub; // Break hard references to make $queue completely
63+
unset($stub); // independent from the original structure
64+
if (isset($hardRefs[$h = $zval['zval_hash']])) {
65+
$hardRefs[$h]->ref = ++$refs;
66+
$queue[$i][$k] = $hardRefs[$h];
67+
continue;
68+
}
69+
}
70+
} else {
71+
$step[$k] = $cookie;
72+
if ($zval['zval_isref'] = $queue[$i][$k] === $cookie) {
73+
$queue[$i][$k] =& $stub; // Break hard references to make $queue completely
74+
unset($stub); // independent from the original structure
75+
if ($v instanceof Stub && isset($hardRefs[spl_object_hash($v)])) {
76+
$v->ref = ++$refs;
77+
$step[$k] = $queue[$i][$k] = $v;
78+
continue;
79+
}
5980
}
60-
$isRef = true;
81+
$zval['type'] = gettype($v);
6182
}
6283
// Create $stub when the original value $v can not be used directly
6384
// If $v is a nested structure, put that structure in array $a
64-
switch (gettype($v)) {
85+
switch ($zval['type']) {
6586
case 'string':
6687
if (isset($v[0]) && !preg_match('//u', $v)) {
6788
$stub = new Stub();
@@ -74,7 +95,7 @@ protected function doClone($var)
7495
$cut = $v;
7596
}
7697
$stub->value = Data::utf8Encode($cut);
77-
} elseif (0 <= $maxString && isset($v[1+($maxString>>2)]) && 0 < $cut = iconv_strlen($v, 'UTF-8') - $maxString) {
98+
} elseif (0 <= $maxString && isset($v[1 + ($maxString >> 2)]) && 0 < $cut = iconv_strlen($v, 'UTF-8') - $maxString) {
7899
$stub = new Stub();
79100
$stub->type = Stub::TYPE_STRING;
80101
$stub->class = Stub::STRING_UTF8;
@@ -91,16 +112,16 @@ protected function doClone($var)
91112
$stub = $arrayRefs[$len] = new Stub();
92113
$stub->type = Stub::TYPE_ARRAY;
93114
$stub->class = Stub::ARRAY_ASSOC;
94-
$stub->value = count($v);
115+
$stub->value = $v ? $zval['array_count'] ?: count($v) : 0;
95116
$a = $v;
96117
}
97118
break;
98119

99120
case 'object':
100-
if (empty($softRefs[$h = spl_object_hash($v)])) {
121+
if (empty($softRefs[$h = $zval['object_hash'] ?: spl_object_hash($v)])) {
101122
$stub = new Stub();
102123
$stub->type = Stub::TYPE_OBJECT;
103-
$stub->class = get_class($v);
124+
$stub->class = $zval['object_class'] ?: get_class($v);
104125
$stub->value = $v;
105126
$a = $this->castObject($stub, 0 < $i);
106127
if ($v !== $stub->value) {
@@ -129,7 +150,7 @@ protected function doClone($var)
129150
if (empty($softRefs[$h = (int) $v])) {
130151
$stub = new Stub();
131152
$stub->type = Stub::TYPE_RESOURCE;
132-
$stub->class = get_resource_type($v);
153+
$stub->class = $zval['resource_type'] ?: get_resource_type($v);
133154
$stub->value = $v;
134155
$a = $this->castResource($stub, 0 < $i);
135156
if ($v !== $stub->value) {
@@ -155,17 +176,25 @@ protected function doClone($var)
155176
}
156177

157178
if (isset($stub)) {
158-
if ($isRef) {
159-
if (Stub::TYPE_ARRAY === $stub->type) {
160-
$step[$k] = $stub;
179+
if ($zval['zval_isref']) {
180+
if ($useExt) {
181+
if (Stub::TYPE_ARRAY === $stub->type) {
182+
$queue[$i][$k] = $hardRefs[$zval['zval_hash']] = $stub;
183+
} else {
184+
$queue[$i][$k] = $hardRefs[$zval['zval_hash']] = $v = new Stub();
185+
$v->value = $stub;
186+
}
161187
} else {
162-
$step[$k] = new Stub();
163-
$step[$k]->value = $stub;
188+
if (Stub::TYPE_ARRAY === $stub->type) {
189+
$step[$k] = $stub;
190+
} else {
191+
$step[$k] = new Stub();
192+
$step[$k]->value = $stub;
193+
}
194+
$h = spl_object_hash($step[$k]);
195+
$queue[$i][$k] = $hardRefs[$h] =& $step[$k];
196+
$values[$h] = $v;
164197
}
165-
$h = spl_object_hash($step[$k]);
166-
$queue[$i][$k] = $hardRefs[$h] =& $step[$k];
167-
$values[$h] = $v;
168-
$isRef = false;
169198
} else {
170199
$queue[$i][$k] = $stub;
171200
}
@@ -193,13 +222,17 @@ protected function doClone($var)
193222
$stub->position = $len++;
194223
}
195224
$stub = $a = null;
196-
} elseif ($isRef) {
197-
$step[$k] = $queue[$i][$k] = new Stub();
198-
$step[$k]->value = $v;
199-
$h = spl_object_hash($step[$k]);
200-
$hardRefs[$h] =& $step[$k];
201-
$values[$h] = $v;
202-
$isRef = false;
225+
} elseif ($zval['zval_isref']) {
226+
if ($useExt) {
227+
$queue[$i][$k] = $hardRefs[$zval['zval_hash']] = new Stub();
228+
$queue[$i][$k]->value = $v;
229+
} else {
230+
$step[$k] = $queue[$i][$k] = new Stub();
231+
$step[$k]->value = $v;
232+
$h = spl_object_hash($step[$k]);
233+
$hardRefs[$h] =& $step[$k];
234+
$values[$h] = $v;
235+
}
203236
}
204237
}
205238

0 commit comments

Comments
 (0)