blob: 0e6a4e0f3c3e3b4ee1a7ad7af603295e4ca1980a [file] [log] [blame]
José Fonseca8fbdd3a2010-11-23 20:55:07 +00001##########################################################################
2#
3# Copyright 2008-2010 VMware, Inc.
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
José Fonseca73d0a962010-11-29 14:49:34 +000026"""Common trace code generation."""
José Fonseca8fbdd3a2010-11-23 20:55:07 +000027
28
José Fonsecabd86a222011-09-27 09:21:38 +010029import specs.stdapi as stdapi
José Fonseca8fbdd3a2010-11-23 20:55:07 +000030
31
José Fonseca87d1cc62010-11-29 15:57:25 +000032def interface_wrap_name(interface):
33 return "Wrap" + interface.expr
34
José Fonseca6fac5ae2010-11-29 16:09:13 +000035
José Fonseca54f304a2012-01-14 19:33:08 +000036class ComplexValueSerializer(stdapi.OnceVisitor):
37 '''Type visitors which generates serialization functions for
38 complex types.
39
40 Simple types are serialized inline.
41 '''
José Fonseca8fbdd3a2010-11-23 20:55:07 +000042
José Fonseca54f304a2012-01-14 19:33:08 +000043 def __init__(self, serializer):
44 stdapi.OnceVisitor.__init__(self)
45 self.serializer = serializer
46
47 def visitVoid(self, literal):
José Fonseca8fbdd3a2010-11-23 20:55:07 +000048 pass
49
José Fonseca54f304a2012-01-14 19:33:08 +000050 def visitLiteral(self, literal):
José Fonseca8fbdd3a2010-11-23 20:55:07 +000051 pass
52
José Fonseca54f304a2012-01-14 19:33:08 +000053 def visitString(self, string):
José Fonseca8fbdd3a2010-11-23 20:55:07 +000054 pass
55
José Fonseca54f304a2012-01-14 19:33:08 +000056 def visitConst(self, const):
José Fonseca8fbdd3a2010-11-23 20:55:07 +000057 self.visit(const.type)
58
José Fonseca54f304a2012-01-14 19:33:08 +000059 def visitStruct(self, struct):
José Fonseca8fbdd3a2010-11-23 20:55:07 +000060 for type, name in struct.members:
61 self.visit(type)
José Fonseca06e85192011-10-16 14:15:36 +010062 print 'static void _write__%s(const %s &value) {' % (struct.tag, struct.expr)
José Fonseca7eef8ce2010-11-26 15:46:36 +000063 print ' static const char * members[%u] = {' % (len(struct.members),)
64 for type, name, in struct.members:
65 print ' "%s",' % (name,)
66 print ' };'
José Fonsecab4a3d142011-10-27 07:43:19 +010067 print ' static const trace::StructSig sig = {'
José Fonseca02c25002011-10-15 13:17:26 +010068 print ' %u, "%s", %u, members' % (struct.id, struct.name, len(struct.members))
José Fonseca7eef8ce2010-11-26 15:46:36 +000069 print ' };'
José Fonsecab4a3d142011-10-27 07:43:19 +010070 print ' trace::localWriter.beginStruct(&sig);'
José Fonseca8fbdd3a2010-11-23 20:55:07 +000071 for type, name in struct.members:
José Fonseca54f304a2012-01-14 19:33:08 +000072 self.serializer.visit(type, 'value.%s' % (name,))
José Fonsecab4a3d142011-10-27 07:43:19 +010073 print ' trace::localWriter.endStruct();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +000074 print '}'
75 print
76
José Fonseca54f304a2012-01-14 19:33:08 +000077 def visitArray(self, array):
José Fonseca8fbdd3a2010-11-23 20:55:07 +000078 self.visit(array.type)
79
José Fonseca54f304a2012-01-14 19:33:08 +000080 def visitBlob(self, array):
José Fonseca8fbdd3a2010-11-23 20:55:07 +000081 pass
82
José Fonseca54f304a2012-01-14 19:33:08 +000083 def visitEnum(self, enum):
José Fonsecaeb644512011-12-11 10:33:55 +000084 print 'static const trace::EnumValue __enum%s_values[] = {' % (enum.tag)
85 for value in enum.values:
86 print ' {"%s", %s},' % (value, value)
87 print '};'
88 print
89 print 'static const trace::EnumSig __enum%s_sig = {' % (enum.tag)
90 print ' %u, %u, __enum%s_values' % (enum.id, len(enum.values), enum.tag)
91 print '};'
José Fonseca8fbdd3a2010-11-23 20:55:07 +000092 print
93
José Fonseca54f304a2012-01-14 19:33:08 +000094 def visitBitmask(self, bitmask):
José Fonsecab4a3d142011-10-27 07:43:19 +010095 print 'static const trace::BitmaskFlag __bitmask%s_flags[] = {' % (bitmask.tag)
José Fonseca8fbdd3a2010-11-23 20:55:07 +000096 for value in bitmask.values:
José Fonsecad35973c2010-11-26 14:14:45 +000097 print ' {"%s", %s},' % (value, value)
98 print '};'
99 print
José Fonsecab4a3d142011-10-27 07:43:19 +0100100 print 'static const trace::BitmaskSig __bitmask%s_sig = {' % (bitmask.tag)
José Fonseca02c25002011-10-15 13:17:26 +0100101 print ' %u, %u, __bitmask%s_flags' % (bitmask.id, len(bitmask.values), bitmask.tag)
José Fonsecad35973c2010-11-26 14:14:45 +0000102 print '};'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000103 print
104
José Fonseca54f304a2012-01-14 19:33:08 +0000105 def visitPointer(self, pointer):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000106 self.visit(pointer.type)
107
José Fonseca59ee88e2012-01-15 14:24:10 +0000108 def visitIntPointer(self, pointer):
109 pass
110
111 def visitLinearPointer(self, pointer):
112 self.visit(pointer.type)
113
José Fonseca54f304a2012-01-14 19:33:08 +0000114 def visitHandle(self, handle):
José Fonseca50d78d82010-11-23 22:13:14 +0000115 self.visit(handle.type)
116
José Fonseca54f304a2012-01-14 19:33:08 +0000117 def visitAlias(self, alias):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000118 self.visit(alias.type)
119
José Fonseca54f304a2012-01-14 19:33:08 +0000120 def visitOpaque(self, opaque):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000121 pass
122
José Fonseca54f304a2012-01-14 19:33:08 +0000123 def visitInterface(self, interface):
José Fonseca87d1cc62010-11-29 15:57:25 +0000124 print "class %s : public %s " % (interface_wrap_name(interface), interface.name)
125 print "{"
126 print "public:"
127 print " %s(%s * pInstance);" % (interface_wrap_name(interface), interface.name)
128 print " virtual ~%s();" % interface_wrap_name(interface)
129 print
José Fonseca54f304a2012-01-14 19:33:08 +0000130 for method in interface.iterMethods():
José Fonseca87d1cc62010-11-29 15:57:25 +0000131 print " " + method.prototype() + ";"
132 print
133 #print "private:"
134 print " %s * m_pInstance;" % (interface.name,)
135 print "};"
136 print
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000137
José Fonseca54f304a2012-01-14 19:33:08 +0000138 def visitPolymorphic(self, polymorphic):
José Fonseca06e85192011-10-16 14:15:36 +0100139 print 'static void _write__%s(int selector, const %s & value) {' % (polymorphic.tag, polymorphic.expr)
José Fonsecac636b9d2011-10-14 10:15:02 +0100140 print ' switch (selector) {'
José Fonseca54f304a2012-01-14 19:33:08 +0000141 for cases, type in polymorphic.iterSwitch():
José Fonsecac636b9d2011-10-14 10:15:02 +0100142 for case in cases:
143 print ' %s:' % case
José Fonseca54f304a2012-01-14 19:33:08 +0000144 self.serializer.visit(type, 'static_cast<%s>(value)' % (type,))
José Fonsecac636b9d2011-10-14 10:15:02 +0100145 print ' break;'
146 print ' }'
147 print '}'
148 print
José Fonseca16d46dd2011-10-13 09:52:52 +0100149
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000150
José Fonseca54f304a2012-01-14 19:33:08 +0000151class ValueSerializer(stdapi.Visitor):
152 '''Visitor which generates code to serialize any type.
153
154 Simple types are serialized inline here, whereas the serialization of
155 complex types is dispatched to the serialization functions generated by
156 ComplexValueSerializer visitor above.
157 '''
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000158
José Fonseca54f304a2012-01-14 19:33:08 +0000159 def visitLiteral(self, literal, instance):
José Fonsecab4a3d142011-10-27 07:43:19 +0100160 print ' trace::localWriter.write%s(%s);' % (literal.kind, instance)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000161
José Fonseca54f304a2012-01-14 19:33:08 +0000162 def visitString(self, string, instance):
José Fonsecae6a50bd2010-11-24 10:12:22 +0000163 if string.length is not None:
José Fonsecab4a3d142011-10-27 07:43:19 +0100164 print ' trace::localWriter.writeString((const char *)%s, %s);' % (instance, string.length)
José Fonsecae6a50bd2010-11-24 10:12:22 +0000165 else:
José Fonsecab4a3d142011-10-27 07:43:19 +0100166 print ' trace::localWriter.writeString((const char *)%s);' % instance
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000167
José Fonseca54f304a2012-01-14 19:33:08 +0000168 def visitConst(self, const, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000169 self.visit(const.type, instance)
170
José Fonseca54f304a2012-01-14 19:33:08 +0000171 def visitStruct(self, struct, instance):
José Fonseca06e85192011-10-16 14:15:36 +0100172 print ' _write__%s(%s);' % (struct.tag, instance)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000173
José Fonseca54f304a2012-01-14 19:33:08 +0000174 def visitArray(self, array, instance):
José Fonseca02c25002011-10-15 13:17:26 +0100175 length = '__c' + array.type.tag
176 index = '__i' + array.type.tag
José Fonsecafd34e4e2011-06-03 19:34:29 +0100177 print ' if (%s) {' % instance
178 print ' size_t %s = %s;' % (length, array.length)
José Fonsecab4a3d142011-10-27 07:43:19 +0100179 print ' trace::localWriter.beginArray(%s);' % length
José Fonsecafd34e4e2011-06-03 19:34:29 +0100180 print ' for (size_t %s = 0; %s < %s; ++%s) {' % (index, index, length, index)
José Fonsecab4a3d142011-10-27 07:43:19 +0100181 print ' trace::localWriter.beginElement();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000182 self.visit(array.type, '(%s)[%s]' % (instance, index))
José Fonsecab4a3d142011-10-27 07:43:19 +0100183 print ' trace::localWriter.endElement();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000184 print ' }'
José Fonsecab4a3d142011-10-27 07:43:19 +0100185 print ' trace::localWriter.endArray();'
José Fonsecafd34e4e2011-06-03 19:34:29 +0100186 print ' } else {'
José Fonsecab4a3d142011-10-27 07:43:19 +0100187 print ' trace::localWriter.writeNull();'
José Fonsecafd34e4e2011-06-03 19:34:29 +0100188 print ' }'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000189
José Fonseca54f304a2012-01-14 19:33:08 +0000190 def visitBlob(self, blob, instance):
José Fonsecab4a3d142011-10-27 07:43:19 +0100191 print ' trace::localWriter.writeBlob(%s, %s);' % (instance, blob.size)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000192
José Fonseca54f304a2012-01-14 19:33:08 +0000193 def visitEnum(self, enum, instance):
José Fonsecaeb644512011-12-11 10:33:55 +0000194 print ' trace::localWriter.writeEnum(&__enum%s_sig, %s);' % (enum.tag, instance)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000195
José Fonseca54f304a2012-01-14 19:33:08 +0000196 def visitBitmask(self, bitmask, instance):
José Fonsecab4a3d142011-10-27 07:43:19 +0100197 print ' trace::localWriter.writeBitmask(&__bitmask%s_sig, %s);' % (bitmask.tag, instance)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000198
José Fonseca54f304a2012-01-14 19:33:08 +0000199 def visitPointer(self, pointer, instance):
José Fonsecadbaae492011-04-21 09:28:10 +0100200 print ' if (%s) {' % instance
José Fonsecab4a3d142011-10-27 07:43:19 +0100201 print ' trace::localWriter.beginArray(1);'
202 print ' trace::localWriter.beginElement();'
José Fonseca54f304a2012-01-14 19:33:08 +0000203 self.visit(pointer.type, "*" + instance)
José Fonsecab4a3d142011-10-27 07:43:19 +0100204 print ' trace::localWriter.endElement();'
205 print ' trace::localWriter.endArray();'
José Fonsecafd34e4e2011-06-03 19:34:29 +0100206 print ' } else {'
José Fonsecab4a3d142011-10-27 07:43:19 +0100207 print ' trace::localWriter.writeNull();'
José Fonsecafd34e4e2011-06-03 19:34:29 +0100208 print ' }'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000209
José Fonseca59ee88e2012-01-15 14:24:10 +0000210 def visitIntPointer(self, pointer, instance):
211 print ' trace::localWriter.writeOpaque((const void *)%s);' % instance
212
213 def visitLinearPointer(self, pointer, instance):
214 print ' trace::localWriter.writeOpaque((const void *)%s);' % instance
215
José Fonseca54f304a2012-01-14 19:33:08 +0000216 def visitHandle(self, handle, instance):
José Fonseca50d78d82010-11-23 22:13:14 +0000217 self.visit(handle.type, instance)
218
José Fonseca54f304a2012-01-14 19:33:08 +0000219 def visitAlias(self, alias, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000220 self.visit(alias.type, instance)
221
José Fonseca54f304a2012-01-14 19:33:08 +0000222 def visitOpaque(self, opaque, instance):
José Fonsecab4a3d142011-10-27 07:43:19 +0100223 print ' trace::localWriter.writeOpaque((const void *)%s);' % instance
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000224
José Fonseca54f304a2012-01-14 19:33:08 +0000225 def visitInterface(self, interface, instance):
José Fonsecab4a3d142011-10-27 07:43:19 +0100226 print ' trace::localWriter.writeOpaque((const void *)&%s);' % instance
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000227
José Fonseca54f304a2012-01-14 19:33:08 +0000228 def visitPolymorphic(self, polymorphic, instance):
229 print ' _write__%s(%s, %s);' % (polymorphic.tag, polymorphic.switchExpr, instance)
José Fonseca16d46dd2011-10-13 09:52:52 +0100230
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000231
José Fonseca54f304a2012-01-14 19:33:08 +0000232class ValueWrapper(stdapi.Visitor):
233 '''Type visitor which will generate the code to wrap an instance.
234
235 Wrapping is necessary mostly for interfaces, however interface pointers can
236 appear anywhere inside complex types.
237 '''
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000238
José Fonseca54f304a2012-01-14 19:33:08 +0000239 def visitVoid(self, type, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000240 raise NotImplementedError
241
José Fonseca54f304a2012-01-14 19:33:08 +0000242 def visitLiteral(self, type, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000243 pass
244
José Fonseca54f304a2012-01-14 19:33:08 +0000245 def visitString(self, type, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000246 pass
247
José Fonseca54f304a2012-01-14 19:33:08 +0000248 def visitConst(self, type, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000249 pass
250
José Fonseca54f304a2012-01-14 19:33:08 +0000251 def visitStruct(self, struct, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000252 for type, name in struct.members:
253 self.visit(type, "(%s).%s" % (instance, name))
254
José Fonseca54f304a2012-01-14 19:33:08 +0000255 def visitArray(self, array, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000256 # XXX: actually it is possible to return an array of pointers
257 pass
258
José Fonseca54f304a2012-01-14 19:33:08 +0000259 def visitBlob(self, blob, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000260 pass
261
José Fonseca54f304a2012-01-14 19:33:08 +0000262 def visitEnum(self, enum, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000263 pass
264
José Fonseca54f304a2012-01-14 19:33:08 +0000265 def visitBitmask(self, bitmask, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000266 pass
267
José Fonseca54f304a2012-01-14 19:33:08 +0000268 def visitPointer(self, pointer, instance):
José Fonseca3a2a4762011-05-26 11:37:30 +0100269 print " if (%s) {" % instance
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000270 self.visit(pointer.type, "*" + instance)
José Fonseca3a2a4762011-05-26 11:37:30 +0100271 print " }"
José Fonseca59ee88e2012-01-15 14:24:10 +0000272
273 def visitIntPointer(self, pointer, instance):
274 pass
275
276 def visitLinearPointer(self, pointer, instance):
277 pass
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000278
José Fonseca54f304a2012-01-14 19:33:08 +0000279 def visitHandle(self, handle, instance):
José Fonseca50d78d82010-11-23 22:13:14 +0000280 self.visit(handle.type, instance)
281
José Fonseca54f304a2012-01-14 19:33:08 +0000282 def visitAlias(self, alias, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000283 self.visit(alias.type, instance)
284
José Fonseca54f304a2012-01-14 19:33:08 +0000285 def visitOpaque(self, opaque, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000286 pass
287
José Fonseca54f304a2012-01-14 19:33:08 +0000288 def visitInterface(self, interface, instance):
José Fonseca87d1cc62010-11-29 15:57:25 +0000289 assert instance.startswith('*')
290 instance = instance[1:]
José Fonseca3a2a4762011-05-26 11:37:30 +0100291 print " if (%s) {" % instance
José Fonseca87d1cc62010-11-29 15:57:25 +0000292 print " %s = new %s(%s);" % (instance, interface_wrap_name(interface), instance)
José Fonseca3a2a4762011-05-26 11:37:30 +0100293 print " }"
José Fonseca16d46dd2011-10-13 09:52:52 +0100294
José Fonseca54f304a2012-01-14 19:33:08 +0000295 def visitPolymorphic(self, type, instance):
José Fonseca16d46dd2011-10-13 09:52:52 +0100296 # XXX: There might be polymorphic values that need wrapping in the future
297 pass
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000298
299
José Fonseca54f304a2012-01-14 19:33:08 +0000300class ValueUnwrapper(ValueWrapper):
301 '''Reverse of ValueWrapper.'''
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000302
José Fonseca54f304a2012-01-14 19:33:08 +0000303 def visitInterface(self, interface, instance):
José Fonseca87d1cc62010-11-29 15:57:25 +0000304 assert instance.startswith('*')
305 instance = instance[1:]
José Fonseca3a2a4762011-05-26 11:37:30 +0100306 print " if (%s) {" % instance
José Fonseca87d1cc62010-11-29 15:57:25 +0000307 print " %s = static_cast<%s *>(%s)->m_pInstance;" % (instance, interface_wrap_name(interface), instance)
José Fonseca3a2a4762011-05-26 11:37:30 +0100308 print " }"
José Fonseca87d1cc62010-11-29 15:57:25 +0000309
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000310
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000311class Tracer:
José Fonseca54f304a2012-01-14 19:33:08 +0000312 '''Base class to orchestrate the code generation of API tracing.'''
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000313
José Fonsecabb8760b2011-05-25 23:21:18 +0100314 def __init__(self):
315 self.api = None
316
José Fonseca54f304a2012-01-14 19:33:08 +0000317 def serializerFactory(self):
318 '''Create a serializer.
319
320 Can be overriden by derived classes to inject their own serialzer.
321 '''
322
323 return ValueSerializer()
324
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000325 def trace_api(self, api):
José Fonsecabb8760b2011-05-25 23:21:18 +0100326 self.api = api
327
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000328 self.header(api)
329
330 # Includes
331 for header in api.headers:
José Fonsecae6a50bd2010-11-24 10:12:22 +0000332 print header
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000333 print
334
José Fonseca54f304a2012-01-14 19:33:08 +0000335 # Generate the serializer functions
José Fonsecae6a50bd2010-11-24 10:12:22 +0000336 types = api.all_types()
José Fonseca54f304a2012-01-14 19:33:08 +0000337 visitor = ComplexValueSerializer(self.serializerFactory())
José Fonsecae6a50bd2010-11-24 10:12:22 +0000338 map(visitor.visit, types)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000339 print
340
341 # Interfaces wrapers
José Fonseca87d1cc62010-11-29 15:57:25 +0000342 interfaces = [type for type in types if isinstance(type, stdapi.Interface)]
José Fonseca54f304a2012-01-14 19:33:08 +0000343 map(self.traceInterfaceImpl, interfaces)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000344 print
345
346 # Function wrappers
José Fonseca54f304a2012-01-14 19:33:08 +0000347 map(self.traceFunctionDecl, api.functions)
348 map(self.traceFunctionImpl, api.functions)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000349 print
350
351 self.footer(api)
352
353 def header(self, api):
José Fonseca0ad465c2011-08-24 16:58:13 +0100354 pass
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000355
356 def footer(self, api):
357 pass
358
José Fonseca54f304a2012-01-14 19:33:08 +0000359 def traceFunctionDecl(self, function):
José Fonseca14c21bc2011-02-20 23:32:22 +0000360 # Per-function declarations
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000361
José Fonseca14c21bc2011-02-20 23:32:22 +0000362 if function.args:
363 print 'static const char * __%s_args[%u] = {%s};' % (function.name, len(function.args), ', '.join(['"%s"' % arg.name for arg in function.args]))
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000364 else:
José Fonseca14c21bc2011-02-20 23:32:22 +0000365 print 'static const char ** __%s_args = NULL;' % (function.name,)
José Fonsecab4a3d142011-10-27 07:43:19 +0100366 print 'static const trace::FunctionSig __%s_sig = {%u, "%s", %u, __%s_args};' % (function.name, function.id, function.name, len(function.args), function.name)
José Fonseca14c21bc2011-02-20 23:32:22 +0000367 print
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000368
José Fonseca54f304a2012-01-14 19:33:08 +0000369 def isFunctionPublic(self, function):
José Fonseca23691292011-04-22 10:40:25 +0100370 return True
371
José Fonseca54f304a2012-01-14 19:33:08 +0000372 def traceFunctionImpl(self, function):
373 if self.isFunctionPublic(function):
José Fonseca23691292011-04-22 10:40:25 +0100374 print 'extern "C" PUBLIC'
375 else:
376 print 'extern "C" PRIVATE'
377 print function.prototype() + ' {'
José Fonseca14c21bc2011-02-20 23:32:22 +0000378 if function.type is not stdapi.Void:
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000379 print ' %s __result;' % function.type
José Fonseca54f304a2012-01-14 19:33:08 +0000380 self.traceFunctionImplBody(function)
José Fonseca14c21bc2011-02-20 23:32:22 +0000381 if function.type is not stdapi.Void:
José Fonseca54f304a2012-01-14 19:33:08 +0000382 self.wrapRet(function, "__result")
José Fonseca14c21bc2011-02-20 23:32:22 +0000383 print ' return __result;'
384 print '}'
385 print
386
José Fonseca54f304a2012-01-14 19:33:08 +0000387 def traceFunctionImplBody(self, function):
José Fonsecab4a3d142011-10-27 07:43:19 +0100388 print ' unsigned __call = trace::localWriter.beginEnter(&__%s_sig);' % (function.name,)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000389 for arg in function.args:
390 if not arg.output:
José Fonseca54f304a2012-01-14 19:33:08 +0000391 self.unwrapArg(function, arg)
392 self.serializeArg(function, arg)
José Fonsecab4a3d142011-10-27 07:43:19 +0100393 print ' trace::localWriter.endEnter();'
José Fonseca54f304a2012-01-14 19:33:08 +0000394 self.invokeFunction(function)
José Fonsecab4a3d142011-10-27 07:43:19 +0100395 print ' trace::localWriter.beginLeave(__call);'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000396 for arg in function.args:
397 if arg.output:
José Fonseca54f304a2012-01-14 19:33:08 +0000398 self.serializeArg(function, arg)
399 self.wrapArg(function, arg)
José Fonseca9796b842010-11-25 11:44:50 +0000400 if function.type is not stdapi.Void:
José Fonseca54f304a2012-01-14 19:33:08 +0000401 self.serializeRet(function, "__result")
José Fonsecab4a3d142011-10-27 07:43:19 +0100402 print ' trace::localWriter.endLeave();'
José Fonseca14c21bc2011-02-20 23:32:22 +0000403
José Fonseca54f304a2012-01-14 19:33:08 +0000404 def invokeFunction(self, function, prefix='__', suffix=''):
José Fonseca14c21bc2011-02-20 23:32:22 +0000405 if function.type is stdapi.Void:
406 result = ''
407 else:
408 result = '__result = '
José Fonsecaa08d2752011-08-25 13:26:43 +0100409 dispatch = prefix + function.name + suffix
José Fonseca14c21bc2011-02-20 23:32:22 +0000410 print ' %s%s(%s);' % (result, dispatch, ', '.join([str(arg.name) for arg in function.args]))
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000411
José Fonseca54f304a2012-01-14 19:33:08 +0000412 def serializeArg(self, function, arg):
José Fonsecab4a3d142011-10-27 07:43:19 +0100413 print ' trace::localWriter.beginArg(%u);' % (arg.index,)
José Fonseca54f304a2012-01-14 19:33:08 +0000414 self.serializeArgValue(function, arg)
José Fonsecab4a3d142011-10-27 07:43:19 +0100415 print ' trace::localWriter.endArg();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000416
José Fonseca54f304a2012-01-14 19:33:08 +0000417 def serializeArgValue(self, function, arg):
418 self.serializeValue(arg.type, arg.name)
José Fonseca99221832011-03-22 22:15:46 +0000419
José Fonseca54f304a2012-01-14 19:33:08 +0000420 def wrapArg(self, function, arg):
421 self.wrapValue(arg.type, arg.name)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000422
José Fonseca54f304a2012-01-14 19:33:08 +0000423 def unwrapArg(self, function, arg):
424 self.unwrapValue(arg.type, arg.name)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000425
José Fonseca54f304a2012-01-14 19:33:08 +0000426 def serializeRet(self, function, instance):
José Fonsecab4a3d142011-10-27 07:43:19 +0100427 print ' trace::localWriter.beginReturn();'
José Fonseca54f304a2012-01-14 19:33:08 +0000428 self.serializeValue(function.type, instance)
José Fonsecab4a3d142011-10-27 07:43:19 +0100429 print ' trace::localWriter.endReturn();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000430
José Fonseca54f304a2012-01-14 19:33:08 +0000431 def serializeValue(self, type, instance):
432 serializer = self.serializerFactory()
433 serializer.visit(type, instance)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000434
José Fonseca54f304a2012-01-14 19:33:08 +0000435 def wrapRet(self, function, instance):
436 self.wrapValue(function.type, instance)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000437
José Fonseca54f304a2012-01-14 19:33:08 +0000438 def unwrapRet(self, function, instance):
439 self.unwrapValue(function.type, instance)
440
441 def wrapValue(self, type, instance):
442 visitor = ValueWrapper()
443 visitor.visit(type, instance)
444
445 def unwrapValue(self, type, instance):
446 visitor = ValueUnwrapper()
447 visitor.visit(type, instance)
448
449 def traceInterfaceImpl(self, interface):
José Fonseca87d1cc62010-11-29 15:57:25 +0000450 print '%s::%s(%s * pInstance) {' % (interface_wrap_name(interface), interface_wrap_name(interface), interface.name)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000451 print ' m_pInstance = pInstance;'
452 print '}'
453 print
José Fonseca87d1cc62010-11-29 15:57:25 +0000454 print '%s::~%s() {' % (interface_wrap_name(interface), interface_wrap_name(interface))
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000455 print '}'
456 print
José Fonseca54f304a2012-01-14 19:33:08 +0000457 for method in interface.iterMethods():
458 self.traceMethod(interface, method)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000459 print
460
José Fonseca54f304a2012-01-14 19:33:08 +0000461 def traceMethod(self, interface, method):
José Fonseca87d1cc62010-11-29 15:57:25 +0000462 print method.prototype(interface_wrap_name(interface) + '::' + method.name) + ' {'
463 print ' static const char * __args[%u] = {%s};' % (len(method.args) + 1, ', '.join(['"this"'] + ['"%s"' % arg.name for arg in method.args]))
José Fonsecab4a3d142011-10-27 07:43:19 +0100464 print ' static const trace::FunctionSig __sig = {%u, "%s", %u, __args};' % (method.id, interface.name + '::' + method.name, len(method.args) + 1)
465 print ' unsigned __call = trace::localWriter.beginEnter(&__sig);'
466 print ' trace::localWriter.beginArg(0);'
467 print ' trace::localWriter.writeOpaque((const void *)m_pInstance);'
468 print ' trace::localWriter.endArg();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000469 for arg in method.args:
470 if not arg.output:
José Fonseca54f304a2012-01-14 19:33:08 +0000471 self.unwrapArg(method, arg)
472 self.serializeArg(method, arg)
José Fonseca87d1cc62010-11-29 15:57:25 +0000473 if method.type is stdapi.Void:
474 result = ''
475 else:
476 print ' %s __result;' % method.type
477 result = '__result = '
José Fonsecab4a3d142011-10-27 07:43:19 +0100478 print ' trace::localWriter.endEnter();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000479 print ' %sm_pInstance->%s(%s);' % (result, method.name, ', '.join([str(arg.name) for arg in method.args]))
José Fonsecab4a3d142011-10-27 07:43:19 +0100480 print ' trace::localWriter.beginLeave(__call);'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000481 for arg in method.args:
482 if arg.output:
José Fonseca54f304a2012-01-14 19:33:08 +0000483 self.serializeArg(method, arg)
484 self.wrapArg(method, arg)
José Fonseca87d1cc62010-11-29 15:57:25 +0000485 if method.type is not stdapi.Void:
José Fonsecab4a3d142011-10-27 07:43:19 +0100486 print ' trace::localWriter.beginReturn();'
José Fonseca54f304a2012-01-14 19:33:08 +0000487 self.serializeValue(method.type, "__result")
José Fonsecab4a3d142011-10-27 07:43:19 +0100488 print ' trace::localWriter.endReturn();'
José Fonseca54f304a2012-01-14 19:33:08 +0000489 self.wrapValue(method.type, '__result')
José Fonsecab4a3d142011-10-27 07:43:19 +0100490 print ' trace::localWriter.endLeave();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000491 if method.name == 'QueryInterface':
José Fonsecabb8760b2011-05-25 23:21:18 +0100492 print ' if (ppvObj && *ppvObj) {'
493 print ' if (*ppvObj == m_pInstance) {'
494 print ' *ppvObj = this;'
495 print ' }'
496 for iface in self.api.interfaces:
José Fonseca38c932b2011-11-11 20:12:15 +0000497 print r' else if (riid == IID_%s) {' % iface.name
498 print r' *ppvObj = new Wrap%s((%s *) *ppvObj);' % (iface.name, iface.name)
499 print r' }'
500 print r' else {'
501 print r' os::log("apitrace: warning: unknown REFIID {0x%08lX,0x%04X,0x%04X,{0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X}}\n",'
502 print r' riid.Data1, riid.Data2, riid.Data3,'
503 print r' riid.Data4[0],'
504 print r' riid.Data4[1],'
505 print r' riid.Data4[2],'
506 print r' riid.Data4[3],'
507 print r' riid.Data4[4],'
508 print r' riid.Data4[5],'
509 print r' riid.Data4[6],'
510 print r' riid.Data4[7]);'
511 print r' }'
José Fonsecabb8760b2011-05-25 23:21:18 +0100512 print ' }'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000513 if method.name == 'Release':
José Fonseca87d1cc62010-11-29 15:57:25 +0000514 assert method.type is not stdapi.Void
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000515 print ' if (!__result)'
516 print ' delete this;'
José Fonseca87d1cc62010-11-29 15:57:25 +0000517 if method.type is not stdapi.Void:
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000518 print ' return __result;'
519 print '}'
520 print
521