def visitArray(self, array):
self.visit(array.type)
+ def visitAttribArray(self, array):
+ pass
+
def visitBlob(self, array):
pass
def visitPolymorphic(self, polymorphic):
if not polymorphic.contextLess:
return
- print 'static void _write__%s(int selector, const %s & value) {' % (polymorphic.tag, polymorphic.expr)
+ print 'static void _write__%s(int selector, %s const & value) {' % (polymorphic.tag, polymorphic.expr)
print ' switch (selector) {'
for cases, type in polymorphic.iterSwitch():
for case in cases:
print ' trace::localWriter.writeNull();'
print ' }'
+ def visitAttribArray(self, array, instance):
+ # For each element, decide if it is a key or a value (which depends on the previous key).
+ # If it is a value, store it as the right type - usually int, some bitfield, or some enum.
+ # It is currently assumed that an unknown key means that it is followed by an int value.
+
+ # determine the array length which must be passed to writeArray() up front
+ count = '_c' + array.baseType.tag
+ print ' {'
+ print ' int %s;' % count
+ print ' for (%(c)s = 0; %(array)s && %(array)s[%(c)s] != %(terminator)s; %(c)s += 2) {' \
+ % {'c': count, 'array': instance, 'terminator': array.terminator}
+ if array.hasKeysWithoutValues:
+ print ' switch (int(%(array)s[%(c)s])) {' % {'array': instance, 'c': count}
+ for key, valueType in array.valueTypes:
+ if valueType is None:
+ print ' case %s:' % key
+ print ' %s--;' % count # the next value is a key again and checked if it's the terminator
+ print ' break;'
+ print ' }'
+ print ' }'
+ print ' %(c)s += %(array)s ? 1 : 0;' % {'c': count, 'array': instance}
+ print ' trace::localWriter.beginArray(%s);' % count
+
+ # for each key / key-value pair write the key and the value, if the key requires one
+
+ index = '_i' + array.baseType.tag
+ print ' for (int %(i)s = 0; %(i)s < %(count)s; %(i)s++) {' % {'i': index, 'count': count}
+ print ' trace::localWriter.beginElement();'
+ self.visit(array.baseType, "%(array)s[%(i)s]" % {'array': instance, 'i': index})
+ print ' trace::localWriter.endElement();'
+ print ' if (%(i)s + 1 >= %(count)s) {' % {'i': index, 'count': count}
+ print ' break;'
+ print ' }'
+ print ' switch (int(%(array)s[%(i)s++])) {' % {'array': instance, 'i': index}
+ # write generic value the usual way
+ for key, valueType in array.valueTypes:
+ if valueType is not None:
+ print ' case %s:' % key
+ print ' trace::localWriter.beginElement();'
+ self.visitElement(index, valueType, '(%(array)s)[%(i)s]' % {'array': instance, 'i': index})
+ print ' trace::localWriter.endElement();'
+ print ' break;'
+ # known key with no value, just decrease the index so we treat the next value as a key
+ if array.hasKeysWithoutValues:
+ for key, valueType in array.valueTypes:
+ if valueType is None:
+ print ' case %s:' % key
+ print ' %s--;' % index
+ print ' break;'
+ # unknown key, write an int value
+ print ' default:'
+ print ' trace::localWriter.beginElement();'
+ print ' os::log("apitrace: warning: %s: unknown key 0x%04X, interpreting value as int\\n", ' + \
+ '__FUNCTION__, int(%(array)s[%(i)s - 1]));' % {'array': instance, 'i': index}
+ print ' trace::localWriter.writeSInt(%(array)s[%(i)s]);' % {'array': instance, 'i': index}
+ print ' trace::localWriter.endElement();'
+ print ' break;'
+ print ' }'
+ print ' }'
+ print ' trace::localWriter.endArray();'
+ print ' }'
+
+
def visitBlob(self, blob, instance):
print ' trace::localWriter.writeBlob(%s, %s);' % (instance, self.expand(blob.size))
# No-op if tracing is disabled
print ' if (!trace::isTracingEnabled()) {'
- Tracer.invokeFunction(self, function)
+ self.doInvokeFunction(function)
if function.type is not stdapi.Void:
print ' return _result;'
else:
for arg in function.args:
if not arg.output:
self.unwrapArg(function, arg)
+ for arg in function.args:
+ if not arg.output:
self.serializeArg(function, arg)
print ' trace::localWriter.endEnter();'
self.invokeFunction(function)
self.wrapRet(function, "_result")
print ' trace::localWriter.endLeave();'
- def invokeFunction(self, function, prefix='_', suffix=''):
+ def invokeFunction(self, function):
+ self.doInvokeFunction(function)
+
+ def doInvokeFunction(self, function, prefix='_', suffix=''):
+ # Same as invokeFunction() but called both when trace is enabled or disabled.
if function.type is stdapi.Void:
result = ''
else:
def wrapRet(self, function, instance):
self.wrapValue(function.type, instance)
- def unwrapRet(self, function, instance):
- self.unwrapValue(function.type, instance)
-
def needsWrapping(self, type):
visitor = WrapDecider()
visitor.visit(type)
# Private constructor
print '%s::%s(%s * pInstance) {' % (getWrapperInterfaceName(interface), getWrapperInterfaceName(interface), interface.name)
for type, name, value in self.enumWrapperInterfaceVariables(interface):
- print ' %s = %s;' % (name, value)
+ if value is not None:
+ print ' %s = %s;' % (name, value)
print '}'
print
for arg in method.args:
if not arg.output:
self.unwrapArg(method, arg)
+ for arg in method.args:
+ if not arg.output:
self.serializeArg(method, arg)
print ' trace::localWriter.endEnter();'
print ' %s_this->%s(%s);' % (result, method.name, ', '.join([str(arg.name) for arg in method.args]))
def emit_memcpy(self, dest, src, length):
- print ' unsigned _call = trace::localWriter.beginEnter(&trace::memcpy_sig);'
+ print ' unsigned _call = trace::localWriter.beginEnter(&trace::memcpy_sig, true);'
print ' trace::localWriter.beginArg(0);'
print ' trace::localWriter.writePointer((uintptr_t)%s);' % dest
print ' trace::localWriter.endArg();'