def vcall(name, args, ci): """ \return the IR for a non-static Babel virtual method call """ try: cdecl = ci.epv.find_method(name) epv_type = ci.epv.get_type() epv = ir.Get_struct_item(ci.obj, ir.Deref(args[0]), ir.Struct_item(epv_type, 'd_epv')) except: if False: # FIXME no_contracts and no_hooks: return ir.Call('_'.join(ci.co.qualified_name + [name]), args) else: cdecl = ci.epv.find_static_method(name) epv_type = ci.epv.get_sepv_type() epv = '_getSEPV()' # this is part of an ugly hack to make sure that self is # dereferenced as self->d_object (by setting attr of self to the # unused value of 'pure') if ci.co.is_interface() and args: _, attrs, type_, id_, arguments, doc = cdecl _, attrs0, mode0, type0, name0 = arguments[0] arguments = [ir.Arg([ir.pure], mode0, type0, name0)] + arguments[1:] cdecl = ir.Fn_decl(attrs, type_, id_, arguments, doc) return ir.Call( ir.Deref( ir.Get_struct_item( epv_type, ir.Deref(epv), ir.Struct_item(ir.Pointer_type(cdecl), 'f_' + name))), args)
def build_function_call(ci, cdecl, static): ''' Build an IR expression that consists of the EPV lookup for a possibly virtual function call using Babel IOR. ''' #if final: # final : Final methods are the opposite of virtual. While # they may still be inherited by child classes, they # cannot be overridden. # static call #The problem with this is that e.g. C++ symbols usere different names #We should modify Babel to generate __attribute__ ((weak, alias ("__entry"))) # callee = '_'.join(['impl']+symbol_table.prefix+[ci.epv.name,Name]) if static: # static : Static methods are sometimes called "class # methods" because they are part of a class, but do not # depend on an object instance. In non-OO languages, this # means that the typical first argument of an instance is # removed. In OO languages, these are mapped directly to # an Java or C++ static method. epv_type = ci.epv.get_type() obj_type = ci.obj callee = ir.Get_struct_item( epv_type, ir.Deref(ir.Call('_getSEPV', [])), ir.Struct_item(ir.Pointer_type(cdecl), 'f_' + ir.fn_decl_id(cdecl))) else: # dynamic virtual method call epv_type = ci.epv.get_type() obj_type = ci.obj callee = ir.Deref( ir.Get_struct_item( epv_type, ir.Deref( ir.Get_struct_item(obj_type, ir.Deref('self'), ir.Struct_item(epv_type, 'd_epv'))), ir.Struct_item(ir.Pointer_type(cdecl), 'f_' + ir.fn_decl_id(cdecl)))) return callee
def reverse_expr(n, datatype): 'b_i = a_{n-i}' def item(name): return ir.Struct_item(ir.Primitive_type(datatype), (name)) t = ir.Struct(ir.Scoped_id([("s")], ('Vector'), ''), [ir.Struct_item(ir.Primitive_type(datatype), ('m%d'%i)) for i in range(1, n+1)], '') revs = [ir.Stmt(ir.Set_struct_item(t, (ir.deref, "b"), item('m%d'%i), ir.Get_struct_item(t, (ir.deref, "a"), item('m%d'%(n-i+1))))) for i in range(1, n+1)] return revs+[ir.Stmt(ir.Return(retval(n, datatype)))]
def get_ir(self): """ return an s-expression of the EPV declaration """ self.finalized = True name = ir.Scoped_id(self.symbol_table.prefix, self.name + '__epv', '') return ir.Struct(name, [ ir.Struct_item(itype, iname) for itype, iname in map(get_type_name, self.methods) ], 'Entry Point Vector (EPV)')
def get_pre_epv_ir(self): """ return an s-expression of the pre_EPV declaration """ self.finalized = True name = ir.Scoped_id(self.symbol_table.prefix, self.name + '__pre_epv', '') elems = [ ir.Struct_item(itype, iname) for itype, iname in map(get_type_name, self.pre_methods) ] if elems == []: elems = [self.nonempty] return ir.Struct(name, elems, 'Pre Hooks Entry Point Vector (pre_EPV)')
def get_sepv_ir(self): """ return an s-expression of the SEPV declaration """ if not self.has_static_methods: return '' self.finalized = True name = ir.Scoped_id(self.symbol_table.prefix, self.name + '__sepv', '') return ir.Struct(name, [ ir.Struct_item(itype, iname) for itype, iname in map(get_type_name, self.static_methods) ], 'Static Entry Point Vector (SEPV)')
def const_access_expr(n, datatype): def add(a, b): return ir.Plus(a, b) def item(name): return ir.Struct_item(ir.Primitive_type(datatype), (name)) t = ir.Struct(ir.Scoped_id([("s")], ('Vector'), ''), [ir.Struct_item(ir.Primitive_type(datatype), ('m%d'%i)) for i in range(1, n+1)], '') e = reduce(add, map(lambda i: ("*", ir.Get_struct_item(t, (ir.deref, "a"), item('m%d'%(i%n+1))), ir.Get_struct_item(t, (ir.deref, "b"), item('m%d'%(i%n+1)))), range(1, 129))) return ir.Stmt(ir.Return(e))
def dotproduct_expr(n, datatype): def add(a, b): return ir.Plus(a, b) def item(name): return ir.Struct_item(ir.Primitive_type(datatype), (name)) a = ir.Struct(ir.Scoped_id([("s")], ('Vector'), ''), [ir.Struct_item(ir.Primitive_type(datatype), ('m%d'%i)) for i in range(1, n+1)], '') b = a e = reduce(add, map(lambda i: ("*", ir.Get_struct_item(a, (ir.deref, "a"), 'm%d'%i), ir.Get_struct_item(b, (ir.deref, "b"), 'm%d'%i)), range(1, n+1))) return ir.Stmt(ir.Return(e))
def get_post_sepv_ir(self): """ return an s-expression of the post_SEPV declaration """ if not self.has_static_methods: return '' self.finalized = True name = ir.Scoped_id(self.symbol_table.prefix, self.name + '__post_sepv', '') if self.static_post_methods: entries = [ ir.Struct_item(itype, iname) for itype, iname in map( get_type_name, self.static_post_methods) ] else: entries = [self.nonempty] return ir.Struct(name, entries, 'Post Hooks Entry Point Vector (post_EPV)')
def item(name): return ir.Struct_item(ir.Primitive_type(datatype), (name))
def get_sepv_ir(self): """ return an s-expression of the SEPV declaration """ if not self.has_static_methods: return '' self.finalized = True name = ir.Scoped_id(self.symbol_table.prefix, self.name + '__sepv', '') return ir.Struct(name, [ ir.Struct_item(itype, iname) for itype, iname in map(get_type_name, self.static_methods) ], 'Static Entry Point Vector (SEPV)') nonempty = ir.Struct_item(ir.pt_char, 'd_not_empty') def get_pre_epv_ir(self): """ return an s-expression of the pre_EPV declaration """ self.finalized = True name = ir.Scoped_id(self.symbol_table.prefix, self.name + '__pre_epv', '') elems = [ ir.Struct_item(itype, iname) for itype, iname in map(get_type_name, self.pre_methods) ] if elems == []: elems = [self.nonempty] return ir.Struct(name, elems, 'Pre Hooks Entry Point Vector (pre_EPV)')
def gen_inherits(baseclass): inherits.append(ir.Struct_item( babel.ir_object_type(baseclass[1], baseclass[2]) [1], # not a pointer, it is an embedded struct 'd_'+str.lower(babel.qual_id(baseclass))))
def gen_default_methods(self, cls, has_contracts, ci): """ Generate default Babel object methods such as _cast() Also generates other IOR data structures such as the _object and the controls and statistics struct. """ def unscope((struct, scoped_id, items, doc)): return struct, c_gen(scoped_id), items, doc def builtin(t, name, args): ci.epv.add_method( sidlir.Method(t, sidlir.Method_name(name, ''), [], args, [], [], [], [], 'Implicit built-in method: '+name)) def static_builtin(t, name, args): ci.epv.add_method( sidlir.Method(t, sidlir.Method_name(name, ''), [sidlir.static], args, [], [], [], [], 'Implicit built-in method: '+name)) def inarg(t, name): return sidlir.Arg([], sidlir.in_, t, name) # Implicit Built-in methods builtin(sidlir.pt_opaque, '_cast', [inarg(sidlir.pt_string, 'name')]) builtin(sidlir.void, '_delete', []) builtin(sidlir.void, '_exec', [ inarg(sidlir.pt_string, 'methodName'), inarg(babel.object_type(['sidl', 'rmi'], 'Call'), 'inArgs'), inarg(babel.object_type(['sidl', 'rmi'], 'Return'), 'outArgs')]) builtin(sidlir.pt_string, '_getURL', []) builtin(sidlir.void, '_raddRef', []) builtin(sidlir.pt_bool, '_isRemote', []) builtin(sidlir.void, '_set_hooks', [inarg(sidlir.pt_bool, 'enable')]) builtin(sidlir.void, '_set_contracts', [ inarg(sidlir.pt_bool, 'enable'), inarg(sidlir.pt_string, 'enfFilename'), inarg(sidlir.pt_bool, 'resetCounters')], ) builtin(sidlir.void, '_dump_stats', [inarg(sidlir.pt_string, 'filename'), inarg(sidlir.pt_string, 'prefix')]) if not cls.is_interface(): builtin(sidlir.void, '_ctor', []) builtin(sidlir.void, '_ctor2', [(sidlir.arg, [], sidlir.in_, ir.void_ptr, 'private_data')]) builtin(sidlir.void, '_dtor', []) builtin(sidlir.void, '_load', []) static_builtin(sidlir.void, '_set_hooks_static', [inarg(sidlir.pt_bool, 'enable')]) static_builtin(sidlir.void, '_set_contracts_static', [ inarg(sidlir.pt_bool, 'enable'), inarg(sidlir.pt_string, 'enfFilename'), inarg(sidlir.pt_bool, 'resetCounters')], ) static_builtin(sidlir.void, '_dump_stats_static', [inarg(sidlir.pt_string, 'filename'), inarg(sidlir.pt_string, 'prefix')]) prefix = ci.epv.symbol_table.prefix # cstats cstats = [] contract_cstats = [] ci.methodcstats = [] num_methods = cls.number_of_methods() if has_contracts: ci.methodcstats = ir.Struct( ir.Scoped_id(prefix, ci.epv.name+'__method_cstats', ''), [ir.Struct_item(ir.Typedef_type('int32_t'), 'tries'), ir.Struct_item(ir.Typedef_type('int32_t'), 'successes'), ir.Struct_item(ir.Typedef_type('int32_t'), 'failures'), ir.Struct_item(ir.Typedef_type('int32_t'), 'nonvio_exceptions')], '') contract_cstats.append(ir.Struct_item(ir.Typedef_type('sidl_bool'), 'enabled')) contract_cstats.append(ir.Struct_item( ci.methodcstats, 'method_cstats[%d]'%num_methods)) ci.cstats = ir.Struct( ir.Scoped_id(prefix, ci.epv.name+'__cstats', ''), [ir.Struct_item(ir.Typedef_type('sidl_bool'), 'use_hooks')]+contract_cstats, 'The controls and statistics structure') # @class@__object inherits = [] def gen_inherits(baseclass): inherits.append(ir.Struct_item( babel.ir_object_type(baseclass[1], baseclass[2]) [1], # not a pointer, it is an embedded struct 'd_'+str.lower(babel.qual_id(baseclass)))) with_sidl_baseclass = not cls.is_interface() and cls.qualified_name <> ['sidl', 'BaseClass'] # pointers to the base class' EPV par = cls.get_parent() if par and par.is_class(): gen_inherits(par.get_scoped_id()) with_sidl_baseclass = False # pointers to the implemented interface's EPV if not cls.is_interface(): for impl in cls.get_unique_interfaces(): if impl <> (sidlir.scoped_id, ('sidl',), 'BaseInterface', ''): gen_inherits(impl) baseclass = [] if with_sidl_baseclass: baseclass.append( ir.Struct_item(ir.Struct('sidl_BaseClass__object', [],''), 'd_sidl_baseclass')) if ior_template.generateContractEPVs(ci.co): cstats = [ir.Struct_item(unscope(ci.cstats), 'd_cstats')] ior_template.braid_config = self.config epv = [ir.Struct_item(ir.Pointer_type(unscope(ci.epv.get_type())), 'd_epv')] bepv = [ir.Struct_item(ir.Pointer_type(unscope(ci.epv.get_type())), 'd_bepv')] \ if ior_template.generateBaseEPVAttr(ci.co) else [] ci.obj = \ ir.Struct(ir.Scoped_id(prefix, ci.epv.name+'__object', ''), baseclass+ inherits+ epv+ bepv+ cstats+ [ir.Struct_item(ir.Pointer_type(ir.pt_void), 'd_object' if cls.is_interface() else 'd_data')], 'The class object structure') ci.external = \ ir.Struct(ir.Scoped_id(prefix, ci.epv.name+'__external', ''), ([ir.Struct_item(ir.Pointer_type(ir.Fn_decl([], ir.Pointer_type(ci.obj), 'createObject', [ ir.Arg([], ir.inout, ir.void_ptr, 'ddata'), ir.Arg([], sidlir.out, babel.ir_exception_type(), '_ex')], '')), 'createObject')] if not cls.is_abstract else []) + ([ir.Struct_item(ir.Pointer_type(ir.Fn_decl([], ir.Pointer_type(unscope(ci.epv.get_sepv_type())), 'getStaticEPV', [], '')), 'getStaticEPV')] if cls.has_static_methods else []) + [ir.Struct_item( ir.Pointer_type( ir.Fn_decl([], ir.Pointer_type(ir.Struct('sidl_BaseClass__epv', [],'')), 'getSuperEPV', [], '')), 'getSuperEPV'), ir.Struct_item(ir.pt_int, 'd_ior_major_version'), ir.Struct_item(ir.pt_int, 'd_ior_minor_version') ], 'The static class object structure')