Implement full-fidelity parsing for unknown shape fields
[hiphop-php.git] / hphp / hhbbc / debug.cpp
blob8daf11fe088cd72b28a7260fecf0764a4513418e
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/hhbbc/debug.h"
18 #include <string>
19 #include <utility>
20 #include <cstdlib>
21 #include <iostream>
23 #include <boost/filesystem/path.hpp>
24 #include <boost/filesystem/operations.hpp>
25 #include <boost/filesystem/fstream.hpp>
26 #include <algorithm>
27 #include <memory>
28 #include <vector>
30 #include <folly/portability/Stdlib.h>
32 #include "hphp/hhbbc/misc.h"
33 #include "hphp/hhbbc/parallel.h"
35 namespace HPHP { namespace HHBBC {
37 namespace fs = boost::filesystem;
39 //////////////////////////////////////////////////////////////////////
41 namespace {
43 template<class Operation>
44 void with_file(fs::path dir, borrowed_ptr<const php::Unit> u, Operation op) {
45 auto const file = dir / fs::path(u->filename->data());
46 fs::create_directories(fs::path(file).remove_filename());
48 fs::ofstream out(file);
49 if (!out.is_open()) {
50 throw std::runtime_error(std::string("failed to open file ") +
51 file.string());
54 op(out);
56 if (out.bad()) {
57 throw std::runtime_error(std::string("couldn't write file ") +
58 file.string());
62 void dump_representation(fs::path dir, const php::Program& program) {
63 parallel::for_each(
64 program.units,
65 [&] (const std::unique_ptr<php::Unit>& u) {
66 with_file(dir, borrow(u), [&] (std::ostream& out) {
67 out << show(*u);
68 });
73 using NameTy = std::pair<SString,Type>;
74 std::vector<NameTy> sorted_prop_state(const PropState& ps) {
75 std::vector<NameTy> ret(begin(ps), end(ps));
76 std::sort(
77 begin(ret), end(ret),
78 [&] (NameTy a, NameTy b) { return a.first->compare(b.first) < 0; }
80 return ret;
83 void dump_class_propstate(std::ostream& out,
84 const Index& index,
85 borrowed_ptr<const php::Class> c) {
86 out << "Class " << c->name->data() << '\n';
88 auto const pprops = sorted_prop_state(
89 index.lookup_private_props(c)
91 for (auto& kv : pprops) {
92 out << "$this->" << kv.first->data() << " :: "
93 << show(kv.second) << '\n';
96 auto const sprops = sorted_prop_state(
97 index.lookup_private_statics(c)
99 for (auto& kv : sprops) {
100 out << "self::$" << kv.first->data() << " :: "
101 << show(kv.second) << '\n';
105 void dump_index(fs::path dir,
106 const Index& index,
107 const php::Program& program) {
108 parallel::for_each(
109 program.units,
110 [&] (const std::unique_ptr<php::Unit>& u) {
111 if (!*u->filename->data()) {
112 // The native systemlibs: for now just skip.
113 return;
116 with_file(dir, borrow(u), [&] (std::ostream& out) {
117 for (auto& c : u->classes) {
118 dump_class_propstate(out, index, borrow(c));
127 //////////////////////////////////////////////////////////////////////
129 void debug_dump_program(const Index& index, const php::Program& program) {
130 if (!Trace::moduleEnabledRelease(Trace::hhbbc_dump, 1)) return;
132 trace_time tracer("debug dump");
134 char dirBuf[] = "/tmp/hhbbcXXXXXX";
135 auto const dtmpRet = mkdtemp(dirBuf);
136 if (!dtmpRet) {
137 throw std::runtime_error(
138 std::string("Failed to create temporary directory") +
139 strerror(errno));
141 auto const dir = fs::path(dtmpRet);
142 fs::create_directory(dir);
143 std::cout << "debug dump going to " << dir << '\n';
146 trace_time tracer2("debug dump: representation");
147 dump_representation(dir / "representation", program);
150 trace_time tracer2("debug dump: index");
151 dump_index(dir / "index", index, program);
154 std::cout << "debug dump done\n";
157 //////////////////////////////////////////////////////////////////////