[omniORB] Virtual Function for the Subs
Malge Nishant
MNishant@quark.co.in
Thu Feb 27 06:18:02 2003
This message is in MIME format. Since your mail reader does not understand
this format, some or all of this message may not be legible.
------_=_NextPart_000_01C2DE26.5A5EF010
Content-Type: text/plain;
charset="iso-8859-1"
hi,
The switch -Wbvirtual_objref is not working with current version.
This option is not being checked while generating _objref class.
I have changed src/lib/omniORB/omniidl_be/cxx/iface.py please validate
-->class _objref_I(Class):
..
..
--> for method in self.methods():
--> methods.append(method.hh())
Changed the above two lines to -
<--class _objref_I(Class):
..
..
<-- for method in self.methods():
<-- if config.state['Virtual Objref Methods']:
<-- methods.append(method.hh(virtual = 1, pure = 0))
<-- else:
<-- methods.append(method.hh())
Now this option is working fine.
Please find iface.py attached with this mail.
Regards
Nishant
-----Original Message-----
From: Duncan Grisby [mailto:duncan@grisby.org]
Sent: Tuesday, February 25, 2003 1:42 AM
To: Malge Nishant
Cc: omniorb-list@omniorb-support.com
Subject: Re: [omniORB] Virtual Function for the Subs
On Monday 24 February, Malge Nishant wrote:
> What is the reason that omniORB doesn't provide mapping for client
> stubs with Virtual Functions? All the ( Mapped IDL )functions in stub
class
> are non-virtual. ORBacus & VisiBroker does so. This helps us to add one
more
> abstraction layer over the client stubs and add some logic too.
> Or is it as per the C++ Mapping specification?
The C++ mapping doesn't have anything to say about the matter, so
either is permitted. omniORB doesn't use virtual functions by default,
since they are slightly slower than non-virtual ones, and most people
have no reason to need them.
As luck would have it, omniidl can output the functions as virtual.
Just use the (undocumented) -Wbvirtual_objref switch after -bcxx.
Cheers,
Duncan.
--
-- Duncan Grisby --
-- duncan@grisby.org --
-- http://www.grisby.org --
------_=_NextPart_000_01C2DE26.5A5EF010
Content-Type: application/octet-stream;
name="iface.py"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="iface.py"
# -*- python -*-
# Package : omniidl
# iface.py Created on: 2000/8/10
# Author : David Scott (djs)
#
# Copyright (C) 2000 AT&T Laboratories Cambridge
#
# This file is part of omniidl.
#
# omniidl is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
#
# Description:
# =20
# Code associated with IDL interfaces
# $Id: iface.py,v 1.2 2002/12/13 05:40:02 nishant Exp $
# $Log: iface.py,v $
# Revision 1.2 2002/12/13 05:40:02 nishant
# updated to 4.0.1
#
# Revision 1.1.4.11 2002/08/16 15:56:27 dgrisby
# Bug in generated code with evil IDL that uses the same parameter
# names as type names.
#
# Revision 1.1.4.10 2001/11/08 16:33:51 dpg1
# Local servant POA shortcut policy.
#
# Revision 1.1.4.9 2001/11/07 15:45:53 dpg1
# Faster _ptrToInterface/_ptrToObjRef in common cases.
#
# Revision 1.1.4.8 2001/08/15 10:26:10 dpg1
# New object table behaviour, correct POA semantics.
#
# Revision 1.1.4.7 2001/07/25 13:40:52 dpg1
# Suppress compiler warning about unused variable in _dispatch() for
# empty interfaces.
#
# Revision 1.1.4.6 2001/07/25 11:42:15 dpg1
# Generate correct code for operation parameters whose names clash with
# C++ keywords.
#
# Revision 1.1.4.5 2001/06/08 17:12:13 dpg1
# Merge all the bug fixes from omni3_develop.
#
# Revision 1.1.4.4 2001/01/25 13:09:11 sll
# Fixed up cxx backend to stop it from dying when a relative
# path name is given to the -p option of omniidl.
#
# Revision 1.1.4.3 2000/11/07 18:27:51 sll
# Pass environment to out_objrefcall.
#
# Revision 1.1.4.2 2000/11/03 19:30:21 sll
# Rationalise code generation. Consolidate all code that use call =
descriptors
# into the CallDescriptor class.
#
# Revision 1.1.4.1 2000/10/12 15:37:47 sll
# Updated from omni3_1_develop.
#
# Revision 1.1.2.2 2000/09/14 16:03:02 djs
# Remodularised C++ descriptor name generator
# Bug in listing all inherited interfaces if one is a forward
# repoID munging function now handles #pragma ID in bootstrap.idl
# Naming environments generating code now copes with new IDL AST types
# Modified type utility functions
# Minor tidying
#
# Revision 1.1.2.1 2000/08/21 11:34:34 djs
# Lots of omniidl/C++ backend changes
#
# o Keep related code in one place
# o Expose internals at a finer granularity than before (useful for
# overriding one aspect (eg _objref class for AMI))
import string
from omniidl import idlast, idltype
from omniidl_be.cxx import types, id, call, ast, cxx, output, config, =
descriptor
# from omniidl_be.cxx import header
# from omniidl_be.cxx import skel
# XXX it seems that the above import fails when this file is import by
# cxx.header.defs AND a relative patch -p argument is given to =
omniidl
# Use the following import works.
import omniidl_be.cxx.skel
import omniidl_be.cxx.header
# Interface is a wrapper around an IDL interface
# .callables(): get a list of Callable objects representing the =
operations
# and attributes
# .inherits(): get a list of all directly inherited interfaces
# .allInherits(): get all inherited interfaces (using a breadth first =
search)
# .name(): return the IDL fully scoped name (as an id.Name)
# .environment(): returns the IDL environment where this interface was
# declared
class Interface:
"""Wrapper around an IDL interface"""
def __init__(self, node):
self._node =3D node
self._environment =3D id.lookup(node)
self._node_name =3D id.Name(node.scopedName())
def callables(self):
"""Return a list of Callable objects representing the combined =
operations
and attributes for this interface"""
=20
if hasattr(self, "_callables"):
return self._callables
=20
# build a list of all the Callable objects
# The old backend processed all operations first
# (FIXME: duplicate for the sake of easy checking)
self._callables =3D []
for c in self._node.callables():
if isinstance(c, idlast.Operation):
self._callables.append(call.operation(self, c))
=20
for c in self._node.callables():
if isinstance(c, idlast.Attribute):
self._callables =3D self._callables + =
call.read_attributes(self, c)
if c.readonly(): continue
self._callables =3D self._callables + =
call.write_attributes(self, c)
=20
return self._callables
def inherits(self):
return map(lambda x:Interface(x), self._node.inherits())
def allInherits(self):
return map(lambda x:Interface(x), ast.allInherits(self._node))
def name(self):
return self._node_name
=20
def environment(self):
return self._environment
=20
=20
_classes =3D {}
_proxy_call_descriptors =3D {}
def instance(name):
if _classes.has_key(name):
return _classes[name]
instance =3D eval(name)
_classes[name] =3D instance
return instance
def register_class(name, cl):
_classes[name] =3D cl
# Class associated with an IDL interface.
# .interface(): return the associated Interface object
# .methods(): return a list of Method objects
# .environment(): return the IDL environment associated with the =
interface
class Class(cxx.Class):
def __init__(self, interface):
assert isinstance(interface, Interface)
cxx.Class.__init__(self, interface.name())
=20
self._interface =3D interface
self._environment =3D interface.environment()
self._methods =3D []
self._callables =3D {}
def interface(self): return self._interface
def methods(self): return self._methods
def environment(self): return self._environment
class _objref_Method(cxx.Method):
def __init__(self, callable, parent_class):
assert isinstance(callable, call.Callable)
assert isinstance(parent_class, cxx.Class)
self._callable =3D callable
self._parent_class =3D parent_class
self.from_Callable()
def callable(self): return self._callable
def from_Callable(self):
self._from_Callable(use_out =3D 1)
def _from_Callable(self, use_out):
# Grab the IDL environment
environment =3D self.callable().interface().environment()
# Kept as a type object because in .cc part the _return_ type
# must be fully qualified.
self._return_type =3D types.Type(self.callable().returnType())
# Parameters are always relative, both in .hh and .cc
(param_types, param_names) =3D ([], [])
for p in self.callable().parameters():
pType =3D types.Type(p.paramType())
direction =3D types.direction(p)
param_types.append(pType.op(direction, environment,
use_out =3D use_out))
# Special ugly case. If the IDL says something like (in foo::bar
# bar), the parameter name may be the same as the relative type
# name. We mangly the parameter name if this happens.
typeBase =3D pType.base(environment)
ident =3D id.mapID(p.identifier())
if typeBase =3D=3D ident:
ident =3D "_" + ident
param_names.append(ident)
=20
# an operation has optional context
if self.callable().contexts() !=3D []:
param_types.append("CORBA::Context_ptr")
param_names.append("_ctxt")
self._arg_types =3D param_types
self._arg_names =3D param_names
self._name =3D self.callable().method_name()
class _impl_Method(_objref_Method):
def __init__(self, callable, parent_class):
_objref_Method.__init__(self, callable, parent_class)
def from_Callable(self):
self._from_Callable(use_out =3D 0)
class I_Helper(Class):
def __init__(self, I):
Class.__init__(self, I)
self._name =3D self._name.suffix("_Helper")
def hh(self, stream):
class_sk_name =3D ""
if config.state['BOA Skeletons']:
class_sk_name =3D "class " + \
self.interface().name().prefix("_sk_").simple() + =
";"
stream.out(omniidl_be.cxx.header.template.interface_Helper,
class_sk_name =3D class_sk_name,
name =3D self.interface().name().simple(),
guard =3D self.interface().name().guard())
def cc(self, stream):
stream.out(omniidl_be.cxx.skel.template.interface_Helper,
name =3D self.interface().name().fullyQualify())
class _objref_I(Class):
def __init__(self, I):
Class.__init__(self, I)
self._name =3D self._name.prefix("_objref_")
for callable in self.interface().callables():
method =3D _objref_Method(callable, self)
self._methods.append(method)
self._callables[method] =3D callable
def hh(self, stream):
# build the inheritance list
objref_inherits =3D []
for i in self.interface().inherits():
objref_inherited_name =3D i.name().prefix("_objref_")
uname =3D objref_inherited_name.unambiguous(self._environment)
objref_inherits.append("public virtual " + uname)
# if already inheriting, the base class will be present
# (transitivity of the inherits-from relation)
if self.interface().inherits() =3D=3D []:
objref_inherits =3D [ "public virtual CORBA::Object, " + \
"public virtual omniObjRef" ]
methods =3D []
for method in self.methods():
if config.state['Virtual Objref Methods']:
methods.append(method.hh(virtual =3D 1, pure =3D 0))
else:
methods.append(method.hh())
=20
if config.state['Shortcut']:
shortcut =3D output.StringStream()
shortcut.out(omniidl_be.cxx.header.template.interface_shortcut,
name =3D self.interface().name().simple())
shortcut =3D str(shortcut)
init_shortcut =3D ": _shortcut(0)"
else:
shortcut =3D ""
init_shortcut =3D ""
stream.out(omniidl_be.cxx.header.template.interface_objref,
name =3D self.interface().name().simple(),
inherits =3D string.join(objref_inherits, ",\n"),
operations =3D string.join(methods, "\n"),
shortcut =3D shortcut,
init_shortcut =3D init_shortcut)
def cc(self, stream):
def _ptrToObjRef_ptr(self =3D self, stream =3D stream):
for i in self.interface().allInherits():
=
stream.out(omniidl_be.cxx.skel.template.interface_objref_repoID_ptr,
inherits_fqname =3D i.name().fullyQualify())
def _ptrToObjRef_str(self =3D self, stream =3D stream):
for i in self.interface().allInherits():
=
stream.out(omniidl_be.cxx.skel.template.interface_objref_repoID_str,
inherits_fqname =3D i.name().fullyQualify())
# build the inherits list
inherits_str =3D ""
for i in self.interface().inherits():
objref_name =3D i.name().prefix("_objref_")
objref_str =3D objref_name.unambiguous(self._environment)
if objref_name.needFlatName(self._environment):
objref_str =3D objref_name.flatName()
this_inherits_str =3D objref_str + "(ior, id),\n"
# FIXME:
# The powerpc-aix OMNIORB_BASE_CTOR workaround still works here
# (in precendence to the flattened base name) but lacking a
# powerpc-aix test machine I can't properly test it. It's =
probably
# not required any more.
if objref_name.relName(self._environment) !=3D =
i.name().fullName():
prefix =3D []
for x in objref_name.fullName():
if x =3D=3D "_objref_" + =
objref_name.relName(self._environment)[0]:
break
prefix.append(x)
inherits_scope_prefix =3D string.join(prefix, "::") + "::"
this_inherits_str =3D "OMNIORB_BASE_CTOR(" + =
inherits_scope_prefix +\
")" + this_inherits_str
inherits_str =3D inherits_str + this_inherits_str
if config.state['Shortcut']:
init_shortcut =3D ", _shortcut(0)"
else:
init_shortcut =3D ""
stream.out(omniidl_be.cxx.skel.template.interface_objref,
name =3D self.interface().name().fullyQualify(),
fq_objref_name =3D self.name().fullyQualify(),
objref_name =3D self.name().simple(),
inherits_str =3D inherits_str,
_ptrToObjRef_ptr =3D _ptrToObjRef_ptr,
_ptrToObjRef_str =3D _ptrToObjRef_str,
init_shortcut =3D init_shortcut)
if config.state['Shortcut']:
inherited =3D output.StringStream()
for i in self.interface().inherits():
objref_name =3D i.name().prefix("_objref_")
objref_str =3D objref_name.unambiguous(self._environment)
if objref_name.needFlatName(self._environment):
objref_str =3D objref_name.flatName()
=
inherited.out(omniidl_be.cxx.skel.template.interface_shortcut_inh,
parent=3Dobjref_str)
=20
stream.out(omniidl_be.cxx.skel.template.interface_shortcut,
name =3D self.interface().name().fullyQualify(),
basename =3D self.interface().name().simple(),
fq_objref_name =3D self.name().fullyQualify(),
inherited =3D str(inherited))
=20
for method in self.methods():
callable =3D self._callables[method]
# signature is a text string form of the complete operation =
signature
signature =3D callable.signature()
# we only need one descriptor for each _signature_ (not =
operation)
if _proxy_call_descriptors.has_key(signature):
call_descriptor =3D _proxy_call_descriptors[signature]
else:
call_descriptor =3D call.CallDescriptor(signature,callable)
call_descriptor.out_desc(stream)
_proxy_call_descriptors[signature] =3D call_descriptor
# produce a localcall function
node_name =3D self.interface().name()
localcall_fn =3D descriptor.local_callback_fn(node_name,
=
callable.operation_name(),
signature)
=
call_descriptor.out_localcall(stream,node_name,callable.method_name(),
localcall_fn)
# produce member function for this operation/attribute.
body =3D output.StringStream()
argnames =3D method.arg_names()
if config.state['Shortcut']:
if method.return_type().kind() !=3D idltype.tk_void:
callreturn =3D "return "
voidreturn =3D ""
else:
callreturn =3D ""
voidreturn =3D " return;"
objref_class =3D method.parent_class()
interface =3D objref_class.interface()
implname =3D =
interface.name().prefix("_impl_").unambiguous(self._environment)
=20
=
body.out(omniidl_be.cxx.skel.template.interface_operation_shortcut,
impl_type =3D implname,
callreturn =3D callreturn,
voidreturn =3D voidreturn,
args =3D string.join(argnames, ", "),
name =3D method.name())
call_descriptor.out_objrefcall(body,
callable.operation_name(),
argnames,
localcall_fn,
self._environment)
method.cc(stream, body)
class _pof_I(Class):
def __init__(self, I):
Class.__init__(self, I)
self._name =3D self._name.prefix("_pof_")
def hh(self, stream):
stream.out(omniidl_be.cxx.header.template.interface_pof,
name =3D self.interface().name().simple())
def cc(self, stream):
inherits =3D output.StringStream()
for i in self.interface().allInherits():
ancestor =3D i.name().fullyQualify()
inherits.out(omniidl_be.cxx.skel.template.interface_pof_repoID, =
inherited =3D ancestor)
node_name =3D self.interface().name()
objref_name =3D node_name.prefix("_objref_")
pof_name =3D node_name.prefix("_pof_")
stream.out(omniidl_be.cxx.skel.template.interface_pof,
pof_name =3D pof_name.fullyQualify(),
objref_fqname =3D objref_name.fullyQualify(),
name =3D node_name.fullyQualify(),
uname =3D pof_name.simple(),
Other_repoIDs =3D inherits,
idname =3D node_name.guard())
=20
class _impl_I(Class):
def __init__(self, I):
Class.__init__(self, I)
self._name =3D self._name.prefix("_impl_")
for callable in self.interface().callables():
method =3D _impl_Method(callable, self)
self._methods.append(method)
self._callables[method] =3D callable
def hh(self, stream):
# build the inheritance list
environment =3D self._environment
impl_inherits =3D []
for i in self.interface().inherits():
impl_inherited_name =3D i.name().prefix("_impl_")
uname =3D impl_inherited_name.unambiguous(environment)
impl_inherits.append("public virtual " + uname)
# if already inheriting, the base class will be present
# (transitivity of the inherits-from relation)
if self.interface().inherits() =3D=3D []:
impl_inherits =3D [ "public virtual omniServant" ]
methods =3D []
for method in self.methods():
methods.append(method.hh(virtual =3D 1, pure =3D 1))
=20
stream.out(omniidl_be.cxx.header.template.interface_impl,
name =3D self.interface().name().simple(),
inherits =3D string.join(impl_inherits, ",\n"),
operations =3D string.join(methods, "\n"))
def cc(self, stream):
# Function to write the _impl_I::dispatch method
def dispatch(self =3D self, stream =3D stream):
# first check if method is from this interface
dispatched =3D []
for method in self.methods():
callable =3D self._callables[method]
operation_name =3D callable.operation_name()
if operation_name not in dispatched:
signature =3D callable.signature()
call_descriptor =3D _proxy_call_descriptors[signature]
localcall_fn =3D =
descriptor.local_callback_fn(self.interface().name(),
=
operation_name,signature)
=
call_descriptor.out_implcall(stream,operation_name,localcall_fn)
dispatched.append(operation_name)
# next call dispatch methods of superclasses
for i in self.interface().inherits():
inherited_name =3D i.name().prefix("_impl_")
impl_inherits =3D inherited_name.simple()
# The MSVC workaround might be needed here again
if inherited_name.needFlatName(self._environment):
impl_inherits =3D inherited_name.flatName()
=
stream.out(omniidl_be.cxx.skel.template.interface_impl_inherit_dispatch,=
impl_inherited_name =3D impl_inherits)
# For each of the inherited interfaces, check their repoId strings
def _ptrToInterface_ptr(self =3D self, stream =3D stream):
for i in self.interface().allInherits():
inherited_name =3D i.name()
impl_inherited_name =3D inherited_name.prefix("_impl_")
inherited_str =3D inherited_name.unambiguous(self._environment)
impl_inherited_str =3D =
impl_inherited_name.unambiguous(self._environment)
if inherited_name.needFlatName(self._environment):
inherited_str =3D inherited_name.flatName()
impl_inherited_str =3D impl_inherited_name.flatName()
=
stream.out(omniidl_be.cxx.skel.template.interface_impl_repoID_ptr,
inherited_name =3D inherited_str,
impl_inherited_name =3D impl_inherited_str)
def _ptrToInterface_str(self =3D self, stream =3D stream):
for i in self.interface().allInherits():
inherited_name =3D i.name()
impl_inherited_name =3D inherited_name.prefix("_impl_")
inherited_str =3D inherited_name.unambiguous(self._environment)
impl_inherited_str =3D =
impl_inherited_name.unambiguous(self._environment)
if inherited_name.needFlatName(self._environment):
inherited_str =3D inherited_name.flatName()
impl_inherited_str =3D impl_inherited_name.flatName()
=
stream.out(omniidl_be.cxx.skel.template.interface_impl_repoID_str,
inherited_name =3D inherited_str,
impl_inherited_name =3D impl_inherited_str)
node_name =3D self.interface().name()
impl_name =3D node_name.prefix("_impl_")
if self.methods():
getopname =3D "const char* op =3D _handle.operation_name();"
else:
getopname =3D ""
stream.out(omniidl_be.cxx.skel.template.interface_impl,
impl_fqname =3D impl_name.fullyQualify(),
uname =3D node_name.simple(),
getopname =3D getopname,
dispatch =3D dispatch,
impl_name =3D impl_name.unambiguous(self._environment),
_ptrToInterface_ptr =3D _ptrToInterface_ptr,
_ptrToInterface_str =3D _ptrToInterface_str,
name =3D node_name.fullyQualify())
=20
class _sk_I(Class):
def __init__(self, I):
Class.__init__(self, I)
def hh(self, stream):
# build the inheritance list
environment =3D self._environment
sk_inherits =3D []
for i in self.interface().inherits():
sk_inherited_name =3D i.name().prefix("_sk_")
uname =3D sk_inherited_name.unambiguous(environment)
sk_inherits.append("public virtual " + uname)
# if already inheriting, the base class will be present
# (transitivity of the inherits-from relation)
if self.interface().inherits() =3D=3D []:
sk_inherits =3D [ "public virtual omniOrbBoaServant" ]
stream.out(omniidl_be.cxx.header.template.interface_sk,
name =3D self.interface().name().simple(),
inherits =3D string.join(sk_inherits, ",\n"))
------_=_NextPart_000_01C2DE26.5A5EF010--