[asterisk-scf-commits] asterisk-scf/release/ice.git branch "unsliceable_patch" updated.

Commits to the Asterisk SCF project code repositories asterisk-scf-commits at lists.digium.com
Mon Dec 6 11:42:57 CST 2010


branch "unsliceable_patch" has been updated
       via  5d676a4a233f4dd8e088334d726fdee41650e8a0 (commit)
       via  068d5366f5ca6779cb5b9ae037024f2da08bf21d (commit)
      from  cfd35498bdb1893155159520f62391420af1c020 (commit)

Summary of changes:
 cpp/src/Ice/SlicedData.cpp                         |    2 +-
 php/src/IcePHP/Types.cpp                           |    3 +-
 php/test/Ice/slicing/objects/Client.php            |  136 +++++++++++---
 php/test/Ice/slicing/objects/ClientPrivate.ice     |   35 ++++
 php/test/Ice/slicing/objects/Test.ice              |    5 +
 py/modules/IcePy/Operation.cpp                     |   26 +++
 py/modules/IcePy/Types.cpp                         |   78 +++++----
 py/test/Ice/slicing/exceptions/AllTests.py         |  116 ++++++++++++-
 .../test/Ice/slicing/exceptions/ClientPrivate.ice  |    0
 py/test/Ice/slicing/exceptions/Server.py           |   35 ++++
 py/test/Ice/slicing/exceptions/ServerAMD.py        |   43 +++++
 py/test/Ice/slicing/exceptions/Test.ice            |   25 +++
 py/test/Ice/slicing/exceptions/TestAMD.ice         |   25 +++
 py/test/Ice/slicing/objects/AllTests.py            |  131 ++++++++++++-
 py/test/Ice/slicing/objects/Server.py              |    3 +
 py/test/Ice/slicing/objects/Test.ice               |    1 +
 rb/src/IceRuby/Types.cpp                           |   36 ++--
 rb/test/Ice/slicing/objects/AllTests.rb            |  196 ++++++++++++++++++++
 rb/test/Ice/slicing/objects/ClientPrivate.ice      |   35 ++++
 rb/test/Ice/slicing/objects/Test.ice               |    5 +
 20 files changed, 852 insertions(+), 84 deletions(-)
 copy {cpp => py}/test/Ice/slicing/exceptions/ClientPrivate.ice (100%)


- Log -----------------------------------------------------------------
commit 5d676a4a233f4dd8e088334d726fdee41650e8a0
Author: Brent Eagles <beagles at digium.com>
Date:   Mon Dec 6 14:10:15 2010 -0330

    Fixed several bugs in unsliceable exceptions in Python as well as fix missing tests.
    Fixed a bug in SlicedData where hasNestedClasses was keying on the wrong data member.

diff --git a/cpp/src/Ice/SlicedData.cpp b/cpp/src/Ice/SlicedData.cpp
index 5240afd..dd7a3f7 100644
--- a/cpp/src/Ice/SlicedData.cpp
+++ b/cpp/src/Ice/SlicedData.cpp
@@ -141,7 +141,7 @@ Ice::SlicedDataImpl::updateObjectId(std::vector<Byte>& buffer, const Ice::Int of
 bool
 Ice::SlicedDataImpl::containsNestedClasses()
 {
-    return _objectIdMap.size() > 0;
+    return _objectMap.size() > 0;
 }
 
 void 
diff --git a/py/modules/IcePy/Operation.cpp b/py/modules/IcePy/Operation.cpp
index b282b51..95dd1a1 100644
--- a/py/modules/IcePy/Operation.cpp
+++ b/py/modules/IcePy/Operation.cpp
@@ -1447,6 +1447,24 @@ IcePy::TypedInvocation::unmarshalResults(const pair<const Ice::Byte*, const Ice:
     return results.release();
 }
 
+static bool
+hasClasses(PyObjectHandle obj)
+{
+    if(PyObject_HasAttrString(obj.get(), "__ice_slicedData__"))
+    {
+        PyObjectHandle slicedData = PyObject_GetAttrString(obj.get(), "__ice_slicedData__");
+        if(!PyCObject_Check(slicedData.get()))
+        {
+            PyErr_Format(PyExc_ValueError, STRCAST("sliced data not found (expected even if empty)"));
+            throw AbortMarshaling();
+        }
+        Ice::SlicedDataPtr* mem = reinterpret_cast<Ice::SlicedDataPtr*>(PyCObject_AsVoidPtr(slicedData.get()));
+        Ice::SlicedDataPtr slices = *mem; 
+        return slices->containsNestedClasses();
+    }
+    return false;
+}
+
 PyObject*
 IcePy::TypedInvocation::unmarshalException(const pair<const Ice::Byte*, const Ice::Byte*>& bytes)
 {
@@ -1472,6 +1490,10 @@ IcePy::TypedInvocation::unmarshalException(const pair<const Ice::Byte*, const Ic
             {
                 is->readPendingObjects();
             }
+            else if(info->isUnsliceable && hasClasses(ex))
+            {
+                is->readPendingObjects();
+            }
 
             if(validateException(ex.get()))
             {
@@ -3150,6 +3172,10 @@ IcePy::TypedUpcall::exception(PyException& ex)
                     {
                         os->writePendingObjects();
                     }
+                    else if(info->isUnsliceable && hasClasses(ex.ex.get()))
+                    {
+                        os->writePendingObjects();
+                    }
 
                     Ice::ByteSeq bytes;
                     os->finished(bytes);
diff --git a/py/modules/IcePy/Types.cpp b/py/modules/IcePy/Types.cpp
index 846605a..4f25cc8 100644
--- a/py/modules/IcePy/Types.cpp
+++ b/py/modules/IcePy/Types.cpp
@@ -2652,7 +2652,6 @@ IcePy::ObjectReader::read(const Ice::InputStreamPtr& is, bool rid)
             PyObjectHandle slicedDataObj = PyCObject_FromVoidPtr(reinterpret_cast<void*>(sliceDataMem), deleteSlicedData);
             if(!slicedDataObj.get())
             {
-                std::cerr<< __FUNCTION__ << ":" << __LINE__ << std::endl;
                 assert(PyErr_Occurred());
                 throw AbortMarshaling();
             }
@@ -2660,7 +2659,6 @@ IcePy::ObjectReader::read(const Ice::InputStreamPtr& is, bool rid)
             int result = PyObject_SetAttrString(_object, "__ice_slicedData__", slicedDataObj.get()); 
             if(result == -1)
             {
-                std::cerr<< __FUNCTION__ << ":" << __LINE__ << std::endl;
                 assert(PyErr_Occurred());
                 throw AbortMarshaling();
             }
@@ -2812,22 +2810,26 @@ IcePy::ExceptionInfo::marshal(PyObject* p, const Ice::OutputStreamPtr& os, Objec
     ExceptionInfoPtr info = this;
 
     Ice::ObjectIdMap idMap;
-    if(info->isUnsliceable)
+
+    if(info->isUnsliceable && PyObject_HasAttrString(p, "__ice_slicedData__"))
     {
         PyObjectHandle slicedDataMem = PyObject_GetAttrString(p, "__ice_slicedData__");
-        if(!slicedDataMem.get() || !PyCObject_Check(slicedDataMem.get()))
+        if(slicedDataMem.get()) 
         {
-            PyErr_Format(PyExc_ValueError, STRCAST("sliced data not found (expected even if empty)"));
-            throw AbortMarshaling();
+            if(!PyCObject_Check(slicedDataMem.get()))
+            {
+                PyErr_Format(PyExc_ValueError, STRCAST("sliced data not found (expected even if empty)"));
+                throw AbortMarshaling();
+            }
+            Ice::SlicedDataPtr* mem = reinterpret_cast<Ice::SlicedDataPtr*>(PyCObject_AsVoidPtr(slicedDataMem.get()));
+            Ice::SlicedDataPtr slicedData = *mem; 
+            //
+            // This writes all of the data that needs be written, and updates any object ids that are in the
+            // slices.
+            //
+            slicedData->transformPreserved(new SlicedObjectsTransform(objectMap));
+            slicedData->write(os, idMap, true);
         }
-        Ice::SlicedDataPtr* mem = reinterpret_cast<Ice::SlicedDataPtr*>(PyCObject_AsVoidPtr(slicedDataMem.get()));
-        Ice::SlicedDataPtr slicedData = *mem; 
-        //
-        // This writes all of the data that needs be written, and updates any object ids that are in the
-        // slices.
-        //
-        slicedData->transformPreserved(new SlicedObjectsTransform(objectMap));
-        slicedData->write(os, idMap, true);
     }
 
     while(info)
@@ -2915,6 +2917,7 @@ IcePy::ExceptionInfo::unmarshal(const Ice::InputStreamPtr& is)
     //
     ExceptionInfoPtr info = this;
     Ice::SlicedDataPtr slicedData;
+    bool addPatchers = false;
     if(info->isUnsliceable)
     {
         //
@@ -2922,25 +2925,28 @@ IcePy::ExceptionInfo::unmarshal(const Ice::InputStreamPtr& is)
         // this is the proper time to get it from then input stream.
         //
         slicedData = is->getSlicedData();
-        if(!slicedData)
-        {
-            slicedData = new Ice::SlicedData;
-        }
-        Ice::SlicedDataPtr* sliceDataMem = new Ice::SlicedDataPtr;
-        *sliceDataMem = slicedData;
-        PyObjectHandle slicedDataObj = PyCObject_FromVoidPtr(reinterpret_cast<void*>(sliceDataMem), deleteSlicedData);
-        if(!slicedDataObj.get())
+        if(slicedData)
         {
-            assert(PyErr_Occurred());
-            throw AbortMarshaling();
-        }
+            Ice::SlicedDataPtr* sliceDataMem = new Ice::SlicedDataPtr;
+            *sliceDataMem = slicedData;
+            PyObjectHandle slicedDataObj = PyCObject_FromVoidPtr(reinterpret_cast<void*>(sliceDataMem), deleteSlicedData);
+            if(!slicedDataObj.get())
+            {
+                assert(PyErr_Occurred());
+                throw AbortMarshaling();
+            }
 
-        int result = PyObject_SetAttrString(p.get(), "__ice_slicedData__", slicedDataObj.get()); 
-        std::cerr << "setting sliced data" << std::endl;
-        if(result == -1)
+            int result = PyObject_SetAttrString(p.get(), "__ice_slicedData__", slicedDataObj.get()); 
+            if(result == -1)
+            {
+                assert(PyErr_Occurred());
+                throw AbortMarshaling();
+            }
+            addPatchers = true;
+        }
+        else
         {
-            assert(PyErr_Occurred());
-            throw AbortMarshaling();
+            slicedData = new Ice::SlicedData;
         }
     }
 
@@ -2952,6 +2958,14 @@ IcePy::ExceptionInfo::unmarshal(const Ice::InputStreamPtr& is)
             DataMemberPtr member = *q;
             member->type->unmarshal(is, member, p.get(), 0, &member->metaData);
         }
+        if(info->isUnsliceable && !info->isParentUnsliceable && slicedData)
+        {
+            slicedData->readMap(is);
+            if(addPatchers)
+            {
+                slicedData->__addPatchObjects(is);
+            }
+        }
         is->endSlice();
 
         info = info->base;
diff --git a/py/test/Ice/slicing/exceptions/AllTests.py b/py/test/Ice/slicing/exceptions/AllTests.py
index f39cf54..825e085 100644
--- a/py/test/Ice/slicing/exceptions/AllTests.py
+++ b/py/test/Ice/slicing/exceptions/AllTests.py
@@ -10,7 +10,7 @@
 
 import Ice, threading, sys
 
-Ice.loadSlice('Test.ice')
+Ice.loadSlice('--all -I. ClientPrivate.ice')
 import Test
 
 def test(b):
@@ -183,9 +183,41 @@ class Callback(CallbackBase):
             test(False)
         self.called()
 
+class ClientI(Test.ClientIntf):
+    def __init__(self):
+        pass
+
+    def baseAsBase(self, current=None):
+        b = Test.Base()
+        b.b = "Base"
+        raise b
+
+    def unknownDerivedAsBase(self, current=None):
+        ex = Test.ClientUnknownDerived()
+        ex.ud = "UnknownDerived"
+        ex.b = "Base"
+        raise ex
+
+    def unsliceableDerivedAsBase(self, current=None):
+        ex = Test.ClientUnsliceableDerived()
+        ex.ud = "UnsliceableDerived"
+        ex.b = "Base"
+        raise ex
+
+    def unsliceableWithInnerClass(self, current=None):
+        ex = Test.ClientUnsliceableWithClass()
+        ex.b = "WithInnerClass"
+        ex.myObj = Test.InnerClassDerived()
+        ex.myObj.ic = "InnerClass"
+        ex.myObj.id = "InnerClassDerived"
+        raise ex
+
 def allTests(communicator):
     obj = communicator.stringToProxy("Test:default -p 12010")
     t = Test.TestIntfPrx.checkedCast(obj)
+    adapter = communicator.createObjectAdapterWithEndpoints("ClientAdapter", "default -p 12020 -t 2000")
+    client = Test.ClientIntfPrx.uncheckedCast(adapter.addWithUUID(ClientI()))
+    adapter.activate()
 
     print "base... ",
     try:
@@ -420,4 +452,86 @@ def allTests(communicator):
     cb.check()
     print "ok"
 
+    print "base pass through server... ",
+    try:
+        t.clientBaseAsBasePass(client)
+        test(False)
+    except Test.Base, b:
+        test(b.b == "Base")
+        test(b.ice_name() == "Test::Base")
+    except:
+        test(False)
+    print "ok"
+
+    print "base rethrown by server... ",
+    try:
+        t.clientBaseAsBaseRethrow(client)
+        test(False)
+    except Test.Base, b:
+        test(b.b == "Base")
+        test(b.ice_name() == "Test::Base")
+    except:
+        test(False)
+    print "ok"
+
+    print "unknown derived pass through server...", 
+    try:
+        t.clientUnknownDerivedAsBasePass(client)
+        test(False)
+    except Test.Base, b:
+        test(b.b == "Base")
+        test(b.ice_name() == "Test::Base")
+    except:
+        test(False)
+    print "ok"
+
+    print "unknown derived pass rethrown by server...", 
+    try:
+        t.clientUnknownDerivedAsBaseRethrow(client)
+        test(False)
+    except Test.Base, b:
+        test(b.b == "Base")
+        test(b.ice_name() == "Test::Base")
+    except:
+        test(False)
+    print "ok"
+
+    print "unsliceable derived pass through server...",
+    try:
+        t.clientUnsliceableDerivedAsBasePass(client)
+        test(False)
+    except Test.Base,b:
+        test(b.b == "Base")
+        test(b.ice_name() == "Test::ClientUnsliceableDerived")
+    except:
+        test(False)
+    print "ok"
+
+    print "Unsliceable derived rethrown by server...",
+    try:
+        t.clientUnsliceableDerivedAsBaseRethrow(client)
+        print "foo"
+        test(False)
+    except Test.Base,b:
+        test(b.b == "Base")
+        test(b.ice_name() == "Test::ClientUnsliceableDerived")
+    except Exception,e:
+        print e
+        test(False)
+    print "ok"
+
+    print "Unsliceable derived rethrown by server with inner class...",
+    try:
+        t.clientUnsliceableInnerClassRethrow(client)
+        test(False)
+    except Test.Base,b:
+        test(b.b == "WithInnerClass")
+        test(b.ice_name() == "Test::ClientUnsliceableWithClass")
+        test(b.myObj != None)
+        test(b.myObj.ic == "InnerClass")
+        test(b.myObj.id == "InnerClassDerived")
+    except Exception,e:
+        test(False)
+    print "ok"
+
     return t
diff --git a/py/test/Ice/slicing/exceptions/ClientPrivate.ice b/py/test/Ice/slicing/exceptions/ClientPrivate.ice
new file mode 100644
index 0000000..1f25e10
--- /dev/null
+++ b/py/test/Ice/slicing/exceptions/ClientPrivate.ice
@@ -0,0 +1,40 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2010 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef CLIENTPRIVATE_ICE
+#define CLIENTPRIVATE_ICE
+
+#include <Test.ice>
+
+module Test
+{
+
+unsliceable class InnerClassDerived extends InnerClass
+{
+    string id;
+};
+
+exception ClientUnknownDerived extends Base
+{
+    string ud;
+};
+
+unsliceable exception ClientUnsliceableDerived extends BaseUnsliceable
+{
+    string ud;
+};
+
+unsliceable exception ClientUnsliceableWithClass extends BaseUnsliceable
+{
+    InnerClassDerived myObj;
+};
+
+};
+
+#endif
diff --git a/py/test/Ice/slicing/exceptions/Server.py b/py/test/Ice/slicing/exceptions/Server.py
index 00b1a1c..465b7ea 100755
--- a/py/test/Ice/slicing/exceptions/Server.py
+++ b/py/test/Ice/slicing/exceptions/Server.py
@@ -100,6 +100,41 @@ class TestI(Test.TestIntf):
         umd2.umd2 = "UnknownMostDerived2.umd2"
         raise umd2
 
+    def clientBaseAsBasePass(self, client, current=None):
+        client.baseAsBase()
+
+    def clientUnknownDerivedAsBasePass(self, client, current=None):
+        client.unknownDerivedAsBase()
+
+    def clientUnsliceableDerivedAsBasePass(self, client, current=None):
+        client.unsliceableDerivedAsBase()
+
+    def clientBaseAsBaseRethrow(self, client, current=None):
+        try:
+            client.baseAsBase()
+        except Test.Base, e:
+            raise 
+
+    def clientUnknownDerivedAsBaseRethrow(self, client, current=None):
+        try:
+            client.unknownDerivedAsBase()
+        except Test.Base, e:
+            raise
+
+    def clientUnsliceableDerivedAsBaseRethrow(self, client, current=None):
+        try:
+            client.unsliceableDerivedAsBase()
+        except Test.Base, e:
+            print e
+            raise 
+
+    def clientUnsliceableInnerClassRethrow(self, client, current=None):
+        try:
+            client.unsliceableWithInnerClass()
+        except Test.Base, e:
+            raise 
+
+
 def run(args, communicator):
     properties = communicator.getProperties()
     properties.setProperty("Ice.Warn.Dispatch", "0")
diff --git a/py/test/Ice/slicing/exceptions/ServerAMD.py b/py/test/Ice/slicing/exceptions/ServerAMD.py
index 1573b01..ac79db3 100755
--- a/py/test/Ice/slicing/exceptions/ServerAMD.py
+++ b/py/test/Ice/slicing/exceptions/ServerAMD.py
@@ -102,6 +102,49 @@ class TestI(Test.TestIntf):
         umd2.umd2 = "UnknownMostDerived2.umd2"
         cb.ice_exception(umd2)
 
+    def clientBaseAsBasePass_async(self, cb, client, current=None):
+        try:
+            client.baseAsBase()
+        except Test.Base, e:
+            cb.ice_exception(e)
+
+    def clientUnknownDerivedAsBasePass_async(self, cb, client, current=None):
+        try:
+            client.unknownDerivedAsBase()
+        except Test.Base, e:
+            cb.ice_exception(e)
+
+    def clientUnsliceableDerivedAsBasePass_async(self, cb, client, current=None):
+        try:
+            client.unsliceableDerivedAsBase()
+        except Test.Base, e:
+            cb.ice_exception(e)
+
+    def clientBaseAsBaseRethrow_async(self, cb, client, current=None):
+        try:
+            client.baseAsBase()
+        except Test.Base, e:
+            cb.ice_exception(e)
+
+    def clientUnknownDerivedAsBaseRethrow_async(self, cb, client, current=None):
+        try:
+            client.unknownDerivedAsBase()
+        except Test.Base, e:
+            cb.ice_exception(e)
+
+    def clientUnsliceableDerivedAsBaseRethrow_async(self, cb, client, current=None):
+        try:
+            client.unsliceableDerivedAsBase()
+        except Test.Base, e:
+            cb.ice_exception(e)
+
+    def clientUnsliceableInnerClassRethrow_async(self, cb, client, current=None):
+        try:
+            client.unsliceableWithInnerClass()
+        except Test.Base, e:
+            cb.ice_exception(e)
+
+
 def run(args, communicator):
     properties = communicator.getProperties()
     properties.setProperty("Ice.Warn.Dispatch", "0")
diff --git a/py/test/Ice/slicing/exceptions/Test.ice b/py/test/Ice/slicing/exceptions/Test.ice
index 9248cdc..e91e67f 100644
--- a/py/test/Ice/slicing/exceptions/Test.ice
+++ b/py/test/Ice/slicing/exceptions/Test.ice
@@ -33,6 +33,23 @@ exception KnownMostDerived extends KnownIntermediate
     string kmd;
 };
 
+unsliceable exception BaseUnsliceable extends Base
+{
+};
+
+unsliceable class InnerClass
+{
+    string ic;
+};
+
+interface ClientIntf
+{
+    void baseAsBase() throws Base;
+    void unknownDerivedAsBase() throws Base;
+    void unsliceableDerivedAsBase() throws Base;
+    void unsliceableWithInnerClass() throws Base;
+};
+
 interface TestIntf
 {
     void baseAsBase() throws Base;
@@ -51,6 +68,14 @@ interface TestIntf
     void unknownMostDerived1AsKnownIntermediate() throws KnownIntermediate;
     void unknownMostDerived2AsBase() throws Base;
 
+    void clientBaseAsBasePass(ClientIntf* client) throws Base;
+    void clientUnknownDerivedAsBasePass(ClientIntf* client) throws Base;
+    void clientUnsliceableDerivedAsBasePass(ClientIntf* client) throws Base;
+    void clientBaseAsBaseRethrow(ClientIntf* client) throws Base;
+    void clientUnknownDerivedAsBaseRethrow(ClientIntf* client) throws Base;
+    void clientUnsliceableDerivedAsBaseRethrow(ClientIntf* client) throws Base;
+    void clientUnsliceableInnerClassRethrow(ClientIntf* client) throws Base;
+
     void shutdown();
 };
 
diff --git a/py/test/Ice/slicing/exceptions/TestAMD.ice b/py/test/Ice/slicing/exceptions/TestAMD.ice
index 3de14d1..c95c16d 100644
--- a/py/test/Ice/slicing/exceptions/TestAMD.ice
+++ b/py/test/Ice/slicing/exceptions/TestAMD.ice
@@ -33,6 +33,23 @@ exception KnownMostDerived extends KnownIntermediate
     string kmd;
 };
 
+unsliceable exception BaseUnsliceable extends Base
+{
+};
+
+unsliceable class InnerClass
+{
+    string ic;
+};
+
+interface ClientIntf
+{
+    void baseAsBase() throws Base;
+    void unknownDerivedAsBase() throws Base;
+    void unsliceableDerivedAsBase() throws Base;
+    void unsliceableWithInnerClass() throws Base;
+};
+
 ["amd"] interface TestIntf
 {
     void baseAsBase() throws Base;
@@ -51,6 +68,14 @@ exception KnownMostDerived extends KnownIntermediate
     void unknownMostDerived1AsKnownIntermediate() throws KnownIntermediate;
     void unknownMostDerived2AsBase() throws Base;
 
+    void clientBaseAsBasePass(ClientIntf* client) throws Base;
+    void clientUnknownDerivedAsBasePass(ClientIntf* client) throws Base;
+    void clientUnsliceableDerivedAsBasePass(ClientIntf* client) throws Base;
+    void clientBaseAsBaseRethrow(ClientIntf* client) throws Base;
+    void clientUnknownDerivedAsBaseRethrow(ClientIntf* client) throws Base;
+    void clientUnsliceableDerivedAsBaseRethrow(ClientIntf* client) throws Base;
+    void clientUnsliceableInnerClassRethrow(ClientIntf* client) throws Base;
+
     void shutdown();
 };
 

commit 068d5366f5ca6779cb5b9ae037024f2da08bf21d
Author: Brent Eagles <beagles at digium.com>
Date:   Fri Dec 3 16:25:02 2010 -0330

    - Add some missing tests.
    - Fixed a bug where null references would cause a crash
    - Fixed an issue in Ruby where the absence of the hidden iceSlicedData would
      cause a crash.

diff --git a/php/src/IcePHP/Types.cpp b/php/src/IcePHP/Types.cpp
index a6fb8a3..edb3d47 100644
--- a/php/src/IcePHP/Types.cpp
+++ b/php/src/IcePHP/Types.cpp
@@ -2221,7 +2221,8 @@ IcePHP::ObjectWriter::write(const Ice::OutputStreamPtr& os) const
             idOffset.offset = os->getWriteSliceOffset();
 
             member->type->marshal(*val, os, _map TSRMLS_CC);
-            if(info->isUnsliceable)
+
+            if(info->isUnsliceable && Z_TYPE_P(*val) != IS_NULL)
             {
                 ClassInfoPtr memberInfo = ClassInfoPtr::dynamicCast(member->type);
                 if(memberInfo != 0)
diff --git a/php/test/Ice/slicing/objects/Client.php b/php/test/Ice/slicing/objects/Client.php
index 2da3430..ec1a6bd 100644
--- a/php/test/Ice/slicing/objects/Client.php
+++ b/php/test/Ice/slicing/objects/Client.php
@@ -27,6 +27,7 @@ function allTests($communicator)
 
     $d1cls = $NS ? "Test\\D1" : "Test_D1";
     $d3cls = $NS ? "Test\\D3" : "Test_D3";
+    $d5cls = $NS ? "Test\\D5" : "Test_D5";
 
     $obj = $communicator->stringToProxy("Test:default -p 12010");
     $test = $obj->ice_checkedCast("::Test::TestIntf");
@@ -380,54 +381,99 @@ function allTests($communicator)
     }
     echo "ok\n";
 
-    echo "testing return value identity for input params unknown first... ";
+    echo "testing return value unsliced input params known first... ";
     flush();
     {
         $d1 = $NS ? eval("return new Test\\D1;") : eval("return new Test_D1;");
         $d1->sb = "D1.sb";
         $d1->sd1 = "D1.sd1";
-        $d3 = $NS ? eval("return new Test\\D3;") : eval("return new Test_D3;");
-        $d3->pb = $d1;
-        $d3->sb = "D3.sb";
-        $d3->sd3 = "D3.sd3";
-        $d3->pd3 = $d1;
-        $d1->pb = $d3;
-        $d1->pd1 = $d3;
+        $d5 = $NS ? eval("return new Test\\D5;") : eval("return new Test_D5;");
+        $d5->pb = $d1;
+        $d5->sb = "D5.sb";
+        $d5->sd5 = "D5.sd5";
+        $d5->pd5 = $d1;
+        $d1->pb = $d5;
+        $d1->pd1 = $d5;
 
-        $b1 = $test->returnTest3($d3, $d1);
+        $b1 = $test->returnTest3($d1, $d5);
 
         test($b1 != null);
-        test($b1->sb == "D3.sb");
-        test(get_class($b1) == ($NS ? "Test\\B" : "Test_B")); // Sliced by server
-        test(!($b1 instanceof $d3cls));
+        test($b1->sb == "D1.sb");
+        test(get_class($b1) == ($NS ? "Test\\D1" : "Test_D1"));
+        $p1 = $b1;
+        test($p1 != null);
+        test($p1->sd1 == "D1.sd1");
+        test($p1->pd1 === $b1->pb); // Object identity comparison
 
         $b2 = $b1->pb;
         test($b2 != null);
-        test($b2->sb == "D1.sb");
-        test(get_class($b2) == ($NS ? "Test\\D1" : "Test_D1"));
+        test($b2->sb == "D5.sb");
+        test(get_class($b2) != ($NS ? "Test\\B" : "Test_B")); // Sliced by server
+        test(get_class($b2) == ($NS ? "Test\\D5" : "Test_D5")); // Sliced by server
         test($b2->pb === $b1); // Object identity comparison
-        $p3 = $b2;
-        test($p3 instanceof $d1cls);
-        test($p3->sd1 == "D1.sd1");
-        test($p3->pd1 === $b1); // Object identity comparison
+        test(($b2 instanceof $d5cls));
 
         test($b1 !== $d1);
-        test($b1 !== $d3);
+        test($b1 !== $d5);
         test($b2 !== $d1);
-        test($b2 !== $d3);
+        test($b2 !== $d5);
 
         //
         // Break cyclic dependencies - helps in detecting leaks.
         //
-        $d3->pb = null;
-        $d3->pd3 = null;
-        $d3->pb = null;
-        $d3->pd3 = null;
+        $d1->pb = null;
+        $d1->pd1 = null;
         $b1->pb = null;
-        $b2->pb = null;
+        $p1->pd1 = null;
     }
     echo "ok\n";
 
+    echo "testing return value unsliced input params unknown first... ";
+    flush();
+    {
+        $d1 = $NS ? eval("return new Test\\D1;") : eval("return new Test_D1;");
+        $d1->sb = "D1.sb";
+        $d1->sd1 = "D1.sd1";
+        $d5 = $NS ? eval("return new Test\\D5;") : eval("return new Test_D5;");
+        $d5->pb = $d1;
+        $d5->sb = "D5.sb";
+        $d5->sd5 = "D5.sd5";
+        $d5->pd5 = $d1;
+        $d1->pb = $d5;
+        $d1->pd1 = $d5;
+
+        $b2 = $test->returnTest3($d5, $d1);
+
+        test($b2 != null);
+        test($b2->sb == "D5.sb");
+        test(get_class($b2) != ($NS ? "Test\\B" : "Test_B")); // Sliced by server
+        test(get_class($b2) == ($NS ? "Test\\D5" : "Test_D5")); // Sliced by server
+        test(($b2 instanceof $d5cls));
+
+	$b1 = $b2->pb;
+        test($b1 != null);
+        test($b1->sb == "D1.sb");
+        test(get_class($b1) == ($NS ? "Test\\D1" : "Test_D1"));
+        $p1 = $b1;
+        test($p1 != null);
+        test($p1->sd1 == "D1.sd1");
+        test($p1->pd1 === $b1->pb); // Object identity comparison
+
+        test($b1 !== $d1);
+        test($b1 !== $d5);
+        test($b2 !== $d1);
+        test($b2 !== $d5);
+
+        //
+        // Break cyclic dependencies - helps in detecting leaks.
+        //
+        $d1->pb = null;
+        $d1->pd1 = null;
+        $b1->pb = null;
+        $p1->pd1 = null;
+    }
+    echo "ok\n";
+    
     echo "testing remainder unmarshaling (3 instances)... ";
     flush();
     {
@@ -467,6 +513,46 @@ function allTests($communicator)
     }
     echo "ok\n";
 
+    echo "object graphs of unsliceable objects...";
+    flush();
+    {
+	$graphBase = $NS ? eval("return new Test\\GraphBase;") : eval("return new Test_GraphBase;");
+        $d6 = $NS ? eval("return new Test\\D6;") : eval("return new Test_D6;");
+        $d6->sd6 = "d6.1";
+        $d6->innerD5 = $NS ? eval("return new Test\\D5;") : eval("return new Test_D5;");
+        $d6->innerD5->sd5 = "d6.1.d5";
+        $d6->innerD5->pd5 = $NS ? eval("return new Test\\B;") : eval("return new Test_B;");
+        $d6->innerD5->pd5->sb = "d6.1.d5.sb";
+        $d6->innerD5->pd5->pb = $NS ? eval("return new Test\\B") : eval("return new Test_B;");
+        $d6->innerD5->pd5->pb->sb = "d6.1.d5.sb.sb";
+        $graphBase->left = $d6;
+
+        $d7 = $NS ? eval("return new Test\\D7;") : eval("return new Test_D7;");
+        $d7->sd7 = "d7";
+        $d7->innerD7 = $NS ? eval("return new Test\\D7;") : eval("return new Test_D7;");
+        $d7->innerD7->sd7 = "d7.d7";
+        $d7->innerD7->innerD7 = $NS ? eval("return new Test\\D7;") : eval("return new Test_D7;");
+        $d7->innerD7->innerD7->sd7 = "d7.d7.d7";
+        $graphBase->right = $d7;
+
+        $result = $test->returnTest3($graphBase, $d7);
+        test($result != null);
+        test($result->left->sd6 == "d6.1");
+        test($result->left->innerD5 != null);
+        test($result->left->innerD5->sd5 == "d6.1.d5");
+        test($result->left->innerD5->pd5 != null);
+        test($result->left->innerD5->pd5->sb == "d6.1.d5.sb");
+        test($result->left->innerD5->pd5->pb != null);
+        test($result->left->innerD5->pd5->pb->sb == "d6.1.d5.sb.sb");
+
+        test($result->right->sd7 == "d7");
+        test($result->right->innerD7 != null);
+        test($result->right->innerD7->sd7 == "d7.d7");
+        test($result->right->innerD7->innerD7 != null);
+        test($result->right->innerD7->innerD7->sd7 == "d7.d7.d7");
+    }
+    echo "ok\n";
+
     echo "testing parameter pointer slicing with first instance marshaled in unknown derived as base... ";
     flush();
     {
diff --git a/php/test/Ice/slicing/objects/ClientPrivate.ice b/php/test/Ice/slicing/objects/ClientPrivate.ice
index 25a4b74..738e653 100644
--- a/php/test/Ice/slicing/objects/ClientPrivate.ice
+++ b/php/test/Ice/slicing/objects/ClientPrivate.ice
@@ -21,6 +21,41 @@ class D3 extends B
     B pd3;
 };
 
+unsliceable class D5 extends BU
+{
+    string sd5;
+    B pd5;
+};
+
+unsliceable class GraphBase extends BU
+{
+    BU left;
+    BU right;
+};
+
+unsliceable class D6 extends BU
+{
+    string sd6;
+    D5 innerD5;
+};
+
+unsliceable class D7 extends BU
+{
+    string sd7;
+    D7 innerD7;
+};
+
+class UnknownInner
+{
+    string ic;
+};
+
+unsliceable class D8 extends BU
+{
+    string sd8;
+    UnknownInner innerObj;
+};
+
 };
 
 #endif
diff --git a/php/test/Ice/slicing/objects/Test.ice b/php/test/Ice/slicing/objects/Test.ice
index caaf53f..1c8dbea 100644
--- a/php/test/Ice/slicing/objects/Test.ice
+++ b/php/test/Ice/slicing/objects/Test.ice
@@ -29,6 +29,10 @@ class B
     B pb;
 };
 
+unsliceable class BU extends B
+{
+};
+
 class D1 extends B
 {
     string sd1;
@@ -95,6 +99,7 @@ class Forward;          // Forward-declared class defined in another compilation
     B returnTest2(out B p2, out B p1);
     B returnTest3(B p1, B p2);
 
+    BSeq echoSeq(BSeq p1, out BSeq p2);
     SS sequenceTest(SS1 p1, SS2 p2);
 
     BDict dictionaryTest(BDict bin, out BDict bout);
diff --git a/py/modules/IcePy/Types.cpp b/py/modules/IcePy/Types.cpp
index f596948..846605a 100644
--- a/py/modules/IcePy/Types.cpp
+++ b/py/modules/IcePy/Types.cpp
@@ -2535,7 +2535,7 @@ IcePy::ObjectWriter::write(const Ice::OutputStreamPtr& os) const
             idOffset.offset = os->getWriteSliceOffset();
 
             member->type->marshal(val.get(), os, _map, &member->metaData);
-            if(info->isUnsliceable)
+            if(info->isUnsliceable && val.get() != Py_None)
             {
                 //
                 // To update the object id map, we need to:
@@ -2862,7 +2862,7 @@ IcePy::ExceptionInfo::marshal(PyObject* p, const Ice::OutputStreamPtr& os, Objec
             Ice::ObjectIdOffset idOffset;
             idOffset.offset = os->getWriteSliceOffset();
             member->type->marshal(val.get(), os, objectMap, &member->metaData);
-            if(info->isUnsliceable)
+            if(info->isUnsliceable && val.get() != Py_None)
             {
                 //
                 // To update the object id map, we need to:
diff --git a/py/test/Ice/slicing/objects/AllTests.py b/py/test/Ice/slicing/objects/AllTests.py
index 44d1701..3a40bb2 100644
--- a/py/test/Ice/slicing/objects/AllTests.py
+++ b/py/test/Ice/slicing/objects/AllTests.py
@@ -736,6 +736,7 @@ def allTests(communicator):
         test(False)
     print "ok"
 
+    
     print "return value unsliced for input params known first...",
     try:
         d1 = Test.D1()
@@ -749,6 +750,43 @@ def allTests(communicator):
         d1.pb = d5
         d1.pd1 = d5
 
+        b1 = t.returnTest3(d1, d5)
+
+        test(b1)
+        test(b1.sb == "D1.sb")
+        test(b1.ice_id() == "::Test::D1")
+        p3 = b1
+        test(isinstance(p3, Test.D1))
+        test(p3.sd1 == "D1.sd1")
+
+        b2 = b1.pb
+        test(b2)
+        test(b2.sb == "D5.sb")
+        test(b2.ice_id() == "::Test::D5")        # Not sliced by server
+        p1 = b2
+        test(isinstance(p1, Test.D5))
+
+        test(b1 != d1)
+        test(b1 != d3)
+        test(b2 != d1)
+        test(b2 != d3)
+    except Ice.Exception, e:
+        test(False)
+    print "ok"
+
+    print "return value unsliced for input params known first (AMI)...",
+    try:
+        d1 = Test.D1()
+        d1.sb = "D1.sb"
+        d1.sd1 = "D1.sd1"
+        d5 = Test.D5()
+        d5.pb = d1
+        d5.sb = "D5.sb"
+        d5.sd5 = "D5.sd5"
+        d5.pd5 = d1
+        d1.pb = d5
+        d1.pd1 = d5
+
         cb = Callback()
         t.begin_returnTest3(d1, d5, cb.response_returnTest3, cb.exception)
         cb.check()
@@ -789,6 +827,45 @@ def allTests(communicator):
         d1.pb = d5
         d1.pd1 = d5
 
+        b1 = t.returnTest3(d5, d1)
+
+        test(b1)
+        test(b1.sb == "D5.sb")
+        test(b1.ice_id() == "::Test::D5")        # Not sliced by server
+        p1 = b1
+        test(isinstance(p1, Test.D5))
+
+        b2 = b1.pb
+        test(b2)
+        test(b2.sb == "D1.sb")
+        test(b2.ice_id() == "::Test::D1")
+        test(b2.pb == b1)
+        p3 = b2
+        test(isinstance(p3, Test.D1))
+        test(p3.sd1 == "D1.sd1")
+        test(p3.pd1 == b1)
+
+        test(b1 != d1)
+        test(b1 != d3)
+        test(b2 != d1)
+        test(b2 != d3)
+    except Ice.Exception, e:
+        test(False)
+    print "ok"
+
+    print "return value unsliced for input params unknown first (AMI)...",
+    try:
+        d1 = Test.D1()
+        d1.sb = "D1.sb"
+        d1.sd1 = "D1.sd1"
+        d5 = Test.D5()
+        d5.pb = d1
+        d5.sb = "D5.sb"
+        d5.sd5 = "D5.sd5"
+        d5.pd5 = d1
+        d1.pb = d5
+        d1.pd1 = d5
+
         cb = Callback()
         t.begin_returnTest3(d5, d1, cb.response_returnTest3, cb.exception)
         cb.check()
@@ -869,6 +946,49 @@ def allTests(communicator):
     cb.check()
     print "ok"
 
+    print "object graphs of unsliceable objects...",
+    try:
+        graphBase = Test.GraphBase()
+        d6 = Test.D6()
+        d6.sd6 = "d6.1"
+        d6.innerD5 = Test.D5()
+        d6.innerD5.sd5 = "d6.1.d5"
+        d6.innerD5.pd5 = Test.B()
+        d6.innerD5.pd5.sb = "d6.1.d5.sb"
+        d6.innerD5.pd5.pb = Test.B()
+        d6.innerD5.pd5.pb.sb = "d6.1.d5.sb.sb"
+        graphBase.left = d6
+
+        d7 = Test.D7()
+        d7.sd7 = "d7"
+        d7.innerD7 = Test.D7()
+        d7.innerD7.sd7 = "d7.d7"
+        d7.innerD7.innerD7 = Test.D7()
+        d7.innerD7.innerD7.sd7 = "d7.d7.d7"
+        graphBase.right = d7
+
+        result = t.returnTest3(graphBase, d7)
+        test(result != None)
+        test(result.left.sd6 == "d6.1")
+        test(result.left.innerD5 != None)
+        test(result.left.innerD5.sd5 == "d6.1.d5")
+        test(result.left.innerD5.pd5 != None)
+        test(result.left.innerD5.pd5.sb == "d6.1.d5.sb")
+        test(result.left.innerD5.pd5.pb != None)
+        test(result.left.innerD5.pd5.pb.sb == "d6.1.d5.sb.sb")
+
+        test(result.right.sd7 == "d7")
+        test(result.right.innerD7 != None)
+        test(result.right.innerD7.sd7 == "d7.d7")
+        test(result.right.innerD7.innerD7 != None)
+        test(result.right.innerD7.innerD7.sd7 == "d7.d7.d7")
+        
+    except Ice.Exception,e:
+        print e
+        test(False)
+
+    print "ok"
+        
     print "param ptr slicing, instance marshaled in unknown derived as base... ",
     try:
         b1 = Test.B()
@@ -1115,21 +1235,14 @@ def allTests(communicator):
         test(ss.c2)
         ss2b = ss.c2.s[0]
         ss2d1 = ss.c2.s[1]
-        ss2d3 = ss.c2.s[2]
+        ss2d5 = ss.c2.s[2]
 
         test(ss1b.pb == ss1b)
         test(ss1d1.pb == ss1b)
 
-
         test(ss2b.pb == ss1b)
         test(ss2d1.pb == ss2b)
-        #
-        # Unsliceable objects are transformed internally
-        # when they are sent across the wire, resulting
-        # in different __hash__ values. A straight 
-        # object comparison will fail.
-        #
-        test(str(ss2d5.pb) == str(ss2b))
+        test(ss2d5.pb == ss2b)
 
         test(ss1b.ice_id() == "::Test::B")
         test(ss1d1.ice_id() == "::Test::D1")
diff --git a/py/test/Ice/slicing/objects/Server.py b/py/test/Ice/slicing/objects/Server.py
index b6eab65..c3cb31b 100755
--- a/py/test/Ice/slicing/objects/Server.py
+++ b/py/test/Ice/slicing/objects/Server.py
@@ -172,6 +172,9 @@ class TestI(Test.TestIntf):
     def returnTest3(self, p1, p2, current=None):
         return p1
 
+    def echoSeq(self, p1, current=None):
+        return (p1, p1)
+
     def sequenceTest(self, p1, p2, current=None):
         ss = Test.SS3()
         ss.c1 = p1
diff --git a/py/test/Ice/slicing/objects/Test.ice b/py/test/Ice/slicing/objects/Test.ice
index 4bf2ea8..07d6bb2 100644
--- a/py/test/Ice/slicing/objects/Test.ice
+++ b/py/test/Ice/slicing/objects/Test.ice
@@ -99,6 +99,7 @@ interface TestIntf
     B returnTest2(out B p2, out B p1);
     B returnTest3(B p1, B p2);
 
+    BSeq echoSeq(BSeq s1, out BSeq s2);
     SS3 sequenceTest(SS1 p1, SS2 p2);
 
     BDict dictionaryTest(BDict bin, out BDict bout);
diff --git a/rb/src/IceRuby/Types.cpp b/rb/src/IceRuby/Types.cpp
index 49be59b..203ff1b 100644
--- a/rb/src/IceRuby/Types.cpp
+++ b/rb/src/IceRuby/Types.cpp
@@ -1661,14 +1661,17 @@ IceRuby::ObjectWriter::write(const Ice::OutputStreamPtr& os) const
     Ice::ObjectIdMap idMap;
     if(info->isUnsliceable)
     {
-        VALUE obj = callRuby(rb_iv_get, _object, "@iceSlicedData");
-        if(obj)
+        if(callRuby(rb_ivar_defined, _object, rb_intern("@iceSlicedData")) != Qfalse)
         {
-            Ice::SlicedDataPtr* m = 0;
-            Data_Get_Struct(obj, Ice::SlicedDataPtr, m);
-            Ice::SlicedDataPtr slicedData = *m;
-            slicedData->transformPreserved(new SlicedObjectsTransform(_map));
-            slicedData->write(os, idMap, false);
+            VALUE obj = callRuby(rb_iv_get, _object, "@iceSlicedData");
+            if(obj)
+            {
+                Ice::SlicedDataPtr* m = 0;
+                Data_Get_Struct(obj, Ice::SlicedDataPtr, m);
+                Ice::SlicedDataPtr slicedData = *m;
+                slicedData->transformPreserved(new SlicedObjectsTransform(_map));
+                slicedData->write(os, idMap, false);
+            }
         }
     }
     while(info)
@@ -1690,7 +1693,7 @@ IceRuby::ObjectWriter::write(const Ice::OutputStreamPtr& os) const
             Ice::ObjectIdOffset idOffset;
             idOffset.offset = os->getWriteSliceOffset();
             member->type->marshal(val, os, _map);
-            if(info->isUnsliceable)
+            if(info->isUnsliceable && !NIL_P(val))
             {
                 ClassInfoPtr memberInfo = ClassInfoPtr::dynamicCast(member->type);
                 if(memberInfo != 0)
@@ -1920,12 +1923,15 @@ IceRuby::ExceptionInfo::marshal(VALUE p, const Ice::OutputStreamPtr& os, ObjectM
     Ice::ObjectIdMap idMap;
     if(info->isUnsliceable)
     {
-        VALUE obj = callRuby(rb_iv_get, p, "@iceSlicedData");
-        Ice::SlicedDataPtr* m = 0;
-        Data_Get_Struct(obj, Ice::SlicedDataPtr, m);
-        assert(m);
-        Ice::SlicedDataPtr slicedData = *m;
-        slicedData->write(os, idMap, false);
+        if(callRuby(rb_ivar_defined, p, rb_intern("@iceSlicedData")) != Qfalse)
+        {
+            VALUE obj = callRuby(rb_iv_get, p, "@iceSlicedData");
+            Ice::SlicedDataPtr* m = 0;
+            Data_Get_Struct(obj, Ice::SlicedDataPtr, m);
+            assert(m);
+            Ice::SlicedDataPtr slicedData = *m;
+            slicedData->write(os, idMap, false);
+        }
     }
 
     os->write(usesClasses);
@@ -1949,7 +1955,7 @@ IceRuby::ExceptionInfo::marshal(VALUE p, const Ice::OutputStreamPtr& os, ObjectM
             Ice::ObjectIdOffset idOffset;
             idOffset.offset = os->getWriteSliceOffset();
             member->type->marshal(val, os, objectMap);
-            if(info->isUnsliceable)
+            if(info->isUnsliceable && !NIL_P(val))
             {
                 ClassInfoPtr memberInfo = ClassInfoPtr::dynamicCast(member->type);
                 if(memberInfo != 0)
diff --git a/rb/test/Ice/slicing/objects/AllTests.rb b/rb/test/Ice/slicing/objects/AllTests.rb
index ff301ee..b60d1ea 100644
--- a/rb/test/Ice/slicing/objects/AllTests.rb
+++ b/rb/test/Ice/slicing/objects/AllTests.rb
@@ -342,6 +342,84 @@ def allTests(communicator)
     end
     puts "ok"
 
+    print "return value unsliced for input params known first..."
+    STDOUT.flush
+    begin
+        d1 = Test::D1.new
+        d1.sb = "D1.sb"
+        d1.sd1 = "D1.sd1"
+        d5 = Test::D5.new
+        d5.pb = d1
+        d5.sb = "D5.sb"
+        d5.sd5 = "D5.sd5"
+        d5.pd5 = d1
+        d1.pb = d5
+        d1.pd1 = d5
+
+        b1 = t.returnTest3(d1, d5)
+
+        test(b1)
+        test(b1.sb == "D1.sb")
+        test(b1.ice_id() == "::Test::D1")
+        p3 = b1
+        test(p3.is_a?(Test::D1))
+        test(p3.sd1 == "D1.sd1")
+
+        b2 = b1.pb
+        test(b2)
+        test(b2.sb == "D5.sb")
+        test(b2.ice_id() == "::Test::D5")        # Not sliced by server
+        p1 = b2
+        test(p1.is_a?(Test::D5))
+
+        test(b1 != d1)
+        test(b1 != d3)
+        test(b2 != d1)
+        test(b2 != d3)
+
+    rescue Ice::Exception
+        test(false)
+    end
+
+   print "return value unsliced for input params unknown first..."
+    STDOUT.flush
+    begin
+        d1 = Test::D1.new
+        d1.sb = "D1.sb"
+        d1.sd1 = "D1.sd1"
+        d5 = Test::D5.new
+        d5.pb = d1
+        d5.sb = "D5.sb"
+        d5.sd5 = "D5.sd5"
+        d5.pd5 = d1
+        d1.pb = d5
+        d1.pd1 = d5
+
+        b2 = t.returnTest3(d5, d1)
+
+        test(b2)
+        test(b2.sb == "D5.sb")
+        test(b2.ice_id() == "::Test::D5")        # Not sliced by server
+        p1 = b2
+        test(p1.is_a?(Test::D5))
+
+        b1 = d5.pb
+        test(b1)
+        test(b1.sb == "D1.sb")
+        test(b1.ice_id() == "::Test::D1")
+        p3 = b1
+        test(p3.is_a?(Test::D1))
+        test(p3.sd1 == "D1.sd1")
+
+        test(b1 != d5)
+        test(b1 != p1)
+        test(b2 != d1)
+        test(b2 != p3)
+
+    rescue Ice::Exception
+        test(false)
+    end
+
     print "remainder unmarshaling (3 instances)... "
     STDOUT.flush
     begin
@@ -385,6 +463,48 @@ def allTests(communicator)
     end
     puts "ok"
 
+    print "object graphs of unsliceable objects..."
+    STDOUT.flush
+    begin
+        graphBase = Test::GraphBase.new
+       d6 = Test::D6.new
+        d6.sd6 = "d6.1"
+        d6.innerD5 = Test::D5.new
+        d6.innerD5.sd5 = "d6.1.d5"
+        d6.innerD5.pd5 = Test::B.new
+        d6.innerD5.pd5.sb = "d6.1.d5.sb"
+        d6.innerD5.pd5.pb = Test::B.new
+        d6.innerD5.pd5.pb.sb = "d6.1.d5.sb.sb"
+        graphBase.left = d6
+
+        d7 = Test::D7.new
+        d7.sd7 = "d7"
+        d7.innerD7 = Test::D7.new
+        d7.innerD7.sd7 = "d7.d7"
+        d7.innerD7.innerD7 = Test::D7.new
+        d7.innerD7.innerD7.sd7 = "d7.d7.d7"
+        graphBase.right = d7
+
+        result = t.returnTest3(graphBase, d7)
+        test(result)
+        test(result.left.sd6 == "d6.1")
+        test(result.left.innerD5)
+        test(result.left.innerD5.sd5 == "d6.1.d5")
+        test(result.left.innerD5.pd5)
+        test(result.left.innerD5.pd5.sb == "d6.1.d5.sb")
+        test(result.left.innerD5.pd5.pb)
+        test(result.left.innerD5.pd5.pb.sb == "d6.1.d5.sb.sb")
+
+        test(result.right.sd7 == "d7")
+        test(result.right.innerD7)
+        test(result.right.innerD7.sd7 == "d7.d7")
+        test(result.right.innerD7.innerD7)
+        test(result.right.innerD7.innerD7.sd7 == "d7.d7.d7")
+  
+    rescue Ice::Exception
+        test(false)
+    end
+
     print "param ptr slicing, instance marshaled in unknown derived as base... "
     STDOUT.flush
     begin
@@ -521,6 +641,82 @@ def allTests(communicator)
     end
     puts "ok"
 
+    print "sequence with unsliceable objects... "
+    STDOUT.flush
+    begin
+        ss = Test::SS.new
+        ss1b = Test::B.new
+        ss1b.sb = "B.sb"
+        ss1b.pb = ss1b
+
+        ss1d1 = Test::D1.new
+        ss1d1.sb = "D1.sb"
+        ss1d1.sd1 = "D1.sd1"
+        ss1d1.pb = ss1b
+
+        ss1d5 = Test::D5.new
+        ss1d5.sb = "D5.sb"
+        ss1d5.sd5 = "D5.sd5"
+        ss1d5.pb = ss1b
+
+        ss2b = Test::B.new
+        ss2b.sb = "B.sb"
+        ss2b.pb = ss1b
+
+        ss2d1 = Test::D1.new
+        ss2d1.sb = "D1.sb"
+        ss2d1.sd1 = "D1.sd1"
+        ss2d1.pb = ss2b
+
+        ss2d5 = Test::D5.new
+        ss2d5.sb = "D5.sb"
+        ss2d5.sd5 = "D5.sd5"
+        ss2d5.pb = ss2b
+
+        ss1d1.pd1 = ss2b
+        ss1d5.pd5 = ss2d1
+
+        ss2d1.pd1 = ss1d3
+        ss2d5.pd5 = ss1d1
+
+        ss1 = Test::SS1.new
+        ss1.s = [ss1b, ss1d1, ss1d5]
+
+        ss2 = Test::SS2.new
+        ss2.s = [ss2b, ss2d1, ss2d5]
+
+        ss = t.sequenceTest(ss1, ss2)
+
+        test(ss.c1)
+        ss1b = ss.c1.s[0]
+        ss1d1 = ss.c1.s[1]
+        test(ss.c2)
+        ss1d3 = ss.c1.s[2]
+
+        test(ss.c2)
+        ss2b = ss.c2.s[0]
+        ss2d1 = ss.c2.s[1]
+        ss2d5 = ss.c2.s[2]
+
+        test(ss1b.pb == ss1b)
+        test(ss1d1.pb == ss1b)
+
+        test(ss2b.pb == ss1b)
+        test(ss2d1.pb == ss2b)
+        test(ss2d5.pb == ss2b)
+
+        test(ss1b.ice_id() == "::Test::B")
+        test(ss1d1.ice_id() == "::Test::D1")
+        test(ss1d5.ice_id() == "::Test::D5")
+
+        test(ss2b.ice_id() == "::Test::B")
+        test(ss2d1.ice_id() == "::Test::D1")
+        test(ss2d5.ice_id() == "::Test::D5")
+    rescue Ice::Exception
+        test(False)
+    end
+    print "ok\n"
+
     print "dictionary slicing... "
     STDOUT.flush
     begin
diff --git a/rb/test/Ice/slicing/objects/ClientPrivate.ice b/rb/test/Ice/slicing/objects/ClientPrivate.ice
index 25a4b74..742fd8d 100644
--- a/rb/test/Ice/slicing/objects/ClientPrivate.ice
+++ b/rb/test/Ice/slicing/objects/ClientPrivate.ice
@@ -21,6 +21,41 @@ class D3 extends B
     B pd3;
 };
 
+unsliceable class D5 extends BU
+{
+    string sd5;
+    B pd5;
+};
+
+unsliceable class GraphBase extends BU
+{
+    BU left;
+    BU right;
+};
+
+unsliceable class D6 extends BU
+{
+    string sd6;
+    D5 innerD5;
+};
+
+unsliceable class D7 extends BU
+{
+    string sd7;
+    D7 innerD7;
+};
+
+class UnknownInner
+{
+    string ic;
+};
+
+unsliceable class D8 extends BU
+{
+    string sd8;
+    UnknownInner innerObj;
+};
+    
 };
 
 #endif
diff --git a/rb/test/Ice/slicing/objects/Test.ice b/rb/test/Ice/slicing/objects/Test.ice
index caaf53f..8cfb2a5 100644
--- a/rb/test/Ice/slicing/objects/Test.ice
+++ b/rb/test/Ice/slicing/objects/Test.ice
@@ -29,6 +29,10 @@ class B
     B pb;
 };
 
+unsliceable class BU extends B
+{
+};
+
 class D1 extends B
 {
     string sd1;
@@ -95,6 +99,7 @@ class Forward;          // Forward-declared class defined in another compilation
     B returnTest2(out B p2, out B p1);
     B returnTest3(B p1, B p2);
 
+    BSeq echoSeq(BSeq s1, out BSeq s2);
     SS sequenceTest(SS1 p1, SS2 p2);
 
     BDict dictionaryTest(BDict bin, out BDict bout);

-----------------------------------------------------------------------


-- 
asterisk-scf/release/ice.git



More information about the asterisk-scf-commits mailing list