1 /**************************************************************************
2 *
3 * Copyright 2011 Jose Fonseca
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 *
24 **************************************************************************/
25
26
27 #include "trace_writer.hpp"
28 #include "trace_format.hpp"
29
30
31 namespace trace {
32
33
34 class ModelWriter : public Visitor
35 {
36 protected:
37 Writer &writer;
38
39 public:
ModelWriter(Writer & _writer)40 ModelWriter(Writer &_writer) :
41 writer(_writer) {
42 }
43
visit(Null *)44 void visit(Null *) override {
45 writer.writeNull();
46 }
47
visit(Bool * node)48 void visit(Bool *node) override {
49 writer.writeBool(node->value);
50 }
51
visit(SInt * node)52 void visit(SInt *node) override {
53 writer.writeSInt(node->value);
54 }
55
visit(UInt * node)56 void visit(UInt *node) override {
57 writer.writeUInt(node->value);
58 }
59
visit(Float * node)60 void visit(Float *node) override {
61 writer.writeFloat(node->value);
62 }
63
visit(Double * node)64 void visit(Double *node) override {
65 writer.writeDouble(node->value);
66 }
67
visit(String * node)68 void visit(String *node) override {
69 writer.writeString(node->value);
70 }
71
visit(WString * node)72 void visit(WString *node) override {
73 writer.writeWString(node->value);
74 }
75
visit(Enum * node)76 void visit(Enum *node) override {
77 writer.writeEnum(node->sig, node->value);
78 }
79
visit(Bitmask * node)80 void visit(Bitmask *node) override {
81 writer.writeBitmask(node->sig, node->value);
82 }
83
visit(Struct * node)84 void visit(Struct *node) override {
85 writer.beginStruct(node->sig);
86 for (unsigned i = 0; i < node->sig->num_members; ++i) {
87 _visit(node->members[i]);
88 }
89 writer.endStruct();
90 }
91
visit(Array * node)92 void visit(Array *node) override {
93 writer.beginArray(node->values.size());
94 for (auto & value : node->values) {
95 _visit(value);
96 }
97 writer.endArray();
98 }
99
visit(Blob * node)100 void visit(Blob *node) override {
101 writer.writeBlob(node->buf, node->size);
102 }
103
visit(Pointer * node)104 void visit(Pointer *node) override {
105 writer.writePointer(node->value);
106 }
107
visit(Repr * node)108 void visit(Repr *node) override {
109 writer.beginRepr();
110 _visit(node->humanValue);
111 _visit(node->machineValue);
112 writer.endRepr();
113 }
114
visit(Call * call)115 void visit(Call *call) {
116 unsigned call_no = writer.beginEnter(call->sig, call->thread_id);
117 if (call->flags & CALL_FLAG_FAKE) {
118 writer.writeFlags(FLAG_FAKE);
119 }
120 if (call->backtrace != NULL) {
121 writer.beginBacktrace(call->backtrace->size());
122 for (auto & frame : *call->backtrace) {
123 writer.writeStackFrame(frame);
124 }
125 writer.endBacktrace();
126 }
127 for (unsigned i = 0; i < call->args.size(); ++i) {
128 if (call->args[i].value) {
129 writer.beginArg(i);
130 _visit(call->args[i].value);
131 writer.endArg();
132 }
133 }
134 writer.endEnter();
135 writer.beginLeave(call_no);
136 if (call->ret) {
137 writer.beginReturn();
138 _visit(call->ret);
139 writer.endReturn();
140 }
141 writer.endLeave();
142 }
143 };
144
145
writeCall(Call * call)146 void Writer::writeCall(Call *call) {
147 ModelWriter visitor(*this);
148 visitor.visit(call);
149 }
150
151
152 } /* namespace trace */
153
154