blob: bb209e408f197d3046e60b41c2685ee58379a30c [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é Fonseca54f304a2012-01-14 19:33:08 +0000108 def visitHandle(self, handle):
José Fonseca50d78d82010-11-23 22:13:14 +0000109 self.visit(handle.type)
110
José Fonseca54f304a2012-01-14 19:33:08 +0000111 def visitAlias(self, alias):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000112 self.visit(alias.type)
113
José Fonseca54f304a2012-01-14 19:33:08 +0000114 def visitOpaque(self, opaque):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000115 pass
116
José Fonseca54f304a2012-01-14 19:33:08 +0000117 def visitInterface(self, interface):
José Fonseca87d1cc62010-11-29 15:57:25 +0000118 print "class %s : public %s " % (interface_wrap_name(interface), interface.name)
119 print "{"
120 print "public:"
121 print " %s(%s * pInstance);" % (interface_wrap_name(interface), interface.name)
122 print " virtual ~%s();" % interface_wrap_name(interface)
123 print
José Fonseca54f304a2012-01-14 19:33:08 +0000124 for method in interface.iterMethods():
José Fonseca87d1cc62010-11-29 15:57:25 +0000125 print " " + method.prototype() + ";"
126 print
127 #print "private:"
128 print " %s * m_pInstance;" % (interface.name,)
129 print "};"
130 print
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000131
José Fonseca54f304a2012-01-14 19:33:08 +0000132 def visitPolymorphic(self, polymorphic):
José Fonseca06e85192011-10-16 14:15:36 +0100133 print 'static void _write__%s(int selector, const %s & value) {' % (polymorphic.tag, polymorphic.expr)
José Fonsecac636b9d2011-10-14 10:15:02 +0100134 print ' switch (selector) {'
José Fonseca54f304a2012-01-14 19:33:08 +0000135 for cases, type in polymorphic.iterSwitch():
José Fonsecac636b9d2011-10-14 10:15:02 +0100136 for case in cases:
137 print ' %s:' % case
José Fonseca54f304a2012-01-14 19:33:08 +0000138 self.serializer.visit(type, 'static_cast<%s>(value)' % (type,))
José Fonsecac636b9d2011-10-14 10:15:02 +0100139 print ' break;'
140 print ' }'
141 print '}'
142 print
José Fonseca16d46dd2011-10-13 09:52:52 +0100143
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000144
José Fonseca54f304a2012-01-14 19:33:08 +0000145class ValueSerializer(stdapi.Visitor):
146 '''Visitor which generates code to serialize any type.
147
148 Simple types are serialized inline here, whereas the serialization of
149 complex types is dispatched to the serialization functions generated by
150 ComplexValueSerializer visitor above.
151 '''
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000152
José Fonseca54f304a2012-01-14 19:33:08 +0000153 def visitLiteral(self, literal, instance):
José Fonsecab4a3d142011-10-27 07:43:19 +0100154 print ' trace::localWriter.write%s(%s);' % (literal.kind, instance)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000155
José Fonseca54f304a2012-01-14 19:33:08 +0000156 def visitString(self, string, instance):
José Fonsecae6a50bd2010-11-24 10:12:22 +0000157 if string.length is not None:
José Fonsecab4a3d142011-10-27 07:43:19 +0100158 print ' trace::localWriter.writeString((const char *)%s, %s);' % (instance, string.length)
José Fonsecae6a50bd2010-11-24 10:12:22 +0000159 else:
José Fonsecab4a3d142011-10-27 07:43:19 +0100160 print ' trace::localWriter.writeString((const char *)%s);' % instance
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000161
José Fonseca54f304a2012-01-14 19:33:08 +0000162 def visitConst(self, const, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000163 self.visit(const.type, instance)
164
José Fonseca54f304a2012-01-14 19:33:08 +0000165 def visitStruct(self, struct, instance):
José Fonseca06e85192011-10-16 14:15:36 +0100166 print ' _write__%s(%s);' % (struct.tag, instance)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000167
José Fonseca54f304a2012-01-14 19:33:08 +0000168 def visitArray(self, array, instance):
José Fonseca02c25002011-10-15 13:17:26 +0100169 length = '__c' + array.type.tag
170 index = '__i' + array.type.tag
José Fonsecafd34e4e2011-06-03 19:34:29 +0100171 print ' if (%s) {' % instance
172 print ' size_t %s = %s;' % (length, array.length)
José Fonsecab4a3d142011-10-27 07:43:19 +0100173 print ' trace::localWriter.beginArray(%s);' % length
José Fonsecafd34e4e2011-06-03 19:34:29 +0100174 print ' for (size_t %s = 0; %s < %s; ++%s) {' % (index, index, length, index)
José Fonsecab4a3d142011-10-27 07:43:19 +0100175 print ' trace::localWriter.beginElement();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000176 self.visit(array.type, '(%s)[%s]' % (instance, index))
José Fonsecab4a3d142011-10-27 07:43:19 +0100177 print ' trace::localWriter.endElement();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000178 print ' }'
José Fonsecab4a3d142011-10-27 07:43:19 +0100179 print ' trace::localWriter.endArray();'
José Fonsecafd34e4e2011-06-03 19:34:29 +0100180 print ' } else {'
José Fonsecab4a3d142011-10-27 07:43:19 +0100181 print ' trace::localWriter.writeNull();'
José Fonsecafd34e4e2011-06-03 19:34:29 +0100182 print ' }'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000183
José Fonseca54f304a2012-01-14 19:33:08 +0000184 def visitBlob(self, blob, instance):
José Fonsecab4a3d142011-10-27 07:43:19 +0100185 print ' trace::localWriter.writeBlob(%s, %s);' % (instance, blob.size)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000186
José Fonseca54f304a2012-01-14 19:33:08 +0000187 def visitEnum(self, enum, instance):
José Fonsecaeb644512011-12-11 10:33:55 +0000188 print ' trace::localWriter.writeEnum(&__enum%s_sig, %s);' % (enum.tag, instance)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000189
José Fonseca54f304a2012-01-14 19:33:08 +0000190 def visitBitmask(self, bitmask, instance):
José Fonsecab4a3d142011-10-27 07:43:19 +0100191 print ' trace::localWriter.writeBitmask(&__bitmask%s_sig, %s);' % (bitmask.tag, instance)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000192
José Fonseca54f304a2012-01-14 19:33:08 +0000193 def visitPointer(self, pointer, instance):
José Fonsecadbaae492011-04-21 09:28:10 +0100194 print ' if (%s) {' % instance
José Fonsecab4a3d142011-10-27 07:43:19 +0100195 print ' trace::localWriter.beginArray(1);'
196 print ' trace::localWriter.beginElement();'
José Fonseca54f304a2012-01-14 19:33:08 +0000197 self.visit(pointer.type, "*" + instance)
José Fonsecab4a3d142011-10-27 07:43:19 +0100198 print ' trace::localWriter.endElement();'
199 print ' trace::localWriter.endArray();'
José Fonsecafd34e4e2011-06-03 19:34:29 +0100200 print ' } else {'
José Fonsecab4a3d142011-10-27 07:43:19 +0100201 print ' trace::localWriter.writeNull();'
José Fonsecafd34e4e2011-06-03 19:34:29 +0100202 print ' }'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000203
José Fonseca54f304a2012-01-14 19:33:08 +0000204 def visitHandle(self, handle, instance):
José Fonseca50d78d82010-11-23 22:13:14 +0000205 self.visit(handle.type, instance)
206
José Fonseca54f304a2012-01-14 19:33:08 +0000207 def visitAlias(self, alias, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000208 self.visit(alias.type, instance)
209
José Fonseca54f304a2012-01-14 19:33:08 +0000210 def visitOpaque(self, opaque, instance):
José Fonsecab4a3d142011-10-27 07:43:19 +0100211 print ' trace::localWriter.writeOpaque((const void *)%s);' % instance
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000212
José Fonseca54f304a2012-01-14 19:33:08 +0000213 def visitInterface(self, interface, instance):
José Fonsecab4a3d142011-10-27 07:43:19 +0100214 print ' trace::localWriter.writeOpaque((const void *)&%s);' % instance
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000215
José Fonseca54f304a2012-01-14 19:33:08 +0000216 def visitPolymorphic(self, polymorphic, instance):
217 print ' _write__%s(%s, %s);' % (polymorphic.tag, polymorphic.switchExpr, instance)
José Fonseca16d46dd2011-10-13 09:52:52 +0100218
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000219
José Fonseca54f304a2012-01-14 19:33:08 +0000220class ValueWrapper(stdapi.Visitor):
221 '''Type visitor which will generate the code to wrap an instance.
222
223 Wrapping is necessary mostly for interfaces, however interface pointers can
224 appear anywhere inside complex types.
225 '''
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000226
José Fonseca54f304a2012-01-14 19:33:08 +0000227 def visitVoid(self, type, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000228 raise NotImplementedError
229
José Fonseca54f304a2012-01-14 19:33:08 +0000230 def visitLiteral(self, type, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000231 pass
232
José Fonseca54f304a2012-01-14 19:33:08 +0000233 def visitString(self, type, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000234 pass
235
José Fonseca54f304a2012-01-14 19:33:08 +0000236 def visitConst(self, type, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000237 pass
238
José Fonseca54f304a2012-01-14 19:33:08 +0000239 def visitStruct(self, struct, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000240 for type, name in struct.members:
241 self.visit(type, "(%s).%s" % (instance, name))
242
José Fonseca54f304a2012-01-14 19:33:08 +0000243 def visitArray(self, array, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000244 # XXX: actually it is possible to return an array of pointers
245 pass
246
José Fonseca54f304a2012-01-14 19:33:08 +0000247 def visitBlob(self, blob, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000248 pass
249
José Fonseca54f304a2012-01-14 19:33:08 +0000250 def visitEnum(self, enum, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000251 pass
252
José Fonseca54f304a2012-01-14 19:33:08 +0000253 def visitBitmask(self, bitmask, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000254 pass
255
José Fonseca54f304a2012-01-14 19:33:08 +0000256 def visitPointer(self, pointer, instance):
José Fonseca3a2a4762011-05-26 11:37:30 +0100257 print " if (%s) {" % instance
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000258 self.visit(pointer.type, "*" + instance)
José Fonseca3a2a4762011-05-26 11:37:30 +0100259 print " }"
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000260
José Fonseca54f304a2012-01-14 19:33:08 +0000261 def visitHandle(self, handle, instance):
José Fonseca50d78d82010-11-23 22:13:14 +0000262 self.visit(handle.type, instance)
263
José Fonseca54f304a2012-01-14 19:33:08 +0000264 def visitAlias(self, alias, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000265 self.visit(alias.type, instance)
266
José Fonseca54f304a2012-01-14 19:33:08 +0000267 def visitOpaque(self, opaque, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000268 pass
269
José Fonseca54f304a2012-01-14 19:33:08 +0000270 def visitInterface(self, interface, instance):
José Fonseca87d1cc62010-11-29 15:57:25 +0000271 assert instance.startswith('*')
272 instance = instance[1:]
José Fonseca3a2a4762011-05-26 11:37:30 +0100273 print " if (%s) {" % instance
José Fonseca87d1cc62010-11-29 15:57:25 +0000274 print " %s = new %s(%s);" % (instance, interface_wrap_name(interface), instance)
José Fonseca3a2a4762011-05-26 11:37:30 +0100275 print " }"
José Fonseca16d46dd2011-10-13 09:52:52 +0100276
José Fonseca54f304a2012-01-14 19:33:08 +0000277 def visitPolymorphic(self, type, instance):
José Fonseca16d46dd2011-10-13 09:52:52 +0100278 # XXX: There might be polymorphic values that need wrapping in the future
279 pass
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000280
281
José Fonseca54f304a2012-01-14 19:33:08 +0000282class ValueUnwrapper(ValueWrapper):
283 '''Reverse of ValueWrapper.'''
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000284
José Fonseca54f304a2012-01-14 19:33:08 +0000285 def visitInterface(self, interface, instance):
José Fonseca87d1cc62010-11-29 15:57:25 +0000286 assert instance.startswith('*')
287 instance = instance[1:]
José Fonseca3a2a4762011-05-26 11:37:30 +0100288 print " if (%s) {" % instance
José Fonseca87d1cc62010-11-29 15:57:25 +0000289 print " %s = static_cast<%s *>(%s)->m_pInstance;" % (instance, interface_wrap_name(interface), instance)
José Fonseca3a2a4762011-05-26 11:37:30 +0100290 print " }"
José Fonseca87d1cc62010-11-29 15:57:25 +0000291
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000292
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000293class Tracer:
José Fonseca54f304a2012-01-14 19:33:08 +0000294 '''Base class to orchestrate the code generation of API tracing.'''
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000295
José Fonsecabb8760b2011-05-25 23:21:18 +0100296 def __init__(self):
297 self.api = None
298
José Fonseca54f304a2012-01-14 19:33:08 +0000299 def serializerFactory(self):
300 '''Create a serializer.
301
302 Can be overriden by derived classes to inject their own serialzer.
303 '''
304
305 return ValueSerializer()
306
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000307 def trace_api(self, api):
José Fonsecabb8760b2011-05-25 23:21:18 +0100308 self.api = api
309
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000310 self.header(api)
311
312 # Includes
313 for header in api.headers:
José Fonsecae6a50bd2010-11-24 10:12:22 +0000314 print header
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000315 print
316
José Fonseca54f304a2012-01-14 19:33:08 +0000317 # Generate the serializer functions
José Fonsecae6a50bd2010-11-24 10:12:22 +0000318 types = api.all_types()
José Fonseca54f304a2012-01-14 19:33:08 +0000319 visitor = ComplexValueSerializer(self.serializerFactory())
José Fonsecae6a50bd2010-11-24 10:12:22 +0000320 map(visitor.visit, types)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000321 print
322
323 # Interfaces wrapers
José Fonseca87d1cc62010-11-29 15:57:25 +0000324 interfaces = [type for type in types if isinstance(type, stdapi.Interface)]
José Fonseca54f304a2012-01-14 19:33:08 +0000325 map(self.traceInterfaceImpl, interfaces)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000326 print
327
328 # Function wrappers
José Fonseca54f304a2012-01-14 19:33:08 +0000329 map(self.traceFunctionDecl, api.functions)
330 map(self.traceFunctionImpl, api.functions)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000331 print
332
333 self.footer(api)
334
335 def header(self, api):
José Fonseca0ad465c2011-08-24 16:58:13 +0100336 pass
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000337
338 def footer(self, api):
339 pass
340
José Fonseca54f304a2012-01-14 19:33:08 +0000341 def traceFunctionDecl(self, function):
José Fonseca14c21bc2011-02-20 23:32:22 +0000342 # Per-function declarations
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000343
José Fonseca14c21bc2011-02-20 23:32:22 +0000344 if function.args:
345 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 +0000346 else:
José Fonseca14c21bc2011-02-20 23:32:22 +0000347 print 'static const char ** __%s_args = NULL;' % (function.name,)
José Fonsecab4a3d142011-10-27 07:43:19 +0100348 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 +0000349 print
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000350
José Fonseca54f304a2012-01-14 19:33:08 +0000351 def isFunctionPublic(self, function):
José Fonseca23691292011-04-22 10:40:25 +0100352 return True
353
José Fonseca54f304a2012-01-14 19:33:08 +0000354 def traceFunctionImpl(self, function):
355 if self.isFunctionPublic(function):
José Fonseca23691292011-04-22 10:40:25 +0100356 print 'extern "C" PUBLIC'
357 else:
358 print 'extern "C" PRIVATE'
359 print function.prototype() + ' {'
José Fonseca14c21bc2011-02-20 23:32:22 +0000360 if function.type is not stdapi.Void:
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000361 print ' %s __result;' % function.type
José Fonseca54f304a2012-01-14 19:33:08 +0000362 self.traceFunctionImplBody(function)
José Fonseca14c21bc2011-02-20 23:32:22 +0000363 if function.type is not stdapi.Void:
José Fonseca54f304a2012-01-14 19:33:08 +0000364 self.wrapRet(function, "__result")
José Fonseca14c21bc2011-02-20 23:32:22 +0000365 print ' return __result;'
366 print '}'
367 print
368
José Fonseca54f304a2012-01-14 19:33:08 +0000369 def traceFunctionImplBody(self, function):
José Fonsecab4a3d142011-10-27 07:43:19 +0100370 print ' unsigned __call = trace::localWriter.beginEnter(&__%s_sig);' % (function.name,)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000371 for arg in function.args:
372 if not arg.output:
José Fonseca54f304a2012-01-14 19:33:08 +0000373 self.unwrapArg(function, arg)
374 self.serializeArg(function, arg)
José Fonsecab4a3d142011-10-27 07:43:19 +0100375 print ' trace::localWriter.endEnter();'
José Fonseca54f304a2012-01-14 19:33:08 +0000376 self.invokeFunction(function)
José Fonsecab4a3d142011-10-27 07:43:19 +0100377 print ' trace::localWriter.beginLeave(__call);'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000378 for arg in function.args:
379 if arg.output:
José Fonseca54f304a2012-01-14 19:33:08 +0000380 self.serializeArg(function, arg)
381 self.wrapArg(function, arg)
José Fonseca9796b842010-11-25 11:44:50 +0000382 if function.type is not stdapi.Void:
José Fonseca54f304a2012-01-14 19:33:08 +0000383 self.serializeRet(function, "__result")
José Fonsecab4a3d142011-10-27 07:43:19 +0100384 print ' trace::localWriter.endLeave();'
José Fonseca14c21bc2011-02-20 23:32:22 +0000385
José Fonseca54f304a2012-01-14 19:33:08 +0000386 def invokeFunction(self, function, prefix='__', suffix=''):
José Fonseca14c21bc2011-02-20 23:32:22 +0000387 if function.type is stdapi.Void:
388 result = ''
389 else:
390 result = '__result = '
José Fonsecaa08d2752011-08-25 13:26:43 +0100391 dispatch = prefix + function.name + suffix
José Fonseca14c21bc2011-02-20 23:32:22 +0000392 print ' %s%s(%s);' % (result, dispatch, ', '.join([str(arg.name) for arg in function.args]))
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000393
José Fonseca54f304a2012-01-14 19:33:08 +0000394 def serializeArg(self, function, arg):
José Fonsecab4a3d142011-10-27 07:43:19 +0100395 print ' trace::localWriter.beginArg(%u);' % (arg.index,)
José Fonseca54f304a2012-01-14 19:33:08 +0000396 self.serializeArgValue(function, arg)
José Fonsecab4a3d142011-10-27 07:43:19 +0100397 print ' trace::localWriter.endArg();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000398
José Fonseca54f304a2012-01-14 19:33:08 +0000399 def serializeArgValue(self, function, arg):
400 self.serializeValue(arg.type, arg.name)
José Fonseca99221832011-03-22 22:15:46 +0000401
José Fonseca54f304a2012-01-14 19:33:08 +0000402 def wrapArg(self, function, arg):
403 self.wrapValue(arg.type, arg.name)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000404
José Fonseca54f304a2012-01-14 19:33:08 +0000405 def unwrapArg(self, function, arg):
406 self.unwrapValue(arg.type, arg.name)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000407
José Fonseca54f304a2012-01-14 19:33:08 +0000408 def serializeRet(self, function, instance):
José Fonsecab4a3d142011-10-27 07:43:19 +0100409 print ' trace::localWriter.beginReturn();'
José Fonseca54f304a2012-01-14 19:33:08 +0000410 self.serializeValue(function.type, instance)
José Fonsecab4a3d142011-10-27 07:43:19 +0100411 print ' trace::localWriter.endReturn();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000412
José Fonseca54f304a2012-01-14 19:33:08 +0000413 def serializeValue(self, type, instance):
414 serializer = self.serializerFactory()
415 serializer.visit(type, instance)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000416
José Fonseca54f304a2012-01-14 19:33:08 +0000417 def wrapRet(self, function, instance):
418 self.wrapValue(function.type, instance)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000419
José Fonseca54f304a2012-01-14 19:33:08 +0000420 def unwrapRet(self, function, instance):
421 self.unwrapValue(function.type, instance)
422
423 def wrapValue(self, type, instance):
424 visitor = ValueWrapper()
425 visitor.visit(type, instance)
426
427 def unwrapValue(self, type, instance):
428 visitor = ValueUnwrapper()
429 visitor.visit(type, instance)
430
431 def traceInterfaceImpl(self, interface):
José Fonseca87d1cc62010-11-29 15:57:25 +0000432 print '%s::%s(%s * pInstance) {' % (interface_wrap_name(interface), interface_wrap_name(interface), interface.name)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000433 print ' m_pInstance = pInstance;'
434 print '}'
435 print
José Fonseca87d1cc62010-11-29 15:57:25 +0000436 print '%s::~%s() {' % (interface_wrap_name(interface), interface_wrap_name(interface))
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000437 print '}'
438 print
José Fonseca54f304a2012-01-14 19:33:08 +0000439 for method in interface.iterMethods():
440 self.traceMethod(interface, method)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000441 print
442
José Fonseca54f304a2012-01-14 19:33:08 +0000443 def traceMethod(self, interface, method):
José Fonseca87d1cc62010-11-29 15:57:25 +0000444 print method.prototype(interface_wrap_name(interface) + '::' + method.name) + ' {'
445 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 +0100446 print ' static const trace::FunctionSig __sig = {%u, "%s", %u, __args};' % (method.id, interface.name + '::' + method.name, len(method.args) + 1)
447 print ' unsigned __call = trace::localWriter.beginEnter(&__sig);'
448 print ' trace::localWriter.beginArg(0);'
449 print ' trace::localWriter.writeOpaque((const void *)m_pInstance);'
450 print ' trace::localWriter.endArg();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000451 for arg in method.args:
452 if not arg.output:
José Fonseca54f304a2012-01-14 19:33:08 +0000453 self.unwrapArg(method, arg)
454 self.serializeArg(method, arg)
José Fonseca87d1cc62010-11-29 15:57:25 +0000455 if method.type is stdapi.Void:
456 result = ''
457 else:
458 print ' %s __result;' % method.type
459 result = '__result = '
José Fonsecab4a3d142011-10-27 07:43:19 +0100460 print ' trace::localWriter.endEnter();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000461 print ' %sm_pInstance->%s(%s);' % (result, method.name, ', '.join([str(arg.name) for arg in method.args]))
José Fonsecab4a3d142011-10-27 07:43:19 +0100462 print ' trace::localWriter.beginLeave(__call);'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000463 for arg in method.args:
464 if arg.output:
José Fonseca54f304a2012-01-14 19:33:08 +0000465 self.serializeArg(method, arg)
466 self.wrapArg(method, arg)
José Fonseca87d1cc62010-11-29 15:57:25 +0000467 if method.type is not stdapi.Void:
José Fonsecab4a3d142011-10-27 07:43:19 +0100468 print ' trace::localWriter.beginReturn();'
José Fonseca54f304a2012-01-14 19:33:08 +0000469 self.serializeValue(method.type, "__result")
José Fonsecab4a3d142011-10-27 07:43:19 +0100470 print ' trace::localWriter.endReturn();'
José Fonseca54f304a2012-01-14 19:33:08 +0000471 self.wrapValue(method.type, '__result')
José Fonsecab4a3d142011-10-27 07:43:19 +0100472 print ' trace::localWriter.endLeave();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000473 if method.name == 'QueryInterface':
José Fonsecabb8760b2011-05-25 23:21:18 +0100474 print ' if (ppvObj && *ppvObj) {'
475 print ' if (*ppvObj == m_pInstance) {'
476 print ' *ppvObj = this;'
477 print ' }'
478 for iface in self.api.interfaces:
José Fonseca38c932b2011-11-11 20:12:15 +0000479 print r' else if (riid == IID_%s) {' % iface.name
480 print r' *ppvObj = new Wrap%s((%s *) *ppvObj);' % (iface.name, iface.name)
481 print r' }'
482 print r' else {'
483 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",'
484 print r' riid.Data1, riid.Data2, riid.Data3,'
485 print r' riid.Data4[0],'
486 print r' riid.Data4[1],'
487 print r' riid.Data4[2],'
488 print r' riid.Data4[3],'
489 print r' riid.Data4[4],'
490 print r' riid.Data4[5],'
491 print r' riid.Data4[6],'
492 print r' riid.Data4[7]);'
493 print r' }'
José Fonsecabb8760b2011-05-25 23:21:18 +0100494 print ' }'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000495 if method.name == 'Release':
José Fonseca87d1cc62010-11-29 15:57:25 +0000496 assert method.type is not stdapi.Void
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000497 print ' if (!__result)'
498 print ' delete this;'
José Fonseca87d1cc62010-11-29 15:57:25 +0000499 if method.type is not stdapi.Void:
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000500 print ' return __result;'
501 print '}'
502 print
503