blob: 5d0a566f413b77119cf26ccf8b4831d038e88090 [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:
211 length = ', %s' % string.length
212 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)
343 else:
José Fonseca467a42a2012-05-04 11:49:19 +0100344 self.visitPointer(pointer, instance)
José Fonsecafbcf6832012-04-05 07:10:30 +0100345
José Fonseca54f304a2012-01-14 19:33:08 +0000346 def visitInterface(self, interface, instance):
José Fonseca9782b292012-04-14 22:02:42 +0100347 raise NotImplementedError
348
349 def visitInterfacePointer(self, interface, instance):
José Fonseca3a2a4762011-05-26 11:37:30 +0100350 print " if (%s) {" % instance
José Fonseca0423d2c2012-01-20 19:16:17 +0000351 print " %s = new %s(%s);" % (instance, getWrapperInterfaceName(interface), instance)
José Fonseca3a2a4762011-05-26 11:37:30 +0100352 print " }"
José Fonseca16d46dd2011-10-13 09:52:52 +0100353
José Fonseca54f304a2012-01-14 19:33:08 +0000354 def visitPolymorphic(self, type, instance):
José Fonseca16d46dd2011-10-13 09:52:52 +0100355 # XXX: There might be polymorphic values that need wrapping in the future
José Fonseca0075f152012-04-14 20:25:52 +0100356 raise NotImplementedError
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000357
358
José Fonseca54f304a2012-01-14 19:33:08 +0000359class ValueUnwrapper(ValueWrapper):
360 '''Reverse of ValueWrapper.'''
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000361
José Fonseca0075f152012-04-14 20:25:52 +0100362 allocated = False
363
364 def visitArray(self, array, instance):
365 if self.allocated or isinstance(instance, stdapi.Interface):
366 return ValueWrapper.visitArray(self, array, instance)
José Fonsecaf6b05132012-11-06 00:16:28 +0000367 array_length = self.expand(array.length)
José Fonseca0075f152012-04-14 20:25:52 +0100368 elem_type = array.type.mutable()
José Fonsecaf6b05132012-11-06 00:16:28 +0000369 print " if (%s && %s) {" % (instance, array_length)
370 print " %s * _t = static_cast<%s *>(alloca(%s * sizeof *_t));" % (elem_type, elem_type, array_length)
371 print " for (size_t _i = 0, _s = %s; _i < _s; ++_i) {" % array_length
José Fonseca0075f152012-04-14 20:25:52 +0100372 print " _t[_i] = %s[_i];" % instance
373 self.allocated = True
374 self.visit(array.type, "_t[_i]")
375 print " }"
376 print " %s = _t;" % instance
377 print " }"
378
José Fonseca9782b292012-04-14 22:02:42 +0100379 def visitInterfacePointer(self, interface, instance):
José Fonseca7aa86902012-01-31 20:14:31 +0000380 print r' if (%s) {' % instance
José Fonseca0075f152012-04-14 20:25:52 +0100381 print r' const %s *pWrapper = static_cast<const %s*>(%s);' % (getWrapperInterfaceName(interface), getWrapperInterfaceName(interface), instance)
José Fonseca7aa86902012-01-31 20:14:31 +0000382 print r' if (pWrapper && pWrapper->m_dwMagic == 0xd8365d6c) {'
383 print r' %s = pWrapper->m_pInstance;' % (instance,)
384 print r' } else {'
385 print r' os::log("apitrace: warning: %%s: unexpected %%s pointer\n", __FUNCTION__, "%s");' % interface.name
386 print r' }'
387 print r' }'
José Fonseca87d1cc62010-11-29 15:57:25 +0000388
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000389
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000390class Tracer:
José Fonseca54f304a2012-01-14 19:33:08 +0000391 '''Base class to orchestrate the code generation of API tracing.'''
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000392
José Fonsecabb8760b2011-05-25 23:21:18 +0100393 def __init__(self):
394 self.api = None
395
José Fonseca54f304a2012-01-14 19:33:08 +0000396 def serializerFactory(self):
397 '''Create a serializer.
398
399 Can be overriden by derived classes to inject their own serialzer.
400 '''
401
402 return ValueSerializer()
403
José Fonseca1b6c8752012-04-15 14:33:00 +0100404 def traceApi(self, api):
José Fonsecabb8760b2011-05-25 23:21:18 +0100405 self.api = api
406
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000407 self.header(api)
408
409 # Includes
410 for header in api.headers:
José Fonsecae6a50bd2010-11-24 10:12:22 +0000411 print header
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000412 print
413
José Fonseca54f304a2012-01-14 19:33:08 +0000414 # Generate the serializer functions
José Fonseca44703822012-01-31 10:48:58 +0000415 types = api.getAllTypes()
José Fonseca54f304a2012-01-14 19:33:08 +0000416 visitor = ComplexValueSerializer(self.serializerFactory())
José Fonsecae6a50bd2010-11-24 10:12:22 +0000417 map(visitor.visit, types)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000418 print
419
420 # Interfaces wrapers
José Fonseca143e9252012-04-15 09:31:18 +0100421 self.traceInterfaces(api)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000422
423 # Function wrappers
José Fonsecabcb26b22012-04-15 08:42:25 +0100424 self.interface = None
425 self.base = None
José Fonseca54f304a2012-01-14 19:33:08 +0000426 map(self.traceFunctionDecl, api.functions)
427 map(self.traceFunctionImpl, api.functions)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000428 print
429
430 self.footer(api)
431
432 def header(self, api):
José Fonsecaba2f08c2012-05-10 17:28:31 +0100433 print '#ifdef _WIN32'
434 print '# include <malloc.h> // alloca'
435 print '# ifndef alloca'
436 print '# define alloca _alloca'
437 print '# endif'
438 print '#else'
439 print '# include <alloca.h> // alloca'
440 print '#endif'
José Fonseca537c5072012-07-07 12:54:09 +0100441 print
442 print '#include "trace.hpp"'
443 print
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000444
445 def footer(self, api):
446 pass
447
José Fonseca54f304a2012-01-14 19:33:08 +0000448 def traceFunctionDecl(self, function):
José Fonseca14c21bc2011-02-20 23:32:22 +0000449 # Per-function declarations
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000450
José Fonseca84cea3b2012-05-09 21:12:30 +0100451 if not function.internal:
452 if function.args:
453 print 'static const char * _%s_args[%u] = {%s};' % (function.name, len(function.args), ', '.join(['"%s"' % arg.name for arg in function.args]))
454 else:
455 print 'static const char ** _%s_args = NULL;' % (function.name,)
456 print 'static const trace::FunctionSig _%s_sig = {%u, "%s", %u, _%s_args};' % (function.name, function.id, function.name, len(function.args), function.name)
457 print
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000458
José Fonseca54f304a2012-01-14 19:33:08 +0000459 def isFunctionPublic(self, function):
José Fonseca23691292011-04-22 10:40:25 +0100460 return True
461
José Fonseca54f304a2012-01-14 19:33:08 +0000462 def traceFunctionImpl(self, function):
463 if self.isFunctionPublic(function):
José Fonseca23691292011-04-22 10:40:25 +0100464 print 'extern "C" PUBLIC'
465 else:
466 print 'extern "C" PRIVATE'
467 print function.prototype() + ' {'
José Fonseca14c21bc2011-02-20 23:32:22 +0000468 if function.type is not stdapi.Void:
José Fonseca632a78d2012-04-19 07:18:59 +0100469 print ' %s _result;' % function.type
José Fonseca537c5072012-07-07 12:54:09 +0100470
471 # No-op if tracing is disabled
472 print ' if (!trace::isTracingEnabled()) {'
Imre Deak1242ab52012-03-30 15:46:26 +0300473 Tracer.invokeFunction(self, function)
474 if function.type is not stdapi.Void:
475 print ' return _result;'
476 else:
477 print ' return;'
478 print ' }'
José Fonseca537c5072012-07-07 12:54:09 +0100479
José Fonseca54f304a2012-01-14 19:33:08 +0000480 self.traceFunctionImplBody(function)
José Fonseca14c21bc2011-02-20 23:32:22 +0000481 if function.type is not stdapi.Void:
José Fonseca632a78d2012-04-19 07:18:59 +0100482 print ' return _result;'
José Fonseca14c21bc2011-02-20 23:32:22 +0000483 print '}'
484 print
485
José Fonseca54f304a2012-01-14 19:33:08 +0000486 def traceFunctionImplBody(self, function):
José Fonseca84cea3b2012-05-09 21:12:30 +0100487 if not function.internal:
488 print ' unsigned _call = trace::localWriter.beginEnter(&_%s_sig);' % (function.name,)
489 for arg in function.args:
490 if not arg.output:
491 self.unwrapArg(function, arg)
492 self.serializeArg(function, arg)
493 print ' trace::localWriter.endEnter();'
José Fonseca54f304a2012-01-14 19:33:08 +0000494 self.invokeFunction(function)
José Fonseca84cea3b2012-05-09 21:12:30 +0100495 if not function.internal:
496 print ' trace::localWriter.beginLeave(_call);'
497 for arg in function.args:
498 if arg.output:
499 self.serializeArg(function, arg)
500 self.wrapArg(function, arg)
501 if function.type is not stdapi.Void:
502 self.serializeRet(function, "_result")
503 print ' trace::localWriter.endLeave();'
504 if function.type is not stdapi.Void:
505 self.wrapRet(function, "_result")
José Fonseca14c21bc2011-02-20 23:32:22 +0000506
José Fonseca632a78d2012-04-19 07:18:59 +0100507 def invokeFunction(self, function, prefix='_', suffix=''):
José Fonseca14c21bc2011-02-20 23:32:22 +0000508 if function.type is stdapi.Void:
509 result = ''
510 else:
José Fonseca632a78d2012-04-19 07:18:59 +0100511 result = '_result = '
José Fonsecaa08d2752011-08-25 13:26:43 +0100512 dispatch = prefix + function.name + suffix
José Fonseca14c21bc2011-02-20 23:32:22 +0000513 print ' %s%s(%s);' % (result, dispatch, ', '.join([str(arg.name) for arg in function.args]))
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000514
José Fonseca54f304a2012-01-14 19:33:08 +0000515 def serializeArg(self, function, arg):
José Fonsecab4a3d142011-10-27 07:43:19 +0100516 print ' trace::localWriter.beginArg(%u);' % (arg.index,)
José Fonseca54f304a2012-01-14 19:33:08 +0000517 self.serializeArgValue(function, arg)
José Fonsecab4a3d142011-10-27 07:43:19 +0100518 print ' trace::localWriter.endArg();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000519
José Fonseca54f304a2012-01-14 19:33:08 +0000520 def serializeArgValue(self, function, arg):
521 self.serializeValue(arg.type, arg.name)
José Fonseca99221832011-03-22 22:15:46 +0000522
José Fonseca54f304a2012-01-14 19:33:08 +0000523 def wrapArg(self, function, arg):
José Fonseca9782b292012-04-14 22:02:42 +0100524 assert not isinstance(arg.type, stdapi.ObjPointer)
José Fonsecabcb26b22012-04-15 08:42:25 +0100525
526 from specs.winapi import REFIID
527 riid = None
528 for other_arg in function.args:
529 if not other_arg.output and other_arg.type is REFIID:
530 riid = other_arg
José Fonsecac328b8c2012-04-28 21:45:38 +0100531 if riid is not None \
532 and isinstance(arg.type, stdapi.Pointer) \
533 and isinstance(arg.type.type, stdapi.ObjPointer):
José Fonsecabcb26b22012-04-15 08:42:25 +0100534 self.wrapIid(function, riid, arg)
535 return
536
José Fonseca54f304a2012-01-14 19:33:08 +0000537 self.wrapValue(arg.type, arg.name)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000538
José Fonseca54f304a2012-01-14 19:33:08 +0000539 def unwrapArg(self, function, arg):
540 self.unwrapValue(arg.type, arg.name)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000541
José Fonseca54f304a2012-01-14 19:33:08 +0000542 def serializeRet(self, function, instance):
José Fonsecab4a3d142011-10-27 07:43:19 +0100543 print ' trace::localWriter.beginReturn();'
José Fonseca54f304a2012-01-14 19:33:08 +0000544 self.serializeValue(function.type, instance)
José Fonsecab4a3d142011-10-27 07:43:19 +0100545 print ' trace::localWriter.endReturn();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000546
José Fonseca54f304a2012-01-14 19:33:08 +0000547 def serializeValue(self, type, instance):
548 serializer = self.serializerFactory()
549 serializer.visit(type, instance)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000550
José Fonseca54f304a2012-01-14 19:33:08 +0000551 def wrapRet(self, function, instance):
552 self.wrapValue(function.type, instance)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000553
José Fonseca54f304a2012-01-14 19:33:08 +0000554 def unwrapRet(self, function, instance):
555 self.unwrapValue(function.type, instance)
556
José Fonseca0075f152012-04-14 20:25:52 +0100557 def needsWrapping(self, type):
558 visitor = WrapDecider()
559 visitor.visit(type)
560 return visitor.needsWrapping
561
José Fonseca54f304a2012-01-14 19:33:08 +0000562 def wrapValue(self, type, instance):
José Fonseca0075f152012-04-14 20:25:52 +0100563 if self.needsWrapping(type):
564 visitor = ValueWrapper()
565 visitor.visit(type, instance)
José Fonseca54f304a2012-01-14 19:33:08 +0000566
567 def unwrapValue(self, type, instance):
José Fonseca0075f152012-04-14 20:25:52 +0100568 if self.needsWrapping(type):
569 visitor = ValueUnwrapper()
570 visitor.visit(type, instance)
José Fonseca54f304a2012-01-14 19:33:08 +0000571
José Fonseca143e9252012-04-15 09:31:18 +0100572 def traceInterfaces(self, api):
573 interfaces = api.getAllInterfaces()
574 if not interfaces:
575 return
576 map(self.declareWrapperInterface, interfaces)
577 self.implementIidWrapper(api)
578 map(self.implementWrapperInterface, interfaces)
579 print
580
José Fonseca0423d2c2012-01-20 19:16:17 +0000581 def declareWrapperInterface(self, interface):
582 print "class %s : public %s " % (getWrapperInterfaceName(interface), interface.name)
583 print "{"
584 print "public:"
585 print " %s(%s * pInstance);" % (getWrapperInterfaceName(interface), interface.name)
586 print " virtual ~%s();" % getWrapperInterfaceName(interface)
587 print
588 for method in interface.iterMethods():
589 print " " + method.prototype() + ";"
590 print
José Fonsecaacc90622012-05-02 13:10:07 +0100591 #print "private:"
592 for type, name, value in self.enumWrapperInterfaceVariables(interface):
593 print ' %s %s;' % (type, name)
José Fonseca0423d2c2012-01-20 19:16:17 +0000594 print "};"
595 print
596
José Fonsecaacc90622012-05-02 13:10:07 +0100597 def enumWrapperInterfaceVariables(self, interface):
598 return [
599 ("DWORD", "m_dwMagic", "0xd8365d6c"),
600 ("%s *" % interface.name, "m_pInstance", "pInstance"),
601 ]
José Fonseca0423d2c2012-01-20 19:16:17 +0000602
603 def implementWrapperInterface(self, interface):
José Fonsecabcb26b22012-04-15 08:42:25 +0100604 self.interface = interface
605
José Fonseca0423d2c2012-01-20 19:16:17 +0000606 print '%s::%s(%s * pInstance) {' % (getWrapperInterfaceName(interface), getWrapperInterfaceName(interface), interface.name)
José Fonsecaacc90622012-05-02 13:10:07 +0100607 for type, name, value in self.enumWrapperInterfaceVariables(interface):
608 print ' %s = %s;' % (name, value)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000609 print '}'
610 print
José Fonseca0423d2c2012-01-20 19:16:17 +0000611 print '%s::~%s() {' % (getWrapperInterfaceName(interface), getWrapperInterfaceName(interface))
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000612 print '}'
613 print
José Fonsecabcb26b22012-04-15 08:42:25 +0100614
José Fonseca4220b1b2012-02-03 19:05:29 +0000615 for base, method in interface.iterBaseMethods():
José Fonsecabcb26b22012-04-15 08:42:25 +0100616 self.base = base
José Fonseca4220b1b2012-02-03 19:05:29 +0000617 self.implementWrapperInterfaceMethod(interface, base, method)
José Fonsecabcb26b22012-04-15 08:42:25 +0100618
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000619 print
620
José Fonseca4220b1b2012-02-03 19:05:29 +0000621 def implementWrapperInterfaceMethod(self, interface, base, method):
José Fonseca0423d2c2012-01-20 19:16:17 +0000622 print method.prototype(getWrapperInterfaceName(interface) + '::' + method.name) + ' {'
623 if method.type is not stdapi.Void:
José Fonseca632a78d2012-04-19 07:18:59 +0100624 print ' %s _result;' % method.type
José Fonseca0423d2c2012-01-20 19:16:17 +0000625
José Fonseca4220b1b2012-02-03 19:05:29 +0000626 self.implementWrapperInterfaceMethodBody(interface, base, method)
José Fonseca0423d2c2012-01-20 19:16:17 +0000627
628 if method.type is not stdapi.Void:
José Fonseca632a78d2012-04-19 07:18:59 +0100629 print ' return _result;'
José Fonseca0423d2c2012-01-20 19:16:17 +0000630 print '}'
631 print
632
José Fonseca4220b1b2012-02-03 19:05:29 +0000633 def implementWrapperInterfaceMethodBody(self, interface, base, method):
José Fonseca84cea3b2012-05-09 21:12:30 +0100634 assert not method.internal
635
José Fonseca632a78d2012-04-19 07:18:59 +0100636 print ' static const char * _args[%u] = {%s};' % (len(method.args) + 1, ', '.join(['"this"'] + ['"%s"' % arg.name for arg in method.args]))
637 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 +0100638
639 print ' %s *_this = static_cast<%s *>(m_pInstance);' % (base, base)
640
José Fonseca632a78d2012-04-19 07:18:59 +0100641 print ' unsigned _call = trace::localWriter.beginEnter(&_sig);'
José Fonsecab4a3d142011-10-27 07:43:19 +0100642 print ' trace::localWriter.beginArg(0);'
José Fonsecad559f022012-04-15 16:13:51 +0100643 print ' trace::localWriter.writePointer((uintptr_t)m_pInstance);'
José Fonsecab4a3d142011-10-27 07:43:19 +0100644 print ' trace::localWriter.endArg();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000645 for arg in method.args:
646 if not arg.output:
José Fonseca54f304a2012-01-14 19:33:08 +0000647 self.unwrapArg(method, arg)
648 self.serializeArg(method, arg)
José Fonsecab4a3d142011-10-27 07:43:19 +0100649 print ' trace::localWriter.endEnter();'
José Fonseca0423d2c2012-01-20 19:16:17 +0000650
José Fonseca4220b1b2012-02-03 19:05:29 +0000651 self.invokeMethod(interface, base, method)
José Fonseca0423d2c2012-01-20 19:16:17 +0000652
José Fonseca632a78d2012-04-19 07:18:59 +0100653 print ' trace::localWriter.beginLeave(_call);'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000654 for arg in method.args:
655 if arg.output:
José Fonseca54f304a2012-01-14 19:33:08 +0000656 self.serializeArg(method, arg)
657 self.wrapArg(method, arg)
José Fonseca1ce52f02012-01-31 12:19:57 +0000658
José Fonseca87d1cc62010-11-29 15:57:25 +0000659 if method.type is not stdapi.Void:
José Fonseca3a259b82012-05-09 19:33:33 +0100660 self.serializeRet(method, '_result')
José Fonsecab4a3d142011-10-27 07:43:19 +0100661 print ' trace::localWriter.endLeave();'
José Fonseca3a259b82012-05-09 19:33:33 +0100662 if method.type is not stdapi.Void:
663 self.wrapRet(method, '_result')
664
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000665 if method.name == 'Release':
José Fonseca87d1cc62010-11-29 15:57:25 +0000666 assert method.type is not stdapi.Void
José Fonseca632a78d2012-04-19 07:18:59 +0100667 print ' if (!_result)'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000668 print ' delete this;'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000669
José Fonseca143e9252012-04-15 09:31:18 +0100670 def implementIidWrapper(self, api):
671 print r'static void'
672 print r'warnIID(const char *functionName, REFIID riid, const char *reason) {'
673 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",'
674 print r' functionName, reason,'
675 print r' riid.Data1, riid.Data2, riid.Data3,'
676 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]);'
677 print r'}'
678 print
679 print r'static void'
680 print r'wrapIID(const char *functionName, REFIID riid, void * * ppvObj) {'
681 print r' if (!ppvObj || !*ppvObj) {'
682 print r' return;'
683 print r' }'
684 else_ = ''
685 for iface in api.getAllInterfaces():
686 print r' %sif (riid == IID_%s) {' % (else_, iface.name)
687 print r' *ppvObj = new Wrap%s((%s *) *ppvObj);' % (iface.name, iface.name)
688 print r' }'
689 else_ = 'else '
690 print r' %s{' % else_
691 print r' warnIID(functionName, riid, "unknown");'
692 print r' }'
693 print r'}'
694 print
695
José Fonsecabcb26b22012-04-15 08:42:25 +0100696 def wrapIid(self, function, riid, out):
José Fonsecac328b8c2012-04-28 21:45:38 +0100697 # Cast output arg to `void **` if necessary
698 out_name = out.name
699 obj_type = out.type.type.type
700 if not obj_type is stdapi.Void:
701 assert isinstance(obj_type, stdapi.Interface)
702 out_name = 'reinterpret_cast<void * *>(%s)' % out_name
703
José Fonsecabcb26b22012-04-15 08:42:25 +0100704 print r' if (%s && *%s) {' % (out.name, out.name)
José Fonseca143e9252012-04-15 09:31:18 +0100705 functionName = function.name
José Fonsecabcb26b22012-04-15 08:42:25 +0100706 else_ = ''
707 if self.interface is not None:
José Fonseca143e9252012-04-15 09:31:18 +0100708 functionName = self.interface.name + '::' + functionName
José Fonsecac328b8c2012-04-28 21:45:38 +0100709 print r' if (*%s == m_pInstance &&' % (out_name,)
José Fonseca828bf102012-04-16 20:48:59 +0100710 print r' (%s)) {' % ' || '.join('%s == IID_%s' % (riid.name, iface.name) for iface in self.interface.iterBases())
José Fonsecac328b8c2012-04-28 21:45:38 +0100711 print r' *%s = this;' % (out_name,)
José Fonsecabcb26b22012-04-15 08:42:25 +0100712 print r' }'
713 else_ = 'else '
714 print r' %s{' % else_
José Fonsecac328b8c2012-04-28 21:45:38 +0100715 print r' wrapIID("%s", %s, %s);' % (functionName, riid.name, out_name)
José Fonsecabcb26b22012-04-15 08:42:25 +0100716 print r' }'
717 print r' }'
José Fonseca1ce52f02012-01-31 12:19:57 +0000718
José Fonseca4220b1b2012-02-03 19:05:29 +0000719 def invokeMethod(self, interface, base, method):
José Fonseca0423d2c2012-01-20 19:16:17 +0000720 if method.type is stdapi.Void:
721 result = ''
722 else:
José Fonseca632a78d2012-04-19 07:18:59 +0100723 result = '_result = '
José Fonsecaa0e97862012-04-29 23:22:52 +0100724 print ' %s_this->%s(%s);' % (result, method.name, ', '.join([str(arg.name) for arg in method.args]))
José Fonseca0423d2c2012-01-20 19:16:17 +0000725
726 def emit_memcpy(self, dest, src, length):
José Fonseca632a78d2012-04-19 07:18:59 +0100727 print ' unsigned _call = trace::localWriter.beginEnter(&trace::memcpy_sig);'
José Fonseca0423d2c2012-01-20 19:16:17 +0000728 print ' trace::localWriter.beginArg(0);'
José Fonsecad559f022012-04-15 16:13:51 +0100729 print ' trace::localWriter.writePointer((uintptr_t)%s);' % dest
José Fonseca0423d2c2012-01-20 19:16:17 +0000730 print ' trace::localWriter.endArg();'
731 print ' trace::localWriter.beginArg(1);'
732 print ' trace::localWriter.writeBlob(%s, %s);' % (src, length)
733 print ' trace::localWriter.endArg();'
734 print ' trace::localWriter.beginArg(2);'
735 print ' trace::localWriter.writeUInt(%s);' % length
736 print ' trace::localWriter.endArg();'
737 print ' trace::localWriter.endEnter();'
José Fonseca632a78d2012-04-19 07:18:59 +0100738 print ' trace::localWriter.beginLeave(_call);'
José Fonseca0423d2c2012-01-20 19:16:17 +0000739 print ' trace::localWriter.endLeave();'
José Fonseca122c9872012-08-02 08:42:24 +0100740
741 def fake_call(self, function, args):
742 print ' unsigned _fake_call = trace::localWriter.beginEnter(&_%s_sig);' % (function.name,)
743 for arg, instance in zip(function.args, args):
744 assert not arg.output
745 print ' trace::localWriter.beginArg(%u);' % (arg.index,)
746 self.serializeValue(arg.type, instance)
747 print ' trace::localWriter.endArg();'
748 print ' trace::localWriter.endEnter();'
749 print ' trace::localWriter.beginLeave(_fake_call);'
750 print ' trace::localWriter.endLeave();'
José Fonseca0423d2c2012-01-20 19:16:17 +0000751