comment out unused parameters
[hiphop-php.git] / hphp / runtime / base / data-walker.cpp
blob5602c16bc74bc6b5fabbbd7e8a1b54a7e8b8eb7e
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
16 #include "hphp/runtime/base/data-walker.h"
18 #include "hphp/runtime/base/array-data.h"
19 #include "hphp/runtime/base/object-data.h"
20 #include "hphp/runtime/base/type-variant.h"
21 #include "hphp/runtime/base/array-iterator.h"
22 #include "hphp/runtime/base/collections.h"
24 namespace HPHP {
26 //////////////////////////////////////////////////////////////////////
28 void DataWalker::traverseData(ArrayData* data,
29 DataFeature& features,
30 PointerSet& visited) const {
31 for (ArrayIter iter(data); iter; ++iter) {
32 auto const rval = iter.secondRval();
34 if (rval.type() == KindOfRef &&
35 rval.val().pref->isReferenced()) {
36 if (markVisited(rval.val().pref->var(), features, visited)) {
37 if (canStopWalk(features)) return;
38 continue; // don't recurse forever; we already went down this path
40 // Right now consider it circular even if the referenced variant only
41 // showed up in one spot. This could be revisted later.
42 features.isCircular = true;
43 if (canStopWalk(features)) return;
46 auto const inner = tvToCell(rval);
47 // cheap enough, do it always
48 features.hasRefCountReference = isRefcountedType(inner.type());
49 if (inner.type() == KindOfObject) {
50 features.hasObjectOrResource = true;
51 traverseData(inner.val().pobj, features, visited);
52 } else if (isArrayLikeType(inner.type())) {
53 traverseData(inner.val().parr, features, visited);
54 } else if (inner.type() == KindOfResource) {
55 features.hasObjectOrResource = true;
57 if (canStopWalk(features)) return;
61 void DataWalker::traverseData(
62 ObjectData* data,
63 DataFeature& features,
64 PointerSet& visited) const {
65 objectFeature(data, features, visited);
66 if (markVisited(data, features, visited)) {
67 return; // avoid infinite recursion
69 if (!canStopWalk(features)) {
70 traverseData(data->toArray().get(), features, visited);
74 inline bool DataWalker::markVisited(
75 void* pvar,
76 DataFeature& features,
77 PointerSet& visited) const {
78 if (!visited.insert(pvar).second) {
79 features.isCircular = true;
80 return true;
82 return false;
85 inline void DataWalker::objectFeature(ObjectData* pobj, DataFeature& features,
86 PointerSet& /*visited*/) const {
87 if (pobj->isCollection()) return;
88 if ((m_features & LookupFeature::DetectSerializable) &&
89 pobj->instanceof(SystemLib::s_SerializableClass)) {
90 features.hasSerializable = true;
94 inline bool DataWalker::canStopWalk(DataFeature& features) const {
95 auto refCountCheck =
96 features.hasRefCountReference ||
97 !(m_features & LookupFeature::RefCountedReference);
98 auto objectCheck =
99 features.hasObjectOrResource ||
100 !(m_features & LookupFeature::HasObjectOrResource);
101 auto defaultChecks = features.isCircular || features.hasSerializable;
102 return refCountCheck && objectCheck && defaultChecks;
105 //////////////////////////////////////////////////////////////////////