blob: 7350d932421e6572b1c4caae15fca059d408d7fb [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
José Fonsecafbcf6832012-04-05 07:10:30 +0100111 def visitObjPointer(self, pointer):
112 self.visit(pointer.type)
113
José Fonseca59ee88e2012-01-15 14:24:10 +0000114 def visitLinearPointer(self, pointer):
115 self.visit(pointer.type)
116
José Fonseca54f304a2012-01-14 19:33:08 +0000117 def visitHandle(self, handle):
José Fonseca50d78d82010-11-23 22:13:14 +0000118 self.visit(handle.type)
119
José Fonsecab89c5932012-04-01 22:47:11 +0200120 def visitReference(self, reference):
121 self.visit(reference.type)
122
José Fonseca54f304a2012-01-14 19:33:08 +0000123 def visitAlias(self, alias):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000124 self.visit(alias.type)
125
José Fonseca54f304a2012-01-14 19:33:08 +0000126 def visitOpaque(self, opaque):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000127 pass
128
José Fonseca54f304a2012-01-14 19:33:08 +0000129 def visitInterface(self, interface):
José Fonseca0423d2c2012-01-20 19:16:17 +0000130 pass
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é Fonseca280a1762012-01-31 15:10:13 +0000157 if string.kind == 'String':
158 cast = 'const char *'
159 elif string.kind == 'WString':
160 cast = 'const wchar_t *'
José Fonsecae6a50bd2010-11-24 10:12:22 +0000161 else:
José Fonseca280a1762012-01-31 15:10:13 +0000162 assert False
163 if cast != string.expr:
164 # reinterpret_cast is necessary for GLubyte * <=> char *
165 instance = 'reinterpret_cast<%s>(%s)' % (cast, instance)
166 if string.length is not None:
167 length = ', %s' % string.length
168 else:
169 length = ''
170 print ' trace::localWriter.write%s(%s%s);' % (string.kind, instance, length)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000171
José Fonseca54f304a2012-01-14 19:33:08 +0000172 def visitConst(self, const, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000173 self.visit(const.type, instance)
174
José Fonseca54f304a2012-01-14 19:33:08 +0000175 def visitStruct(self, struct, instance):
José Fonseca06e85192011-10-16 14:15:36 +0100176 print ' _write__%s(%s);' % (struct.tag, instance)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000177
José Fonseca54f304a2012-01-14 19:33:08 +0000178 def visitArray(self, array, instance):
José Fonseca02c25002011-10-15 13:17:26 +0100179 length = '__c' + array.type.tag
180 index = '__i' + array.type.tag
José Fonsecafd34e4e2011-06-03 19:34:29 +0100181 print ' if (%s) {' % instance
182 print ' size_t %s = %s;' % (length, array.length)
José Fonsecab4a3d142011-10-27 07:43:19 +0100183 print ' trace::localWriter.beginArray(%s);' % length
José Fonsecafd34e4e2011-06-03 19:34:29 +0100184 print ' for (size_t %s = 0; %s < %s; ++%s) {' % (index, index, length, index)
José Fonsecab4a3d142011-10-27 07:43:19 +0100185 print ' trace::localWriter.beginElement();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000186 self.visit(array.type, '(%s)[%s]' % (instance, index))
José Fonsecab4a3d142011-10-27 07:43:19 +0100187 print ' trace::localWriter.endElement();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000188 print ' }'
José Fonsecab4a3d142011-10-27 07:43:19 +0100189 print ' trace::localWriter.endArray();'
José Fonsecafd34e4e2011-06-03 19:34:29 +0100190 print ' } else {'
José Fonsecab4a3d142011-10-27 07:43:19 +0100191 print ' trace::localWriter.writeNull();'
José Fonsecafd34e4e2011-06-03 19:34:29 +0100192 print ' }'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000193
José Fonseca54f304a2012-01-14 19:33:08 +0000194 def visitBlob(self, blob, instance):
José Fonsecab4a3d142011-10-27 07:43:19 +0100195 print ' trace::localWriter.writeBlob(%s, %s);' % (instance, blob.size)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000196
José Fonseca54f304a2012-01-14 19:33:08 +0000197 def visitEnum(self, enum, instance):
José Fonsecaeb644512011-12-11 10:33:55 +0000198 print ' trace::localWriter.writeEnum(&__enum%s_sig, %s);' % (enum.tag, instance)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000199
José Fonseca54f304a2012-01-14 19:33:08 +0000200 def visitBitmask(self, bitmask, instance):
José Fonsecab4a3d142011-10-27 07:43:19 +0100201 print ' trace::localWriter.writeBitmask(&__bitmask%s_sig, %s);' % (bitmask.tag, instance)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000202
José Fonseca54f304a2012-01-14 19:33:08 +0000203 def visitPointer(self, pointer, instance):
José Fonsecadbaae492011-04-21 09:28:10 +0100204 print ' if (%s) {' % instance
José Fonsecab4a3d142011-10-27 07:43:19 +0100205 print ' trace::localWriter.beginArray(1);'
206 print ' trace::localWriter.beginElement();'
José Fonseca54f304a2012-01-14 19:33:08 +0000207 self.visit(pointer.type, "*" + instance)
José Fonsecab4a3d142011-10-27 07:43:19 +0100208 print ' trace::localWriter.endElement();'
209 print ' trace::localWriter.endArray();'
José Fonsecafd34e4e2011-06-03 19:34:29 +0100210 print ' } else {'
José Fonsecab4a3d142011-10-27 07:43:19 +0100211 print ' trace::localWriter.writeNull();'
José Fonsecafd34e4e2011-06-03 19:34:29 +0100212 print ' }'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000213
José Fonseca59ee88e2012-01-15 14:24:10 +0000214 def visitIntPointer(self, pointer, instance):
215 print ' trace::localWriter.writeOpaque((const void *)%s);' % instance
216
José Fonsecafbcf6832012-04-05 07:10:30 +0100217 def visitObjPointer(self, pointer, instance):
218 print ' trace::localWriter.writeOpaque((const void *)%s);' % instance
219
José Fonseca59ee88e2012-01-15 14:24:10 +0000220 def visitLinearPointer(self, pointer, instance):
221 print ' trace::localWriter.writeOpaque((const void *)%s);' % instance
222
José Fonsecab89c5932012-04-01 22:47:11 +0200223 def visitReference(self, reference, instance):
224 self.visit(reference.type, instance)
225
José Fonseca54f304a2012-01-14 19:33:08 +0000226 def visitHandle(self, handle, instance):
José Fonseca50d78d82010-11-23 22:13:14 +0000227 self.visit(handle.type, instance)
228
José Fonseca54f304a2012-01-14 19:33:08 +0000229 def visitAlias(self, alias, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000230 self.visit(alias.type, instance)
231
José Fonseca54f304a2012-01-14 19:33:08 +0000232 def visitOpaque(self, opaque, instance):
José Fonsecab4a3d142011-10-27 07:43:19 +0100233 print ' trace::localWriter.writeOpaque((const void *)%s);' % instance
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000234
José Fonseca54f304a2012-01-14 19:33:08 +0000235 def visitInterface(self, interface, instance):
José Fonsecab4a3d142011-10-27 07:43:19 +0100236 print ' trace::localWriter.writeOpaque((const void *)&%s);' % instance
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000237
José Fonseca54f304a2012-01-14 19:33:08 +0000238 def visitPolymorphic(self, polymorphic, instance):
239 print ' _write__%s(%s, %s);' % (polymorphic.tag, polymorphic.switchExpr, instance)
José Fonseca16d46dd2011-10-13 09:52:52 +0100240
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000241
José Fonseca54f304a2012-01-14 19:33:08 +0000242class ValueWrapper(stdapi.Visitor):
243 '''Type visitor which will generate the code to wrap an instance.
244
245 Wrapping is necessary mostly for interfaces, however interface pointers can
246 appear anywhere inside complex types.
247 '''
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000248
José Fonseca54f304a2012-01-14 19:33:08 +0000249 def visitVoid(self, type, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000250 raise NotImplementedError
251
José Fonseca54f304a2012-01-14 19:33:08 +0000252 def visitLiteral(self, type, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000253 pass
254
José Fonseca54f304a2012-01-14 19:33:08 +0000255 def visitString(self, type, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000256 pass
257
José Fonseca54f304a2012-01-14 19:33:08 +0000258 def visitConst(self, type, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000259 pass
260
José Fonseca54f304a2012-01-14 19:33:08 +0000261 def visitStruct(self, struct, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000262 for type, name in struct.members:
263 self.visit(type, "(%s).%s" % (instance, name))
264
José Fonseca54f304a2012-01-14 19:33:08 +0000265 def visitArray(self, array, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000266 # XXX: actually it is possible to return an array of pointers
267 pass
268
José Fonseca54f304a2012-01-14 19:33:08 +0000269 def visitBlob(self, blob, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000270 pass
271
José Fonseca54f304a2012-01-14 19:33:08 +0000272 def visitEnum(self, enum, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000273 pass
274
José Fonseca54f304a2012-01-14 19:33:08 +0000275 def visitBitmask(self, bitmask, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000276 pass
277
José Fonseca54f304a2012-01-14 19:33:08 +0000278 def visitPointer(self, pointer, instance):
José Fonseca3a2a4762011-05-26 11:37:30 +0100279 print " if (%s) {" % instance
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000280 self.visit(pointer.type, "*" + instance)
José Fonseca3a2a4762011-05-26 11:37:30 +0100281 print " }"
José Fonseca59ee88e2012-01-15 14:24:10 +0000282
283 def visitIntPointer(self, pointer, instance):
284 pass
285
José Fonsecafbcf6832012-04-05 07:10:30 +0100286 def visitObjPointer(self, pointer, instance):
287 print " if (%s) {" % instance
288 self.visit(pointer.type, "*" + instance)
289 print " }"
290
José Fonseca59ee88e2012-01-15 14:24:10 +0000291 def visitLinearPointer(self, pointer, instance):
292 pass
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000293
José Fonsecab89c5932012-04-01 22:47:11 +0200294 def visitReference(self, reference, instance):
295 self.visit(reference.type, instance)
296
José Fonseca54f304a2012-01-14 19:33:08 +0000297 def visitHandle(self, handle, instance):
José Fonseca50d78d82010-11-23 22:13:14 +0000298 self.visit(handle.type, instance)
299
José Fonseca54f304a2012-01-14 19:33:08 +0000300 def visitAlias(self, alias, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000301 self.visit(alias.type, instance)
302
José Fonseca54f304a2012-01-14 19:33:08 +0000303 def visitOpaque(self, opaque, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000304 pass
305
José Fonseca54f304a2012-01-14 19:33:08 +0000306 def visitInterface(self, interface, instance):
José Fonseca87d1cc62010-11-29 15:57:25 +0000307 assert instance.startswith('*')
308 instance = instance[1:]
José Fonseca3a2a4762011-05-26 11:37:30 +0100309 print " if (%s) {" % instance
José Fonseca0423d2c2012-01-20 19:16:17 +0000310 print " %s = new %s(%s);" % (instance, getWrapperInterfaceName(interface), instance)
José Fonseca3a2a4762011-05-26 11:37:30 +0100311 print " }"
José Fonseca16d46dd2011-10-13 09:52:52 +0100312
José Fonseca54f304a2012-01-14 19:33:08 +0000313 def visitPolymorphic(self, type, instance):
José Fonseca16d46dd2011-10-13 09:52:52 +0100314 # XXX: There might be polymorphic values that need wrapping in the future
315 pass
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000316
317
José Fonseca54f304a2012-01-14 19:33:08 +0000318class ValueUnwrapper(ValueWrapper):
319 '''Reverse of ValueWrapper.'''
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000320
José Fonseca54f304a2012-01-14 19:33:08 +0000321 def visitInterface(self, interface, instance):
José Fonseca87d1cc62010-11-29 15:57:25 +0000322 assert instance.startswith('*')
323 instance = instance[1:]
José Fonseca7aa86902012-01-31 20:14:31 +0000324 print r' if (%s) {' % instance
325 print r' %s *pWrapper = static_cast<%s*>(%s);' % (getWrapperInterfaceName(interface), getWrapperInterfaceName(interface), instance)
326 print r' if (pWrapper && pWrapper->m_dwMagic == 0xd8365d6c) {'
327 print r' %s = pWrapper->m_pInstance;' % (instance,)
328 print r' } else {'
329 print r' os::log("apitrace: warning: %%s: unexpected %%s pointer\n", __FUNCTION__, "%s");' % interface.name
330 print r' }'
331 print r' }'
José Fonseca87d1cc62010-11-29 15:57:25 +0000332
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000333
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000334class Tracer:
José Fonseca54f304a2012-01-14 19:33:08 +0000335 '''Base class to orchestrate the code generation of API tracing.'''
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000336
José Fonsecabb8760b2011-05-25 23:21:18 +0100337 def __init__(self):
338 self.api = None
339
José Fonseca54f304a2012-01-14 19:33:08 +0000340 def serializerFactory(self):
341 '''Create a serializer.
342
343 Can be overriden by derived classes to inject their own serialzer.
344 '''
345
346 return ValueSerializer()
347
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000348 def trace_api(self, api):
José Fonsecabb8760b2011-05-25 23:21:18 +0100349 self.api = api
350
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000351 self.header(api)
352
353 # Includes
354 for header in api.headers:
José Fonsecae6a50bd2010-11-24 10:12:22 +0000355 print header
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000356 print
357
José Fonseca54f304a2012-01-14 19:33:08 +0000358 # Generate the serializer functions
José Fonseca44703822012-01-31 10:48:58 +0000359 types = api.getAllTypes()
José Fonseca54f304a2012-01-14 19:33:08 +0000360 visitor = ComplexValueSerializer(self.serializerFactory())
José Fonsecae6a50bd2010-11-24 10:12:22 +0000361 map(visitor.visit, types)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000362 print
363
364 # Interfaces wrapers
José Fonseca2ef6d5b2012-01-31 10:56:38 +0000365 interfaces = api.getAllInterfaces()
José Fonseca0423d2c2012-01-20 19:16:17 +0000366 map(self.declareWrapperInterface, interfaces)
367 map(self.implementWrapperInterface, interfaces)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000368 print
369
370 # Function wrappers
José Fonseca54f304a2012-01-14 19:33:08 +0000371 map(self.traceFunctionDecl, api.functions)
372 map(self.traceFunctionImpl, api.functions)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000373 print
374
375 self.footer(api)
376
377 def header(self, api):
José Fonseca0ad465c2011-08-24 16:58:13 +0100378 pass
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000379
380 def footer(self, api):
381 pass
382
José Fonseca54f304a2012-01-14 19:33:08 +0000383 def traceFunctionDecl(self, function):
José Fonseca14c21bc2011-02-20 23:32:22 +0000384 # Per-function declarations
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000385
José Fonseca14c21bc2011-02-20 23:32:22 +0000386 if function.args:
387 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 +0000388 else:
José Fonseca14c21bc2011-02-20 23:32:22 +0000389 print 'static const char ** __%s_args = NULL;' % (function.name,)
José Fonsecab4a3d142011-10-27 07:43:19 +0100390 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 +0000391 print
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000392
José Fonseca54f304a2012-01-14 19:33:08 +0000393 def isFunctionPublic(self, function):
José Fonseca23691292011-04-22 10:40:25 +0100394 return True
395
José Fonseca54f304a2012-01-14 19:33:08 +0000396 def traceFunctionImpl(self, function):
397 if self.isFunctionPublic(function):
José Fonseca23691292011-04-22 10:40:25 +0100398 print 'extern "C" PUBLIC'
399 else:
400 print 'extern "C" PRIVATE'
401 print function.prototype() + ' {'
José Fonseca14c21bc2011-02-20 23:32:22 +0000402 if function.type is not stdapi.Void:
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000403 print ' %s __result;' % function.type
José Fonseca54f304a2012-01-14 19:33:08 +0000404 self.traceFunctionImplBody(function)
José Fonseca14c21bc2011-02-20 23:32:22 +0000405 if function.type is not stdapi.Void:
José Fonseca54f304a2012-01-14 19:33:08 +0000406 self.wrapRet(function, "__result")
José Fonseca14c21bc2011-02-20 23:32:22 +0000407 print ' return __result;'
408 print '}'
409 print
410
José Fonseca54f304a2012-01-14 19:33:08 +0000411 def traceFunctionImplBody(self, function):
José Fonsecab4a3d142011-10-27 07:43:19 +0100412 print ' unsigned __call = trace::localWriter.beginEnter(&__%s_sig);' % (function.name,)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000413 for arg in function.args:
414 if not arg.output:
José Fonseca54f304a2012-01-14 19:33:08 +0000415 self.unwrapArg(function, arg)
416 self.serializeArg(function, arg)
José Fonsecab4a3d142011-10-27 07:43:19 +0100417 print ' trace::localWriter.endEnter();'
José Fonseca54f304a2012-01-14 19:33:08 +0000418 self.invokeFunction(function)
José Fonsecab4a3d142011-10-27 07:43:19 +0100419 print ' trace::localWriter.beginLeave(__call);'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000420 for arg in function.args:
421 if arg.output:
José Fonseca54f304a2012-01-14 19:33:08 +0000422 self.serializeArg(function, arg)
423 self.wrapArg(function, arg)
José Fonseca9796b842010-11-25 11:44:50 +0000424 if function.type is not stdapi.Void:
José Fonseca54f304a2012-01-14 19:33:08 +0000425 self.serializeRet(function, "__result")
José Fonsecab4a3d142011-10-27 07:43:19 +0100426 print ' trace::localWriter.endLeave();'
José Fonseca14c21bc2011-02-20 23:32:22 +0000427
José Fonseca54f304a2012-01-14 19:33:08 +0000428 def invokeFunction(self, function, prefix='__', suffix=''):
José Fonseca14c21bc2011-02-20 23:32:22 +0000429 if function.type is stdapi.Void:
430 result = ''
431 else:
432 result = '__result = '
José Fonsecaa08d2752011-08-25 13:26:43 +0100433 dispatch = prefix + function.name + suffix
José Fonseca14c21bc2011-02-20 23:32:22 +0000434 print ' %s%s(%s);' % (result, dispatch, ', '.join([str(arg.name) for arg in function.args]))
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000435
José Fonseca54f304a2012-01-14 19:33:08 +0000436 def serializeArg(self, function, arg):
José Fonsecab4a3d142011-10-27 07:43:19 +0100437 print ' trace::localWriter.beginArg(%u);' % (arg.index,)
José Fonseca54f304a2012-01-14 19:33:08 +0000438 self.serializeArgValue(function, arg)
José Fonsecab4a3d142011-10-27 07:43:19 +0100439 print ' trace::localWriter.endArg();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000440
José Fonseca54f304a2012-01-14 19:33:08 +0000441 def serializeArgValue(self, function, arg):
442 self.serializeValue(arg.type, arg.name)
José Fonseca99221832011-03-22 22:15:46 +0000443
José Fonseca54f304a2012-01-14 19:33:08 +0000444 def wrapArg(self, function, arg):
445 self.wrapValue(arg.type, arg.name)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000446
José Fonseca54f304a2012-01-14 19:33:08 +0000447 def unwrapArg(self, function, arg):
448 self.unwrapValue(arg.type, arg.name)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000449
José Fonseca54f304a2012-01-14 19:33:08 +0000450 def serializeRet(self, function, instance):
José Fonsecab4a3d142011-10-27 07:43:19 +0100451 print ' trace::localWriter.beginReturn();'
José Fonseca54f304a2012-01-14 19:33:08 +0000452 self.serializeValue(function.type, instance)
José Fonsecab4a3d142011-10-27 07:43:19 +0100453 print ' trace::localWriter.endReturn();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000454
José Fonseca54f304a2012-01-14 19:33:08 +0000455 def serializeValue(self, type, instance):
456 serializer = self.serializerFactory()
457 serializer.visit(type, instance)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000458
José Fonseca54f304a2012-01-14 19:33:08 +0000459 def wrapRet(self, function, instance):
460 self.wrapValue(function.type, instance)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000461
José Fonseca54f304a2012-01-14 19:33:08 +0000462 def unwrapRet(self, function, instance):
463 self.unwrapValue(function.type, instance)
464
465 def wrapValue(self, type, instance):
466 visitor = ValueWrapper()
467 visitor.visit(type, instance)
468
469 def unwrapValue(self, type, instance):
470 visitor = ValueUnwrapper()
471 visitor.visit(type, instance)
472
José Fonseca0423d2c2012-01-20 19:16:17 +0000473 def declareWrapperInterface(self, interface):
474 print "class %s : public %s " % (getWrapperInterfaceName(interface), interface.name)
475 print "{"
476 print "public:"
477 print " %s(%s * pInstance);" % (getWrapperInterfaceName(interface), interface.name)
478 print " virtual ~%s();" % getWrapperInterfaceName(interface)
479 print
480 for method in interface.iterMethods():
481 print " " + method.prototype() + ";"
482 print
483 self.declareWrapperInterfaceVariables(interface)
484 print "};"
485 print
486
487 def declareWrapperInterfaceVariables(self, interface):
488 #print "private:"
José Fonseca7aa86902012-01-31 20:14:31 +0000489 print " DWORD m_dwMagic;"
José Fonseca0423d2c2012-01-20 19:16:17 +0000490 print " %s * m_pInstance;" % (interface.name,)
491
492 def implementWrapperInterface(self, interface):
493 print '%s::%s(%s * pInstance) {' % (getWrapperInterfaceName(interface), getWrapperInterfaceName(interface), interface.name)
José Fonseca7aa86902012-01-31 20:14:31 +0000494 print ' m_dwMagic = 0xd8365d6c;'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000495 print ' m_pInstance = pInstance;'
496 print '}'
497 print
José Fonseca0423d2c2012-01-20 19:16:17 +0000498 print '%s::~%s() {' % (getWrapperInterfaceName(interface), getWrapperInterfaceName(interface))
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000499 print '}'
500 print
José Fonseca4220b1b2012-02-03 19:05:29 +0000501 for base, method in interface.iterBaseMethods():
502 self.implementWrapperInterfaceMethod(interface, base, method)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000503 print
504
José Fonseca4220b1b2012-02-03 19:05:29 +0000505 def implementWrapperInterfaceMethod(self, interface, base, method):
José Fonseca0423d2c2012-01-20 19:16:17 +0000506 print method.prototype(getWrapperInterfaceName(interface) + '::' + method.name) + ' {'
507 if method.type is not stdapi.Void:
508 print ' %s __result;' % method.type
509
José Fonseca4220b1b2012-02-03 19:05:29 +0000510 self.implementWrapperInterfaceMethodBody(interface, base, method)
José Fonseca0423d2c2012-01-20 19:16:17 +0000511
512 if method.type is not stdapi.Void:
513 print ' return __result;'
514 print '}'
515 print
516
José Fonseca4220b1b2012-02-03 19:05:29 +0000517 def implementWrapperInterfaceMethodBody(self, interface, base, method):
José Fonseca87d1cc62010-11-29 15:57:25 +0000518 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 +0100519 print ' static const trace::FunctionSig __sig = {%u, "%s", %u, __args};' % (method.id, interface.name + '::' + method.name, len(method.args) + 1)
520 print ' unsigned __call = trace::localWriter.beginEnter(&__sig);'
521 print ' trace::localWriter.beginArg(0);'
522 print ' trace::localWriter.writeOpaque((const void *)m_pInstance);'
523 print ' trace::localWriter.endArg();'
José Fonseca1ce52f02012-01-31 12:19:57 +0000524
525 from specs.winapi import REFIID
José Fonseca3d2b0652012-01-31 19:35:24 +0000526 from specs.stdapi import Pointer, Opaque, Interface
José Fonseca1ce52f02012-01-31 12:19:57 +0000527
528 riid = None
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000529 for arg in method.args:
530 if not arg.output:
José Fonseca54f304a2012-01-14 19:33:08 +0000531 self.unwrapArg(method, arg)
532 self.serializeArg(method, arg)
José Fonseca1ce52f02012-01-31 12:19:57 +0000533 if arg.type is REFIID:
534 riid = arg
José Fonsecab4a3d142011-10-27 07:43:19 +0100535 print ' trace::localWriter.endEnter();'
José Fonseca0423d2c2012-01-20 19:16:17 +0000536
José Fonseca4220b1b2012-02-03 19:05:29 +0000537 self.invokeMethod(interface, base, method)
José Fonseca0423d2c2012-01-20 19:16:17 +0000538
José Fonsecab4a3d142011-10-27 07:43:19 +0100539 print ' trace::localWriter.beginLeave(__call);'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000540 for arg in method.args:
541 if arg.output:
José Fonseca54f304a2012-01-14 19:33:08 +0000542 self.serializeArg(method, arg)
543 self.wrapArg(method, arg)
José Fonseca1ce52f02012-01-31 12:19:57 +0000544 if riid is not None and isinstance(arg.type, Pointer):
José Fonseca3d2b0652012-01-31 19:35:24 +0000545 if isinstance(arg.type.type, Opaque):
546 self.wrapIid(riid, arg)
547 else:
548 assert isinstance(arg.type.type, Pointer)
549 assert isinstance(arg.type.type.type, Interface)
José Fonseca1ce52f02012-01-31 12:19:57 +0000550
José Fonseca87d1cc62010-11-29 15:57:25 +0000551 if method.type is not stdapi.Void:
José Fonsecab4a3d142011-10-27 07:43:19 +0100552 print ' trace::localWriter.beginReturn();'
José Fonseca54f304a2012-01-14 19:33:08 +0000553 self.serializeValue(method.type, "__result")
José Fonsecab4a3d142011-10-27 07:43:19 +0100554 print ' trace::localWriter.endReturn();'
José Fonseca54f304a2012-01-14 19:33:08 +0000555 self.wrapValue(method.type, '__result')
José Fonsecab4a3d142011-10-27 07:43:19 +0100556 print ' trace::localWriter.endLeave();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000557 if method.name == 'Release':
José Fonseca87d1cc62010-11-29 15:57:25 +0000558 assert method.type is not stdapi.Void
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000559 print ' if (!__result)'
560 print ' delete this;'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000561
José Fonseca7aa86902012-01-31 20:14:31 +0000562 def wrapIid(self, riid, out):
José Fonseca1ce52f02012-01-31 12:19:57 +0000563 print ' if (%s && *%s) {' % (out.name, out.name)
564 print ' if (*%s == m_pInstance) {' % (out.name,)
565 print ' *%s = this;' % (out.name,)
566 print ' }'
José Fonsecaccf250c2012-02-03 19:06:31 +0000567 for iface in self.api.getAllInterfaces():
José Fonseca1ce52f02012-01-31 12:19:57 +0000568 print r' else if (%s == IID_%s) {' % (riid.name, iface.name)
569 print r' *%s = new Wrap%s((%s *) *%s);' % (out.name, iface.name, iface.name, out.name)
570 print r' }'
571 print r' else {'
José Fonseca7aa86902012-01-31 20:14:31 +0000572 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",'
573 print r' __FUNCTION__,'
José Fonseca1ce52f02012-01-31 12:19:57 +0000574 print r' %s.Data1, %s.Data2, %s.Data3,' % (riid.name, riid.name, riid.name)
575 print r' %s.Data4[0],' % (riid.name,)
576 print r' %s.Data4[1],' % (riid.name,)
577 print r' %s.Data4[2],' % (riid.name,)
578 print r' %s.Data4[3],' % (riid.name,)
579 print r' %s.Data4[4],' % (riid.name,)
580 print r' %s.Data4[5],' % (riid.name,)
581 print r' %s.Data4[6],' % (riid.name,)
582 print r' %s.Data4[7]);' % (riid.name,)
583 print r' }'
584 print ' }'
585
José Fonseca4220b1b2012-02-03 19:05:29 +0000586 def invokeMethod(self, interface, base, method):
José Fonseca0423d2c2012-01-20 19:16:17 +0000587 if method.type is stdapi.Void:
588 result = ''
589 else:
590 result = '__result = '
José Fonseca4220b1b2012-02-03 19:05:29 +0000591 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 +0000592
593 def emit_memcpy(self, dest, src, length):
594 print ' unsigned __call = trace::localWriter.beginEnter(&trace::memcpy_sig);'
595 print ' trace::localWriter.beginArg(0);'
596 print ' trace::localWriter.writeOpaque(%s);' % dest
597 print ' trace::localWriter.endArg();'
598 print ' trace::localWriter.beginArg(1);'
599 print ' trace::localWriter.writeBlob(%s, %s);' % (src, length)
600 print ' trace::localWriter.endArg();'
601 print ' trace::localWriter.beginArg(2);'
602 print ' trace::localWriter.writeUInt(%s);' % length
603 print ' trace::localWriter.endArg();'
604 print ' trace::localWriter.endEnter();'
605 print ' trace::localWriter.beginLeave(__call);'
606 print ' trace::localWriter.endLeave();'
607