blob: 0d973a21082bcd1989feeb9b39ad969c1a7a09bc [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é Fonseca0423d2c2012-01-20 19:16:17 +000032def getWrapperInterfaceName(interface):
José Fonseca87d1cc62010-11-29 15:57:25 +000033 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é Fonseca0423d2c2012-01-20 19:16:17 +0000124 pass
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000125
José Fonseca54f304a2012-01-14 19:33:08 +0000126 def visitPolymorphic(self, polymorphic):
José Fonseca06e85192011-10-16 14:15:36 +0100127 print 'static void _write__%s(int selector, const %s & value) {' % (polymorphic.tag, polymorphic.expr)
José Fonsecac636b9d2011-10-14 10:15:02 +0100128 print ' switch (selector) {'
José Fonseca54f304a2012-01-14 19:33:08 +0000129 for cases, type in polymorphic.iterSwitch():
José Fonsecac636b9d2011-10-14 10:15:02 +0100130 for case in cases:
131 print ' %s:' % case
José Fonseca54f304a2012-01-14 19:33:08 +0000132 self.serializer.visit(type, 'static_cast<%s>(value)' % (type,))
José Fonsecac636b9d2011-10-14 10:15:02 +0100133 print ' break;'
134 print ' }'
135 print '}'
136 print
José Fonseca16d46dd2011-10-13 09:52:52 +0100137
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000138
José Fonseca54f304a2012-01-14 19:33:08 +0000139class ValueSerializer(stdapi.Visitor):
140 '''Visitor which generates code to serialize any type.
141
142 Simple types are serialized inline here, whereas the serialization of
143 complex types is dispatched to the serialization functions generated by
144 ComplexValueSerializer visitor above.
145 '''
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000146
José Fonseca54f304a2012-01-14 19:33:08 +0000147 def visitLiteral(self, literal, instance):
José Fonsecab4a3d142011-10-27 07:43:19 +0100148 print ' trace::localWriter.write%s(%s);' % (literal.kind, instance)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000149
José Fonseca54f304a2012-01-14 19:33:08 +0000150 def visitString(self, string, instance):
José Fonsecae6a50bd2010-11-24 10:12:22 +0000151 if string.length is not None:
José Fonsecab4a3d142011-10-27 07:43:19 +0100152 print ' trace::localWriter.writeString((const char *)%s, %s);' % (instance, string.length)
José Fonsecae6a50bd2010-11-24 10:12:22 +0000153 else:
José Fonsecab4a3d142011-10-27 07:43:19 +0100154 print ' trace::localWriter.writeString((const char *)%s);' % instance
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000155
José Fonseca54f304a2012-01-14 19:33:08 +0000156 def visitConst(self, const, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000157 self.visit(const.type, instance)
158
José Fonseca54f304a2012-01-14 19:33:08 +0000159 def visitStruct(self, struct, instance):
José Fonseca06e85192011-10-16 14:15:36 +0100160 print ' _write__%s(%s);' % (struct.tag, instance)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000161
José Fonseca54f304a2012-01-14 19:33:08 +0000162 def visitArray(self, array, instance):
José Fonseca02c25002011-10-15 13:17:26 +0100163 length = '__c' + array.type.tag
164 index = '__i' + array.type.tag
José Fonsecafd34e4e2011-06-03 19:34:29 +0100165 print ' if (%s) {' % instance
166 print ' size_t %s = %s;' % (length, array.length)
José Fonsecab4a3d142011-10-27 07:43:19 +0100167 print ' trace::localWriter.beginArray(%s);' % length
José Fonsecafd34e4e2011-06-03 19:34:29 +0100168 print ' for (size_t %s = 0; %s < %s; ++%s) {' % (index, index, length, index)
José Fonsecab4a3d142011-10-27 07:43:19 +0100169 print ' trace::localWriter.beginElement();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000170 self.visit(array.type, '(%s)[%s]' % (instance, index))
José Fonsecab4a3d142011-10-27 07:43:19 +0100171 print ' trace::localWriter.endElement();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000172 print ' }'
José Fonsecab4a3d142011-10-27 07:43:19 +0100173 print ' trace::localWriter.endArray();'
José Fonsecafd34e4e2011-06-03 19:34:29 +0100174 print ' } else {'
José Fonsecab4a3d142011-10-27 07:43:19 +0100175 print ' trace::localWriter.writeNull();'
José Fonsecafd34e4e2011-06-03 19:34:29 +0100176 print ' }'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000177
José Fonseca54f304a2012-01-14 19:33:08 +0000178 def visitBlob(self, blob, instance):
José Fonsecab4a3d142011-10-27 07:43:19 +0100179 print ' trace::localWriter.writeBlob(%s, %s);' % (instance, blob.size)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000180
José Fonseca54f304a2012-01-14 19:33:08 +0000181 def visitEnum(self, enum, instance):
José Fonsecaeb644512011-12-11 10:33:55 +0000182 print ' trace::localWriter.writeEnum(&__enum%s_sig, %s);' % (enum.tag, instance)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000183
José Fonseca54f304a2012-01-14 19:33:08 +0000184 def visitBitmask(self, bitmask, instance):
José Fonsecab4a3d142011-10-27 07:43:19 +0100185 print ' trace::localWriter.writeBitmask(&__bitmask%s_sig, %s);' % (bitmask.tag, instance)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000186
José Fonseca54f304a2012-01-14 19:33:08 +0000187 def visitPointer(self, pointer, instance):
José Fonsecadbaae492011-04-21 09:28:10 +0100188 print ' if (%s) {' % instance
José Fonsecab4a3d142011-10-27 07:43:19 +0100189 print ' trace::localWriter.beginArray(1);'
190 print ' trace::localWriter.beginElement();'
José Fonseca54f304a2012-01-14 19:33:08 +0000191 self.visit(pointer.type, "*" + instance)
José Fonsecab4a3d142011-10-27 07:43:19 +0100192 print ' trace::localWriter.endElement();'
193 print ' trace::localWriter.endArray();'
José Fonsecafd34e4e2011-06-03 19:34:29 +0100194 print ' } else {'
José Fonsecab4a3d142011-10-27 07:43:19 +0100195 print ' trace::localWriter.writeNull();'
José Fonsecafd34e4e2011-06-03 19:34:29 +0100196 print ' }'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000197
José Fonseca59ee88e2012-01-15 14:24:10 +0000198 def visitIntPointer(self, pointer, instance):
199 print ' trace::localWriter.writeOpaque((const void *)%s);' % instance
200
201 def visitLinearPointer(self, pointer, instance):
202 print ' trace::localWriter.writeOpaque((const void *)%s);' % instance
203
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é Fonseca59ee88e2012-01-15 14:24:10 +0000260
261 def visitIntPointer(self, pointer, instance):
262 pass
263
264 def visitLinearPointer(self, pointer, instance):
265 pass
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000266
José Fonseca54f304a2012-01-14 19:33:08 +0000267 def visitHandle(self, handle, instance):
José Fonseca50d78d82010-11-23 22:13:14 +0000268 self.visit(handle.type, instance)
269
José Fonseca54f304a2012-01-14 19:33:08 +0000270 def visitAlias(self, alias, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000271 self.visit(alias.type, instance)
272
José Fonseca54f304a2012-01-14 19:33:08 +0000273 def visitOpaque(self, opaque, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000274 pass
275
José Fonseca54f304a2012-01-14 19:33:08 +0000276 def visitInterface(self, interface, instance):
José Fonseca87d1cc62010-11-29 15:57:25 +0000277 assert instance.startswith('*')
278 instance = instance[1:]
José Fonseca3a2a4762011-05-26 11:37:30 +0100279 print " if (%s) {" % instance
José Fonseca0423d2c2012-01-20 19:16:17 +0000280 print " %s = new %s(%s);" % (instance, getWrapperInterfaceName(interface), instance)
José Fonseca3a2a4762011-05-26 11:37:30 +0100281 print " }"
José Fonseca16d46dd2011-10-13 09:52:52 +0100282
José Fonseca54f304a2012-01-14 19:33:08 +0000283 def visitPolymorphic(self, type, instance):
José Fonseca16d46dd2011-10-13 09:52:52 +0100284 # XXX: There might be polymorphic values that need wrapping in the future
285 pass
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000286
287
José Fonseca54f304a2012-01-14 19:33:08 +0000288class ValueUnwrapper(ValueWrapper):
289 '''Reverse of ValueWrapper.'''
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000290
José Fonseca54f304a2012-01-14 19:33:08 +0000291 def visitInterface(self, interface, instance):
José Fonseca87d1cc62010-11-29 15:57:25 +0000292 assert instance.startswith('*')
293 instance = instance[1:]
José Fonseca3a2a4762011-05-26 11:37:30 +0100294 print " if (%s) {" % instance
José Fonseca0423d2c2012-01-20 19:16:17 +0000295 print " %s = static_cast<%s *>(%s)->m_pInstance;" % (instance, getWrapperInterfaceName(interface), instance)
José Fonseca3a2a4762011-05-26 11:37:30 +0100296 print " }"
José Fonseca87d1cc62010-11-29 15:57:25 +0000297
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000298
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000299class Tracer:
José Fonseca54f304a2012-01-14 19:33:08 +0000300 '''Base class to orchestrate the code generation of API tracing.'''
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000301
José Fonsecabb8760b2011-05-25 23:21:18 +0100302 def __init__(self):
303 self.api = None
304
José Fonseca54f304a2012-01-14 19:33:08 +0000305 def serializerFactory(self):
306 '''Create a serializer.
307
308 Can be overriden by derived classes to inject their own serialzer.
309 '''
310
311 return ValueSerializer()
312
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000313 def trace_api(self, api):
José Fonsecabb8760b2011-05-25 23:21:18 +0100314 self.api = api
315
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000316 self.header(api)
317
318 # Includes
319 for header in api.headers:
José Fonsecae6a50bd2010-11-24 10:12:22 +0000320 print header
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000321 print
322
José Fonseca54f304a2012-01-14 19:33:08 +0000323 # Generate the serializer functions
José Fonseca44703822012-01-31 10:48:58 +0000324 types = api.getAllTypes()
José Fonseca54f304a2012-01-14 19:33:08 +0000325 visitor = ComplexValueSerializer(self.serializerFactory())
José Fonsecae6a50bd2010-11-24 10:12:22 +0000326 map(visitor.visit, types)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000327 print
328
329 # Interfaces wrapers
José Fonseca2ef6d5b2012-01-31 10:56:38 +0000330 interfaces = api.getAllInterfaces()
José Fonseca0423d2c2012-01-20 19:16:17 +0000331 map(self.declareWrapperInterface, interfaces)
332 map(self.implementWrapperInterface, interfaces)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000333 print
334
335 # Function wrappers
José Fonseca54f304a2012-01-14 19:33:08 +0000336 map(self.traceFunctionDecl, api.functions)
337 map(self.traceFunctionImpl, api.functions)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000338 print
339
340 self.footer(api)
341
342 def header(self, api):
José Fonseca0ad465c2011-08-24 16:58:13 +0100343 pass
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000344
345 def footer(self, api):
346 pass
347
José Fonseca54f304a2012-01-14 19:33:08 +0000348 def traceFunctionDecl(self, function):
José Fonseca14c21bc2011-02-20 23:32:22 +0000349 # Per-function declarations
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000350
José Fonseca14c21bc2011-02-20 23:32:22 +0000351 if function.args:
352 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 +0000353 else:
José Fonseca14c21bc2011-02-20 23:32:22 +0000354 print 'static const char ** __%s_args = NULL;' % (function.name,)
José Fonsecab4a3d142011-10-27 07:43:19 +0100355 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 +0000356 print
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000357
José Fonseca54f304a2012-01-14 19:33:08 +0000358 def isFunctionPublic(self, function):
José Fonseca23691292011-04-22 10:40:25 +0100359 return True
360
José Fonseca54f304a2012-01-14 19:33:08 +0000361 def traceFunctionImpl(self, function):
362 if self.isFunctionPublic(function):
José Fonseca23691292011-04-22 10:40:25 +0100363 print 'extern "C" PUBLIC'
364 else:
365 print 'extern "C" PRIVATE'
366 print function.prototype() + ' {'
José Fonseca14c21bc2011-02-20 23:32:22 +0000367 if function.type is not stdapi.Void:
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000368 print ' %s __result;' % function.type
José Fonseca54f304a2012-01-14 19:33:08 +0000369 self.traceFunctionImplBody(function)
José Fonseca14c21bc2011-02-20 23:32:22 +0000370 if function.type is not stdapi.Void:
José Fonseca54f304a2012-01-14 19:33:08 +0000371 self.wrapRet(function, "__result")
José Fonseca14c21bc2011-02-20 23:32:22 +0000372 print ' return __result;'
373 print '}'
374 print
375
José Fonseca54f304a2012-01-14 19:33:08 +0000376 def traceFunctionImplBody(self, function):
José Fonsecab4a3d142011-10-27 07:43:19 +0100377 print ' unsigned __call = trace::localWriter.beginEnter(&__%s_sig);' % (function.name,)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000378 for arg in function.args:
379 if not arg.output:
José Fonseca54f304a2012-01-14 19:33:08 +0000380 self.unwrapArg(function, arg)
381 self.serializeArg(function, arg)
José Fonsecab4a3d142011-10-27 07:43:19 +0100382 print ' trace::localWriter.endEnter();'
José Fonseca54f304a2012-01-14 19:33:08 +0000383 self.invokeFunction(function)
José Fonsecab4a3d142011-10-27 07:43:19 +0100384 print ' trace::localWriter.beginLeave(__call);'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000385 for arg in function.args:
386 if arg.output:
José Fonseca54f304a2012-01-14 19:33:08 +0000387 self.serializeArg(function, arg)
388 self.wrapArg(function, arg)
José Fonseca9796b842010-11-25 11:44:50 +0000389 if function.type is not stdapi.Void:
José Fonseca54f304a2012-01-14 19:33:08 +0000390 self.serializeRet(function, "__result")
José Fonsecab4a3d142011-10-27 07:43:19 +0100391 print ' trace::localWriter.endLeave();'
José Fonseca14c21bc2011-02-20 23:32:22 +0000392
José Fonseca54f304a2012-01-14 19:33:08 +0000393 def invokeFunction(self, function, prefix='__', suffix=''):
José Fonseca14c21bc2011-02-20 23:32:22 +0000394 if function.type is stdapi.Void:
395 result = ''
396 else:
397 result = '__result = '
José Fonsecaa08d2752011-08-25 13:26:43 +0100398 dispatch = prefix + function.name + suffix
José Fonseca14c21bc2011-02-20 23:32:22 +0000399 print ' %s%s(%s);' % (result, dispatch, ', '.join([str(arg.name) for arg in function.args]))
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000400
José Fonseca54f304a2012-01-14 19:33:08 +0000401 def serializeArg(self, function, arg):
José Fonsecab4a3d142011-10-27 07:43:19 +0100402 print ' trace::localWriter.beginArg(%u);' % (arg.index,)
José Fonseca54f304a2012-01-14 19:33:08 +0000403 self.serializeArgValue(function, arg)
José Fonsecab4a3d142011-10-27 07:43:19 +0100404 print ' trace::localWriter.endArg();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000405
José Fonseca54f304a2012-01-14 19:33:08 +0000406 def serializeArgValue(self, function, arg):
407 self.serializeValue(arg.type, arg.name)
José Fonseca99221832011-03-22 22:15:46 +0000408
José Fonseca54f304a2012-01-14 19:33:08 +0000409 def wrapArg(self, function, arg):
410 self.wrapValue(arg.type, arg.name)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000411
José Fonseca54f304a2012-01-14 19:33:08 +0000412 def unwrapArg(self, function, arg):
413 self.unwrapValue(arg.type, arg.name)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000414
José Fonseca54f304a2012-01-14 19:33:08 +0000415 def serializeRet(self, function, instance):
José Fonsecab4a3d142011-10-27 07:43:19 +0100416 print ' trace::localWriter.beginReturn();'
José Fonseca54f304a2012-01-14 19:33:08 +0000417 self.serializeValue(function.type, instance)
José Fonsecab4a3d142011-10-27 07:43:19 +0100418 print ' trace::localWriter.endReturn();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000419
José Fonseca54f304a2012-01-14 19:33:08 +0000420 def serializeValue(self, type, instance):
421 serializer = self.serializerFactory()
422 serializer.visit(type, instance)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000423
José Fonseca54f304a2012-01-14 19:33:08 +0000424 def wrapRet(self, function, instance):
425 self.wrapValue(function.type, instance)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000426
José Fonseca54f304a2012-01-14 19:33:08 +0000427 def unwrapRet(self, function, instance):
428 self.unwrapValue(function.type, instance)
429
430 def wrapValue(self, type, instance):
431 visitor = ValueWrapper()
432 visitor.visit(type, instance)
433
434 def unwrapValue(self, type, instance):
435 visitor = ValueUnwrapper()
436 visitor.visit(type, instance)
437
José Fonseca0423d2c2012-01-20 19:16:17 +0000438 def declareWrapperInterface(self, interface):
439 print "class %s : public %s " % (getWrapperInterfaceName(interface), interface.name)
440 print "{"
441 print "public:"
442 print " %s(%s * pInstance);" % (getWrapperInterfaceName(interface), interface.name)
443 print " virtual ~%s();" % getWrapperInterfaceName(interface)
444 print
445 for method in interface.iterMethods():
446 print " " + method.prototype() + ";"
447 print
448 self.declareWrapperInterfaceVariables(interface)
449 print "};"
450 print
451
452 def declareWrapperInterfaceVariables(self, interface):
453 #print "private:"
454 print " %s * m_pInstance;" % (interface.name,)
455
456 def implementWrapperInterface(self, interface):
457 print '%s::%s(%s * pInstance) {' % (getWrapperInterfaceName(interface), getWrapperInterfaceName(interface), interface.name)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000458 print ' m_pInstance = pInstance;'
459 print '}'
460 print
José Fonseca0423d2c2012-01-20 19:16:17 +0000461 print '%s::~%s() {' % (getWrapperInterfaceName(interface), getWrapperInterfaceName(interface))
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000462 print '}'
463 print
José Fonseca54f304a2012-01-14 19:33:08 +0000464 for method in interface.iterMethods():
José Fonseca0423d2c2012-01-20 19:16:17 +0000465 self.implementWrapperInterfaceMethod(interface, method)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000466 print
467
José Fonseca0423d2c2012-01-20 19:16:17 +0000468 def implementWrapperInterfaceMethod(self, interface, method):
469 print method.prototype(getWrapperInterfaceName(interface) + '::' + method.name) + ' {'
470 if method.type is not stdapi.Void:
471 print ' %s __result;' % method.type
472
473 self.implementWrapperInterfaceMethodBody(interface, method)
474
475 if method.type is not stdapi.Void:
476 print ' return __result;'
477 print '}'
478 print
479
480 def implementWrapperInterfaceMethodBody(self, interface, method):
José Fonseca87d1cc62010-11-29 15:57:25 +0000481 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 +0100482 print ' static const trace::FunctionSig __sig = {%u, "%s", %u, __args};' % (method.id, interface.name + '::' + method.name, len(method.args) + 1)
483 print ' unsigned __call = trace::localWriter.beginEnter(&__sig);'
484 print ' trace::localWriter.beginArg(0);'
485 print ' trace::localWriter.writeOpaque((const void *)m_pInstance);'
486 print ' trace::localWriter.endArg();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000487 for arg in method.args:
488 if not arg.output:
José Fonseca54f304a2012-01-14 19:33:08 +0000489 self.unwrapArg(method, arg)
490 self.serializeArg(method, arg)
José Fonsecab4a3d142011-10-27 07:43:19 +0100491 print ' trace::localWriter.endEnter();'
José Fonseca0423d2c2012-01-20 19:16:17 +0000492
493 self.invokeMethod(interface, method)
494
José Fonsecab4a3d142011-10-27 07:43:19 +0100495 print ' trace::localWriter.beginLeave(__call);'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000496 for arg in method.args:
497 if arg.output:
José Fonseca54f304a2012-01-14 19:33:08 +0000498 self.serializeArg(method, arg)
499 self.wrapArg(method, arg)
José Fonseca87d1cc62010-11-29 15:57:25 +0000500 if method.type is not stdapi.Void:
José Fonsecab4a3d142011-10-27 07:43:19 +0100501 print ' trace::localWriter.beginReturn();'
José Fonseca54f304a2012-01-14 19:33:08 +0000502 self.serializeValue(method.type, "__result")
José Fonsecab4a3d142011-10-27 07:43:19 +0100503 print ' trace::localWriter.endReturn();'
José Fonseca54f304a2012-01-14 19:33:08 +0000504 self.wrapValue(method.type, '__result')
José Fonsecab4a3d142011-10-27 07:43:19 +0100505 print ' trace::localWriter.endLeave();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000506 if method.name == 'QueryInterface':
José Fonsecabb8760b2011-05-25 23:21:18 +0100507 print ' if (ppvObj && *ppvObj) {'
508 print ' if (*ppvObj == m_pInstance) {'
509 print ' *ppvObj = this;'
510 print ' }'
511 for iface in self.api.interfaces:
José Fonseca38c932b2011-11-11 20:12:15 +0000512 print r' else if (riid == IID_%s) {' % iface.name
513 print r' *ppvObj = new Wrap%s((%s *) *ppvObj);' % (iface.name, iface.name)
514 print r' }'
515 print r' else {'
516 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",'
517 print r' riid.Data1, riid.Data2, riid.Data3,'
518 print r' riid.Data4[0],'
519 print r' riid.Data4[1],'
520 print r' riid.Data4[2],'
521 print r' riid.Data4[3],'
522 print r' riid.Data4[4],'
523 print r' riid.Data4[5],'
524 print r' riid.Data4[6],'
525 print r' riid.Data4[7]);'
526 print r' }'
José Fonsecabb8760b2011-05-25 23:21:18 +0100527 print ' }'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000528 if method.name == 'Release':
José Fonseca87d1cc62010-11-29 15:57:25 +0000529 assert method.type is not stdapi.Void
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000530 print ' if (!__result)'
531 print ' delete this;'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000532
José Fonseca0423d2c2012-01-20 19:16:17 +0000533 def invokeMethod(self, interface, method):
534 if method.type is stdapi.Void:
535 result = ''
536 else:
537 result = '__result = '
538 print ' %sm_pInstance->%s(%s);' % (result, method.name, ', '.join([str(arg.name) for arg in method.args]))
539
540 def emit_memcpy(self, dest, src, length):
541 print ' unsigned __call = trace::localWriter.beginEnter(&trace::memcpy_sig);'
542 print ' trace::localWriter.beginArg(0);'
543 print ' trace::localWriter.writeOpaque(%s);' % dest
544 print ' trace::localWriter.endArg();'
545 print ' trace::localWriter.beginArg(1);'
546 print ' trace::localWriter.writeBlob(%s, %s);' % (src, length)
547 print ' trace::localWriter.endArg();'
548 print ' trace::localWriter.beginArg(2);'
549 print ' trace::localWriter.writeUInt(%s);' % length
550 print ' trace::localWriter.endArg();'
551 print ' trace::localWriter.endEnter();'
552 print ' trace::localWriter.beginLeave(__call);'
553 print ' trace::localWriter.endLeave();'
554