blob: da61e2a9660c5319abd6e6508bb47d38e86d3344 [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);'
José Fonseca4fb1ab02012-11-08 10:23:40 +0000497 print ' if (%s) {' % self.wasFunctionSuccessful(function)
José Fonseca84cea3b2012-05-09 21:12:30 +0100498 for arg in function.args:
499 if arg.output:
500 self.serializeArg(function, arg)
501 self.wrapArg(function, arg)
José Fonseca4fb1ab02012-11-08 10:23:40 +0000502 print ' }'
José Fonseca84cea3b2012-05-09 21:12:30 +0100503 if function.type is not stdapi.Void:
504 self.serializeRet(function, "_result")
505 print ' trace::localWriter.endLeave();'
506 if function.type is not stdapi.Void:
507 self.wrapRet(function, "_result")
José Fonseca14c21bc2011-02-20 23:32:22 +0000508
José Fonseca632a78d2012-04-19 07:18:59 +0100509 def invokeFunction(self, function, prefix='_', suffix=''):
José Fonseca14c21bc2011-02-20 23:32:22 +0000510 if function.type is stdapi.Void:
511 result = ''
512 else:
José Fonseca632a78d2012-04-19 07:18:59 +0100513 result = '_result = '
José Fonsecaa08d2752011-08-25 13:26:43 +0100514 dispatch = prefix + function.name + suffix
José Fonseca14c21bc2011-02-20 23:32:22 +0000515 print ' %s%s(%s);' % (result, dispatch, ', '.join([str(arg.name) for arg in function.args]))
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000516
José Fonseca4fb1ab02012-11-08 10:23:40 +0000517 def wasFunctionSuccessful(self, function):
518 if function.type is stdapi.Void:
519 return 'true'
520 if str(function.type) == 'HRESULT':
521 return 'SUCCEEDED(_result)'
522 return 'false'
523
José Fonseca54f304a2012-01-14 19:33:08 +0000524 def serializeArg(self, function, arg):
José Fonsecab4a3d142011-10-27 07:43:19 +0100525 print ' trace::localWriter.beginArg(%u);' % (arg.index,)
José Fonseca54f304a2012-01-14 19:33:08 +0000526 self.serializeArgValue(function, arg)
José Fonsecab4a3d142011-10-27 07:43:19 +0100527 print ' trace::localWriter.endArg();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000528
José Fonseca54f304a2012-01-14 19:33:08 +0000529 def serializeArgValue(self, function, arg):
530 self.serializeValue(arg.type, arg.name)
José Fonseca99221832011-03-22 22:15:46 +0000531
José Fonseca54f304a2012-01-14 19:33:08 +0000532 def wrapArg(self, function, arg):
José Fonseca9782b292012-04-14 22:02:42 +0100533 assert not isinstance(arg.type, stdapi.ObjPointer)
José Fonsecabcb26b22012-04-15 08:42:25 +0100534
535 from specs.winapi import REFIID
536 riid = None
537 for other_arg in function.args:
538 if not other_arg.output and other_arg.type is REFIID:
539 riid = other_arg
José Fonsecac328b8c2012-04-28 21:45:38 +0100540 if riid is not None \
541 and isinstance(arg.type, stdapi.Pointer) \
542 and isinstance(arg.type.type, stdapi.ObjPointer):
José Fonsecabcb26b22012-04-15 08:42:25 +0100543 self.wrapIid(function, riid, arg)
544 return
545
José Fonseca54f304a2012-01-14 19:33:08 +0000546 self.wrapValue(arg.type, arg.name)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000547
José Fonseca54f304a2012-01-14 19:33:08 +0000548 def unwrapArg(self, function, arg):
549 self.unwrapValue(arg.type, arg.name)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000550
José Fonseca54f304a2012-01-14 19:33:08 +0000551 def serializeRet(self, function, instance):
José Fonsecab4a3d142011-10-27 07:43:19 +0100552 print ' trace::localWriter.beginReturn();'
José Fonseca54f304a2012-01-14 19:33:08 +0000553 self.serializeValue(function.type, instance)
José Fonsecab4a3d142011-10-27 07:43:19 +0100554 print ' trace::localWriter.endReturn();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000555
José Fonseca54f304a2012-01-14 19:33:08 +0000556 def serializeValue(self, type, instance):
557 serializer = self.serializerFactory()
558 serializer.visit(type, instance)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000559
José Fonseca54f304a2012-01-14 19:33:08 +0000560 def wrapRet(self, function, instance):
561 self.wrapValue(function.type, instance)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000562
José Fonseca54f304a2012-01-14 19:33:08 +0000563 def unwrapRet(self, function, instance):
564 self.unwrapValue(function.type, instance)
565
José Fonseca0075f152012-04-14 20:25:52 +0100566 def needsWrapping(self, type):
567 visitor = WrapDecider()
568 visitor.visit(type)
569 return visitor.needsWrapping
570
José Fonseca54f304a2012-01-14 19:33:08 +0000571 def wrapValue(self, type, instance):
José Fonseca0075f152012-04-14 20:25:52 +0100572 if self.needsWrapping(type):
573 visitor = ValueWrapper()
574 visitor.visit(type, instance)
José Fonseca54f304a2012-01-14 19:33:08 +0000575
576 def unwrapValue(self, type, instance):
José Fonseca0075f152012-04-14 20:25:52 +0100577 if self.needsWrapping(type):
578 visitor = ValueUnwrapper()
579 visitor.visit(type, instance)
José Fonseca54f304a2012-01-14 19:33:08 +0000580
José Fonseca143e9252012-04-15 09:31:18 +0100581 def traceInterfaces(self, api):
582 interfaces = api.getAllInterfaces()
583 if not interfaces:
584 return
585 map(self.declareWrapperInterface, interfaces)
586 self.implementIidWrapper(api)
587 map(self.implementWrapperInterface, interfaces)
588 print
589
José Fonseca0423d2c2012-01-20 19:16:17 +0000590 def declareWrapperInterface(self, interface):
591 print "class %s : public %s " % (getWrapperInterfaceName(interface), interface.name)
592 print "{"
593 print "public:"
594 print " %s(%s * pInstance);" % (getWrapperInterfaceName(interface), interface.name)
595 print " virtual ~%s();" % getWrapperInterfaceName(interface)
596 print
597 for method in interface.iterMethods():
598 print " " + method.prototype() + ";"
599 print
José Fonsecaacc90622012-05-02 13:10:07 +0100600 #print "private:"
601 for type, name, value in self.enumWrapperInterfaceVariables(interface):
602 print ' %s %s;' % (type, name)
José Fonseca0423d2c2012-01-20 19:16:17 +0000603 print "};"
604 print
605
José Fonsecaacc90622012-05-02 13:10:07 +0100606 def enumWrapperInterfaceVariables(self, interface):
607 return [
608 ("DWORD", "m_dwMagic", "0xd8365d6c"),
609 ("%s *" % interface.name, "m_pInstance", "pInstance"),
610 ]
José Fonseca0423d2c2012-01-20 19:16:17 +0000611
612 def implementWrapperInterface(self, interface):
José Fonsecabcb26b22012-04-15 08:42:25 +0100613 self.interface = interface
614
José Fonseca0423d2c2012-01-20 19:16:17 +0000615 print '%s::%s(%s * pInstance) {' % (getWrapperInterfaceName(interface), getWrapperInterfaceName(interface), interface.name)
José Fonsecaacc90622012-05-02 13:10:07 +0100616 for type, name, value in self.enumWrapperInterfaceVariables(interface):
617 print ' %s = %s;' % (name, value)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000618 print '}'
619 print
José Fonseca0423d2c2012-01-20 19:16:17 +0000620 print '%s::~%s() {' % (getWrapperInterfaceName(interface), getWrapperInterfaceName(interface))
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000621 print '}'
622 print
José Fonsecabcb26b22012-04-15 08:42:25 +0100623
José Fonseca4220b1b2012-02-03 19:05:29 +0000624 for base, method in interface.iterBaseMethods():
José Fonsecabcb26b22012-04-15 08:42:25 +0100625 self.base = base
José Fonseca4220b1b2012-02-03 19:05:29 +0000626 self.implementWrapperInterfaceMethod(interface, base, method)
José Fonsecabcb26b22012-04-15 08:42:25 +0100627
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000628 print
629
José Fonseca4220b1b2012-02-03 19:05:29 +0000630 def implementWrapperInterfaceMethod(self, interface, base, method):
José Fonseca0423d2c2012-01-20 19:16:17 +0000631 print method.prototype(getWrapperInterfaceName(interface) + '::' + method.name) + ' {'
632 if method.type is not stdapi.Void:
José Fonseca632a78d2012-04-19 07:18:59 +0100633 print ' %s _result;' % method.type
José Fonseca0423d2c2012-01-20 19:16:17 +0000634
José Fonseca4220b1b2012-02-03 19:05:29 +0000635 self.implementWrapperInterfaceMethodBody(interface, base, method)
José Fonseca0423d2c2012-01-20 19:16:17 +0000636
637 if method.type is not stdapi.Void:
José Fonseca632a78d2012-04-19 07:18:59 +0100638 print ' return _result;'
José Fonseca0423d2c2012-01-20 19:16:17 +0000639 print '}'
640 print
641
José Fonseca4220b1b2012-02-03 19:05:29 +0000642 def implementWrapperInterfaceMethodBody(self, interface, base, method):
José Fonseca84cea3b2012-05-09 21:12:30 +0100643 assert not method.internal
644
José Fonseca632a78d2012-04-19 07:18:59 +0100645 print ' static const char * _args[%u] = {%s};' % (len(method.args) + 1, ', '.join(['"this"'] + ['"%s"' % arg.name for arg in method.args]))
646 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 +0100647
648 print ' %s *_this = static_cast<%s *>(m_pInstance);' % (base, base)
649
José Fonseca632a78d2012-04-19 07:18:59 +0100650 print ' unsigned _call = trace::localWriter.beginEnter(&_sig);'
José Fonsecab4a3d142011-10-27 07:43:19 +0100651 print ' trace::localWriter.beginArg(0);'
José Fonsecad559f022012-04-15 16:13:51 +0100652 print ' trace::localWriter.writePointer((uintptr_t)m_pInstance);'
José Fonsecab4a3d142011-10-27 07:43:19 +0100653 print ' trace::localWriter.endArg();'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000654 for arg in method.args:
655 if not arg.output:
José Fonseca54f304a2012-01-14 19:33:08 +0000656 self.unwrapArg(method, arg)
657 self.serializeArg(method, arg)
José Fonsecab4a3d142011-10-27 07:43:19 +0100658 print ' trace::localWriter.endEnter();'
José Fonseca0423d2c2012-01-20 19:16:17 +0000659
José Fonseca4220b1b2012-02-03 19:05:29 +0000660 self.invokeMethod(interface, base, method)
José Fonseca0423d2c2012-01-20 19:16:17 +0000661
José Fonseca632a78d2012-04-19 07:18:59 +0100662 print ' trace::localWriter.beginLeave(_call);'
José Fonseca4fb1ab02012-11-08 10:23:40 +0000663
664 print ' if (%s) {' % self.wasFunctionSuccessful(method)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000665 for arg in method.args:
666 if arg.output:
José Fonseca54f304a2012-01-14 19:33:08 +0000667 self.serializeArg(method, arg)
668 self.wrapArg(method, arg)
José Fonseca4fb1ab02012-11-08 10:23:40 +0000669 print ' }'
José Fonseca1ce52f02012-01-31 12:19:57 +0000670
José Fonseca87d1cc62010-11-29 15:57:25 +0000671 if method.type is not stdapi.Void:
José Fonseca3a259b82012-05-09 19:33:33 +0100672 self.serializeRet(method, '_result')
José Fonsecab4a3d142011-10-27 07:43:19 +0100673 print ' trace::localWriter.endLeave();'
José Fonseca3a259b82012-05-09 19:33:33 +0100674 if method.type is not stdapi.Void:
675 self.wrapRet(method, '_result')
676
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000677 if method.name == 'Release':
José Fonseca87d1cc62010-11-29 15:57:25 +0000678 assert method.type is not stdapi.Void
José Fonseca632a78d2012-04-19 07:18:59 +0100679 print ' if (!_result)'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000680 print ' delete this;'
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000681
José Fonseca143e9252012-04-15 09:31:18 +0100682 def implementIidWrapper(self, api):
683 print r'static void'
684 print r'warnIID(const char *functionName, REFIID riid, const char *reason) {'
685 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",'
686 print r' functionName, reason,'
687 print r' riid.Data1, riid.Data2, riid.Data3,'
688 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]);'
689 print r'}'
690 print
691 print r'static void'
692 print r'wrapIID(const char *functionName, REFIID riid, void * * ppvObj) {'
693 print r' if (!ppvObj || !*ppvObj) {'
694 print r' return;'
695 print r' }'
696 else_ = ''
697 for iface in api.getAllInterfaces():
698 print r' %sif (riid == IID_%s) {' % (else_, iface.name)
699 print r' *ppvObj = new Wrap%s((%s *) *ppvObj);' % (iface.name, iface.name)
700 print r' }'
701 else_ = 'else '
702 print r' %s{' % else_
703 print r' warnIID(functionName, riid, "unknown");'
704 print r' }'
705 print r'}'
706 print
707
José Fonsecabcb26b22012-04-15 08:42:25 +0100708 def wrapIid(self, function, riid, out):
José Fonsecac328b8c2012-04-28 21:45:38 +0100709 # Cast output arg to `void **` if necessary
710 out_name = out.name
711 obj_type = out.type.type.type
712 if not obj_type is stdapi.Void:
713 assert isinstance(obj_type, stdapi.Interface)
714 out_name = 'reinterpret_cast<void * *>(%s)' % out_name
715
José Fonsecabcb26b22012-04-15 08:42:25 +0100716 print r' if (%s && *%s) {' % (out.name, out.name)
José Fonseca143e9252012-04-15 09:31:18 +0100717 functionName = function.name
José Fonsecabcb26b22012-04-15 08:42:25 +0100718 else_ = ''
719 if self.interface is not None:
José Fonseca143e9252012-04-15 09:31:18 +0100720 functionName = self.interface.name + '::' + functionName
José Fonsecac328b8c2012-04-28 21:45:38 +0100721 print r' if (*%s == m_pInstance &&' % (out_name,)
José Fonseca828bf102012-04-16 20:48:59 +0100722 print r' (%s)) {' % ' || '.join('%s == IID_%s' % (riid.name, iface.name) for iface in self.interface.iterBases())
José Fonsecac328b8c2012-04-28 21:45:38 +0100723 print r' *%s = this;' % (out_name,)
José Fonsecabcb26b22012-04-15 08:42:25 +0100724 print r' }'
725 else_ = 'else '
726 print r' %s{' % else_
José Fonsecac328b8c2012-04-28 21:45:38 +0100727 print r' wrapIID("%s", %s, %s);' % (functionName, riid.name, out_name)
José Fonsecabcb26b22012-04-15 08:42:25 +0100728 print r' }'
729 print r' }'
José Fonseca1ce52f02012-01-31 12:19:57 +0000730
José Fonseca4220b1b2012-02-03 19:05:29 +0000731 def invokeMethod(self, interface, base, method):
José Fonseca0423d2c2012-01-20 19:16:17 +0000732 if method.type is stdapi.Void:
733 result = ''
734 else:
José Fonseca632a78d2012-04-19 07:18:59 +0100735 result = '_result = '
José Fonsecaa0e97862012-04-29 23:22:52 +0100736 print ' %s_this->%s(%s);' % (result, method.name, ', '.join([str(arg.name) for arg in method.args]))
José Fonseca0423d2c2012-01-20 19:16:17 +0000737
738 def emit_memcpy(self, dest, src, length):
José Fonseca632a78d2012-04-19 07:18:59 +0100739 print ' unsigned _call = trace::localWriter.beginEnter(&trace::memcpy_sig);'
José Fonseca0423d2c2012-01-20 19:16:17 +0000740 print ' trace::localWriter.beginArg(0);'
José Fonsecad559f022012-04-15 16:13:51 +0100741 print ' trace::localWriter.writePointer((uintptr_t)%s);' % dest
José Fonseca0423d2c2012-01-20 19:16:17 +0000742 print ' trace::localWriter.endArg();'
743 print ' trace::localWriter.beginArg(1);'
744 print ' trace::localWriter.writeBlob(%s, %s);' % (src, length)
745 print ' trace::localWriter.endArg();'
746 print ' trace::localWriter.beginArg(2);'
747 print ' trace::localWriter.writeUInt(%s);' % length
748 print ' trace::localWriter.endArg();'
749 print ' trace::localWriter.endEnter();'
José Fonseca632a78d2012-04-19 07:18:59 +0100750 print ' trace::localWriter.beginLeave(_call);'
José Fonseca0423d2c2012-01-20 19:16:17 +0000751 print ' trace::localWriter.endLeave();'
José Fonseca122c9872012-08-02 08:42:24 +0100752
753 def fake_call(self, function, args):
754 print ' unsigned _fake_call = trace::localWriter.beginEnter(&_%s_sig);' % (function.name,)
755 for arg, instance in zip(function.args, args):
756 assert not arg.output
757 print ' trace::localWriter.beginArg(%u);' % (arg.index,)
758 self.serializeValue(arg.type, instance)
759 print ' trace::localWriter.endArg();'
760 print ' trace::localWriter.endEnter();'
761 print ' trace::localWriter.beginLeave(_fake_call);'
762 print ' trace::localWriter.endLeave();'
José Fonseca0423d2c2012-01-20 19:16:17 +0000763