Arquivos
hhvm/hphp/runtime/base/tracer.h
T
Kyle Delong a8e3321fbd HPHP/XHP: 'mixed' type in attribute declarations
We'd like to start using ##mixed## instead of ##var## for attribute types to be consistent with Hack. As a followup to this (once released), we would codemod all ##var## to ##mixed##.
2013-07-18 17:28:37 -07:00

122 linhas
3.7 KiB
C++

/*
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 2.00 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.zend.com/license/2_00.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_TRACER_H
#define incl_HPHP_TRACER_H
#include <functional>
#include <queue>
#include <set>
#include <vector>
#include "hphp/runtime/base/complex_types.h"
#include "hphp/util/trace.h"
namespace HPHP {
template<typename Accum>
struct Tracer {
typedef std::function<void(TypedValue *, Accum&)> NodeFunc;
typedef std::function<void(TypedValue *,TypedValue *,Accum&)> EdgeFunc;
static void trace(TypedValue *self,
NodeFunc atNode,
EdgeFunc atEdge,
Accum& accumulator) {
std::set<TypedValue *> visited;
traceImpl(self, visited, atNode, atEdge, accumulator);
}
static void traceAll(std::vector<TypedValue *> &ts,
NodeFunc atNode,
EdgeFunc atEdge,
Accum& accumulator) {
std::set<TypedValue *> visited;
for (TypedValue *t : ts) {
traceImpl(t, visited, atNode, atEdge, accumulator);
}
}
private:
static void traceImpl(TypedValue *self,
std::set<TypedValue *> &visited,
NodeFunc atNode,
EdgeFunc atEdge,
Accum& accumulator) {
std::queue<TypedValue *> tvs;
const auto traceSingle = [&](TypedValue *parent, TypedValue *child) {
atEdge(parent, child, accumulator);
tvs.push(child);
};
const auto traceMultiple = [&](TypedValue *parent) {
std::vector<TypedValue *> children;
switch(parent->m_type) {
case KindOfArray:
parent->m_data.parr->getChildren(children);
break;
case KindOfObject:
parent->m_data.pobj->getChildren(children);
break;
default:
not_reached();
}
for (TypedValue *child : children) {
traceSingle(parent, child);
}
};
tvs.push(self);
while (!tvs.empty()) {
TypedValue *top = tvs.front();
tvs.pop();
if (visited.find(top) != visited.end()) {
continue;
}
visited.insert(top);
atNode(top, accumulator);
switch (top->m_type) {
case KindOfUninit:
case KindOfNull:
case KindOfBoolean:
case KindOfInt64:
case KindOfDouble:
case KindOfStaticString:
case KindOfString:
break;
case KindOfArray:
case KindOfObject:
traceMultiple(top);
break;
case KindOfRef:
traceSingle(top, top->m_data.pref->tv());
break;
case KindOfIndirect:
traceSingle(top, top->m_data.pind);
break;
default:
not_reached();
}
}
}
};
}
#undef TRACE_SINGLE_CHILD
#undef TRACE_MULTIPLE_CHILDREN
#endif