blob: bd977724484de670baffa9f5b2305531f4edc0f4 [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é Fonseca280a1762012-01-31 15:10:13 +0000151 if string.kind == 'String':
152 cast = 'const char *'
153 elif string.kind == 'WString':
154 cast = 'const wchar_t *'
José Fonsecae6a50bd2010-11-24 10:12:22 +0000155 else:
José Fonseca280a1762012-01-31 15:10:13 +0000156 assert False
157 if cast != string.expr:
158 # reinterpret_cast is necessary for GLubyte * <=> char *
159 instance = 'reinterpret_cast<%s>(%s)' % (cast, instance)
160 if string.length is not None:
161 length = ', %s' % string.length
162 else:
163 length = ''
164 print ' trace::localWriter.write%s(%s%s);' % (string.kind, instance, length)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000165
José Fonseca54f304a2012-01-14 19:33:08 +0000166 def visitConst(self, const, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000167 self.visit(const.type, instance)
168
José Fonseca54f304a2012-01-14 19:33:08 +0000169 def visitStruct(self, struct, instance):
José Fonseca06e85192011-10-16 14:15:36 +0100170 print ' _write__%s(%s);' % (struct.tag, instance)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000171
José Fonseca54f304a2012-01-14 19:33:08 +0000172 def visitArray(self, array, instance):
José Fonseca02c25002011-10-15 13:17:26 +0100173 length = '__c' + array.type.tag
174 index = '__i' + array.type.tag
José Fonsecafd34e4e2011-06-03 19:34:29 +0100175 print ' if (%s) {' % instance
176 print ' size_t %s = %s;' % (length, array.length)
José Fonsecab4a3d142011-10-27 07:43:19 +0100177 print ' trace::localWriter.beginArray(%s);' % length
José Fonsecafd34e4e2011-06-03 19:34:29 +0100178 print ' for (size_t %s = 0; %s < %s; ++%s) {' % (index, index, length, index)
José Fonsecab4a3d142011-10-27 07:43:19 +0100179 print ' trace::localWriter.beginElement();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000180 self.visit(array.type, '(%s)[%s]' % (instance, index))
José Fonsecab4a3d142011-10-27 07:43:19 +0100181 print ' trace::localWriter.endElement();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000182 print ' }'
José Fonsecab4a3d142011-10-27 07:43:19 +0100183 print ' trace::localWriter.endArray();'
José Fonsecafd34e4e2011-06-03 19:34:29 +0100184 print ' } else {'
José Fonsecab4a3d142011-10-27 07:43:19 +0100185 print ' trace::localWriter.writeNull();'
José Fonsecafd34e4e2011-06-03 19:34:29 +0100186 print ' }'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000187
José Fonseca54f304a2012-01-14 19:33:08 +0000188 def visitBlob(self, blob, instance):
José Fonsecab4a3d142011-10-27 07:43:19 +0100189 print ' trace::localWriter.writeBlob(%s, %s);' % (instance, blob.size)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000190
José Fonseca54f304a2012-01-14 19:33:08 +0000191 def visitEnum(self, enum, instance):
José Fonsecaeb644512011-12-11 10:33:55 +0000192 print ' trace::localWriter.writeEnum(&__enum%s_sig, %s);' % (enum.tag, instance)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000193
José Fonseca54f304a2012-01-14 19:33:08 +0000194 def visitBitmask(self, bitmask, instance):
José Fonsecab4a3d142011-10-27 07:43:19 +0100195 print ' trace::localWriter.writeBitmask(&__bitmask%s_sig, %s);' % (bitmask.tag, instance)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000196
José Fonseca54f304a2012-01-14 19:33:08 +0000197 def visitPointer(self, pointer, instance):
José Fonsecadbaae492011-04-21 09:28:10 +0100198 print ' if (%s) {' % instance
José Fonsecab4a3d142011-10-27 07:43:19 +0100199 print ' trace::localWriter.beginArray(1);'
200 print ' trace::localWriter.beginElement();'
José Fonseca54f304a2012-01-14 19:33:08 +0000201 self.visit(pointer.type, "*" + instance)
José Fonsecab4a3d142011-10-27 07:43:19 +0100202 print ' trace::localWriter.endElement();'
203 print ' trace::localWriter.endArray();'
José Fonsecafd34e4e2011-06-03 19:34:29 +0100204 print ' } else {'
José Fonsecab4a3d142011-10-27 07:43:19 +0100205 print ' trace::localWriter.writeNull();'
José Fonsecafd34e4e2011-06-03 19:34:29 +0100206 print ' }'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000207
José Fonseca59ee88e2012-01-15 14:24:10 +0000208 def visitIntPointer(self, pointer, instance):
209 print ' trace::localWriter.writeOpaque((const void *)%s);' % instance
210
211 def visitLinearPointer(self, pointer, instance):
212 print ' trace::localWriter.writeOpaque((const void *)%s);' % instance
213
José Fonseca54f304a2012-01-14 19:33:08 +0000214 def visitHandle(self, handle, instance):
José Fonseca50d78d82010-11-23 22:13:14 +0000215 self.visit(handle.type, instance)
216
José Fonseca54f304a2012-01-14 19:33:08 +0000217 def visitAlias(self, alias, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000218 self.visit(alias.type, instance)
219
José Fonseca54f304a2012-01-14 19:33:08 +0000220 def visitOpaque(self, opaque, instance):
José Fonsecab4a3d142011-10-27 07:43:19 +0100221 print ' trace::localWriter.writeOpaque((const void *)%s);' % instance
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000222
José Fonseca54f304a2012-01-14 19:33:08 +0000223 def visitInterface(self, interface, instance):
José Fonsecab4a3d142011-10-27 07:43:19 +0100224 print ' trace::localWriter.writeOpaque((const void *)&%s);' % instance
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000225
José Fonseca54f304a2012-01-14 19:33:08 +0000226 def visitPolymorphic(self, polymorphic, instance):
227 print ' _write__%s(%s, %s);' % (polymorphic.tag, polymorphic.switchExpr, instance)
José Fonseca16d46dd2011-10-13 09:52:52 +0100228
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000229
José Fonseca54f304a2012-01-14 19:33:08 +0000230class ValueWrapper(stdapi.Visitor):
231 '''Type visitor which will generate the code to wrap an instance.
232
233 Wrapping is necessary mostly for interfaces, however interface pointers can
234 appear anywhere inside complex types.
235 '''
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000236
José Fonseca54f304a2012-01-14 19:33:08 +0000237 def visitVoid(self, type, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000238 raise NotImplementedError
239
José Fonseca54f304a2012-01-14 19:33:08 +0000240 def visitLiteral(self, type, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000241 pass
242
José Fonseca54f304a2012-01-14 19:33:08 +0000243 def visitString(self, type, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000244 pass
245
José Fonseca54f304a2012-01-14 19:33:08 +0000246 def visitConst(self, type, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000247 pass
248
José Fonseca54f304a2012-01-14 19:33:08 +0000249 def visitStruct(self, struct, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000250 for type, name in struct.members:
251 self.visit(type, "(%s).%s" % (instance, name))
252
José Fonseca54f304a2012-01-14 19:33:08 +0000253 def visitArray(self, array, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000254 # XXX: actually it is possible to return an array of pointers
255 pass
256
José Fonseca54f304a2012-01-14 19:33:08 +0000257 def visitBlob(self, blob, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000258 pass
259
José Fonseca54f304a2012-01-14 19:33:08 +0000260 def visitEnum(self, enum, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000261 pass
262
José Fonseca54f304a2012-01-14 19:33:08 +0000263 def visitBitmask(self, bitmask, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000264 pass
265
José Fonseca54f304a2012-01-14 19:33:08 +0000266 def visitPointer(self, pointer, instance):
José Fonseca3a2a4762011-05-26 11:37:30 +0100267 print " if (%s) {" % instance
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000268 self.visit(pointer.type, "*" + instance)
José Fonseca3a2a4762011-05-26 11:37:30 +0100269 print " }"
José Fonseca59ee88e2012-01-15 14:24:10 +0000270
271 def visitIntPointer(self, pointer, instance):
272 pass
273
274 def visitLinearPointer(self, pointer, instance):
275 pass
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000276
José Fonseca54f304a2012-01-14 19:33:08 +0000277 def visitHandle(self, handle, instance):
José Fonseca50d78d82010-11-23 22:13:14 +0000278 self.visit(handle.type, instance)
279
José Fonseca54f304a2012-01-14 19:33:08 +0000280 def visitAlias(self, alias, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000281 self.visit(alias.type, instance)
282
José Fonseca54f304a2012-01-14 19:33:08 +0000283 def visitOpaque(self, opaque, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000284 pass
285
José Fonseca54f304a2012-01-14 19:33:08 +0000286 def visitInterface(self, interface, instance):
José Fonseca87d1cc62010-11-29 15:57:25 +0000287 assert instance.startswith('*')
288 instance = instance[1:]
José Fonseca3a2a4762011-05-26 11:37:30 +0100289 print " if (%s) {" % instance
José Fonseca0423d2c2012-01-20 19:16:17 +0000290 print " %s = new %s(%s);" % (instance, getWrapperInterfaceName(interface), instance)
José Fonseca3a2a4762011-05-26 11:37:30 +0100291 print " }"
José Fonseca16d46dd2011-10-13 09:52:52 +0100292
José Fonseca54f304a2012-01-14 19:33:08 +0000293 def visitPolymorphic(self, type, instance):
José Fonseca16d46dd2011-10-13 09:52:52 +0100294 # XXX: There might be polymorphic values that need wrapping in the future
295 pass
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000296
297
José Fonseca54f304a2012-01-14 19:33:08 +0000298class ValueUnwrapper(ValueWrapper):
299 '''Reverse of ValueWrapper.'''
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000300
José Fonseca54f304a2012-01-14 19:33:08 +0000301 def visitInterface(self, interface, instance):
José Fonseca87d1cc62010-11-29 15:57:25 +0000302 assert instance.startswith('*')
303 instance = instance[1:]
José Fonseca7aa86902012-01-31 20:14:31 +0000304 print r' if (%s) {' % instance
305 print r' %s *pWrapper = static_cast<%s*>(%s);' % (getWrapperInterfaceName(interface), getWrapperInterfaceName(interface), instance)
306 print r' if (pWrapper && pWrapper->m_dwMagic == 0xd8365d6c) {'
307 print r' %s = pWrapper->m_pInstance;' % (instance,)
308 print r' } else {'
309 print r' os::log("apitrace: warning: %%s: unexpected %%s pointer\n", __FUNCTION__, "%s");' % interface.name
310 print r' }'
311 print r' }'
José Fonseca87d1cc62010-11-29 15:57:25 +0000312
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000313
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000314class Tracer:
José Fonseca54f304a2012-01-14 19:33:08 +0000315 '''Base class to orchestrate the code generation of API tracing.'''
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000316
José Fonsecabb8760b2011-05-25 23:21:18 +0100317 def __init__(self):
318 self.api = None
319
José Fonseca54f304a2012-01-14 19:33:08 +0000320 def serializerFactory(self):
321 '''Create a serializer.
322
323 Can be overriden by derived classes to inject their own serialzer.
324 '''
325
326 return ValueSerializer()
327
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000328 def trace_api(self, api):
José Fonsecabb8760b2011-05-25 23:21:18 +0100329 self.api = api
330
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000331 self.header(api)
332
333 # Includes
334 for header in api.headers:
José Fonsecae6a50bd2010-11-24 10:12:22 +0000335 print header
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000336 print
337
José Fonseca54f304a2012-01-14 19:33:08 +0000338 # Generate the serializer functions
José Fonseca44703822012-01-31 10:48:58 +0000339 types = api.getAllTypes()
José Fonseca54f304a2012-01-14 19:33:08 +0000340 visitor = ComplexValueSerializer(self.serializerFactory())
José Fonsecae6a50bd2010-11-24 10:12:22 +0000341 map(visitor.visit, types)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000342 print
343
344 # Interfaces wrapers
José Fonseca2ef6d5b2012-01-31 10:56:38 +0000345 interfaces = api.getAllInterfaces()
José Fonseca0423d2c2012-01-20 19:16:17 +0000346 map(self.declareWrapperInterface, interfaces)
347 map(self.implementWrapperInterface, interfaces)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000348 print
349
350 # Function wrappers
José Fonseca54f304a2012-01-14 19:33:08 +0000351 map(self.traceFunctionDecl, api.functions)
352 map(self.traceFunctionImpl, api.functions)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000353 print
354
355 self.footer(api)
356
357 def header(self, api):
José Fonseca0ad465c2011-08-24 16:58:13 +0100358 pass
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000359
360 def footer(self, api):
361 pass
362
José Fonseca54f304a2012-01-14 19:33:08 +0000363 def traceFunctionDecl(self, function):
José Fonseca14c21bc2011-02-20 23:32:22 +0000364 # Per-function declarations
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000365
José Fonseca14c21bc2011-02-20 23:32:22 +0000366 if function.args:
367 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 +0000368 else:
José Fonseca14c21bc2011-02-20 23:32:22 +0000369 print 'static const char ** __%s_args = NULL;' % (function.name,)
José Fonsecab4a3d142011-10-27 07:43:19 +0100370 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 +0000371 print
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000372
José Fonseca54f304a2012-01-14 19:33:08 +0000373 def isFunctionPublic(self, function):
José Fonseca23691292011-04-22 10:40:25 +0100374 return True
375
José Fonseca54f304a2012-01-14 19:33:08 +0000376 def traceFunctionImpl(self, function):
377 if self.isFunctionPublic(function):
José Fonseca23691292011-04-22 10:40:25 +0100378 print 'extern "C" PUBLIC'
379 else:
380 print 'extern "C" PRIVATE'
381 print function.prototype() + ' {'
José Fonseca14c21bc2011-02-20 23:32:22 +0000382 if function.type is not stdapi.Void:
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000383 print ' %s __result;' % function.type
José Fonseca54f304a2012-01-14 19:33:08 +0000384 self.traceFunctionImplBody(function)
José Fonseca14c21bc2011-02-20 23:32:22 +0000385 if function.type is not stdapi.Void:
José Fonseca54f304a2012-01-14 19:33:08 +0000386 self.wrapRet(function, "__result")
José Fonseca14c21bc2011-02-20 23:32:22 +0000387 print ' return __result;'
388 print '}'
389 print
390
José Fonseca54f304a2012-01-14 19:33:08 +0000391 def traceFunctionImplBody(self, function):
José Fonsecab4a3d142011-10-27 07:43:19 +0100392 print ' unsigned __call = trace::localWriter.beginEnter(&__%s_sig);' % (function.name,)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000393 for arg in function.args:
394 if not arg.output:
José Fonseca54f304a2012-01-14 19:33:08 +0000395 self.unwrapArg(function, arg)
396 self.serializeArg(function, arg)
José Fonsecab4a3d142011-10-27 07:43:19 +0100397 print ' trace::localWriter.endEnter();'
José Fonseca54f304a2012-01-14 19:33:08 +0000398 self.invokeFunction(function)
José Fonsecab4a3d142011-10-27 07:43:19 +0100399 print ' trace::localWriter.beginLeave(__call);'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000400 for arg in function.args:
401 if arg.output:
José Fonseca54f304a2012-01-14 19:33:08 +0000402 self.serializeArg(function, arg)
403 self.wrapArg(function, arg)
José Fonseca9796b842010-11-25 11:44:50 +0000404 if function.type is not stdapi.Void:
José Fonseca54f304a2012-01-14 19:33:08 +0000405 self.serializeRet(function, "__result")
José Fonsecab4a3d142011-10-27 07:43:19 +0100406 print ' trace::localWriter.endLeave();'
José Fonseca14c21bc2011-02-20 23:32:22 +0000407
José Fonseca54f304a2012-01-14 19:33:08 +0000408 def invokeFunction(self, function, prefix='__', suffix=''):
José Fonseca14c21bc2011-02-20 23:32:22 +0000409 if function.type is stdapi.Void:
410 result = ''
411 else:
412 result = '__result = '
José Fonsecaa08d2752011-08-25 13:26:43 +0100413 dispatch = prefix + function.name + suffix
José Fonseca14c21bc2011-02-20 23:32:22 +0000414 print ' %s%s(%s);' % (result, dispatch, ', '.join([str(arg.name) for arg in function.args]))
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000415
José Fonseca54f304a2012-01-14 19:33:08 +0000416 def serializeArg(self, function, arg):
José Fonsecab4a3d142011-10-27 07:43:19 +0100417 print ' trace::localWriter.beginArg(%u);' % (arg.index,)
José Fonseca54f304a2012-01-14 19:33:08 +0000418 self.serializeArgValue(function, arg)
José Fonsecab4a3d142011-10-27 07:43:19 +0100419 print ' trace::localWriter.endArg();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000420
José Fonseca54f304a2012-01-14 19:33:08 +0000421 def serializeArgValue(self, function, arg):
422 self.serializeValue(arg.type, arg.name)
José Fonseca99221832011-03-22 22:15:46 +0000423
José Fonseca54f304a2012-01-14 19:33:08 +0000424 def wrapArg(self, function, arg):
425 self.wrapValue(arg.type, arg.name)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000426
José Fonseca54f304a2012-01-14 19:33:08 +0000427 def unwrapArg(self, function, arg):
428 self.unwrapValue(arg.type, arg.name)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000429
José Fonseca54f304a2012-01-14 19:33:08 +0000430 def serializeRet(self, function, instance):
José Fonsecab4a3d142011-10-27 07:43:19 +0100431 print ' trace::localWriter.beginReturn();'
José Fonseca54f304a2012-01-14 19:33:08 +0000432 self.serializeValue(function.type, instance)
José Fonsecab4a3d142011-10-27 07:43:19 +0100433 print ' trace::localWriter.endReturn();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000434
José Fonseca54f304a2012-01-14 19:33:08 +0000435 def serializeValue(self, type, instance):
436 serializer = self.serializerFactory()
437 serializer.visit(type, instance)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000438
José Fonseca54f304a2012-01-14 19:33:08 +0000439 def wrapRet(self, function, instance):
440 self.wrapValue(function.type, instance)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000441
José Fonseca54f304a2012-01-14 19:33:08 +0000442 def unwrapRet(self, function, instance):
443 self.unwrapValue(function.type, instance)
444
445 def wrapValue(self, type, instance):
446 visitor = ValueWrapper()
447 visitor.visit(type, instance)
448
449 def unwrapValue(self, type, instance):
450 visitor = ValueUnwrapper()
451 visitor.visit(type, instance)
452
José Fonseca0423d2c2012-01-20 19:16:17 +0000453 def declareWrapperInterface(self, interface):
454 print "class %s : public %s " % (getWrapperInterfaceName(interface), interface.name)
455 print "{"
456 print "public:"
457 print " %s(%s * pInstance);" % (getWrapperInterfaceName(interface), interface.name)
458 print " virtual ~%s();" % getWrapperInterfaceName(interface)
459 print
460 for method in interface.iterMethods():
461 print " " + method.prototype() + ";"
462 print
463 self.declareWrapperInterfaceVariables(interface)
464 print "};"
465 print
466
467 def declareWrapperInterfaceVariables(self, interface):
468 #print "private:"
José Fonseca7aa86902012-01-31 20:14:31 +0000469 print " DWORD m_dwMagic;"
José Fonseca0423d2c2012-01-20 19:16:17 +0000470 print " %s * m_pInstance;" % (interface.name,)
471
472 def implementWrapperInterface(self, interface):
473 print '%s::%s(%s * pInstance) {' % (getWrapperInterfaceName(interface), getWrapperInterfaceName(interface), interface.name)
José Fonseca7aa86902012-01-31 20:14:31 +0000474 print ' m_dwMagic = 0xd8365d6c;'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000475 print ' m_pInstance = pInstance;'
476 print '}'
477 print
José Fonseca0423d2c2012-01-20 19:16:17 +0000478 print '%s::~%s() {' % (getWrapperInterfaceName(interface), getWrapperInterfaceName(interface))
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000479 print '}'
480 print
José Fonseca4220b1b2012-02-03 19:05:29 +0000481 for base, method in interface.iterBaseMethods():
482 self.implementWrapperInterfaceMethod(interface, base, method)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000483 print
484
José Fonseca4220b1b2012-02-03 19:05:29 +0000485 def implementWrapperInterfaceMethod(self, interface, base, method):
José Fonseca0423d2c2012-01-20 19:16:17 +0000486 print method.prototype(getWrapperInterfaceName(interface) + '::' + method.name) + ' {'
487 if method.type is not stdapi.Void:
488 print ' %s __result;' % method.type
489
José Fonseca4220b1b2012-02-03 19:05:29 +0000490 self.implementWrapperInterfaceMethodBody(interface, base, method)
José Fonseca0423d2c2012-01-20 19:16:17 +0000491
492 if method.type is not stdapi.Void:
493 print ' return __result;'
494 print '}'
495 print
496
José Fonseca4220b1b2012-02-03 19:05:29 +0000497 def implementWrapperInterfaceMethodBody(self, interface, base, method):
José Fonseca87d1cc62010-11-29 15:57:25 +0000498 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 +0100499 print ' static const trace::FunctionSig __sig = {%u, "%s", %u, __args};' % (method.id, interface.name + '::' + method.name, len(method.args) + 1)
500 print ' unsigned __call = trace::localWriter.beginEnter(&__sig);'
501 print ' trace::localWriter.beginArg(0);'
502 print ' trace::localWriter.writeOpaque((const void *)m_pInstance);'
503 print ' trace::localWriter.endArg();'
José Fonseca1ce52f02012-01-31 12:19:57 +0000504
505 from specs.winapi import REFIID
José Fonseca3d2b0652012-01-31 19:35:24 +0000506 from specs.stdapi import Pointer, Opaque, Interface
José Fonseca1ce52f02012-01-31 12:19:57 +0000507
508 riid = None
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000509 for arg in method.args:
510 if not arg.output:
José Fonseca54f304a2012-01-14 19:33:08 +0000511 self.unwrapArg(method, arg)
512 self.serializeArg(method, arg)
José Fonseca1ce52f02012-01-31 12:19:57 +0000513 if arg.type is REFIID:
514 riid = arg
José Fonsecab4a3d142011-10-27 07:43:19 +0100515 print ' trace::localWriter.endEnter();'
José Fonseca0423d2c2012-01-20 19:16:17 +0000516
José Fonseca4220b1b2012-02-03 19:05:29 +0000517 self.invokeMethod(interface, base, method)
José Fonseca0423d2c2012-01-20 19:16:17 +0000518
José Fonsecab4a3d142011-10-27 07:43:19 +0100519 print ' trace::localWriter.beginLeave(__call);'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000520 for arg in method.args:
521 if arg.output:
José Fonseca54f304a2012-01-14 19:33:08 +0000522 self.serializeArg(method, arg)
523 self.wrapArg(method, arg)
José Fonseca1ce52f02012-01-31 12:19:57 +0000524 if riid is not None and isinstance(arg.type, Pointer):
José Fonseca3d2b0652012-01-31 19:35:24 +0000525 if isinstance(arg.type.type, Opaque):
526 self.wrapIid(riid, arg)
527 else:
528 assert isinstance(arg.type.type, Pointer)
529 assert isinstance(arg.type.type.type, Interface)
José Fonseca1ce52f02012-01-31 12:19:57 +0000530
José Fonseca87d1cc62010-11-29 15:57:25 +0000531 if method.type is not stdapi.Void:
José Fonsecab4a3d142011-10-27 07:43:19 +0100532 print ' trace::localWriter.beginReturn();'
José Fonseca54f304a2012-01-14 19:33:08 +0000533 self.serializeValue(method.type, "__result")
José Fonsecab4a3d142011-10-27 07:43:19 +0100534 print ' trace::localWriter.endReturn();'
José Fonseca54f304a2012-01-14 19:33:08 +0000535 self.wrapValue(method.type, '__result')
José Fonsecab4a3d142011-10-27 07:43:19 +0100536 print ' trace::localWriter.endLeave();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000537 if method.name == 'Release':
José Fonseca87d1cc62010-11-29 15:57:25 +0000538 assert method.type is not stdapi.Void
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000539 print ' if (!__result)'
540 print ' delete this;'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000541
José Fonseca7aa86902012-01-31 20:14:31 +0000542 def wrapIid(self, riid, out):
José Fonseca1ce52f02012-01-31 12:19:57 +0000543 print ' if (%s && *%s) {' % (out.name, out.name)
544 print ' if (*%s == m_pInstance) {' % (out.name,)
José Fonsecaccf250c2012-02-03 19:06:31 +0000545 print ' AddRef();'
546 print ' m_pInstance->Release();'
José Fonseca1ce52f02012-01-31 12:19:57 +0000547 print ' *%s = this;' % (out.name,)
548 print ' }'
José Fonsecaccf250c2012-02-03 19:06:31 +0000549 for iface in self.api.getAllInterfaces():
José Fonseca1ce52f02012-01-31 12:19:57 +0000550 print r' else if (%s == IID_%s) {' % (riid.name, iface.name)
551 print r' *%s = new Wrap%s((%s *) *%s);' % (out.name, iface.name, iface.name, out.name)
552 print r' }'
553 print r' else {'
José Fonseca7aa86902012-01-31 20:14:31 +0000554 print r' os::log("apitrace: warning: %s: 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",'
555 print r' __FUNCTION__,'
José Fonseca1ce52f02012-01-31 12:19:57 +0000556 print r' %s.Data1, %s.Data2, %s.Data3,' % (riid.name, riid.name, riid.name)
557 print r' %s.Data4[0],' % (riid.name,)
558 print r' %s.Data4[1],' % (riid.name,)
559 print r' %s.Data4[2],' % (riid.name,)
560 print r' %s.Data4[3],' % (riid.name,)
561 print r' %s.Data4[4],' % (riid.name,)
562 print r' %s.Data4[5],' % (riid.name,)
563 print r' %s.Data4[6],' % (riid.name,)
564 print r' %s.Data4[7]);' % (riid.name,)
565 print r' }'
566 print ' }'
567
José Fonseca4220b1b2012-02-03 19:05:29 +0000568 def invokeMethod(self, interface, base, method):
José Fonseca0423d2c2012-01-20 19:16:17 +0000569 if method.type is stdapi.Void:
570 result = ''
571 else:
572 result = '__result = '
José Fonseca4220b1b2012-02-03 19:05:29 +0000573 print ' %sstatic_cast<%s *>(m_pInstance)->%s(%s);' % (result, base, method.name, ', '.join([str(arg.name) for arg in method.args]))
José Fonseca0423d2c2012-01-20 19:16:17 +0000574
575 def emit_memcpy(self, dest, src, length):
576 print ' unsigned __call = trace::localWriter.beginEnter(&trace::memcpy_sig);'
577 print ' trace::localWriter.beginArg(0);'
578 print ' trace::localWriter.writeOpaque(%s);' % dest
579 print ' trace::localWriter.endArg();'
580 print ' trace::localWriter.beginArg(1);'
581 print ' trace::localWriter.writeBlob(%s, %s);' % (src, length)
582 print ' trace::localWriter.endArg();'
583 print ' trace::localWriter.beginArg(2);'
584 print ' trace::localWriter.writeUInt(%s);' % length
585 print ' trace::localWriter.endArg();'
586 print ' trace::localWriter.endEnter();'
587 print ' trace::localWriter.beginLeave(__call);'
588 print ' trace::localWriter.endLeave();'
589