Example #1
0
def make_proxy_impl_tmpl_body(cls):
    csname = schema.cpp2csname(cls.get_name())
    iname = schema.get_iname(cls)
    funcs = get_funcs(cls, False)
    static_funcs = []
    for func in cls.get_static_funcs():
        static_funcs.append( get_func_parts(func, 0) )

    result = []

    for func in static_funcs:
        append_xmldoc(result, func['obj'].get_comment())
        result.append('public static %(csn_retval)s %(name)s(%(csn_args_proto)s)' % func)
        result.append('{')
        result.append('    throw new NotImplementedException(); // TODO: %(csname)s.%(name)s' % { 'csname': csname, 'name' : func['name'] })
        result.append('}')
        result.append('')

    for func in funcs:
        name = func['name']
        retval = func['csn_retval']
        args = func['csn_args_proto']
        if func['csn_args'][0]['name'] == 'self':
            args = ', '.join(map(lambda x: '%s %s' % (x['type'], x['name']), func['csn_args'][1:]))

        append_xmldoc(result, func['obj'].get_comment())

        result.append('public %s %s(%s)' % (retval, name, args))
        result.append('{')
        result.append('    throw new NotImplementedException(); // TODO: %(csname)s.%(name)s' % { 'csname': csname, 'name' : func['name'] })
        result.append('}')
        result.append('')

    return result
def get_base_func(cls, slot, name, cname):
    cretval = ''
    if name == 'AddRef':
        cretval = 'void'
    elif name == 'Release':
        cretval = 'int'
    elif name == 'HasOneRef':
        cretval = 'int'
    return {
            'basefunc': True,
            'virtual': True,
            'obj': None,
            'slot': '%x' % slot,
            'name': name,
            'field_name': '_base._%s' % cname,
            'delegate_type': '%s_delegate' % cname,
            'delegate_slot': '_ds%x' % slot,
            'capi_name': cname,
            'capi_retval': cretval,
            'capi_args': ['%s* self' % cls.get_capi_name()],

            'csn_name': cname,
            'csn_retval': cretval,
            'csn_args': [ { 'type': '%s*' % cls.get_capi_name(), 'name': 'self' } ],

            'csn_args_proto': '%s* self' % cls.get_capi_name(),

            'iname': schema.get_iname(cls),
        }
Example #3
0
def get_func_parts(func, slot, is_global = False):
    virtual = isinstance(func, obj_function_virtual)
    capi_parts = func.get_capi_parts()

    csn_name = capi_parts['name']
    if not virtual:
        if is_global:
            if csn_name[0:4] == 'cef_':
                csn_name = csn_name[4:]
        else:
            csn_name = get_capi_name(func.get_name(), False, None)
            prefix = func.parent.get_capi_name()
            if prefix[-2:] == '_t':
                prefix = prefix[:-2]
            if prefix[0:3] == 'cef':
                subprefix = prefix[3:]
                pos = csn_name.find(subprefix)
                if pos >= 0:
                    csn_name = csn_name[0:pos]

    csn_args = []
    for carg in capi_parts['args']:
        type = schema.c2cs_type( carg[:carg.rindex(' ')] )
        name = schema.quote_name( carg[carg.rindex(' ')+1:] )
        csn_args.append({'name' : name, 'type' : type})

    iname = ''
    if virtual:
        iname = schema.get_iname(func.parent)

    result = {
        'basefunc': False,
        'virtual': virtual,
        'obj': func,
        'slot': '%x' % slot,
        'name': func.get_name(),
        'field_name': '_' + func.get_capi_name(),
        'delegate_type': func.get_capi_name() + '_delegate',
        'delegate_slot': '_ds%x' % slot,

        'capi_name': capi_parts['name'],
        'capi_retval': capi_parts['retval'],
        'capi_args': capi_parts['args'],

        'csn_name': csn_name,
        'csn_retval': schema.c2cs_type( capi_parts['retval'] ),
        'csn_args': csn_args,
        'csn_entrypoint': capi_parts['name'],

        'csn_args_proto': ', '.join(map(lambda x: '%s %s' % (x['type'], x['name']), csn_args)),

        'iname': iname,
        }
    return result
Example #4
0
def get_base_func(cls, slot, name, cname):
    return {
            'basefunc': True,
            'virtual': True,
            'obj': None,
            'slot': '%x' % slot,
            'name': name,
            'field_name': '_base._%s' % cname,
            'delegate_type': '%s_delegate' % cname,
            'delegate_slot': '_ds%x' % slot,
            'capi_name': cname,
            'capi_retval': 'int',
            'capi_args': ['%s* self' % cls.get_capi_name()],

            'csn_name': cname,
            'csn_retval': 'int',
            'csn_args': [ { 'type': '%s*' % cls.get_capi_name(), 'name': 'self' } ],

            'csn_args_proto': '%s* self' % cls.get_capi_name(),

            'iname': schema.get_iname(cls),
        }
Example #5
0
def make_struct_file(cls):
    body = []
    body.append('using System;')
    body.append('using System.Diagnostics.CodeAnalysis;')
    body.append('using System.Runtime.InteropServices;')
    body.append('using System.Security;')
    body.append('');

    body.append('[StructLayout(LayoutKind.Sequential, Pack = %s)]' % schema.CEF_ALIGN)
    body.append('[SuppressMessage("Microsoft.Design", "CA1049:TypesThatOwnNativeResourcesShouldBeDisposable")]')
    body.append('internal unsafe struct %s' % schema.get_iname(cls))
    body.append('{')
    body.append( indent + ('\n' + indent + indent).join( make_struct_members(cls) ) )
    body.append('}')

    return make_file_header() + \
"""namespace %(namespace)s
{
%(body)s
}
""" % {
        'namespace': schema.interop_namespace,
        'body': indent + ('\n'+indent).join(body)
      }
Example #6
0
def make_handler_g_body(cls):
    csname = schema.cpp2csname(cls.get_name())
    iname = schema.get_iname(cls)

    funcs = get_funcs(cls)

    result = []

    # this dictionary used to keep object alive even when we doesn't reference object directly, but it can be referenced only from native side
    result.append('private static Dictionary<IntPtr, %(csname)s> _roots = new Dictionary<IntPtr, %(csname)s>();' % { 'csname' : csname })
    result.append('')

    result.append('private int _refct;')
    result.append('private %s* _self;' % iname)
    # result.append('private bool _disposed;')
    result.append('')

    result.append('protected object SyncRoot { get { return this; } }')
    result.append('')

    if schema.is_reversible(cls):
        result.append('internal static %s FromNativeOrNull(%s* ptr)' % (csname, iname))
        result.append('{')
        result.append(indent + '%s value = null;' % csname)
        result.append(indent + 'bool found;')
        result.append(indent + 'lock (_roots)')
        result.append(indent + '{')
        result.append(indent + indent + 'found = _roots.TryGetValue((IntPtr)ptr, out value);')
        result.append(indent + '}')
        result.append(indent + 'return found ? value : null;')
        result.append('}')
        result.append('')

        result.append('internal static %s FromNative(%s* ptr)' % (csname, iname))
        result.append('{')
        result.append(indent + 'var value = FromNativeOrNull(ptr);')
        result.append(indent + 'if (value == null) throw ExceptionBuilder.ObjectNotFound();')
        result.append(indent + 'return value;')
        result.append('}')
        result.append('')

    for func in funcs:
        result.append('private %(iname)s.%(delegate_type)s %(delegate_slot)s;' % func)
    result.append('')

    # ctor
    result.append('protected %s()' % csname)
    result.append('{')
    result.append(indent + '_self = %s.Alloc();' % iname)
    result.append('');
    for func in funcs:
        result.append(indent + '%(delegate_slot)s = new %(iname)s.%(delegate_type)s(%(csn_name)s);' % func)
        result.append(indent + '_self->%(field_name)s = Marshal.GetFunctionPointerForDelegate(%(delegate_slot)s);' % func)
    result.append('}')
    result.append('')

    # finalizer & dispose
    result.append('~%s()' % csname)
    result.append('{')
    result.append(indent + 'Dispose(false);')
    result.append('}')
    result.append('')

    result.append('protected virtual void Dispose(bool disposing)')
    result.append('{')
    # result.append(indent + '_disposed = true;')
    result.append(indent + 'if (_self != null)')
    result.append(indent + '{')
    result.append(indent + indent + '%s.Free(_self);' % iname)
    result.append(indent + indent + '_self = null;')
    result.append(indent + '}')
    result.append('}')
    result.append('')

    # todo: this methods must throw exception if object already disposed
    # todo: verify self pointer in debug
    result.append('private int add_ref(%s* self)' % iname)
    result.append('{')
    result.append(indent + 'lock (SyncRoot)')
    result.append(indent + '{')
    result.append(indent + indent + 'var result = ++_refct;')
    result.append(indent + indent + 'if (result == 1)')
    result.append(indent + indent + '{')
    result.append(indent + indent + indent + 'lock (_roots) { _roots.Add((IntPtr)_self, this); }')
    result.append(indent + indent + '}')
    result.append(indent + indent + 'return result;')
    result.append(indent + '}')
    result.append('}')
    result.append('')

    result.append('private int release(%s* self)' % iname)
    result.append('{')
    result.append(indent + 'lock (SyncRoot)')
    result.append(indent + '{')
    result.append(indent + indent + 'var result = --_refct;')
    result.append(indent + indent + 'if (result == 0)')
    result.append(indent + indent + '{')
    result.append(indent + indent + indent + 'lock (_roots) { _roots.Remove((IntPtr)_self); }')
    result.append(indent + indent + '}')
    result.append(indent + indent + 'return result;')
    result.append(indent + '}')
    result.append('}')
    result.append('')

    result.append('private int get_refct(%s* self)' % iname)
    result.append('{')
    result.append(indent + 'return _refct;')
    result.append('}')
    result.append('')

    result.append('internal %s* ToNative()' % iname)
    result.append('{')
    result.append(indent + 'add_ref(_self);')
    result.append(indent + 'return _self;')
    result.append('}')
    result.append('')

    result.append('[Conditional("DEBUG")]')
    result.append('private void CheckSelf(%s* self)' % iname)
    result.append('{')
    result.append(indent + 'if (_self != self) throw ExceptionBuilder.InvalidSelfReference();')
    result.append('}')
    result.append('')

    return result
Example #7
0
def make_proxy_g_body(cls):
    csname = schema.cpp2csname(cls.get_name())
    iname = schema.get_iname(cls)

    result = []

    # result.append('#if DEBUG')
    # result.append('private static int _objCt;')
    # result.append('internal static int ObjCt { get { return _objCt; } }')
    # result.append('#endif')
    # result.append('')

    # static methods
    result.append('internal static %(csname)s FromNative(%(iname)s* ptr)' % { 'csname' : csname, 'iname' : iname })
    result.append('{')
    result.append(indent + 'return new %s(ptr);' % csname)
    result.append('}')
    result.append('')

    result.append('internal static %(csname)s FromNativeOrNull(%(iname)s* ptr)' % { 'csname' : csname, 'iname' : iname })
    result.append('{')
    result.append(indent + 'if (ptr == null) return null;')
    result.append(indent + 'return new %s(ptr);' % csname)
    result.append('}')
    result.append('')

    # private fields
    result.append('private %s* _self;' % iname)
    result.append('')

    # ctor
    result.append('private %(csname)s(%(iname)s* ptr)' % { 'csname' : csname, 'iname' : iname })
    result.append('{')
    result.append(indent + 'if (ptr == null) throw new ArgumentNullException("ptr");')
    result.append(indent + '_self = ptr;')
    #
    # todo: diagnostics code: Interlocked.Increment(ref _objCt);
    #
    result.append('}')
    result.append('')

    # disposable
    result.append('~%s()' % csname)
    result.append('{')
    result.append(indent + 'if (_self != null)')
    result.append(indent + '{')
    result.append(indent + indent + 'Release();')
    result.append(indent + indent + '_self = null;')
    result.append(indent + '}')
    result.append('}')
    result.append('')

    result.append('public void Dispose()')
    result.append('{')
    result.append(indent + 'if (_self != null)')
    result.append(indent + '{')
    result.append(indent + indent + 'Release();')
    result.append(indent + indent + '_self = null;')
    result.append(indent + '}')
    result.append(indent + 'GC.SuppressFinalize(this);')
    result.append('}')
    result.append('')

    result.append('internal int AddRef()')
    result.append('{')
    result.append(indent + 'return %(iname)s.add_ref(_self);' % { 'iname': iname })
    result.append('}')
    result.append('')

    result.append('internal int Release()')
    result.append('{')
    result.append(indent + 'return %(iname)s.release(_self);' % { 'iname': iname })
    result.append('}')
    result.append('')

    result.append('internal int RefCt')
    result.append('{')
    result.append(indent + 'get { return %(iname)s.get_refct(_self); }' % { 'iname': iname })
    result.append('}')
    result.append('')

    # TODO: use it only if it is really necessary!
    # result.append('internal %(iname)s* Pointer' % { 'iname' : iname })
    # result.append('{')
    # result.append(indent + 'get { return _self; }')
    # result.append('}')
    # result.append('')

    result.append('internal %(iname)s* ToNative()' % { 'iname' : iname })
    result.append('{')
    result.append(indent + 'AddRef();')
    result.append(indent + 'return _self;')
    result.append('}')

    return result
Example #8
0
def make_struct_members(cls):
    result = []

    static_funcs = []
    funcs = get_funcs(cls)

    delegate_visibility = "internal"
    if schema.is_proxy(cls):
        delegate_visibility = "private"

    for func in cls.get_static_funcs():
        static_funcs.append( get_func_parts(func, 0) )

    result.append('internal cef_base_t _base;')
    for func in funcs:
        if not func['basefunc']:
            result.append('internal IntPtr %(field_name)s;' % func)
    result.append('')

    for func in static_funcs:
        append_dllimport(result, func)

    for func in funcs:
        postfixs = schema.get_platform_retval_postfixs(func['csn_retval'])
        for px in postfixs:
            func['px'] = px
            result.append('[UnmanagedFunctionPointer(%s)]' % schema.CEF_CALLBACK)
            result.append('#if !DEBUG')
            result.append('[SuppressUnmanagedCodeSecurity]')
            result.append('#endif')
            result.append(delegate_visibility + ' delegate %(csn_retval)s%(px)s %(delegate_type)s%(px)s(%(csn_args_proto)s);' % func)
            result.append('')

    for func in funcs:
        if schema.is_proxy(cls):
            postfixs = schema.get_platform_retval_postfixs(func['csn_retval'])
            for px in postfixs:
                func['px'] = px
                result.append('// %(name)s' % func)
                result.append('private static IntPtr _p%(slot)s%(px)s;' % func)
                result.append('private static %(delegate_type)s%(px)s _d%(slot)s%(px)s;' % func)
                result.append('')
                result.append('public static %(csn_retval)s%(px)s %(csn_name)s%(px)s(%(csn_args_proto)s)' % func)
                result.append('{')
                result.append('    %(delegate_type)s%(px)s d;' % func)
                result.append('    var p = self->%(field_name)s;' % func)
                result.append('    if (p == _p%(slot)s%(px)s) { d = _d%(slot)s%(px)s; }' % func)
                result.append('    else')
                result.append('    {')
                result.append('        d = (%(delegate_type)s%(px)s)Marshal.GetDelegateForFunctionPointer(p, typeof(%(delegate_type)s%(px)s));' % func)
                result.append('        if (_p%(slot)s%(px)s == IntPtr.Zero) { _d%(slot)s%(px)s = d; _p%(slot)s%(px)s = p; }' % func)
                result.append('    }')
                args = ', '.join(map(lambda x: x['name'], func['csn_args']))
                if func['csn_retval'] == 'void':
                    result.append('    d(%s);' % args)
                else:
                    result.append('    return d(%s);' % args)
                result.append('}')
                result.append('')

    if schema.is_handler(cls):
        iname = schema.get_iname(cls)
        result.append('private static int _sizeof;')
        result.append('')
        result.append('static %s()' % iname)
        result.append('{')
        result.append(indent + '_sizeof = Marshal.SizeOf(typeof(%s));' % iname)
        result.append('}')
        result.append('')

        result.append('internal static %s* Alloc()' % iname)
        result.append('{')
        result.append(indent + 'var ptr = (%s*)Marshal.AllocHGlobal(_sizeof);' % iname)
        result.append(indent + '*ptr = new %s();' % iname)
        result.append(indent + 'ptr->_base._size = (UIntPtr)_sizeof;')
        result.append(indent + 'return ptr;')
        result.append('}')
        result.append('')

        result.append('internal static void Free(%s* ptr)' % iname)
        result.append('{')
        result.append(indent + 'Marshal.FreeHGlobal((IntPtr)ptr);')
        result.append('}')
        result.append('')

    return result
def make_proxy_g_body(cls):
    csname = schema.cpp2csname(cls.get_name())
    iname = schema.get_iname(cls)

    result = []

    # result.append('#if DEBUG')
    # result.append('private static int _objCt;')
    # result.append('internal static int ObjCt { get { return _objCt; } }')
    # result.append('#endif')
    # result.append('')

    # static methods
    result.append('internal static %(csname)s FromNative(%(iname)s* ptr)' % {
        'csname': csname,
        'iname': iname
    })
    result.append('{')
    result.append(indent + 'return new %s(ptr);' % csname)
    result.append('}')
    result.append('')

    result.append(
        'internal static %(csname)s FromNativeOrNull(%(iname)s* ptr)' % {
            'csname': csname,
            'iname': iname
        })
    result.append('{')
    result.append(indent + 'if (ptr == null) return null;')
    result.append(indent + 'return new %s(ptr);' % csname)
    result.append('}')
    result.append('')

    # private fields
    result.append('private %s* _self;' % iname)
    result.append('')

    # ctor
    result.append('private %(csname)s(%(iname)s* ptr)' % {
        'csname': csname,
        'iname': iname
    })
    result.append('{')
    result.append(indent +
                  'if (ptr == null) throw new ArgumentNullException("ptr");')
    result.append(indent + '_self = ptr;')
    #
    # todo: diagnostics code: Interlocked.Increment(ref _objCt);
    #
    result.append('}')
    result.append('')

    # disposable
    result.append('~%s()' % csname)
    result.append('{')
    result.append(indent + 'if (_self != null)')
    result.append(indent + '{')
    result.append(indent + indent + 'Release();')
    result.append(indent + indent + '_self = null;')
    result.append(indent + '}')
    result.append('}')
    result.append('')

    result.append('public void Dispose()')
    result.append('{')
    result.append(indent + 'if (_self != null)')
    result.append(indent + '{')
    result.append(indent + indent + 'Release();')
    result.append(indent + indent + '_self = null;')
    result.append(indent + '}')
    result.append(indent + 'GC.SuppressFinalize(this);')
    result.append('}')
    result.append('')

    result.append('internal int AddRef()')
    result.append('{')
    result.append(indent +
                  'return %(iname)s.add_ref(_self);' % {'iname': iname})
    result.append('}')
    result.append('')

    result.append('internal int Release()')
    result.append('{')
    result.append(indent +
                  'return %(iname)s.release(_self);' % {'iname': iname})
    result.append('}')
    result.append('')

    result.append('internal int RefCt')
    result.append('{')
    result.append(indent + 'get { return %(iname)s.get_refct(_self); }' %
                  {'iname': iname})
    result.append('}')
    result.append('')

    # TODO: use it only if it is really necessary!
    # result.append('internal %(iname)s* Pointer' % { 'iname' : iname })
    # result.append('{')
    # result.append(indent + 'get { return _self; }')
    # result.append('}')
    # result.append('')

    result.append('internal %(iname)s* ToNative()' % {'iname': iname})
    result.append('{')
    result.append(indent + 'AddRef();')
    result.append(indent + 'return _self;')
    result.append('}')

    return result
Example #10
0
def make_struct_members(cls):
    result = []

    static_funcs = []
    funcs = get_funcs(cls)

    delegate_visibility = "internal"
    if schema.is_proxy(cls):
        delegate_visibility = "private"

    for func in cls.get_static_funcs():
        static_funcs.append(get_func_parts(func, 0))

    result.append('internal cef_base_t _base;')
    for func in funcs:
        if not func['basefunc']:
            result.append('internal IntPtr %(field_name)s;' % func)
    result.append('')

    for func in static_funcs:
        append_dllimport(result, func)

    for func in funcs:
        postfixs = schema.get_platform_retval_postfixs(func['csn_retval'])
        for px in postfixs:
            func['px'] = px
            result.append('[UnmanagedFunctionPointer(%s)]' %
                          schema.CEF_CALLBACK)
            result.append('#if !DEBUG')
            result.append('[SuppressUnmanagedCodeSecurity]')
            result.append('#endif')
            result.append(
                delegate_visibility +
                ' delegate %(csn_retval)s%(px)s %(delegate_type)s%(px)s(%(csn_args_proto)s);'
                % func)
            result.append('')

    for func in funcs:
        if schema.is_proxy(cls):
            postfixs = schema.get_platform_retval_postfixs(func['csn_retval'])
            for px in postfixs:
                func['px'] = px
                result.append('// %(name)s' % func)
                result.append('private static IntPtr _p%(slot)s%(px)s;' % func)
                result.append(
                    'private static %(delegate_type)s%(px)s _d%(slot)s%(px)s;'
                    % func)
                result.append('')
                result.append(
                    'public static %(csn_retval)s%(px)s %(csn_name)s%(px)s(%(csn_args_proto)s)'
                    % func)
                result.append('{')
                result.append('    %(delegate_type)s%(px)s d;' % func)
                result.append('    var p = self->%(field_name)s;' % func)
                result.append(
                    '    if (p == _p%(slot)s%(px)s) { d = _d%(slot)s%(px)s; }'
                    % func)
                result.append('    else')
                result.append('    {')
                result.append(
                    '        d = (%(delegate_type)s%(px)s)Marshal.GetDelegateForFunctionPointer(p, typeof(%(delegate_type)s%(px)s));'
                    % func)
                result.append(
                    '        if (_p%(slot)s%(px)s == IntPtr.Zero) { _d%(slot)s%(px)s = d; _p%(slot)s%(px)s = p; }'
                    % func)
                result.append('    }')
                args = ', '.join(map(lambda x: x['name'], func['csn_args']))
                if func['csn_retval'] == 'void':
                    result.append('    d(%s);' % args)
                else:
                    result.append('    return d(%s);' % args)
                result.append('}')
                result.append('')

    if schema.is_handler(cls):
        iname = schema.get_iname(cls)
        result.append('private static int _sizeof;')
        result.append('')
        result.append('static %s()' % iname)
        result.append('{')
        result.append(indent + '_sizeof = Marshal.SizeOf(typeof(%s));' % iname)
        result.append('}')
        result.append('')

        result.append('internal static %s* Alloc()' % iname)
        result.append('{')
        result.append(indent +
                      'var ptr = (%s*)Marshal.AllocHGlobal(_sizeof);' % iname)
        result.append(indent + '*ptr = new %s();' % iname)
        result.append(indent + 'ptr->_base._size = (UIntPtr)_sizeof;')
        result.append(indent + 'return ptr;')
        result.append('}')
        result.append('')

        result.append('internal static void Free(%s* ptr)' % iname)
        result.append('{')
        result.append(indent + 'Marshal.FreeHGlobal((IntPtr)ptr);')
        result.append('}')
        result.append('')

    return result
Example #11
0
def get_func_parts(func, slot, is_global=False):
    virtual = isinstance(func, obj_function_virtual)
    capi_parts = func.get_capi_parts()

    csn_name = capi_parts['name']
    if not virtual:
        if is_global:
            if csn_name[0:4] == 'cef_':
                csn_name = csn_name[4:]
        else:
            csn_name = get_capi_name(func.get_name(), False, None)
            prefix = func.parent.get_capi_name()
            if prefix[-2:] == '_t':
                prefix = prefix[:-2]
            if prefix[0:3] == 'cef':
                subprefix = prefix[3:]
                pos = csn_name.find(subprefix)
                if pos >= 0:
                    csn_name = csn_name[0:pos]

    csn_args = []
    for carg in capi_parts['args']:
        type = schema.c2cs_type(carg[:carg.rindex(' ')])
        name = schema.quote_name(carg[carg.rindex(' ') + 1:])
        csn_args.append({'name': name, 'type': type})

    iname = ''
    if virtual:
        iname = schema.get_iname(func.parent)

    result = {
        'basefunc':
        False,
        'virtual':
        virtual,
        'obj':
        func,
        'slot':
        '%x' % slot,
        'name':
        func.get_name(),
        'field_name':
        '_' + func.get_capi_name(),
        'delegate_type':
        func.get_capi_name() + '_delegate',
        'delegate_slot':
        '_ds%x' % slot,
        'capi_name':
        capi_parts['name'],
        'capi_retval':
        capi_parts['retval'],
        'capi_args':
        capi_parts['args'],
        'csn_name':
        csn_name,
        'csn_retval':
        schema.c2cs_type(capi_parts['retval']),
        'csn_args':
        csn_args,
        'csn_entrypoint':
        capi_parts['name'],
        'csn_args_proto':
        ', '.join(map(lambda x: '%s %s' % (x['type'], x['name']), csn_args)),
        'iname':
        iname,
    }
    return result
def make_handler_g_body(cls):
    csname = schema.cpp2csname(cls.get_name())
    iname = schema.get_iname(cls)

    funcs = get_funcs(cls)

    result = []

    # this dictionary used to keep object alive even when we doesn't reference object directly, but it can be referenced only from native side
    result.append(
        'private static Dictionary<IntPtr, %(csname)s> _roots = new Dictionary<IntPtr, %(csname)s>();'
        % {'csname': csname})
    result.append('')

    result.append('private int _refct;')
    result.append('private %s* _self;' % iname)
    # result.append('private bool _disposed;')
    result.append('')

    result.append('protected object SyncRoot { get { return this; } }')
    result.append('')

    if schema.is_reversible(cls):
        result.append('internal static %s FromNativeOrNull(%s* ptr)' %
                      (csname, iname))
        result.append('{')
        result.append(indent + '%s value = null;' % csname)
        result.append(indent + 'bool found;')
        result.append(indent + 'lock (_roots)')
        result.append(indent + '{')
        result.append(indent + indent +
                      'found = _roots.TryGetValue((IntPtr)ptr, out value);')
        result.append(indent + '}')
        result.append(indent + 'return found ? value : null;')
        result.append('}')
        result.append('')

        result.append('internal static %s FromNative(%s* ptr)' %
                      (csname, iname))
        result.append('{')
        result.append(indent + 'var value = FromNativeOrNull(ptr);')
        result.append(
            indent +
            'if (value == null) throw ExceptionBuilder.ObjectNotFound();')
        result.append(indent + 'return value;')
        result.append('}')
        result.append('')

    for func in funcs:
        result.append(
            'private %(iname)s.%(delegate_type)s %(delegate_slot)s;' % func)
    result.append('')

    # ctor
    result.append('protected %s()' % csname)
    result.append('{')
    result.append(indent + '_self = %s.Alloc();' % iname)
    result.append('')
    for func in funcs:
        result.append(
            indent +
            '%(delegate_slot)s = new %(iname)s.%(delegate_type)s(%(csn_name)s);'
            % func)
        result.append(
            indent +
            '_self->%(field_name)s = Marshal.GetFunctionPointerForDelegate(%(delegate_slot)s);'
            % func)
    result.append('}')
    result.append('')

    # finalizer & dispose
    result.append('~%s()' % csname)
    result.append('{')
    result.append(indent + 'Dispose(false);')
    result.append('}')
    result.append('')

    if schema.is_autodispose(cls):
        result.append('private void Dispose()')
        result.append('{')
        result.append(indent + 'Dispose(true);')
        result.append(indent + 'GC.SuppressFinalize(this);')
        result.append('}')
        result.append('')

    result.append('protected virtual void Dispose(bool disposing)')
    result.append('{')
    # result.append(indent + '_disposed = true;')
    result.append(indent + 'if (_self != null)')
    result.append(indent + '{')
    result.append(indent + indent + '%s.Free(_self);' % iname)
    result.append(indent + indent + '_self = null;')
    result.append(indent + '}')
    result.append('}')
    result.append('')

    # todo: this methods must throw exception if object already disposed
    # todo: verify self pointer in debug
    result.append('private void add_ref(%s* self)' % iname)
    result.append('{')
    result.append(indent + 'lock (SyncRoot)')
    result.append(indent + '{')
    result.append(indent + indent + 'var result = ++_refct;')
    result.append(indent + indent + 'if (result == 1)')
    result.append(indent + indent + '{')
    result.append(indent + indent + indent +
                  'lock (_roots) { _roots.Add((IntPtr)_self, this); }')
    result.append(indent + indent + '}')
    result.append(indent + '}')
    result.append('}')
    result.append('')

    result.append('private int release(%s* self)' % iname)
    result.append('{')
    result.append(indent + 'lock (SyncRoot)')
    result.append(indent + '{')
    result.append(indent + indent + 'var result = --_refct;')
    result.append(indent + indent + 'if (result == 0)')
    result.append(indent + indent + '{')
    result.append(indent + indent + indent +
                  'lock (_roots) { _roots.Remove((IntPtr)_self); }')
    if schema.is_autodispose(cls):
        result.append(indent + indent + indent + 'Dispose();')
    result.append(indent + indent + indent + 'return 1;')
    result.append(indent + indent + '}')
    result.append(indent + indent + 'return 0;')
    result.append(indent + '}')
    result.append('}')
    result.append('')

    result.append('private int has_one_ref(%s* self)' % iname)
    result.append('{')
    result.append(indent + 'lock (SyncRoot) { return _refct == 1 ? 1 : 0; }')
    result.append('}')
    result.append('')

    result.append('internal %s* ToNative()' % iname)
    result.append('{')
    result.append(indent + 'add_ref(_self);')
    result.append(indent + 'return _self;')
    result.append('}')
    result.append('')

    result.append('[Conditional("DEBUG")]')
    result.append('private void CheckSelf(%s* self)' % iname)
    result.append('{')
    result.append(
        indent +
        'if (_self != self) throw ExceptionBuilder.InvalidSelfReference();')
    result.append('}')
    result.append('')

    return result
def make_proxy_g_body(cls):
    csname = schema.cpp2csname(cls.get_name())
    iname = schema.get_iname(cls)

    result = []

    # result.append('#if DEBUG')
    # result.append('private static int _objCt;')
    # result.append('internal static int ObjCt { get { return _objCt; } }')
    # result.append('#endif')
    # result.append('')

    # static methods
    result.append('internal static %(csname)s FromNative(%(iname)s* ptr)' % {
        'csname': csname,
        'iname': iname
    })
    result.append('{')
    result.append(indent + 'return new %s(ptr);' % csname)
    result.append('}')
    result.append('')

    result.append(
        'internal static %(csname)s FromNativeOrNull(%(iname)s* ptr)' % {
            'csname': csname,
            'iname': iname
        })
    result.append('{')
    result.append(indent + 'if (ptr == null) return null;')
    result.append(indent + 'return new %s(ptr);' % csname)
    result.append('}')
    result.append('')

    # private fields
    result.append('private %s* _self;' % iname)
    result.append('')

    # ctor
    result.append('private %(csname)s(%(iname)s* ptr)' % {
        'csname': csname,
        'iname': iname
    })
    result.append('{')
    result.append(indent +
                  'if (ptr == null) throw new ArgumentNullException("ptr");')
    result.append(indent + '_self = ptr;')
    #
    # todo: diagnostics code: Interlocked.Increment(ref _objCt);
    #
    result.append('}')
    result.append('')

    isRefCounted = cls.get_parent_capi_name() == "cef_base_ref_counted_t"
    isScoped = cls.get_parent_capi_name() == "cef_base_scoped_t"

    if isRefCounted:
        # disposable
        result.append('~%s()' % csname)
        result.append('{')
        result.append(indent + 'if (_self != null)')
        result.append(indent + '{')
        result.append(indent + indent + 'Release();')
        result.append(indent + indent + '_self = null;')
        result.append(indent + '}')
        result.append('}')
        result.append('')

        result.append('public void Dispose()')
        result.append('{')
        result.append(indent + 'if (_self != null)')
        result.append(indent + '{')
        result.append(indent + indent + 'Release();')
        result.append(indent + indent + '_self = null;')
        result.append(indent + '}')
        result.append(indent + 'GC.SuppressFinalize(this);')
        result.append('}')
        result.append('')

        result.append('internal void AddRef()')
        result.append('{')
        result.append(indent + '%(iname)s.add_ref(_self);' % {'iname': iname})
        result.append('}')
        result.append('')

        result.append('internal bool Release()')
        result.append('{')
        result.append(indent + 'return %(iname)s.release(_self) != 0;' %
                      {'iname': iname})
        result.append('}')
        result.append('')

        result.append('internal bool HasOneRef')
        result.append('{')
        result.append(indent +
                      'get { return %(iname)s.has_one_ref(_self) != 0; }' %
                      {'iname': iname})
        result.append('}')
        result.append('')
    elif isScoped:
        result.append("// FIXME: code for CefBaseScoped is not generated")
        result.append("")
    else:
        raise Exception("Unsupported base class name.")

    # TODO: use it only if it is really necessary!
    # result.append('internal %(iname)s* Pointer' % { 'iname' : iname })
    # result.append('{')
    # result.append(indent + 'get { return _self; }')
    # result.append('}')
    # result.append('')

    result.append('internal %(iname)s* ToNative()' % {'iname': iname})
    result.append('{')
    if isRefCounted:
        result.append(indent + 'AddRef();')
    result.append(indent + 'return _self;')
    result.append('}')

    return result