blob: f1aaf82c67474ab8263c707b1fa8f0dc10aed11e [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é Fonseca452d3252012-04-14 15:55:40 +010029# Adjust path
30import os.path
31import sys
32sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
33
34
José Fonsecabd86a222011-09-27 09:21:38 +010035import specs.stdapi as stdapi
José Fonseca8fbdd3a2010-11-23 20:55:07 +000036
37
José Fonseca0423d2c2012-01-20 19:16:17 +000038def getWrapperInterfaceName(interface):
José Fonseca87d1cc62010-11-29 15:57:25 +000039 return "Wrap" + interface.expr
40
José Fonseca6fac5ae2010-11-29 16:09:13 +000041
José Fonsecaf6b05132012-11-06 00:16:28 +000042
43class ExpanderMixin:
44 '''Mixin class that provides a bunch of methods to expand C expressions
45 from the specifications.'''
46
47 __structs = None
48 __indices = None
49
50 def expand(self, expr):
51 # Expand a C expression, replacing certain variables
52 if not isinstance(expr, basestring):
53 return expr
54 variables = {}
55
56 if self.__structs is not None:
57 variables['self'] = '(%s)' % self.__structs[0]
58 if self.__indices is not None:
59 variables['i'] = self.__indices[0]
60
61 expandedExpr = expr.format(**variables)
62 if expandedExpr != expr and 0:
63 sys.stderr.write(" %r -> %r\n" % (expr, expandedExpr))
64 return expandedExpr
65
66 def visitMember(self, structInstance, member_type, *args, **kwargs):
67 self.__structs = (structInstance, self.__structs)
68 try:
69 return self.visit(member_type, *args, **kwargs)
70 finally:
71 _, self.__structs = self.__structs
72
73 def visitElement(self, element_index, element_type, *args, **kwargs):
74 self.__indices = (element_index, self.__indices)
75 try:
76 return self.visit(element_type, *args, **kwargs)
77 finally:
78 _, self.__indices = self.__indices
79
80
José Fonseca54f304a2012-01-14 19:33:08 +000081class ComplexValueSerializer(stdapi.OnceVisitor):
82 '''Type visitors which generates serialization functions for
83 complex types.
84
85 Simple types are serialized inline.
86 '''
José Fonseca8fbdd3a2010-11-23 20:55:07 +000087
José Fonseca54f304a2012-01-14 19:33:08 +000088 def __init__(self, serializer):
89 stdapi.OnceVisitor.__init__(self)
90 self.serializer = serializer
91
92 def visitVoid(self, literal):
José Fonseca8fbdd3a2010-11-23 20:55:07 +000093 pass
94
José Fonseca54f304a2012-01-14 19:33:08 +000095 def visitLiteral(self, literal):
José Fonseca8fbdd3a2010-11-23 20:55:07 +000096 pass
97
José Fonseca54f304a2012-01-14 19:33:08 +000098 def visitString(self, string):
José Fonseca8fbdd3a2010-11-23 20:55:07 +000099 pass
100
José Fonseca54f304a2012-01-14 19:33:08 +0000101 def visitConst(self, const):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000102 self.visit(const.type)
103
José Fonseca54f304a2012-01-14 19:33:08 +0000104 def visitStruct(self, struct):
José Fonseca30fb4c32012-11-04 11:07:45 +0000105 print 'static const char * _struct%s_members[%u] = {' % (struct.tag, len(struct.members))
José Fonseca7eef8ce2010-11-26 15:46:36 +0000106 for type, name, in struct.members:
José Fonseca30fb4c32012-11-04 11:07:45 +0000107 print ' "%s",' % (name,)
108 print '};'
109 print 'static const trace::StructSig _struct%s_sig = {' % (struct.tag,)
110 print ' %u, "%s", %u, _struct%s_members' % (struct.id, struct.name, len(struct.members), struct.tag)
111 print '};'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000112 print
113
José Fonseca54f304a2012-01-14 19:33:08 +0000114 def visitArray(self, array):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000115 self.visit(array.type)
116
José Fonseca54f304a2012-01-14 19:33:08 +0000117 def visitBlob(self, array):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000118 pass
119
José Fonseca54f304a2012-01-14 19:33:08 +0000120 def visitEnum(self, enum):
José Fonseca632a78d2012-04-19 07:18:59 +0100121 print 'static const trace::EnumValue _enum%s_values[] = {' % (enum.tag)
José Fonsecaeb644512011-12-11 10:33:55 +0000122 for value in enum.values:
123 print ' {"%s", %s},' % (value, value)
124 print '};'
125 print
José Fonseca632a78d2012-04-19 07:18:59 +0100126 print 'static const trace::EnumSig _enum%s_sig = {' % (enum.tag)
127 print ' %u, %u, _enum%s_values' % (enum.id, len(enum.values), enum.tag)
José Fonsecaeb644512011-12-11 10:33:55 +0000128 print '};'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000129 print
130
José Fonseca54f304a2012-01-14 19:33:08 +0000131 def visitBitmask(self, bitmask):
José Fonseca632a78d2012-04-19 07:18:59 +0100132 print 'static const trace::BitmaskFlag _bitmask%s_flags[] = {' % (bitmask.tag)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000133 for value in bitmask.values:
José Fonsecad35973c2010-11-26 14:14:45 +0000134 print ' {"%s", %s},' % (value, value)
135 print '};'
136 print
José Fonseca632a78d2012-04-19 07:18:59 +0100137 print 'static const trace::BitmaskSig _bitmask%s_sig = {' % (bitmask.tag)
138 print ' %u, %u, _bitmask%s_flags' % (bitmask.id, len(bitmask.values), bitmask.tag)
José Fonsecad35973c2010-11-26 14:14:45 +0000139 print '};'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000140 print
141
José Fonseca54f304a2012-01-14 19:33:08 +0000142 def visitPointer(self, pointer):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000143 self.visit(pointer.type)
144
José Fonseca59ee88e2012-01-15 14:24:10 +0000145 def visitIntPointer(self, pointer):
146 pass
147
José Fonsecafbcf6832012-04-05 07:10:30 +0100148 def visitObjPointer(self, pointer):
149 self.visit(pointer.type)
150
José Fonseca59ee88e2012-01-15 14:24:10 +0000151 def visitLinearPointer(self, pointer):
152 self.visit(pointer.type)
153
José Fonseca54f304a2012-01-14 19:33:08 +0000154 def visitHandle(self, handle):
José Fonseca50d78d82010-11-23 22:13:14 +0000155 self.visit(handle.type)
156
José Fonsecab89c5932012-04-01 22:47:11 +0200157 def visitReference(self, reference):
158 self.visit(reference.type)
159
José Fonseca54f304a2012-01-14 19:33:08 +0000160 def visitAlias(self, alias):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000161 self.visit(alias.type)
162
José Fonseca54f304a2012-01-14 19:33:08 +0000163 def visitOpaque(self, opaque):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000164 pass
165
José Fonseca54f304a2012-01-14 19:33:08 +0000166 def visitInterface(self, interface):
José Fonseca0423d2c2012-01-20 19:16:17 +0000167 pass
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000168
José Fonseca54f304a2012-01-14 19:33:08 +0000169 def visitPolymorphic(self, polymorphic):
José Fonsecab95e3722012-04-16 14:01:15 +0100170 if not polymorphic.contextLess:
171 return
José Fonseca06e85192011-10-16 14:15:36 +0100172 print 'static void _write__%s(int selector, const %s & value) {' % (polymorphic.tag, polymorphic.expr)
José Fonsecac636b9d2011-10-14 10:15:02 +0100173 print ' switch (selector) {'
José Fonseca54f304a2012-01-14 19:33:08 +0000174 for cases, type in polymorphic.iterSwitch():
José Fonsecac636b9d2011-10-14 10:15:02 +0100175 for case in cases:
176 print ' %s:' % case
José Fonseca54f304a2012-01-14 19:33:08 +0000177 self.serializer.visit(type, 'static_cast<%s>(value)' % (type,))
José Fonsecac636b9d2011-10-14 10:15:02 +0100178 print ' break;'
179 print ' }'
180 print '}'
181 print
José Fonseca16d46dd2011-10-13 09:52:52 +0100182
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000183
José Fonsecaf6b05132012-11-06 00:16:28 +0000184class ValueSerializer(stdapi.Visitor, ExpanderMixin):
José Fonseca54f304a2012-01-14 19:33:08 +0000185 '''Visitor which generates code to serialize any type.
186
187 Simple types are serialized inline here, whereas the serialization of
188 complex types is dispatched to the serialization functions generated by
189 ComplexValueSerializer visitor above.
190 '''
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000191
José Fonseca30fb4c32012-11-04 11:07:45 +0000192 def __init__(self):
193 #stdapi.Visitor.__init__(self)
194 self.indices = []
195 self.instances = []
196
José Fonseca54f304a2012-01-14 19:33:08 +0000197 def visitLiteral(self, literal, instance):
José Fonsecab4a3d142011-10-27 07:43:19 +0100198 print ' trace::localWriter.write%s(%s);' % (literal.kind, instance)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000199
José Fonseca54f304a2012-01-14 19:33:08 +0000200 def visitString(self, string, instance):
José Fonsecabcfc81b2012-08-07 21:07:22 +0100201 if not string.wide:
José Fonseca280a1762012-01-31 15:10:13 +0000202 cast = 'const char *'
José Fonsecabcfc81b2012-08-07 21:07:22 +0100203 suffix = 'String'
José Fonsecae6a50bd2010-11-24 10:12:22 +0000204 else:
José Fonsecabcfc81b2012-08-07 21:07:22 +0100205 cast = 'const wchar_t *'
206 suffix = 'WString'
José Fonseca280a1762012-01-31 15:10:13 +0000207 if cast != string.expr:
208 # reinterpret_cast is necessary for GLubyte * <=> char *
209 instance = 'reinterpret_cast<%s>(%s)' % (cast, instance)
210 if string.length is not None:
José Fonsecadcf52cc2012-11-17 10:18:08 +0000211 length = ', %s' % self.expand(string.length)
José Fonseca280a1762012-01-31 15:10:13 +0000212 else:
213 length = ''
José Fonsecabcfc81b2012-08-07 21:07:22 +0100214 print ' trace::localWriter.write%s(%s%s);' % (suffix, instance, length)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000215
José Fonseca54f304a2012-01-14 19:33:08 +0000216 def visitConst(self, const, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000217 self.visit(const.type, instance)
218
José Fonseca54f304a2012-01-14 19:33:08 +0000219 def visitStruct(self, struct, instance):
José Fonseca30fb4c32012-11-04 11:07:45 +0000220 print ' trace::localWriter.beginStruct(&_struct%s_sig);' % (struct.tag,)
José Fonsecaf6b05132012-11-06 00:16:28 +0000221 for type, name in struct.members:
222 self.visitMember(instance, type, '(%s).%s' % (instance, name,))
José Fonseca30fb4c32012-11-04 11:07:45 +0000223 print ' trace::localWriter.endStruct();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000224
José Fonseca54f304a2012-01-14 19:33:08 +0000225 def visitArray(self, array, instance):
José Fonseca632a78d2012-04-19 07:18:59 +0100226 length = '_c' + array.type.tag
227 index = '_i' + array.type.tag
José Fonsecaf6b05132012-11-06 00:16:28 +0000228 array_length = self.expand(array.length)
José Fonsecafd34e4e2011-06-03 19:34:29 +0100229 print ' if (%s) {' % instance
José Fonsecaf6b05132012-11-06 00:16:28 +0000230 print ' size_t %s = %s > 0 ? %s : 0;' % (length, array_length, array_length)
José Fonsecab4a3d142011-10-27 07:43:19 +0100231 print ' trace::localWriter.beginArray(%s);' % length
José Fonsecafd34e4e2011-06-03 19:34:29 +0100232 print ' for (size_t %s = 0; %s < %s; ++%s) {' % (index, index, length, index)
José Fonsecab4a3d142011-10-27 07:43:19 +0100233 print ' trace::localWriter.beginElement();'
José Fonsecaf6b05132012-11-06 00:16:28 +0000234 self.visitElement(index, array.type, '(%s)[%s]' % (instance, index))
José Fonsecab4a3d142011-10-27 07:43:19 +0100235 print ' trace::localWriter.endElement();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000236 print ' }'
José Fonsecab4a3d142011-10-27 07:43:19 +0100237 print ' trace::localWriter.endArray();'
José Fonsecafd34e4e2011-06-03 19:34:29 +0100238 print ' } else {'
José Fonsecab4a3d142011-10-27 07:43:19 +0100239 print ' trace::localWriter.writeNull();'
José Fonsecafd34e4e2011-06-03 19:34:29 +0100240 print ' }'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000241
José Fonseca54f304a2012-01-14 19:33:08 +0000242 def visitBlob(self, blob, instance):
José Fonseca30fb4c32012-11-04 11:07:45 +0000243 print ' trace::localWriter.writeBlob(%s, %s);' % (instance, self.expand(blob.size))
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000244
José Fonseca54f304a2012-01-14 19:33:08 +0000245 def visitEnum(self, enum, instance):
José Fonseca632a78d2012-04-19 07:18:59 +0100246 print ' trace::localWriter.writeEnum(&_enum%s_sig, %s);' % (enum.tag, instance)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000247
José Fonseca54f304a2012-01-14 19:33:08 +0000248 def visitBitmask(self, bitmask, instance):
José Fonseca632a78d2012-04-19 07:18:59 +0100249 print ' trace::localWriter.writeBitmask(&_bitmask%s_sig, %s);' % (bitmask.tag, instance)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000250
José Fonseca54f304a2012-01-14 19:33:08 +0000251 def visitPointer(self, pointer, instance):
José Fonsecadbaae492011-04-21 09:28:10 +0100252 print ' if (%s) {' % instance
José Fonsecab4a3d142011-10-27 07:43:19 +0100253 print ' trace::localWriter.beginArray(1);'
254 print ' trace::localWriter.beginElement();'
José Fonseca54f304a2012-01-14 19:33:08 +0000255 self.visit(pointer.type, "*" + instance)
José Fonsecab4a3d142011-10-27 07:43:19 +0100256 print ' trace::localWriter.endElement();'
257 print ' trace::localWriter.endArray();'
José Fonsecafd34e4e2011-06-03 19:34:29 +0100258 print ' } else {'
José Fonsecab4a3d142011-10-27 07:43:19 +0100259 print ' trace::localWriter.writeNull();'
José Fonsecafd34e4e2011-06-03 19:34:29 +0100260 print ' }'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000261
José Fonseca59ee88e2012-01-15 14:24:10 +0000262 def visitIntPointer(self, pointer, instance):
José Fonsecad559f022012-04-15 16:13:51 +0100263 print ' trace::localWriter.writePointer((uintptr_t)%s);' % instance
José Fonseca59ee88e2012-01-15 14:24:10 +0000264
José Fonsecafbcf6832012-04-05 07:10:30 +0100265 def visitObjPointer(self, pointer, instance):
José Fonsecad559f022012-04-15 16:13:51 +0100266 print ' trace::localWriter.writePointer((uintptr_t)%s);' % instance
José Fonsecafbcf6832012-04-05 07:10:30 +0100267
José Fonseca59ee88e2012-01-15 14:24:10 +0000268 def visitLinearPointer(self, pointer, instance):
José Fonsecad559f022012-04-15 16:13:51 +0100269 print ' trace::localWriter.writePointer((uintptr_t)%s);' % instance
José Fonseca59ee88e2012-01-15 14:24:10 +0000270
José Fonsecab89c5932012-04-01 22:47:11 +0200271 def visitReference(self, reference, instance):
272 self.visit(reference.type, instance)
273
José Fonseca54f304a2012-01-14 19:33:08 +0000274 def visitHandle(self, handle, instance):
José Fonseca50d78d82010-11-23 22:13:14 +0000275 self.visit(handle.type, instance)
276
José Fonseca54f304a2012-01-14 19:33:08 +0000277 def visitAlias(self, alias, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000278 self.visit(alias.type, instance)
279
José Fonseca54f304a2012-01-14 19:33:08 +0000280 def visitOpaque(self, opaque, instance):
José Fonsecad559f022012-04-15 16:13:51 +0100281 print ' trace::localWriter.writePointer((uintptr_t)%s);' % instance
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000282
José Fonseca54f304a2012-01-14 19:33:08 +0000283 def visitInterface(self, interface, instance):
José Fonsecad559f022012-04-15 16:13:51 +0100284 assert False
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000285
José Fonseca54f304a2012-01-14 19:33:08 +0000286 def visitPolymorphic(self, polymorphic, instance):
José Fonsecab95e3722012-04-16 14:01:15 +0100287 if polymorphic.contextLess:
288 print ' _write__%s(%s, %s);' % (polymorphic.tag, polymorphic.switchExpr, instance)
289 else:
290 print ' switch (%s) {' % polymorphic.switchExpr
291 for cases, type in polymorphic.iterSwitch():
292 for case in cases:
293 print ' %s:' % case
294 self.visit(type, 'static_cast<%s>(%s)' % (type, instance))
295 print ' break;'
296 print ' }'
José Fonseca16d46dd2011-10-13 09:52:52 +0100297
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000298
José Fonseca0075f152012-04-14 20:25:52 +0100299class WrapDecider(stdapi.Traverser):
300 '''Type visitor which will decide wheter this type will need wrapping or not.
301
302 For complex types (arrays, structures), we need to know this before hand.
303 '''
304
305 def __init__(self):
306 self.needsWrapping = False
307
José Fonseca0075f152012-04-14 20:25:52 +0100308 def visitLinearPointer(self, void):
309 pass
310
311 def visitInterface(self, interface):
312 self.needsWrapping = True
313
314
José Fonsecaf6b05132012-11-06 00:16:28 +0000315class ValueWrapper(stdapi.Traverser, ExpanderMixin):
José Fonseca54f304a2012-01-14 19:33:08 +0000316 '''Type visitor which will generate the code to wrap an instance.
317
318 Wrapping is necessary mostly for interfaces, however interface pointers can
319 appear anywhere inside complex types.
320 '''
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000321
José Fonseca54f304a2012-01-14 19:33:08 +0000322 def visitStruct(self, struct, instance):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000323 for type, name in struct.members:
José Fonsecaf6b05132012-11-06 00:16:28 +0000324 self.visitMember(instance, type, "(%s).%s" % (instance, name))
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000325
José Fonseca54f304a2012-01-14 19:33:08 +0000326 def visitArray(self, array, instance):
José Fonsecaf6b05132012-11-06 00:16:28 +0000327 array_length = self.expand(array.length)
José Fonseca0075f152012-04-14 20:25:52 +0100328 print " if (%s) {" % instance
José Fonsecaf6b05132012-11-06 00:16:28 +0000329 print " for (size_t _i = 0, _s = %s; _i < _s; ++_i) {" % array_length
330 self.visitElement('_i', array.type, instance + "[_i]")
José Fonseca0075f152012-04-14 20:25:52 +0100331 print " }"
332 print " }"
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000333
José Fonseca54f304a2012-01-14 19:33:08 +0000334 def visitPointer(self, pointer, instance):
José Fonseca3a2a4762011-05-26 11:37:30 +0100335 print " if (%s) {" % instance
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000336 self.visit(pointer.type, "*" + instance)
José Fonseca3a2a4762011-05-26 11:37:30 +0100337 print " }"
José Fonseca59ee88e2012-01-15 14:24:10 +0000338
José Fonsecafbcf6832012-04-05 07:10:30 +0100339 def visitObjPointer(self, pointer, instance):
José Fonseca9782b292012-04-14 22:02:42 +0100340 elem_type = pointer.type.mutable()
341 if isinstance(elem_type, stdapi.Interface):
342 self.visitInterfacePointer(elem_type, instance)
José Fonsecae7cb2b92012-09-28 08:40:24 +0100343 elif isinstance(elem_type, stdapi.Alias) and isinstance(elem_type.type, stdapi.Interface):
344 self.visitInterfacePointer(elem_type.type, instance)
José Fonseca9782b292012-04-14 22:02:42 +0100345 else:
José Fonseca467a42a2012-05-04 11:49:19 +0100346 self.visitPointer(pointer, instance)
José Fonsecafbcf6832012-04-05 07:10:30 +0100347
José Fonseca54f304a2012-01-14 19:33:08 +0000348 def visitInterface(self, interface, instance):
José Fonseca9782b292012-04-14 22:02:42 +0100349 raise NotImplementedError
350
351 def visitInterfacePointer(self, interface, instance):
José Fonseca3a2a4762011-05-26 11:37:30 +0100352 print " if (%s) {" % instance
José Fonseca0423d2c2012-01-20 19:16:17 +0000353 print " %s = new %s(%s);" % (instance, getWrapperInterfaceName(interface), instance)
José Fonseca3a2a4762011-05-26 11:37:30 +0100354 print " }"
José Fonseca16d46dd2011-10-13 09:52:52 +0100355
José Fonseca54f304a2012-01-14 19:33:08 +0000356 def visitPolymorphic(self, type, instance):
José Fonseca16d46dd2011-10-13 09:52:52 +0100357 # XXX: There might be polymorphic values that need wrapping in the future
José Fonseca0075f152012-04-14 20:25:52 +0100358 raise NotImplementedError
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000359
360
José Fonseca54f304a2012-01-14 19:33:08 +0000361class ValueUnwrapper(ValueWrapper):
362 '''Reverse of ValueWrapper.'''
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000363
José Fonseca0075f152012-04-14 20:25:52 +0100364 allocated = False
365
José Fonsecae7cb2b92012-09-28 08:40:24 +0100366 def visitStruct(self, struct, instance):
367 if not self.allocated:
368 # Argument is constant. We need to create a non const
369 print ' {'
370 print " %s * _t = static_cast<%s *>(alloca(sizeof *_t));" % (struct, struct)
371 print ' *_t = %s;' % (instance,)
372 assert instance.startswith('*')
373 print ' %s = _t;' % (instance[1:],)
374 instance = '*_t'
375 self.allocated = True
376 try:
377 return ValueWrapper.visitStruct(self, struct, instance)
378 finally:
379 print ' }'
380 else:
381 return ValueWrapper.visitStruct(self, struct, instance)
382
José Fonseca0075f152012-04-14 20:25:52 +0100383 def visitArray(self, array, instance):
384 if self.allocated or isinstance(instance, stdapi.Interface):
385 return ValueWrapper.visitArray(self, array, instance)
José Fonsecaf6b05132012-11-06 00:16:28 +0000386 array_length = self.expand(array.length)
José Fonseca0075f152012-04-14 20:25:52 +0100387 elem_type = array.type.mutable()
José Fonsecaf6b05132012-11-06 00:16:28 +0000388 print " if (%s && %s) {" % (instance, array_length)
389 print " %s * _t = static_cast<%s *>(alloca(%s * sizeof *_t));" % (elem_type, elem_type, array_length)
390 print " for (size_t _i = 0, _s = %s; _i < _s; ++_i) {" % array_length
José Fonseca0075f152012-04-14 20:25:52 +0100391 print " _t[_i] = %s[_i];" % instance
392 self.allocated = True
393 self.visit(array.type, "_t[_i]")
394 print " }"
395 print " %s = _t;" % instance
396 print " }"
397
José Fonseca9782b292012-04-14 22:02:42 +0100398 def visitInterfacePointer(self, interface, instance):
José Fonseca7aa86902012-01-31 20:14:31 +0000399 print r' if (%s) {' % instance
José Fonseca0075f152012-04-14 20:25:52 +0100400 print r' const %s *pWrapper = static_cast<const %s*>(%s);' % (getWrapperInterfaceName(interface), getWrapperInterfaceName(interface), instance)
José Fonseca7aa86902012-01-31 20:14:31 +0000401 print r' if (pWrapper && pWrapper->m_dwMagic == 0xd8365d6c) {'
402 print r' %s = pWrapper->m_pInstance;' % (instance,)
403 print r' } else {'
404 print r' os::log("apitrace: warning: %%s: unexpected %%s pointer\n", __FUNCTION__, "%s");' % interface.name
405 print r' }'
406 print r' }'
José Fonseca87d1cc62010-11-29 15:57:25 +0000407
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000408
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000409class Tracer:
José Fonseca54f304a2012-01-14 19:33:08 +0000410 '''Base class to orchestrate the code generation of API tracing.'''
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000411
José Fonsecabb8760b2011-05-25 23:21:18 +0100412 def __init__(self):
413 self.api = None
414
José Fonseca54f304a2012-01-14 19:33:08 +0000415 def serializerFactory(self):
416 '''Create a serializer.
417
418 Can be overriden by derived classes to inject their own serialzer.
419 '''
420
421 return ValueSerializer()
422
José Fonseca1b6c8752012-04-15 14:33:00 +0100423 def traceApi(self, api):
José Fonsecabb8760b2011-05-25 23:21:18 +0100424 self.api = api
425
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000426 self.header(api)
427
428 # Includes
José Fonseca81301932012-11-11 00:10:20 +0000429 for module in api.modules:
430 for header in module.headers:
431 print header
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000432 print
433
José Fonseca54f304a2012-01-14 19:33:08 +0000434 # Generate the serializer functions
José Fonseca44703822012-01-31 10:48:58 +0000435 types = api.getAllTypes()
José Fonseca54f304a2012-01-14 19:33:08 +0000436 visitor = ComplexValueSerializer(self.serializerFactory())
José Fonsecae6a50bd2010-11-24 10:12:22 +0000437 map(visitor.visit, types)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000438 print
439
440 # Interfaces wrapers
José Fonseca143e9252012-04-15 09:31:18 +0100441 self.traceInterfaces(api)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000442
443 # Function wrappers
José Fonsecabcb26b22012-04-15 08:42:25 +0100444 self.interface = None
445 self.base = None
José Fonseca81301932012-11-11 00:10:20 +0000446 for function in api.getAllFunctions():
447 self.traceFunctionDecl(function)
448 for function in api.getAllFunctions():
449 self.traceFunctionImpl(function)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000450 print
451
452 self.footer(api)
453
454 def header(self, api):
José Fonsecaba2f08c2012-05-10 17:28:31 +0100455 print '#ifdef _WIN32'
456 print '# include <malloc.h> // alloca'
457 print '# ifndef alloca'
458 print '# define alloca _alloca'
459 print '# endif'
460 print '#else'
461 print '# include <alloca.h> // alloca'
462 print '#endif'
José Fonseca537c5072012-07-07 12:54:09 +0100463 print
464 print '#include "trace.hpp"'
465 print
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000466
467 def footer(self, api):
468 pass
469
José Fonseca54f304a2012-01-14 19:33:08 +0000470 def traceFunctionDecl(self, function):
José Fonseca14c21bc2011-02-20 23:32:22 +0000471 # Per-function declarations
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000472
José Fonseca84cea3b2012-05-09 21:12:30 +0100473 if not function.internal:
474 if function.args:
475 print 'static const char * _%s_args[%u] = {%s};' % (function.name, len(function.args), ', '.join(['"%s"' % arg.name for arg in function.args]))
476 else:
477 print 'static const char ** _%s_args = NULL;' % (function.name,)
478 print 'static const trace::FunctionSig _%s_sig = {%u, "%s", %u, _%s_args};' % (function.name, function.id, function.name, len(function.args), function.name)
479 print
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000480
José Fonseca54f304a2012-01-14 19:33:08 +0000481 def isFunctionPublic(self, function):
José Fonseca23691292011-04-22 10:40:25 +0100482 return True
483
José Fonseca54f304a2012-01-14 19:33:08 +0000484 def traceFunctionImpl(self, function):
485 if self.isFunctionPublic(function):
José Fonseca23691292011-04-22 10:40:25 +0100486 print 'extern "C" PUBLIC'
487 else:
488 print 'extern "C" PRIVATE'
489 print function.prototype() + ' {'
José Fonseca14c21bc2011-02-20 23:32:22 +0000490 if function.type is not stdapi.Void:
José Fonseca632a78d2012-04-19 07:18:59 +0100491 print ' %s _result;' % function.type
José Fonseca537c5072012-07-07 12:54:09 +0100492
493 # No-op if tracing is disabled
494 print ' if (!trace::isTracingEnabled()) {'
Imre Deak1242ab52012-03-30 15:46:26 +0300495 Tracer.invokeFunction(self, function)
496 if function.type is not stdapi.Void:
497 print ' return _result;'
498 else:
499 print ' return;'
500 print ' }'
José Fonseca537c5072012-07-07 12:54:09 +0100501
José Fonseca54f304a2012-01-14 19:33:08 +0000502 self.traceFunctionImplBody(function)
José Fonseca14c21bc2011-02-20 23:32:22 +0000503 if function.type is not stdapi.Void:
José Fonseca632a78d2012-04-19 07:18:59 +0100504 print ' return _result;'
José Fonseca14c21bc2011-02-20 23:32:22 +0000505 print '}'
506 print
507
José Fonseca54f304a2012-01-14 19:33:08 +0000508 def traceFunctionImplBody(self, function):
José Fonseca84cea3b2012-05-09 21:12:30 +0100509 if not function.internal:
510 print ' unsigned _call = trace::localWriter.beginEnter(&_%s_sig);' % (function.name,)
511 for arg in function.args:
512 if not arg.output:
513 self.unwrapArg(function, arg)
514 self.serializeArg(function, arg)
515 print ' trace::localWriter.endEnter();'
José Fonseca54f304a2012-01-14 19:33:08 +0000516 self.invokeFunction(function)
José Fonseca84cea3b2012-05-09 21:12:30 +0100517 if not function.internal:
518 print ' trace::localWriter.beginLeave(_call);'
José Fonseca4fb1ab02012-11-08 10:23:40 +0000519 print ' if (%s) {' % self.wasFunctionSuccessful(function)
José Fonseca84cea3b2012-05-09 21:12:30 +0100520 for arg in function.args:
521 if arg.output:
522 self.serializeArg(function, arg)
523 self.wrapArg(function, arg)
José Fonseca4fb1ab02012-11-08 10:23:40 +0000524 print ' }'
José Fonseca84cea3b2012-05-09 21:12:30 +0100525 if function.type is not stdapi.Void:
526 self.serializeRet(function, "_result")
527 print ' trace::localWriter.endLeave();'
528 if function.type is not stdapi.Void:
529 self.wrapRet(function, "_result")
José Fonseca14c21bc2011-02-20 23:32:22 +0000530
José Fonseca632a78d2012-04-19 07:18:59 +0100531 def invokeFunction(self, function, prefix='_', suffix=''):
José Fonseca14c21bc2011-02-20 23:32:22 +0000532 if function.type is stdapi.Void:
533 result = ''
534 else:
José Fonseca632a78d2012-04-19 07:18:59 +0100535 result = '_result = '
José Fonsecaa08d2752011-08-25 13:26:43 +0100536 dispatch = prefix + function.name + suffix
José Fonseca14c21bc2011-02-20 23:32:22 +0000537 print ' %s%s(%s);' % (result, dispatch, ', '.join([str(arg.name) for arg in function.args]))
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000538
José Fonseca4fb1ab02012-11-08 10:23:40 +0000539 def wasFunctionSuccessful(self, function):
540 if function.type is stdapi.Void:
541 return 'true'
542 if str(function.type) == 'HRESULT':
543 return 'SUCCEEDED(_result)'
José Fonsecad7771932012-11-13 11:13:38 +0000544 return 'true'
José Fonseca4fb1ab02012-11-08 10:23:40 +0000545
José Fonseca54f304a2012-01-14 19:33:08 +0000546 def serializeArg(self, function, arg):
José Fonsecab4a3d142011-10-27 07:43:19 +0100547 print ' trace::localWriter.beginArg(%u);' % (arg.index,)
José Fonseca54f304a2012-01-14 19:33:08 +0000548 self.serializeArgValue(function, arg)
José Fonsecab4a3d142011-10-27 07:43:19 +0100549 print ' trace::localWriter.endArg();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000550
José Fonseca54f304a2012-01-14 19:33:08 +0000551 def serializeArgValue(self, function, arg):
552 self.serializeValue(arg.type, arg.name)
José Fonseca99221832011-03-22 22:15:46 +0000553
José Fonseca54f304a2012-01-14 19:33:08 +0000554 def wrapArg(self, function, arg):
José Fonseca9782b292012-04-14 22:02:42 +0100555 assert not isinstance(arg.type, stdapi.ObjPointer)
José Fonsecabcb26b22012-04-15 08:42:25 +0100556
557 from specs.winapi import REFIID
558 riid = None
559 for other_arg in function.args:
560 if not other_arg.output and other_arg.type is REFIID:
561 riid = other_arg
José Fonsecac328b8c2012-04-28 21:45:38 +0100562 if riid is not None \
563 and isinstance(arg.type, stdapi.Pointer) \
564 and isinstance(arg.type.type, stdapi.ObjPointer):
José Fonsecabcb26b22012-04-15 08:42:25 +0100565 self.wrapIid(function, riid, arg)
566 return
567
José Fonseca54f304a2012-01-14 19:33:08 +0000568 self.wrapValue(arg.type, arg.name)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000569
José Fonseca54f304a2012-01-14 19:33:08 +0000570 def unwrapArg(self, function, arg):
571 self.unwrapValue(arg.type, arg.name)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000572
José Fonseca54f304a2012-01-14 19:33:08 +0000573 def serializeRet(self, function, instance):
José Fonsecab4a3d142011-10-27 07:43:19 +0100574 print ' trace::localWriter.beginReturn();'
José Fonseca54f304a2012-01-14 19:33:08 +0000575 self.serializeValue(function.type, instance)
José Fonsecab4a3d142011-10-27 07:43:19 +0100576 print ' trace::localWriter.endReturn();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000577
José Fonseca54f304a2012-01-14 19:33:08 +0000578 def serializeValue(self, type, instance):
579 serializer = self.serializerFactory()
580 serializer.visit(type, instance)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000581
José Fonseca54f304a2012-01-14 19:33:08 +0000582 def wrapRet(self, function, instance):
583 self.wrapValue(function.type, instance)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000584
José Fonseca54f304a2012-01-14 19:33:08 +0000585 def unwrapRet(self, function, instance):
586 self.unwrapValue(function.type, instance)
587
José Fonseca0075f152012-04-14 20:25:52 +0100588 def needsWrapping(self, type):
589 visitor = WrapDecider()
590 visitor.visit(type)
591 return visitor.needsWrapping
592
José Fonseca54f304a2012-01-14 19:33:08 +0000593 def wrapValue(self, type, instance):
José Fonseca0075f152012-04-14 20:25:52 +0100594 if self.needsWrapping(type):
595 visitor = ValueWrapper()
596 visitor.visit(type, instance)
José Fonseca54f304a2012-01-14 19:33:08 +0000597
598 def unwrapValue(self, type, instance):
José Fonseca0075f152012-04-14 20:25:52 +0100599 if self.needsWrapping(type):
600 visitor = ValueUnwrapper()
601 visitor.visit(type, instance)
José Fonseca54f304a2012-01-14 19:33:08 +0000602
José Fonseca143e9252012-04-15 09:31:18 +0100603 def traceInterfaces(self, api):
604 interfaces = api.getAllInterfaces()
605 if not interfaces:
606 return
607 map(self.declareWrapperInterface, interfaces)
608 self.implementIidWrapper(api)
609 map(self.implementWrapperInterface, interfaces)
610 print
611
José Fonseca0423d2c2012-01-20 19:16:17 +0000612 def declareWrapperInterface(self, interface):
613 print "class %s : public %s " % (getWrapperInterfaceName(interface), interface.name)
614 print "{"
615 print "public:"
616 print " %s(%s * pInstance);" % (getWrapperInterfaceName(interface), interface.name)
617 print " virtual ~%s();" % getWrapperInterfaceName(interface)
618 print
619 for method in interface.iterMethods():
620 print " " + method.prototype() + ";"
621 print
José Fonsecaacc90622012-05-02 13:10:07 +0100622 #print "private:"
623 for type, name, value in self.enumWrapperInterfaceVariables(interface):
624 print ' %s %s;' % (type, name)
José Fonseca0423d2c2012-01-20 19:16:17 +0000625 print "};"
626 print
627
José Fonsecaacc90622012-05-02 13:10:07 +0100628 def enumWrapperInterfaceVariables(self, interface):
629 return [
630 ("DWORD", "m_dwMagic", "0xd8365d6c"),
631 ("%s *" % interface.name, "m_pInstance", "pInstance"),
632 ]
José Fonseca0423d2c2012-01-20 19:16:17 +0000633
634 def implementWrapperInterface(self, interface):
José Fonsecabcb26b22012-04-15 08:42:25 +0100635 self.interface = interface
636
José Fonseca0423d2c2012-01-20 19:16:17 +0000637 print '%s::%s(%s * pInstance) {' % (getWrapperInterfaceName(interface), getWrapperInterfaceName(interface), interface.name)
José Fonsecaacc90622012-05-02 13:10:07 +0100638 for type, name, value in self.enumWrapperInterfaceVariables(interface):
639 print ' %s = %s;' % (name, value)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000640 print '}'
641 print
José Fonseca0423d2c2012-01-20 19:16:17 +0000642 print '%s::~%s() {' % (getWrapperInterfaceName(interface), getWrapperInterfaceName(interface))
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000643 print '}'
644 print
José Fonsecabcb26b22012-04-15 08:42:25 +0100645
José Fonseca4220b1b2012-02-03 19:05:29 +0000646 for base, method in interface.iterBaseMethods():
José Fonsecabcb26b22012-04-15 08:42:25 +0100647 self.base = base
José Fonseca4220b1b2012-02-03 19:05:29 +0000648 self.implementWrapperInterfaceMethod(interface, base, method)
José Fonsecabcb26b22012-04-15 08:42:25 +0100649
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000650 print
651
José Fonseca4220b1b2012-02-03 19:05:29 +0000652 def implementWrapperInterfaceMethod(self, interface, base, method):
José Fonseca0423d2c2012-01-20 19:16:17 +0000653 print method.prototype(getWrapperInterfaceName(interface) + '::' + method.name) + ' {'
654 if method.type is not stdapi.Void:
José Fonseca632a78d2012-04-19 07:18:59 +0100655 print ' %s _result;' % method.type
José Fonseca0423d2c2012-01-20 19:16:17 +0000656
José Fonseca4220b1b2012-02-03 19:05:29 +0000657 self.implementWrapperInterfaceMethodBody(interface, base, method)
José Fonseca0423d2c2012-01-20 19:16:17 +0000658
659 if method.type is not stdapi.Void:
José Fonseca632a78d2012-04-19 07:18:59 +0100660 print ' return _result;'
José Fonseca0423d2c2012-01-20 19:16:17 +0000661 print '}'
662 print
663
José Fonseca4220b1b2012-02-03 19:05:29 +0000664 def implementWrapperInterfaceMethodBody(self, interface, base, method):
José Fonseca84cea3b2012-05-09 21:12:30 +0100665 assert not method.internal
666
José Fonseca632a78d2012-04-19 07:18:59 +0100667 print ' static const char * _args[%u] = {%s};' % (len(method.args) + 1, ', '.join(['"this"'] + ['"%s"' % arg.name for arg in method.args]))
668 print ' static const trace::FunctionSig _sig = {%u, "%s", %u, _args};' % (method.id, interface.name + '::' + method.name, len(method.args) + 1)
José Fonsecaa0e97862012-04-29 23:22:52 +0100669
670 print ' %s *_this = static_cast<%s *>(m_pInstance);' % (base, base)
671
José Fonseca632a78d2012-04-19 07:18:59 +0100672 print ' unsigned _call = trace::localWriter.beginEnter(&_sig);'
José Fonsecab4a3d142011-10-27 07:43:19 +0100673 print ' trace::localWriter.beginArg(0);'
José Fonsecad559f022012-04-15 16:13:51 +0100674 print ' trace::localWriter.writePointer((uintptr_t)m_pInstance);'
José Fonsecab4a3d142011-10-27 07:43:19 +0100675 print ' trace::localWriter.endArg();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000676 for arg in method.args:
677 if not arg.output:
José Fonseca54f304a2012-01-14 19:33:08 +0000678 self.unwrapArg(method, arg)
679 self.serializeArg(method, arg)
José Fonsecab4a3d142011-10-27 07:43:19 +0100680 print ' trace::localWriter.endEnter();'
José Fonseca0423d2c2012-01-20 19:16:17 +0000681
José Fonseca4220b1b2012-02-03 19:05:29 +0000682 self.invokeMethod(interface, base, method)
José Fonseca0423d2c2012-01-20 19:16:17 +0000683
José Fonseca632a78d2012-04-19 07:18:59 +0100684 print ' trace::localWriter.beginLeave(_call);'
José Fonseca4fb1ab02012-11-08 10:23:40 +0000685
686 print ' if (%s) {' % self.wasFunctionSuccessful(method)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000687 for arg in method.args:
688 if arg.output:
José Fonseca54f304a2012-01-14 19:33:08 +0000689 self.serializeArg(method, arg)
690 self.wrapArg(method, arg)
José Fonseca4fb1ab02012-11-08 10:23:40 +0000691 print ' }'
José Fonseca1ce52f02012-01-31 12:19:57 +0000692
José Fonseca87d1cc62010-11-29 15:57:25 +0000693 if method.type is not stdapi.Void:
José Fonseca3a259b82012-05-09 19:33:33 +0100694 self.serializeRet(method, '_result')
José Fonsecab4a3d142011-10-27 07:43:19 +0100695 print ' trace::localWriter.endLeave();'
José Fonseca3a259b82012-05-09 19:33:33 +0100696 if method.type is not stdapi.Void:
697 self.wrapRet(method, '_result')
698
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000699 if method.name == 'Release':
José Fonseca87d1cc62010-11-29 15:57:25 +0000700 assert method.type is not stdapi.Void
José Fonseca632a78d2012-04-19 07:18:59 +0100701 print ' if (!_result)'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000702 print ' delete this;'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000703
José Fonseca143e9252012-04-15 09:31:18 +0100704 def implementIidWrapper(self, api):
705 print r'static void'
706 print r'warnIID(const char *functionName, REFIID riid, const char *reason) {'
707 print r' os::log("apitrace: warning: %s: %s IID {0x%08lX,0x%04X,0x%04X,{0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X}}\n",'
708 print r' functionName, reason,'
709 print r' riid.Data1, riid.Data2, riid.Data3,'
710 print r' riid.Data4[0], riid.Data4[1], riid.Data4[2], riid.Data4[3], riid.Data4[4], riid.Data4[5], riid.Data4[6], riid.Data4[7]);'
711 print r'}'
712 print
713 print r'static void'
714 print r'wrapIID(const char *functionName, REFIID riid, void * * ppvObj) {'
715 print r' if (!ppvObj || !*ppvObj) {'
716 print r' return;'
717 print r' }'
718 else_ = ''
719 for iface in api.getAllInterfaces():
720 print r' %sif (riid == IID_%s) {' % (else_, iface.name)
721 print r' *ppvObj = new Wrap%s((%s *) *ppvObj);' % (iface.name, iface.name)
722 print r' }'
723 else_ = 'else '
724 print r' %s{' % else_
725 print r' warnIID(functionName, riid, "unknown");'
726 print r' }'
727 print r'}'
728 print
729
José Fonsecabcb26b22012-04-15 08:42:25 +0100730 def wrapIid(self, function, riid, out):
José Fonsecac328b8c2012-04-28 21:45:38 +0100731 # Cast output arg to `void **` if necessary
732 out_name = out.name
733 obj_type = out.type.type.type
734 if not obj_type is stdapi.Void:
735 assert isinstance(obj_type, stdapi.Interface)
736 out_name = 'reinterpret_cast<void * *>(%s)' % out_name
737
José Fonsecabcb26b22012-04-15 08:42:25 +0100738 print r' if (%s && *%s) {' % (out.name, out.name)
José Fonseca143e9252012-04-15 09:31:18 +0100739 functionName = function.name
José Fonsecabcb26b22012-04-15 08:42:25 +0100740 else_ = ''
741 if self.interface is not None:
José Fonseca143e9252012-04-15 09:31:18 +0100742 functionName = self.interface.name + '::' + functionName
José Fonsecac328b8c2012-04-28 21:45:38 +0100743 print r' if (*%s == m_pInstance &&' % (out_name,)
José Fonseca828bf102012-04-16 20:48:59 +0100744 print r' (%s)) {' % ' || '.join('%s == IID_%s' % (riid.name, iface.name) for iface in self.interface.iterBases())
José Fonsecac328b8c2012-04-28 21:45:38 +0100745 print r' *%s = this;' % (out_name,)
José Fonsecabcb26b22012-04-15 08:42:25 +0100746 print r' }'
747 else_ = 'else '
748 print r' %s{' % else_
José Fonsecac328b8c2012-04-28 21:45:38 +0100749 print r' wrapIID("%s", %s, %s);' % (functionName, riid.name, out_name)
José Fonsecabcb26b22012-04-15 08:42:25 +0100750 print r' }'
751 print r' }'
José Fonseca1ce52f02012-01-31 12:19:57 +0000752
José Fonseca4220b1b2012-02-03 19:05:29 +0000753 def invokeMethod(self, interface, base, method):
José Fonseca0423d2c2012-01-20 19:16:17 +0000754 if method.type is stdapi.Void:
755 result = ''
756 else:
José Fonseca632a78d2012-04-19 07:18:59 +0100757 result = '_result = '
José Fonsecaa0e97862012-04-29 23:22:52 +0100758 print ' %s_this->%s(%s);' % (result, method.name, ', '.join([str(arg.name) for arg in method.args]))
José Fonseca0423d2c2012-01-20 19:16:17 +0000759
760 def emit_memcpy(self, dest, src, length):
José Fonseca632a78d2012-04-19 07:18:59 +0100761 print ' unsigned _call = trace::localWriter.beginEnter(&trace::memcpy_sig);'
José Fonseca0423d2c2012-01-20 19:16:17 +0000762 print ' trace::localWriter.beginArg(0);'
José Fonsecad559f022012-04-15 16:13:51 +0100763 print ' trace::localWriter.writePointer((uintptr_t)%s);' % dest
José Fonseca0423d2c2012-01-20 19:16:17 +0000764 print ' trace::localWriter.endArg();'
765 print ' trace::localWriter.beginArg(1);'
766 print ' trace::localWriter.writeBlob(%s, %s);' % (src, length)
767 print ' trace::localWriter.endArg();'
768 print ' trace::localWriter.beginArg(2);'
769 print ' trace::localWriter.writeUInt(%s);' % length
770 print ' trace::localWriter.endArg();'
771 print ' trace::localWriter.endEnter();'
José Fonseca632a78d2012-04-19 07:18:59 +0100772 print ' trace::localWriter.beginLeave(_call);'
José Fonseca0423d2c2012-01-20 19:16:17 +0000773 print ' trace::localWriter.endLeave();'
José Fonseca122c9872012-08-02 08:42:24 +0100774
775 def fake_call(self, function, args):
776 print ' unsigned _fake_call = trace::localWriter.beginEnter(&_%s_sig);' % (function.name,)
777 for arg, instance in zip(function.args, args):
778 assert not arg.output
779 print ' trace::localWriter.beginArg(%u);' % (arg.index,)
780 self.serializeValue(arg.type, instance)
781 print ' trace::localWriter.endArg();'
782 print ' trace::localWriter.endEnter();'
783 print ' trace::localWriter.beginLeave(_fake_call);'
784 print ' trace::localWriter.endLeave();'
José Fonseca0423d2c2012-01-20 19:16:17 +0000785